Files
ai_dianshang/web/assets/js/api.js
2025-11-28 15:18:10 +08:00

589 lines
17 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// API接口调用模块
// 环境检测函数
function getAPIBaseURL() {
// 优先使用 localStorage 中的手动配置(用于调试)
const manualBaseURL = localStorage.getItem('API_BASE_URL');
if (manualBaseURL) {
console.log('[API] 使用手动配置的后端地址:', manualBaseURL);
return manualBaseURL;
}
const hostname = window.location.hostname;
const protocol = window.location.protocol;
// 开发环境判断localhost 或 127.0.0.1
if (hostname === 'localhost' || hostname === '127.0.0.1') {
return 'http://localhost:8081/api/v1';
}
// 生产环境根据域名映射API地址
// vizee.cn 域名使用 https://tral.cc/api/v1
if (hostname.includes('vizee.cn')) {
console.log('[API] 检测到 vizee.cn 域名,使用 tral.cc API');
return 'https://tral.cc/api/v1';
}
// gvizee.com 域名使用相对路径,由 Nginx 代理到后端
if (hostname.includes('gvizee.com')) {
console.log('[API] 检测到 gvizee.com 域名,使用 Nginx 代理');
// 使用相对路径自动继承当前页面的协议HTTPS
// Nginx 会将 /api/v1 请求代理到 http://104.244.91.212:8060/api/v1
return '/api/v1';
}
// 默认使用 tral.cc
console.log('[API] 使用默认 API 地址: tral.cc');
return 'https://tral.cc/api/v1';
}
// API配置
const API_CONFIG = {
baseURL: getAPIBaseURL(),
timeout: 30000,
headers: {
'Content-Type': 'application/json'
},
// 环境信息
env: {
isDevelopment: window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1',
isProduction: window.location.hostname !== 'localhost' && window.location.hostname !== '127.0.0.1'
}
};
// 控制台输出当前环境信息
console.log('[API] 当前环境:', API_CONFIG.env.isDevelopment ? '开发环境' : '生产环境');
console.log('[API] 后端地址:', API_CONFIG.baseURL);
// 全局辅助函数(用于开发调试)
window.API_DEBUG = {
// 设置后端地址
setBaseURL: function(url) {
localStorage.setItem('API_BASE_URL', url);
console.log('[API] 后端地址已设置为:', url);
console.log('[API] 请刷新页面使配置生效');
},
// 重置为自动检测
resetBaseURL: function() {
localStorage.removeItem('API_BASE_URL');
console.log('[API] 已重置为自动检测模式');
console.log('[API] 请刷新页面使配置生效');
},
// 查看当前配置
getConfig: function() {
return {
baseURL: API_CONFIG.baseURL,
environment: API_CONFIG.env.isDevelopment ? 'development' : 'production',
manualConfig: localStorage.getItem('API_BASE_URL') || 'auto',
currentURL: window.location.href
};
},
// 测试连接
testConnection: function() {
console.log('[API] 测试后端连接...');
fetch(API_CONFIG.baseURL.replace('/api/v1', '/health'))
.then(response => response.json())
.then(data => {
console.log('[API] ✅ 后端连接成功:', data);
})
.catch(error => {
console.error('[API] ❌ 后端连接失败:', error.message);
console.log('[API] 请确认后端服务已启动');
});
},
// 使用说明
help: function() {
console.log(`
=== API调试工具使用说明 ===
域名映射规则:
- vizee.cn 域名使用: https://tral.cc/api/v1
- gvizee.com 域名使用: https://104.244.91.212:8060/api/v1
- localhost/127.0.0.1 使用: http://localhost:8081/api/v1
- 其他域名默认使用: https://tral.cc/api/v1
1. 查看当前配置:
API_DEBUG.getConfig()
2. 手动设置后端地址:
API_DEBUG.setBaseURL('http://localhost:8080/api/v1')
API_DEBUG.setBaseURL('https://api.example.com/api/v1')
3. 重置为自动检测:
API_DEBUG.resetBaseURL()
4. 测试后端连接:
API_DEBUG.testConnection()
5. 查看帮助:
API_DEBUG.help()
`);
}
};
// 启动时提示
if (API_CONFIG.env.isDevelopment) {
console.log('[API] 💡 开发提示:在控制台输入 API_DEBUG.help() 查看调试工具使用说明');
}
// API模块
const API = {
// 获取Token
getToken: function() {
const user = localStorage.getItem('currentUser');
if (user) {
try {
const userData = JSON.parse(user);
return userData.token || '';
} catch (e) {
return '';
}
}
return '';
},
// 设置Token
setToken: function(token) {
const user = localStorage.getItem('currentUser');
if (user) {
try {
const userData = JSON.parse(user);
userData.token = token;
localStorage.setItem('currentUser', JSON.stringify(userData));
} catch (e) {
console.error('设置Token失败:', e);
}
}
},
// 通用请求方法
request: function(options) {
const url = API_CONFIG.baseURL + options.url;
const method = options.method || 'GET';
const data = options.data || null;
const headers = Object.assign({}, API_CONFIG.headers, options.headers || {});
// 添加认证Token
const token = this.getToken();
if (token) {
headers['Authorization'] = 'Bearer ' + token;
}
const ajaxOptions = {
url: url,
method: method,
headers: headers,
timeout: API_CONFIG.timeout,
xhrFields: {
withCredentials: true
}
};
// 添加数据
if (data) {
if (method === 'GET') {
ajaxOptions.data = data;
} else {
ajaxOptions.data = JSON.stringify(data);
}
}
// 返回Promise
return new Promise((resolve, reject) => {
$.ajax(ajaxOptions)
.done(function(response) {
// 检查响应格式
if (response && response.code === 200) {
resolve(response.data);
} else {
reject(response);
}
})
.fail(function(xhr, status, error) {
// 处理错误
const errorMsg = xhr.responseJSON?.message || error || '网络请求失败';
// 401未授权提示并跳转登录
if (xhr.status === 401) {
// 判断是未登录还是登录过期
const hadToken = !!localStorage.getItem('currentUser');
const message = hadToken ? '登录已过期,请重新登录' : '请先登录';
console.log('[401 拦截]', message);
// 清除登录状态
localStorage.removeItem('currentUser');
// 使用 Toast.alert 显示提示iOS 风格)
if (typeof Toast !== 'undefined' && Toast.alert) {
Toast.alert(message).then(() => {
// 用户点击确定后跳转
handleRedirectToLogin();
});
} else if (typeof Toast !== 'undefined' && Toast.warning) {
// 降级使用 warning
Toast.warning(message);
setTimeout(handleRedirectToLogin, 2000);
} else {
// 最后降级使用原生 alert
alert(message);
handleRedirectToLogin();
}
// 跳转逻辑封装
function handleRedirectToLogin() {
console.log('[401 跳转] 准备跳转登录页');
// 记录当前页面,登录后可以返回(排除登录页和用户中心)
const currentPage = window.location.pathname + window.location.search;
const shouldRedirect = !currentPage.includes('login.html') &&
!currentPage.includes('user-center.html');
if (shouldRedirect) {
localStorage.setItem('redirectUrl', currentPage);
console.log('[401 跳转] 保存 redirectUrl:', currentPage);
} else {
// 确保清除之前的redirectUrl
localStorage.removeItem('redirectUrl');
console.log('[401 跳转] 不保存 redirectUrl');
}
window.location.href = 'login.html';
}
reject({
code: 401,
message: message,
data: xhr.responseJSON
});
return;
}
reject({
code: xhr.status,
message: errorMsg,
data: xhr.responseJSON
});
});
});
},
// GET请求
get: function(url, params) {
return this.request({
url: url,
method: 'GET',
data: params
});
},
// POST请求
post: function(url, data) {
return this.request({
url: url,
method: 'POST',
data: data
});
},
// PUT请求
put: function(url, data) {
return this.request({
url: url,
method: 'PUT',
data: data
});
},
// DELETE请求
delete: function(url, data) {
return this.request({
url: url,
method: 'DELETE',
data: data
});
}
};
// 价格工具函数
const PriceUtils = {
/**
* 将后端返回的价格(分)转换为前端显示的价格(元)
* @param {number} price - 以分为单位的价格
* @returns {number} - 以元为单位的价格
*/
fenToYuan: function(price) {
return (price || 0) / 100;
},
/**
* 将前端输入的价格(元)转换为后端需要的价格(分)
* @param {number} price - 以元为单位的价格
* @returns {number} - 以分为单位的价格
*/
yuanToFen: function(price) {
return Math.round((price || 0) * 100);
},
/**
* 格式化价格显示(带货币符号)
* @param {number} price - 以分为单位的价格
* @param {string} currency - 货币符号,默认为¥
* @returns {string} - 格式化后的价格字符串
*/
formatPrice: function(price, currency = '¥') {
return currency + this.fenToYuan(price).toFixed(2);
}
};
// 具体业务API
const UserAPI = {
// 用户登录(邮箱密码)
login: function(email, password) {
return API.post('/users/email-login', {
email: email,
password: password
});
},
// 用户注册(邮箱密码)
register: function(email, password, nickname) {
return API.post('/users/email-register', {
email: email,
password: password,
nickname: nickname
});
},
// 获取用户信息
getProfile: function() {
return API.get('/users/profile');
},
// 更新用户信息
updateProfile: function(data) {
return API.put('/users/profile', data);
},
// 获取地址列表
getAddresses: function() {
return API.get('/users/addresses');
},
// 添加地址
addAddress: function(data) {
return API.post('/users/addresses', data);
},
// 更新地址
updateAddress: function(id, data) {
return API.put('/users/addresses/' + id, data);
},
// 删除地址
deleteAddress: function(id) {
return API.delete('/users/addresses/' + id);
}
};
const ProductAPI = {
// 获取商品列表
getList: function(params) {
return API.get('/products', params);
},
// 获取商品详情
getDetail: function(id) {
return API.get('/products/' + id);
},
// 获取热门商品
getHot: function() {
return API.get('/products/hot');
},
// 获取推荐商品
getRecommend: function() {
return API.get('/products/recommend');
},
// 搜索商品
search: function(keyword) {
return API.get('/products/search', { keyword: keyword });
},
// 获取商品评价
getReviews: function(id, params) {
return API.get('/products/' + id + '/reviews', params);
},
// 获取分类列表
getCategories: function() {
return API.get('/products/categories', { platform: 'web' });
}
};
const CartAPI = {
// 获取购物车
getCart: function() {
return API.get('/cart');
},
// 添加到购物车
addToCart: function(productId, skuId, quantity) {
return API.post('/cart', {
product_id: productId,
sku_id: skuId,
quantity: quantity
});
},
// 更新购物车数量
updateQuantity: function(productId, quantity) {
return API.put('/cart/' + productId, {
quantity: quantity
});
},
// 删除购物车商品
removeItem: function(productId) {
return API.delete('/cart/' + productId);
},
// 清空购物车
clearCart: function() {
return API.delete('/cart');
},
// 获取购物车数量
getCount: function() {
return API.get('/cart/count');
}
};
const OrderAPI = {
// 创建订单
createOrder: function(data) {
return API.post('/orders', data);
},
// 获取订单列表
getList: function(params) {
return API.get('/orders', params);
},
// 获取订单详情
getDetail: function(id) {
return API.get('/orders/' + id);
},
// 取消订单
cancelOrder: function(id, reason) {
return API.post('/orders/' + id + '/cancel', {
reason: reason
});
},
// 确认收货
confirmReceive: function(id) {
return API.post('/orders/' + id + '/confirm');
}
};
const BannerAPI = {
// 获取轮播图
getList: function() {
return API.get('/banners');
}
};
const CouponAPI = {
// 获取可用优惠券
getAvailable: function() {
return API.get('/coupons');
},
// 获取我的优惠券
getMyCoupons: function(status) {
return API.get('/coupons/user', { status: status });
},
// 领取优惠券
receive: function(id) {
return API.post('/coupons/' + id + '/receive');
}
};
const CommentAPI = {
// 获取商品评论
getProductComments: function(productId, params) {
return API.get('/comments/products/' + productId, params);
},
// 获取评论统计
getStats: function(productId) {
return API.get('/comments/products/' + productId + '/stats');
},
// 创建评论
create: function(data) {
return API.post('/comments', data);
}
};
const UploadAPI = {
// 上传图片
uploadImage: function(file) {
const formData = new FormData();
formData.append('file', file);
return new Promise((resolve, reject) => {
const token = API.getToken();
$.ajax({
url: API_CONFIG.baseURL + '/upload/image',
method: 'POST',
data: formData,
processData: false,
contentType: false,
headers: {
'Authorization': 'Bearer ' + token
},
xhrFields: {
withCredentials: true
}
})
.done(function(response) {
if (response && response.code === 200) {
resolve(response.data);
} else {
reject(response);
}
})
.fail(function(xhr, status, error) {
reject({
code: xhr.status,
message: xhr.responseJSON?.message || error,
data: xhr.responseJSON
});
});
});
}
};
const LiveStreamAPI = {
// 获取启用的投流源
getActiveLiveStreams: function() {
return API.get('/livestreams');
},
// 增加观看次数
incrementViewCount: function(id) {
return API.post('/livestreams/' + id + '/view');
}
};