/** * API服务层 * 封装所有后端API调用 */ const config = require('../config/index') // ==================== 请求封装 ==================== /** * 基础请求方法 * @param {string} url - API路径 * @param {object} options - 请求选项 * @returns {Promise} */ const request = (url, options = {}) => { return new Promise((resolve, reject) => { const token = wx.getStorageSync(config.STORAGE_KEYS.TOKEN) wx.request({ url: config.API_BASE_URL + url, method: options.method || 'GET', data: options.data, timeout: config.REQUEST_TIMEOUT, header: { 'Authorization': token ? `Bearer ${token}` : '', 'Content-Type': 'application/json', // 注意:x-user-id 已废弃,后端通过 Token 验证用户身份 ...options.header }, success: (res) => { // 始终打印简短的请求和响应信息用于调试 console.log(`[API] ${options.method || 'GET'} ${url} -> ${res.statusCode}`) // 如果返回的是 HTML (通常是 404 页面),打印简短提示而非全文 const isHtml = typeof res.data === 'string' && res.data.trim().startsWith(' { console.error(`[API Error] ${url}`, err) // 不自动显示toast,让调用方处理错误 reject({ code: -1, message: '网络错误', errMsg: err.errMsg || 'request:fail', error: err }) } }) }) } /** * 文件上传 * @param {string} filePath - 本地文件路径 * @param {string} folder - 存储目录 (avatar/image/audio) * @returns {Promise} */ const uploadFile = (filePath, folder = 'uploads') => { return new Promise((resolve, reject) => { console.log('[uploadFile] ========== 开始上传任务 ==========') console.log('[uploadFile] 文件路径:', filePath) console.log('[uploadFile] 目标目录:', folder) // 验证目录是否合法,不合法则使用默认的 uploads const allowedFolders = ['uploads', 'image', 'images', 'avatars', 'characters', 'audio', 'documents', 'temp', 'assets'] if (!allowedFolders.includes(folder)) { console.warn(`[uploadFile] 目录 "${folder}" 不在允许列表中,将使用 "uploads"`) folder = 'uploads' } const token = wx.getStorageSync(config.STORAGE_KEYS.TOKEN) const userId = wx.getStorageSync(config.STORAGE_KEYS.USER_ID) const deviceId = wx.getStorageSync('deviceId') || userId || 'unknown' // 始终包含 x-device-id,如果有 token 则包含 Authorization const header = { 'x-device-id': deviceId } if (token) { header['Authorization'] = `Bearer ${token}` console.log('[uploadFile] 使用Token认证') } else { header['x-device-id'] = deviceId console.log('[uploadFile] 使用DeviceId认证:', deviceId) } wx.uploadFile({ url: config.API_BASE_URL + '/upload', filePath: filePath, name: 'file', formData: { folder }, header: header, success: (res) => { console.log('[uploadFile] ========== 上传响应 ==========') console.log('[uploadFile] 状态码:', res.statusCode) console.log('[uploadFile] 响应头:', JSON.stringify(res.header)) console.log('[uploadFile] 响应体:', res.data) if (res.statusCode === 200) { try { const data = JSON.parse(res.data) console.log('[uploadFile] 解析后的数据:', JSON.stringify(data)) // 兼容两种响应格式 if (data.code === 0 && data.data) { console.log('[uploadFile] ✓ 上传成功 (code=0):', data.data.url) resolve({ success: true, data: data.data }) } else if (data.success && data.data) { console.log('[uploadFile] ✓ 上传成功 (success=true):', data.data.url) resolve(data) } else { const errMsg = data.message || '上传失败' console.error('[uploadFile] ✗ 业务错误:', errMsg) reject({ code: data.code || -1, message: errMsg }) } } catch (e) { console.error('[uploadFile] ✗ 解析响应JSON失败:', e) reject({ code: -1, message: '服务器响应格式错误' }) } } else if (res.statusCode === 500) { let errorData = {} try { errorData = JSON.parse(res.data) } catch (e) {} console.error('[uploadFile] ✗ 服务器内部错误 (500):', errorData) reject({ code: 500, message: errorData.message || '服务器内部错误,请稍后重试', detail: errorData }) } else if (res.statusCode === 413) { console.error('[uploadFile] ✗ 文件太大 (413)') reject({ code: 413, message: '文件太大,请选择较小的图片' }) } else if (res.statusCode === 401 || res.statusCode === 403) { console.error('[uploadFile] ✗ 权限错误 (401/403)') reject({ code: res.statusCode, message: '权限不足,请重新登录' }) } else { console.error('[uploadFile] ✗ HTTP错误:', res.statusCode) reject({ code: res.statusCode, message: `上传失败 (${res.statusCode})` }) } }, fail: (err) => { console.error('[uploadFile] ✗ wx.uploadFile 接口调用失败:', err) reject({ code: -1, message: '网络连接失败,请检查网络' }) } }) }) } // ==================== 认证模块 API ==================== const auth = { /** * 发送短信验证码 * @param {string} phone - 手机号 */ sendSms: (phone) => request('/auth/send-sms', { method: 'POST', data: { phone } }), /** * 手机号登录 * @param {string} phone - 手机号 * @param {string} code - 验证码 */ phoneLogin: (phone, code) => request('/auth/phone-login', { method: 'POST', data: { phone, code } }), /** * 微信手机号快速登录 * @param {string} code - 微信getPhoneNumber返回的code */ wxPhoneLogin: (code, loginCode) => request('/auth/wx-phone-login', { method: 'POST', data: { code, loginCode } }), /** * 微信登录 * @param {string} code - 微信登录code * @param {object} userInfo - 用户信息(可选) */ wxLogin: (code, userInfo = null) => request('/auth/wx-login', { method: 'POST', data: { code, userInfo } }), /** * 获取当前用户信息 */ getCurrentUser: () => request('/auth/me'), /** * 退出登录 */ logout: () => request('/auth/logout', { method: 'POST' }) } // ==================== 用户模块 API ==================== const user = { /** * 获取用户资料 */ getProfile: () => request('/users/profile'), /** * 更新用户资料 * @param {object} data - 用户资料 */ updateProfile: (data) => request('/users/profile', { method: 'PUT', data }), /** * 获取用户余额 * 注意:后端通过 Token 验证用户身份,不再需要传递 userId */ getBalance: () => request('/user/balance'), /** * 获取余额历史 * @param {object} params - 分页参数 * 注意:后端通过 Token 验证用户身份,不再需要传递 userId */ getBalanceHistory: (params = {}) => request('/user/balance/history', { data: params }), /** * 绑定手机号(微信授权方式) * @param {object} data - { code: 微信授权code } */ bindPhone: (data) => request('/users/bindPhone', { method: 'POST', data: data }), /** * 获取用户记忆/档案 * @param {string} characterId - 角色ID(可选) */ getMemories: (characterId = null) => { const params = characterId ? { character_id: characterId } : {} return request('/memory/memories', { data: params }) }, /** * 获取用户档案 */ getMemoryProfile: () => request('/memory/profile') } // ==================== 角色模块 API ==================== const character = { /** * 获取角色列表 * @param {object} params - 查询参数 { page, limit, gender, category } */ getList: (params = {}) => request('/characters', { data: { page: 1, limit: 20, ...params } }), /** * 获取角色详情 * @param {string} id - 角色ID */ getDetail: (id) => request(`/characters/${id}`), /** * 随机推荐角色 * @param {number} count - 数量 * @param {object} options - 可选参数 * @param {Array} options.excludeIds - 排除的角色ID列表 * @param {string} options.gender - 性别筛选 (male/female) */ getRandom: (count = 6, options = {}) => { const params = { count } if (options.excludeIds && options.excludeIds.length > 0) { params.excludeIds = options.excludeIds.join(',') } if (options.gender) { params.gender = options.gender } return request('/characters/random', { data: params }) }, /** * 喜欢/取消喜欢角色 * @param {string} id - 角色ID */ toggleLike: (id) => request(`/characters/${id}/like`, { method: 'POST' }), /** * 获取喜欢的角色列表 */ getLikedList: () => request('/characters/liked'), /** * 解锁角色 * @param {object} data - { character_id, unlock_type: 'hearts'|'payment' } */ unlock: (data) => request('/characters/unlock', { method: 'POST', data }), /** * 检查角色是否已解锁 * @param {string} id - 角色ID */ checkUnlockStatus: (id) => request(`/characters/${id}/unlock-status`, { silent: true }) } // ==================== 聊天模块 API ==================== const chat = { /** * 发送AI聊天消息(使用简化版非流式API) * @param {object} data - { character_id, message, conversation_id } */ sendMessage: (data) => request('/chat/simple', { method: 'POST', data }), /** * 获取聊天配额状态 * @param {string} characterId - 角色ID */ getQuota: (characterId) => request('/chat/quota', { data: { character_id: characterId }, silent: true }), /** * 消费聊天配额 * @param {string} characterId - 角色ID */ consumeQuota: (characterId) => request('/chat/quota/consume', { method: 'POST', data: { character_id: characterId } }), /** * 获取会话列表 * 注意:后端通过 Token 验证用户身份,不再需要传递 userId */ getConversations: () => request('/conversations', { silent: true }), /** * 删除会话 * @param {string} conversationId - 会话ID * 注意:后端通过 Token 验证用户身份,不再需要传递 userId */ deleteConversation: (conversationId) => request(`/conversations/${conversationId}`, { method: 'DELETE' }), /** * 清空聊天记录(保留会话) * @param {string} characterId - 角色ID * 注意:只清空聊天记录,会话仍然显示在消息列表中 * 使用后端提供的 /api/memory/chat-history/by-character 接口 */ clearChatHistory: (characterId) => request(`/memory/chat-history/by-character?character_id=${characterId}&action=clear`, { method: 'POST' }), /** * 创建会话 * @param {string} characterId - 角色ID * 注意:后端通过 Token 验证用户身份,不再需要传递 userId */ createConversation: (characterId) => request('/conversations', { method: 'POST', data: { targetId: characterId, targetType: 'character' } }), /** * 获取聊天历史(通过会话ID) * @param {string} conversationId - 会话ID * @param {object} params - 分页参数 */ getChatHistory: (conversationId, params = {}) => request('/memory/chat-history', { data: { conversation_id: conversationId, ...params } }), /** * 获取聊天历史(通过角色ID) * @param {string} characterId - 角色ID * @param {object} params - 分页参数 * 注意:后端通过 Token 验证用户身份,不再需要传递 userId */ getChatHistoryByCharacter: (characterId, params = {}) => { // 手动构建查询参数字符串(微信小程序不支持 URLSearchParams) const queryParts = [`character_id=${encodeURIComponent(characterId)}`] // 添加其他参数 Object.keys(params).forEach(key => { if (params[key] !== undefined && params[key] !== null) { queryParts.push(`${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`) } }) const queryString = queryParts.join('&') const fullUrl = `/memory/chat-history/by-character?${queryString}` console.log('[API] getChatHistoryByCharacter 请求URL:', fullUrl) console.log('[API] characterId:', characterId, 'params:', params) return request(fullUrl, { method: 'GET', silent: true // 静默模式,401时不清除登录状态 }) }, /** * 标记会话已读 * @param {string} conversationId - 会话ID */ markAsRead: (conversationId) => request(`/conversations/${conversationId}/read`, { method: 'POST', silent: true // 静默模式,401时不弹出登录提示 }), /** * 切换聊天模式(AI/真人) * @param {string} conversationId - 会话ID * @param {string} mode - 模式 (ai/human) */ switchMode: (conversationId, mode) => request(`/conversations/${conversationId}/switch-mode`, { method: 'POST', data: { mode } }), /** * 发送图片消息 * @param {object} data - { character_id, conversation_id, image_url } */ sendImage: (data) => request('/chat/send-image', { method: 'POST', data }), /** * 获取免费畅聊时间 */ getFreeTime: () => request('/chat/free-time', { silent: true }), /** * 领取免费畅聊时间 */ claimFreeTime: () => request('/chat/free-time/claim', { method: 'POST' }) } // ==================== 陪聊模块 API ==================== const companion = { /** * 发送陪聊消息 * @param {object} data - { order_id, message } */ sendMessage: (data) => request('/companion-chat', { method: 'POST', data }), /** * 获取陪聊师列表 * 返回数据包含等级信息:levelCode, levelName, textPrice, voicePrice * @param {object} params - 查询参数 { status, gender, sortBy, page, pageSize } */ getList: (params = {}) => request('/companions', { data: { page: 1, pageSize: 20, ...params } }), /** * 获取陪聊师详情 * 返回数据包含等级信息:levelCode, levelName, textPrice, voicePrice * @param {string} id - 陪聊师ID */ getDetail: (id) => request(`/companions/${id}`), /** * 获取陪聊师状态(包含等级信息) * 返回数据包含:isCompanion, companionId, levelCode, levelName, textPrice, voicePrice * 注意:后端通过 Token 验证用户身份,不再需要传递 userId */ getStatus: () => request('/companion/status'), /** * 更新在线状态 * @param {string} status - 状态 (online/busy/offline) * 注意:后端通过 Token 验证用户身份,不再需要传递 userId */ updateStatus: (status) => request('/companion/status', { method: 'POST', data: { status } }), /** * 获取申请状态 * 注意:后端通过 Token 验证用户身份,不再需要传递 userId */ getApplyStatus: () => request('/companion/apply'), /** * 申请成为陪聊师 * @param {object} data - 申请资料 * 注意:后端通过 Token 验证用户身份,不再需要传递 userId */ apply: (data) => request('/companion/apply', { method: 'POST', data }), /** * AI辅助回复 * @param {object} data - { message, context } */ aiAssist: (data) => request('/companion/ai-assist', { method: 'POST', data }), /** * 获取工作台数据(包含等级信息) * 返回数据包含:levelCode, levelName, textPrice, voicePrice * 注意:后端通过 Token 验证用户身份,不再需要传递 userId */ getWorkbench: () => request('/companion/workbench'), /** * 获取客户列表 * @param {object} params - 查询参数 { keyword, page, pageSize } */ getCustomers: (params = {}) => request('/companion/customers', { data: params }), /** * 获取陪聊师订单列表 * @param {object} params - 查询参数 { status, page, pageSize } */ getOrders: (params = {}) => request('/companion/orders', { data: params }), /** * 获取陪聊师订单统计 */ getOrderStats: () => request('/companion/orders/stats'), /** * 获取所有等级配置 * 返回等级列表:[{ levelCode, levelName, textPrice, voicePrice }] */ getLevels: () => request('/companion/levels'), /** * 获取陪聊师评价列表 * @param {string} companionId - 陪聊师ID * @param {object} params - 查询参数 { page, limit } */ getReviews: (companionId, params = {}) => request(`/companions/${companionId}/reviews`, { data: { page: 1, limit: 10, ...params } }), /** * 点赞评价 * @param {string} reviewId - 评价ID */ likeReview: (reviewId) => request(`/reviews/${reviewId}/like`, { method: 'POST' }), /** * 陪聊师回复评价 * @param {string} reviewId - 评价ID * @param {string} reply - 回复内容 */ replyReview: (reviewId, reply) => request(`/reviews/${reviewId}/reply`, { method: 'POST', data: { reply } }) } // ==================== 语音合成 API ==================== const tts = { /** * 文字转语音 * @param {object} data - { text, voice_id, character_id } */ synthesize: (data) => request('/tts', { method: 'POST', data }), /** * 查询TTS状态 * @param {string} taskId - 任务ID */ getStatus: (taskId) => request('/tts/status', { data: { task_id: taskId } }) } // ==================== 语音识别 API ==================== const speech = { /** * 语音识别 - 将语音转换为文字 * @param {object} data - { audio: base64编码的音频, format: 音频格式(mp3/wav/pcm) } * @returns {Promise<{success: boolean, data: {text: string}}>} */ recognize: (data) => request('/speech/recognize', { method: 'POST', data }) } // ==================== 支付模块 API ==================== const payment = { /** * 获取充值套餐 */ getPackages: () => request('/payment/packages'), /** * 创建充值订单 * @param {object} data - { packageId, amount, paymentMethod } */ createRechargeOrder: (data) => request('/payment/recharge', { method: 'POST', data }), /** * 创建VIP订单 * @param {object} data - { planId, duration, paymentMethod } */ createVipOrder: (data) => request('/payment/vip', { method: 'POST', data }), /** * 获取支付参数(统一下单) * @param {object} data - { orderId, orderType } */ prepay: (data) => request('/payment/prepay', { method: 'POST', data }), /** * 查询订单状态 * @param {string} orderId - 订单ID * @param {object} params - 查询参数 { confirm: 1 } */ queryOrder: (orderId, params = {}) => request(`/payment/orders/${orderId}`, { method: 'GET', data: params }), /** * 取消订单 * @param {string} orderId - 订单ID */ cancelOrder: (orderId) => request(`/payment/orders/${orderId}/cancel`, { method: 'POST' }), /** * 测试模式充值 - 直接增加爱心余额(仅测试环境使用) * @param {object} data - 充值参数 * @param {number} data.amount - 充值爱心数量 * @param {string} data.package_name - 套餐名称(可选) */ testRecharge: (data) => request('/payment/test-recharge', { method: 'POST', data }), /** * 测试模式支付 - 直接标记订单为已支付(仅测试环境使用) * @param {object} data - 支付参数 * @param {string} data.orderId - 订单ID */ testPay: (data) => request('/payment/test-pay', { method: 'POST', data }), /** * 创建统一支付订单 * @param {object} data - 订单参数 * @param {string} data.orderType - 订单类型: recharge|vip|companion_chat|agent_purchase|identity_card * @param {number} data.amount - 支付金额 * @param {number} data.rechargeValue - 充值金额(充值订单) * @param {string} data.vipType - VIP类型: month|quarter|year(VIP订单) * @param {string} data.agentId - 智能体ID(智能体订单) * @param {string} data.companionId - 陪聊师ID(陪聊订单) * @param {number} data.duration - 陪聊时长(陪聊订单) * @param {string} data.cardType - 身份卡类型: basic|premium(身份卡订单) * @param {string} data.referralCode - 推荐码(可选) * @param {string} data.promotionLinkCode - 推广链接码(可选) * @param {string} data.confirm - 是否主动确认支付状态 (1) * 注意:后端通过 Token 验证用户身份,不再需要传递 userId */ createUnifiedOrder: (data) => request('/payment/unified-order', { method: 'POST', data }), /** * 创建支付订单(兼容旧接口) * @param {object} data - { package_id, payment_method } * 注意:后端通过 Token 验证用户身份,不再需要传递 userId */ createOrder: (data) => request('/payment/unified-order', { method: 'POST', data }), /** * 获取订单列表 * @param {object} params - 查询参数 * @param {string} params.orderType - 订单类型(可选) * @param {string} params.status - 订单状态(可选) * @param {number} params.page - 页码 * @param {number} params.pageSize - 每页数量 * @param {string} params.confirm - 是否主动确认支付状态 (1) * 注意:后端通过 Token 验证用户身份,不再需要传递 userId */ getOrders: (params = {}) => request('/payment/unified-order', { data: { page: 1, pageSize: 20, ...params } }), /** * 获取订单详情 * @param {string} orderId - 订单ID * @param {object} params - { confirm: 1 } */ getOrderDetail: (orderId, params = {}) => request('/payment/unified-order', { data: { orderId, ...params } }), /** * 查询支付状态 * @param {string} orderId - 订单ID * @param {object} params - { confirm: 1 } */ checkStatus: (orderId, params = {}) => request('/payment/unified-order', { data: { orderId, ...params } }), /** * 使用爱心值兑换套餐 * @param {object} data - 兑换参数 * @param {string} data.packageId - 套餐ID (first/month/quarter/year) * @param {number} data.heartCost - 需要的爱心值数量 */ exchangeWithHeart: (data) => request('/payment/exchange-with-heart', { method: 'POST', data }) } // ==================== 智能体商品 API ==================== const agentProduct = { /** * 获取商品列表 * @param {object} params - 查询参数 * @param {string} params.status - 状态(默认active) * @param {number} params.page - 页码 * @param {number} params.pageSize - 每页数量 */ getList: (params = {}) => request('/agent-products', { data: { status: 'active', page: 1, pageSize: 20, ...params } }), /** * 获取商品详情 * @param {string} id - 商品ID */ getDetail: (id) => request(`/agent-products/${id}`), /** * 购买智能体 * @param {string} id - 商品ID * @param {object} options - 可选参数 * @param {string} options.referralCode - 推荐码 * @param {string} options.promotionLinkCode - 推广链接码 * 注意:后端通过 Token 验证用户身份,不再需要传递 userId */ purchase: (id, options = {}) => request(`/agent-products/${id}/purchase`, { method: 'POST', data: options }), /** * 获取用户已购智能体列表 * 注意:后端通过 Token 验证用户身份,不再需要传递 userId */ getPurchased: () => request('/user/purchased-agents'), /** * 检查是否有权访问某角色 * @param {string} characterId - 角色ID * 注意:后端通过 Token 验证用户身份,不再需要传递 userId */ checkAccess: (characterId) => request('/user/purchased-agents', { data: { action: 'checkAccess', characterId } }), /** * 获取可访问的角色ID列表 * 注意:后端通过 Token 验证用户身份,不再需要传递 userId */ getAccessibleIds: () => request('/user/purchased-agents', { data: { action: 'accessibleIds' } }) } // ==================== 页面素材 API ==================== const pageAssets = { /** * 获取通用素材配置 * @param {string} group - 素材分组 */ getAssets: (group = null) => { const url = group ? `/page-assets?group=${group}` : '/page-assets' return request(url) }, /** * 获取服务页在线Banner列表 */ getServiceBanners: () => request('/page-assets/service-banners'), /** * 获取娱乐页在线Banner列表 */ getEntertainmentBanners: () => request('/page-assets/entertainment-banners'), /** * 获取合作入驻页在线Banner列表 */ getCooperationBanners: () => request('/page-assets/cooperation-banners') } // ==================== 推广系统 API ==================== const promotion = { /** * 创建推广链接 * @param {object} data - 链接参数 * @param {string} data.targetType - 目标类型: agent|vip|recharge|general * @param {string} data.targetId - 目标ID(智能体推广时需要) * 注意:后端通过 Token 验证用户身份,不再需要传递 userId */ createLink: (data) => request('/promotion', { method: 'POST', data }), /** * 获取推广链接列表 * 注意:后端通过 Token 验证用户身份,不再需要传递 userId */ getLinks: () => request('/promotion'), /** * 获取推广统计 * 注意:后端通过 Token 验证用户身份,不再需要传递 userId */ getStats: () => request('/promotion', { data: { action: 'stats' } }), /** * 获取链接详情 * @param {string} linkId - 链接ID * 注意:后端通过 Token 验证用户身份,不再需要传递 userId */ getLinkDetail: (linkId) => request('/promotion', { data: { action: 'detail', linkId } }), /** * 获取分销商排行榜 * @param {object} params - 查询参数 * @param {string} params.period - 周期: day|week|month|all * @param {number} params.limit - 返回数量 */ getRanking: (params = {}) => request('/promotion', { data: { action: 'ranking', period: 'month', limit: 10, ...params } }), /** * 获取分享配置 * @param {string} pageKey - 页面标识: index|promote 等 * 返回: { title, desc, path, imageUrl } */ getShareConfig: (pageKey) => request('/promotion/share-config', { data: { page: pageKey } }), /** * 记录分享行为 * @param {object} data - 分享参数 * @param {string} data.type - 分享类型: app_message|timeline * @param {string} data.page - 页面路径 * @param {string} data.referralCode - 推荐码(可选) */ recordShare: (data) => request('/promotion', { method: 'POST', data: { action: 'recordShare', ...data } }) } // ==================== 订单模块 API ==================== const order = { /** * 获取订单列表 * @param {object} params - { type, status, page, limit } * 注意:后端通过 Token 验证用户身份,不再需要传递 userId */ getList: (params = {}) => request('/orders', { data: { page: 1, pageSize: 20, ...params } }), /** * 获取订单详情 * @param {string} id - 订单ID */ getDetail: (id) => request(`/orders/${id}`), /** * 创建陪聊订单 * @param {object} data - { companion_id, duration, message } * 注意:后端通过 Token 验证用户身份,不再需要传递 userId */ createCompanionOrder: (data) => request('/orders/companion', { method: 'POST', data }), /** * 取消订单 * @param {string} id - 订单ID * @param {string} reason - 取消原因 */ cancel: (id, reason = '') => request(`/orders/${id}/cancel`, { method: 'POST', data: { reason } }), /** * 评价订单 * @param {string} id - 订单ID * @param {object} data - { rating, content, tags, isAnonymous } */ review: (id, data) => request(`/orders/${id}/review`, { method: 'POST', data }), /** * 获取订单大厅(陪聊师用) */ getHall: () => request('/orders/hall'), /** * 接受订单 * @param {string} id - 订单ID */ accept: (id) => request(`/orders/${id}/accept`, { method: 'POST' }), /** * 拒绝订单 * @param {string} id - 订单ID * @param {string} reason - 拒绝原因 */ reject: (id, reason) => request(`/orders/${id}/reject`, { method: 'POST', data: { reason } }), /** * 开始服务 * @param {string} id - 订单ID */ startService: (id) => request(`/orders/${id}/start-service`, { method: 'POST' }), /** * 结束服务 * @param {string} id - 订单ID */ endService: (id) => request(`/orders/${id}/end-service`, { method: 'POST' }) } // ==================== 佣金与提现 API ==================== const commission = { /** * 获取佣金统计 * 注意:后端通过 Token 验证用户身份,不再需要传递 userId */ getStats: () => request('/commission', { data: { action: 'stats' } }), /** * 获取佣金记录 * @param {object} params - 分页参数 { page, pageSize } * 注意:后端通过 Token 验证用户身份,不再需要传递 userId */ getRecords: (params = {}) => request('/commission', { data: { action: 'records', ...params } }), /** * 获取推荐列表 * @param {object} params - 分页参数 { page, pageSize } * 注意:后端通过 Token 验证用户身份,不再需要传递 userId */ getReferrals: (params = {}) => request('/commission', { data: { action: 'referrals', ...params } }), /** * 获取提现记录 * 注意:后端通过 Token 验证用户身份,不再需要传递 userId */ getWithdrawals: () => request('/commission', { data: { action: 'withdrawals' } }), /** * 绑定推荐码 * @param {string} referralCode - 推荐码 * 注意:后端通过 Token 验证用户身份,不再需要传递 userId */ bindReferral: (referralCode) => request('/commission', { method: 'POST', data: { action: 'bindReferral', referralCode } }), /** * 申请提现 * @param {object} data - 提现参数 * @param {number} data.amount - 提现金额 * @param {string} data.withdrawType - 提现方式: wechat|alipay|bank * @param {object} data.accountInfo - 账户信息 { name, account } * 注意:后端通过 Token 验证用户身份,不再需要传递 userId */ withdraw: (data) => request('/commission', { method: 'POST', data: { action: 'withdraw', ...data } }) } // ==================== 交易流水 API ==================== const transaction = { /** * 获取交易流水 * @param {object} params - 查询参数 * @param {string} params.type - 交易类型(可选) * @param {string} params.status - 状态(可选) * @param {number} params.page - 页码 * @param {number} params.pageSize - 每页数量 * 注意:后端通过 Token 验证用户身份,不再需要传递 userId */ getList: (params = {}) => request('/user/transactions', { data: { page: 1, pageSize: 20, ...params } }), /** * 获取余额统计 * 注意:后端通过 Token 验证用户身份,不再需要传递 userId */ getStats: () => request('/user/transactions', { data: { action: 'stats' } }) } const withdraw = { /** * 申请提现 * @param {object} data - { amount, account_type, account_info } */ apply: (data) => request('/withdraw/apply', { method: 'POST', data }), /** * 获取提现记录 * @param {object} params - 分页参数 */ getRecords: (params = {}) => request('/withdraw/records', { data: params }) } // ==================== 社交广场 API ==================== const post = { /** * 获取动态列表 * @param {object} params - { page, limit, type } */ getList: (params = {}) => request('/posts', { data: { page: 1, limit: 20, ...params } }), /** * 发布动态 * @param {object} data - { content, images } */ create: (data) => request('/posts', { method: 'POST', data }), /** * 获取动态详情 * @param {string} id - 动态ID */ getDetail: (id) => request(`/posts/${id}`), /** * 删除动态 * @param {string} id - 动态ID */ delete: (id) => request(`/posts/${id}`, { method: 'DELETE' }), /** * 点赞/取消点赞 * @param {string} id - 动态ID */ toggleLike: (id) => request(`/posts/${id}/like`, { method: 'POST' }), /** * 发表评论 * @param {string} postId - 动态ID * @param {string} content - 评论内容 */ addComment: (postId, content) => request(`/posts/${postId}/comments`, { method: 'POST', data: { content } }), /** * 删除评论 * @param {string} postId - 动态ID * @param {string} commentId - 评论ID */ deleteComment: (postId, commentId) => request(`/posts/${postId}/comments/${commentId}`, { method: 'DELETE' }) } // ==================== 背包道具 API ==================== const backpack = { /** * 获取背包物品 */ getItems: () => request('/backpack'), /** * 使用物品 * @param {string} itemId - 物品ID */ useItem: (itemId) => request('/backpack/use', { method: 'POST', data: { item_id: itemId } }), /** * 赠送礼物 * @param {object} data - { item_id, target_id, target_type, quantity } */ giftItem: (data) => request('/backpack/gift', { method: 'POST', data }), /** * 装备道具 * @param {string} itemId - 物品ID */ equipItem: (itemId) => request('/backpack/equip', { method: 'POST', data: { item_id: itemId } }) } // ==================== 商城 API ==================== const shop = { /** * 获取商城物品 * @param {object} params - { category } */ getItems: (params = {}) => request('/shop/items', { data: params }), /** * 购买物品 * @param {object} data - { item_id, quantity } */ buyItem: (data) => request('/shop/buy', { method: 'POST', data }) } // ==================== 客服系统 API ==================== const customerService = { /** * 创建咨询 (开启新会话) * @param {object} data - { category, content, userName, userPhone, subject, guestId } */ create: (data) => request('/customer-service', { method: 'POST', data: { action: 'create', ...data } }), /** * 发送回复消息 * @param {object} data - { ticketId, content, userName } */ reply: (data) => request('/customer-service', { method: 'POST', data: { action: 'reply', ...data } }), /** * 获取咨询列表 * @param {string} guestId - 访客唯一ID */ getList: (guestId) => request(`/customer-service?guestId=${guestId}`), /** * 获取咨询详情及消息记录 * @param {string} ticketId - 工单ID */ getDetail: (ticketId) => request(`/customer-service?ticketId=${ticketId}`) } // ==================== 系统设置 API ==================== const settings = { /** * 获取用户设置 */ get: () => request('/settings'), /** * 更新用户设置 * @param {object} data - 设置数据 */ update: (data) => request('/settings', { method: 'PUT', data }), /** * 获取黑名单 */ getBlacklist: () => request('/settings/blacklist'), /** * 添加黑名单 * @param {string} userId - 用户ID */ addToBlacklist: (userId) => request('/settings/blacklist', { method: 'POST', data: { user_id: userId } }), /** * 移除黑名单 * @param {string} userId - 用户ID */ removeFromBlacklist: (userId) => request(`/settings/blacklist/${userId}`, { method: 'DELETE' }), /** * 清除缓存 */ clearCache: () => request('/settings/clear-cache', { method: 'POST' }), /** * 检查更新 */ checkUpdate: () => request('/settings/check-update'), /** * 提交反馈 * @param {object} data - { type, content, contact } */ submitFeedback: (data) => request('/settings/feedback', { method: 'POST', data }) } // ==================== 公共接口 API ==================== const common = { /** * 获取审核状态 * 1 表示开启(审核中),0 表示关闭(正式环境) */ getAuditStatus: () => request('/common/audit-status'), /** * 获取品牌配置 * 返回品牌故事、介绍等内容 */ getBrandConfig: () => request('/public/brand-config'), /** * 获取公告列表 * 返回启用的公告列表(按 sortOrder 升序排列) */ getNotices: () => request('/public/entertainment/notices'), /** * 获取公告详情 * @param {number} id - 公告ID */ getNoticeDetail: (id) => request(`/public/entertainment/notices/${id}`) } // ==================== 协议模块 API ==================== const agreement = { /** * 获取协议内容 * @param {string} code - 协议代码 (phone-guide, user-agreement, privacy-policy) */ get: (code) => request(`/agreements/${code}`) } // ==================== 图片回复话术 API ==================== const imageReply = { /** * 获取随机图片回复话术 * 用于用户发送图片时,AI返回预设的话术回复 */ getRandom: () => request('/image-reply/random') } // ==================== 主动推送消息 API ==================== const proactiveMessage = { /** * 获取待推送消息 * 返回AI角色主动发送的消息列表(跟进消息和打招呼消息) * 只返回未读(read_at IS NULL)的消息 */ getPending: () => request('/proactive-messages/pending', { silent: true }), /** * 标记消息已读 * @param {object} data - 参数(二选一) * @param {string} data.character_id - 按角色ID标记(推荐) * @param {Array} data.message_ids - 按消息ID列表标记 */ markAsRead: (data) => request('/proactive-messages/read', { method: 'POST', data, silent: true }) } // ==================== 活动模块 API ==================== const activity = { /** * 获取活动列表 * @param {object} params - 查询参数 * @param {string} params.tab - 活动标签:featured(精选)、newbie(新手) * @param {string} params.category - 活动分类:city(同城)、outdoor(户外)、travel(旅行)、featured(精选) * @param {string} params.city - 城市筛选 * @param {string} params.keyword - 关键词搜索 * @param {string} params.priceType - 价格类型:free(免费)、paid(付费) * @param {string} params.dateFrom - 开始日期筛选 (YYYY-MM-DD) * @param {string} params.dateTo - 结束日期筛选 (YYYY-MM-DD) * @param {string} params.sortBy - 排序方式:date(日期)、likes(点赞数)、participants(参与人数) * @param {number} params.page - 页码 * @param {number} params.limit - 每页数量 */ getList: (params = {}) => request('/entertainment/activities', { data: params }), /** * 获取活动详情 * @param {string} id - 活动ID */ getDetail: (id) => request(`/entertainment/activities/${id}`), /** * 获取活动参与者列表 * @param {string} id - 活动ID * @param {object} params - 分页参数 { page, limit } */ getParticipants: (id, params = {}) => request(`/entertainment/activities/${id}/registrations`, { data: params }), /** * 报名活动 * @param {string} id - 活动ID */ signup: (id) => request(`/entertainment/activities/${id}/signup`, { method: 'POST' }), /** * 取消报名 * @param {string} id - 活动ID */ cancelSignup: (id) => request(`/entertainment/activities/${id}/signup`, { method: 'DELETE' }), /** * 点赞/收藏活动 * @param {string} id - 活动ID */ favorite: (id) => request(`/entertainment/activities/${id}/like`, { method: 'POST' }), /** * 取消点赞/收藏活动 * @param {string} id - 活动ID */ unfavorite: (id) => request(`/entertainment/activities/${id}/like`, { method: 'POST' }), /** * 取消点赞/取消点赞活动 * @param {string} id - 活动ID */ toggleLike: (id) => request(`/entertainment/activities/${id}/like`, { method: 'POST' }), /** * 获取我的报名列表 * @param {object} params - { status, page, limit } */ getMyRegistrations: (params = {}) => request('/my-registrations', { data: params }) } // ==================== 兴趣搭子 API ==================== const interest = { /** * 获取兴趣分类列表 */ getCategories: () => request('/interest-categories'), /** * 获取兴趣搭子列表 * @param {object} params - 查询参数 * @param {number} params.page - 页码 * @param {number} params.limit - 每页数量 * @param {string} params.city - 城市筛选 * @param {string} params.province - 省份筛选 * @param {number} params.category_id - 分类ID筛选 */ getList: (params = {}) => request('/interest-partners', { data: params }), /** * 获取兴趣搭子详情 * @param {number} id - 搭子ID */ getDetail: (id) => request(`/interest-partners/${id}`) } // ==================== 文娱页面 API ==================== const entertainment = { /** * 获取首页数据(包含轮播图、分类、公告、精选活动、新手活动) * @param {string} city - 城市名称(可选) */ getHome: (city = null) => { const params = city ? { city } : {} return request('/entertainment/home', { data: params }) }, /** * 获取轮播Banner */ getBanners: () => request('/entertainment/banners'), /** * 获取滚动公告 */ getNotices: () => request('/entertainment/notices'), /** * 每日签到 */ checkin: () => request('/entertainment/checkin', { method: 'POST' }), /** * 获取签到记录 * @param {string} month - 月份 (YYYY-MM) */ getCheckinRecords: (month) => request('/entertainment/checkin/records', { data: { month } }), /** * 爱心传递 * @param {object} data - 传递信息 */ transferLove: (data) => request('/entertainment/love/transfer', { method: 'POST', data }), /** * 获取爱心榜 * @param {string} type - 榜单类型 (day/week/month) * @param {number} limit - 返回数量 */ getLoveRanking: (type = 'day', limit = 10) => request('/entertainment/love/ranking', { data: { type, limit } }) } // ==================== 爱心值系统 API ==================== const lovePoints = { /** * 记录分享获得爱心值 */ share: () => request('/love-points/share', { method: 'POST' }), /** * 登录获得爱心值(B自己+100,分享人也可获得+100) * 后端会检查是否有inviter参数,给分享人也+100 */ login: () => request('/love-points/login', { method: 'POST' }), /** * 获取邀请码 */ getInvitationCode: () => request('/love-points/invitation-code'), /** * 完善资料获得爱心值 */ profileComplete: () => request('/love-points/profile-complete', { method: 'POST' }), /** * 获取爱心值流水记录 * @param {object} params - 查询参数 { page, limit } */ getTransactions: (params = {}) => request('/love-points/transactions', { data: { limit: 100, ...params } }), /** * 检查注册奖励领取资格 */ checkRegistrationReward: () => request('/love-points/registration-reward/check'), /** * 领取注册奖励 */ claimRegistrationReward: () => request('/love-points/registration-reward', { method: 'POST' }), /** * 检查 GF100 弹窗领取资格 */ checkGf100Status: () => request('/love-points/gf100'), /** * 领取 GF100 奖励 */ claimGf100: () => request('/love-points/gf100', { method: 'POST' }) } const loveExchange = { /** * 获取可兑换选项(包含当前爱心值余额) */ getOptions: () => request('/love-exchange/options'), /** * 使用爱心值兑换会员 * @param {object} data - { package_id, love_cost } */ exchangeVip: (data) => request('/love-exchange/vip', { method: 'POST', data }) } const gifts = { /** * 获取礼品列表 * @param {object} params - 查询参数 { category, page, limit } */ getList: (params = {}) => request('/gifts', { data: params }), /** * 获取礼品详情 * @param {string} id - 礼品ID */ getDetail: (id) => request(`/gifts/${id}`), /** * 兑换礼品 * @param {object} data - { giftId, shippingInfo: { name, phone, address } } */ exchange: (data) => request('/gifts/exchange', { method: 'POST', data }), /** * 获取我的兑换记录 * @param {object} params - 查询参数 { page, limit } */ getMyExchanges: (params = {}) => request('/gifts/my-exchanges', { data: { limit: 50, ...params } }) } // ==================== 推荐关系 API ==================== const referral = { /** * 绑定推荐关系 * @param {object} data - 绑定参数 * @param {string} data.userId - 用户ID * @param {string} data.referralCode - 推荐码 */ bind: (data) => request('/referral/bind', { method: 'POST', data }), /** * 保存待绑定推荐码 * @param {object} data - 参数 * @param {string} data.userId - 用户ID * @param {string} data.referralCode - 推荐码 */ savePending: (data) => request('/referral/pending', { method: 'POST', data }), /** * 获取待绑定推荐码 * @param {string} userId - 用户ID */ getPending: (userId) => request('/referral/pending', { data: { userId } }) } // ==================== 快乐学堂 API ==================== const happySchool = { /** * 获取分类列表 */ getCategories: () => request('/xinban/categories'), /** * 获取文章列表 * @param {object} params - 查询参数 * @param {number} params.categoryId - 分类ID * @param {string} params.keyword - 关键词搜索 * @param {number} params.page - 页码 * @param {number} params.limit - 每页数量 */ getArticles: (params = {}) => request('/xinban/articles', { data: { page: 1, limit: 20, ...params } }), /** * 获取文章详情 * @param {number} id - 文章ID */ getArticleDetail: (id) => request(`/xinban/articles/${id}`), /** * 点赞/取消点赞文章 * @param {number} id - 文章ID */ toggleLike: (id) => request(`/xinban/articles/${id}/like`, { method: 'POST' }), /** * 记录阅读 * @param {number} id - 文章ID * @param {number} readDuration - 阅读时长(秒) */ recordRead: (id, readDuration = 0) => request(`/xinban/articles/${id}/read`, { method: 'POST', data: { readDuration } }) } // ==================== 导出所有API ==================== module.exports = { // 基础方法 request, uploadFile, // 模块API auth, user, character, chat, companion, tts, speech, payment, agentProduct, pageAssets, promotion, order, commission, transaction, withdraw, post, backpack, shop, customerService, settings, common, agreement, imageReply, proactiveMessage, // 娱乐页面相关API activity, interest, entertainment, // 爱心值系统API lovePoints, loveExchange, gifts, // 推荐关系API referral, // 快乐学堂API happySchool }