1857 lines
48 KiB
JavaScript
1857 lines
48 KiB
JavaScript
/**
|
||
* 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('<!DOCTYPE')
|
||
if (isHtml) {
|
||
console.warn(`[API] ${url} 返回了 HTML 页面,可能是 404 或服务器错误`)
|
||
} else if (config.DEBUG) {
|
||
console.log(`[API] Response Data:`, JSON.stringify(res.data).substring(0, 200))
|
||
}
|
||
|
||
if (res.statusCode === 200) {
|
||
resolve(res.data)
|
||
} else if (res.statusCode === 401) {
|
||
// Token过期或无效
|
||
console.warn('[API] 401 错误,Token 可能已过期:', url)
|
||
|
||
// 静默模式下不清除登录状态,只返回错误
|
||
if (options.silent) {
|
||
reject({ code: 401, message: '登录已过期' })
|
||
return
|
||
}
|
||
|
||
// 非静默模式:清除登录状态并提示用户
|
||
wx.removeStorageSync(config.STORAGE_KEYS.TOKEN)
|
||
wx.removeStorageSync(config.STORAGE_KEYS.USER_INFO)
|
||
wx.removeStorageSync(config.STORAGE_KEYS.USER_ID)
|
||
wx.removeStorageSync(config.STORAGE_KEYS.TOKEN_EXPIRY)
|
||
|
||
// 更新全局登录状态
|
||
const app = getApp()
|
||
if (app && app.globalData) {
|
||
app.globalData.isLoggedIn = false
|
||
app.globalData.userInfo = null
|
||
app.globalData.userId = null
|
||
}
|
||
|
||
// 触发登录弹窗
|
||
const pages = getCurrentPages()
|
||
const currentPage = pages[pages.length - 1]
|
||
if (currentPage && currentPage.onAuthRequired) {
|
||
currentPage.onAuthRequired()
|
||
}
|
||
|
||
reject({ code: 401, message: '登录已过期,请重新登录' })
|
||
} else {
|
||
reject(res.data || { code: res.statusCode, message: '请求失败' })
|
||
}
|
||
},
|
||
fail: (err) => {
|
||
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<string>} 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<number>} 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
|
||
}
|