/** * 宠物助手相关API接口模块 * 对接后端宠物助手服务接口 */ import BaseRequest from '../utils/request-helper.js' import { LOADING_TEXTS } from '../config/constants.js' // ==================== 宠物助手聊天接口 ==================== /** * 向宠物助手提问(非流式) * @description 发送消息给宠物助手,获取专业的宠物护理建议 * @param {Object} messageData 消息数据对象 * @param {string} messageData.message 用户消息内容,必填,1-2000字符 * @param {string} [messageData.sessionId] 会话ID,可选,UUID格式 * @param {boolean} [messageData.stream=false] 是否流式响应 * @param {number} [messageData.temperature=0.7] 温度参数,控制随机性,范围0-2 * @param {number} [messageData.maxTokens=1000] 最大生成token数,范围1-4000 * @param {string} [messageData.model] 模型名称,可选 * @param {Object} [config={}] 自定义请求配置 * @returns {Promise} 返回聊天响应对象 * @example * // 基本用法 * const response = await askPetAssistant({ * message: '我的狗狗不吃饭怎么办?' * }) * * // 指定会话和参数 * const response = await askPetAssistant({ * message: '还有其他建议吗?', * sessionId: 'uuid-session-id', * temperature: 0.8, * maxTokens: 1500 * }) */ export const askPetAssistant = (messageData, config = {}) => { return BaseRequest.post('/pet/user/assistant/ask', messageData, 'AUTHENTICATED_UPDATE', LOADING_TEXTS.AI_THINKING, config) } /** * 向宠物助手流式提问 * @description 发送消息给宠物助手,获取流式响应(实时显示回复过程) * @param {Object} messageData 消息数据对象 * @param {string} messageData.message 用户消息内容 * @param {string} [messageData.sessionId] 会话ID,可选 * @param {number} [messageData.temperature=0.7] 温度参数 * @param {number} [messageData.maxTokens=1000] 最大token数 * @param {Object} [config={}] 自定义请求配置 * @returns {Promise} 返回流式响应对象 * @example * const response = await streamAskPetAssistant({ * message: '我的猫咪呕吐是什么原因?', * sessionId: 'uuid-session-id' * }) */ export const streamAskPetAssistant = (messageData, config = {}) => { // 强制设置为流式响应 const streamData = { ...messageData, stream: true } return BaseRequest.post('/pet/user/assistant/stream-ask', streamData, 'AUTHENTICATED_UPDATE', LOADING_TEXTS.AI_THINKING, config) } /** * 获取宠物助手对话历史 * @description 获取用户与宠物助手的对话历史记录(单一会话) * @param {Object} [params={}] 查询参数 * @param {number} [params.page=1] 页码,默认第1页 * @param {number} [params.pageSize=20] 每页数量,默认20条 * @param {Object} [config={}] 自定义请求配置 * @returns {Promise} 返回历史记录列表 * @example * // 获取历史记录 * const history = await getAssistantHistory({ * page: 1, * pageSize: 50 * }) */ export const getAssistantHistory = (params = {}, config = {}) => { return BaseRequest.get('/pet/user/assistant/history', params, 'AUTHENTICATED_QUERY', config) } /** * 清空宠物助手对话历史 * @description 清空用户与宠物助手的对话历史记录 * @param {Object} [config={}] 自定义请求配置 * @returns {Promise} 返回操作结果 * @example * // 清空历史记录 * await clearAssistantHistory() */ export const clearAssistantHistory = (config = {}) => { return BaseRequest.delete('/pet/user/assistant/clear-history', {}, 'AUTHENTICATED_DELETE', '正在清除历史记录...', config) } // ==================== 兼容性接口(保持向后兼容) ==================== /** * 发送消息给AI助手(兼容旧版本) * @deprecated 请使用 askPetAssistant 替代 * @param {Object} messageData 消息数据 * @param {Object} config 自定义配置 * @returns {Promise} */ export const sendMessage = (messageData, config = {}) => { console.warn('sendMessage is deprecated, please use askPetAssistant instead') return askPetAssistant(messageData, config) } /** * 获取聊天历史(兼容旧版本) * @deprecated 请使用 getAssistantHistory 替代 * @param {Object} params 查询参数 * @param {Object} config 自定义配置 * @returns {Promise} */ export const getChatHistory = (params = {}, config = {}) => { console.warn('getChatHistory is deprecated, please use getAssistantHistory instead') return getAssistantHistory(params, config) } /** * 清除聊天历史(兼容旧版本) * @deprecated 请使用 clearAssistantHistory 替代 * @param {Object} config 自定义配置 * @returns {Promise} */ export const clearChatHistory = (config = {}) => { console.warn('clearChatHistory is deprecated, please use clearAssistantHistory instead') return clearAssistantHistory({}, config) } // ==================== 工具函数 ==================== /** * 验证消息内容 * @description 验证用户输入的消息是否符合要求 * @param {string} message 消息内容 * @returns {Object} 验证结果 { valid: boolean, error?: string } */ export const validateMessage = (message) => { if (!message || typeof message !== 'string') { return { valid: false, error: '消息内容不能为空' } } const trimmedMessage = message.trim() if (trimmedMessage.length === 0) { return { valid: false, error: '消息内容不能为空' } } if (trimmedMessage.length > 2000) { return { valid: false, error: '消息内容不能超过2000个字符' } } return { valid: true } } /** * 格式化聊天消息 * @description 将API返回的消息格式化为前端显示格式 * @param {Object} apiMessage API返回的消息对象 * @returns {Object} 格式化后的消息对象 */ export const formatChatMessage = (apiMessage) => { return { id: apiMessage.id, type: apiMessage.role === 'user' ? 'user' : 'ai', content: apiMessage.messageContent || apiMessage.message || '', time: formatMessageTime(apiMessage.createdAt || apiMessage.created_at), sessionId: apiMessage.sessionId, isSensitive: apiMessage.isSensitive || false, tokenCount: apiMessage.tokenCount || 0, responseTime: apiMessage.responseTime || 0 } } /** * 格式化消息时间 * @description 将时间戳或时间字符串格式化为显示格式 * @param {string|number|Date} timestamp 时间戳或时间对象 * @returns {string} 格式化后的时间字符串 */ export const formatMessageTime = (timestamp) => { if (!timestamp) return '' const date = new Date(timestamp) const now = new Date() const today = new Date(now.getFullYear(), now.getMonth(), now.getDate()) const messageDate = new Date(date.getFullYear(), date.getMonth(), date.getDate()) const timeStr = date.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit', hour12: false }) if (messageDate.getTime() === today.getTime()) { return timeStr } else if (messageDate.getTime() === today.getTime() - 24 * 60 * 60 * 1000) { return `昨天 ${timeStr}` } else { return date.toLocaleDateString('zh-CN', { month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', hour12: false }) } }