// 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'); } };