/** * API请求工具类 */ // 开发环境配置 // 真机调试时,请将 DEV_BASE_URL 改为你电脑的局域网IP地址 // 例如:const DEV_BASE_URL = 'http://192.168.1.3:8080' // 可以通过命令 ipconfig (Windows) 或 ifconfig (Mac/Linux) 查看IP地址 const DEV_BASE_URL = 'http://192.168.1.3:8080' // 生产环境配置(部署后的服务器地址) const PROD_BASE_URL = 'https://your-domain.com' // 根据环境自动选择BASE_URL // 在微信开发者工具中使用 localhost,真机调试使用局域网IP const BASE_URL = DEV_BASE_URL /** * 获取本地存储的token(避免循环依赖) */ const getToken = () => { return uni.getStorageSync('user_token') || null } /** * 统一请求封装 * 自动添加token到请求头 * @param {object} options - 请求配置对象 * @returns {Promise} 请求Promise */ const request = (options) => { return new Promise((resolve, reject) => { // 获取token并添加到请求头 const token = getToken() const header = options.header || {} if (token) { header['Authorization'] = `Bearer ${token}` } uni.request({ url: `${BASE_URL}${options.url}`, method: options.method || 'GET', data: options.data || {}, header: header, success: (res) => { // 统一处理响应 if (res.statusCode === 200) { resolve(res.data) } else if (res.statusCode === 401) { // token过期或未登录 uni.showToast({ title: '登录已过期,请重新登录', icon: 'none', duration: 2000 }) // 清除token uni.removeStorageSync('user_token') uni.removeStorageSync('user_info') // 延迟后显示登录弹窗 setTimeout(() => { uni.showModal({ title: '登录提示', content: '登录已过期,请前往"模拟排名"或"强势池"页面重新登录', confirmText: '去登录', cancelText: '取消', success: (modalRes) => { if (modalRes.confirm) { // 跳转到模拟排名页面 uni.switchTab({ url: '/pages/rank/rank' }) } } }) }, 2000) reject(new Error('未授权')) } else { reject(new Error(res.data.message || '服务暂不可用')) } }, fail: (err) => { reject(new Error('网络异常')) } }) }) } /** * 第一步:微信静默登录接口(检查是否为老用户) * @param {object} params - { loginCode } * @returns {Promise} 返回 { isSign, token?, code? } */ export const wxSilentLoginApi = (params) => { return request({ url: '/v1/auth/wx/silent-login', method: 'POST', header: { 'content-type': 'application/json' }, data: params }) } /** * 第二步:手机号授权登录接口(新用户验证手机号) * @param {object} params - { loginCode, phoneCode, encryptedData, iv } * @returns {Promise} 返回 { isSign, token?, openid?, unionid?, phoneNumber? } */ export const wxPhoneLoginApi = (params) => { return request({ url: '/v1/auth/wx/phone-verify', method: 'POST', header: { 'content-type': 'application/json' }, data: params }) } /** * 第三步:完善用户信息接口(首次登录) * @param {object} params - { openid, unionid, phoneNumber, nickname, avatarUrl } * @returns {Promise} 返回 { token } */ export const wxCompleteUserInfoApi = (params) => { return request({ url: '/v1/auth/wx/register', method: 'POST', header: { 'content-type': 'application/json' }, data: params }) } /** * 获取用户完整信息接口 * @returns {Promise} 返回用户信息 */ export const getUserInfoApi = () => { return request({ url: '/v1/user/info', method: 'GET' }) } /** * 文件上传配置 */ export const uploadFile = { url: `${BASE_URL}/v1/file/upload` } /** * 更新用户资料 * @param {object} data - 用户资料 * @param {string} data.nickname - 昵称 * @param {string} data.avatar - 头像URL * @returns {Promise} 返回更新结果 */ export const updateUserProfile = (data) => { return request({ url: '/v1/user/profile', method: 'PUT', header: { 'content-type': 'application/json' }, data: data }) } /** * 模糊搜索(联想建议) * @param {string} keyword - 搜索关键词 * @returns {Promise} 返回搜索建议列表 */ export const getSuggestions = (keyword) => { return request({ url: '/v1/stock/suggestion', method: 'GET', data: { keyword } }) } /** * 股票详情查询 * @param {string} keyword - 股票代码或名称 * @returns {Promise} 返回股票详情信息 */ export const searchStocks = (keyword) => { return request({ url: '/v1/stock/search', method: 'POST', header: { 'content-type': 'application/json' }, data: { keyword } }) } /** * 获取用户模拟资产(需要登录) * @returns {Promise} 返回用户资产信息 */ export const getUserPortfolio = () => { return request({ url: '/v1/user/portfolio', method: 'GET' }) } /** * 获取模拟交易排行榜 * @returns {Promise} 返回排行榜数据 */ export const getLeaderboard = () => { return request({ url: '/v1/rank/leaderboard', method: 'GET' }) }