diff --git a/examples/api-usage-example.js b/examples/api-usage-example.js new file mode 100644 index 0000000..e081a37 --- /dev/null +++ b/examples/api-usage-example.js @@ -0,0 +1,249 @@ +// HTTP API使用示例 +// 注意:鉴权配置已简化,只需要在 http/config/config.js 中配置不需要鉴权的接口即可 + +// 导入API模块 +import { petsApi, assistantApi, adoptionApi, profileApi, commonApi, addNoAuthApis, setEnvironment } from '@/http/index.js' + +// 或者导入所有API +// import api from '@/http/index.js' + +export default { + data() { + return { + petsList: [], + userInfo: {}, + loading: false + } + }, + + methods: { + // 示例1:获取宠物列表(自动鉴权) + async loadPets() { + try { + // 使用默认配置,自动根据接口判断是否需要鉴权 + const pets = await petsApi.getPetsList() + this.petsList = pets + } catch (error) { + console.error('获取宠物列表失败:', error) + } + }, + + // 示例2:添加不需要鉴权的接口 + addCustomNoAuthApis() { + // 如果有自定义的接口不需要鉴权,可以这样添加 + addNoAuthApis([ + '/custom/public-api', + '/special/no-auth-endpoint' + ]) + }, + + // 示例3:切换环境 + switchEnvironment() { + // 根据需要切换环境 + // #ifdef H5 + setEnvironment('development') // H5开发环境 + // #endif + + // #ifdef MP-WEIXIN + setEnvironment('production') // 小程序生产环境 + // #endif + + // 或者根据条件动态切换 + const isDev = process.env.NODE_ENV === 'development' + setEnvironment(isDev ? 'development' : 'production') + }, + + // 示例2:添加宠物 + async addNewPet() { + try { + const petData = { + name: '小白', + breed: '金毛', + age: 2, + gender: '公' + } + + const result = await petsApi.addPet(petData, { + custom: { + auth: true, + loading: true, + toast: true // 显示成功/失败提示 + } + }) + + uni.showToast({ + title: '添加成功', + icon: 'success' + }) + + // 重新加载列表 + this.loadPets() + } catch (error) { + // 错误已在拦截器中处理,这里可以做额外处理 + console.error('添加宠物失败:', error) + } + }, + + // 示例3:AI助手对话 + async sendMessageToAI() { + try { + const messageData = { + message: '我的猫咪最近不爱吃饭,怎么办?', + petId: 123 + } + + const response = await assistantApi.sendMessage(messageData, { + custom: { + auth: true, + loading: true, + loadingText: 'AI正在思考中...' + } + }) + + console.log('AI回复:', response.reply) + } catch (error) { + console.error('AI对话失败:', error) + } + }, + + // 示例4:用户登录 + async userLogin() { + try { + const loginData = { + username: 'user@example.com', + password: '123456' + } + + const result = await profileApi.userLogin(loginData, { + custom: { + auth: false, // 登录接口不需要token + loading: true, + loadingText: '正在登录...' + } + }) + + // 保存token和用户信息 + uni.setStorageSync('token', result.token) + uni.setStorageSync('userInfo', result.userInfo) + + uni.showToast({ + title: '登录成功', + icon: 'success' + }) + } catch (error) { + console.error('登录失败:', error) + } + }, + + // 示例5:上传图片 + async uploadPetImage() { + try { + // 选择图片 + const chooseResult = await uni.chooseImage({ + count: 1, + sizeType: ['compressed'], + sourceType: ['album', 'camera'] + }) + + const imageData = { + filePath: chooseResult.tempFilePaths[0], + name: 'petImage', + formData: { + type: 'pet', + petId: 123 + } + } + + const uploadResult = await commonApi.uploadImage(imageData, { + custom: { + auth: true, + loading: true, + loadingText: '正在上传图片...' + } + }) + + console.log('上传成功:', uploadResult.url) + + uni.showToast({ + title: '上传成功', + icon: 'success' + }) + } catch (error) { + console.error('上传失败:', error) + } + }, + + // 示例6:搜索领养宠物 + async searchAdoptionPets() { + try { + const searchParams = { + keyword: '金毛', + type: 'dog', + age: '1-3', + location: '北京' + } + + const pets = await adoptionApi.searchPets(searchParams, { + custom: { + auth: false, // 搜索不需要登录 + loading: true + } + }) + + console.log('搜索结果:', pets) + } catch (error) { + console.error('搜索失败:', error) + } + }, + + // 示例7:批量操作 + async batchOperations() { + try { + // 并发执行多个请求 + const [pets, userInfo, adoptionPets] = await Promise.all([ + petsApi.getPetsList(), + profileApi.getUserInfo(), + adoptionApi.getAdoptionPets() + ]) + + console.log('批量获取数据成功:', { pets, userInfo, adoptionPets }) + } catch (error) { + console.error('批量操作失败:', error) + } + }, + + // 示例8:自定义错误处理 + async customErrorHandling() { + try { + const result = await petsApi.getPetsList({}, { + custom: { + auth: true, + loading: true, + toast: false, // 不显示默认错误提示 + catch: true // 允许catch捕获错误 + } + }) + } catch (error) { + // 自定义错误处理 + if (error.code === 401) { + uni.showModal({ + title: '提示', + content: '登录已过期,请重新登录', + success: (res) => { + if (res.confirm) { + uni.reLaunch({ + url: '/pages/login/login' + }) + } + } + }) + } else { + uni.showToast({ + title: error.message || '操作失败', + icon: 'none' + }) + } + } + } + } +} diff --git a/http/api/adoption.js b/http/api/adoption.js new file mode 100644 index 0000000..10b730d --- /dev/null +++ b/http/api/adoption.js @@ -0,0 +1,212 @@ +// 领养专区相关API接口 + +/** + * 获取待领养宠物列表 + * @param {Object} params 查询参数 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const getAdoptionPets = (params = {}, config = {}) => { + return uni.$u.http.get('/adoption/pets', { + params, + custom: { + auth: false, + loading: true, + ...config.custom + }, + ...config + }) +} + +/** + * 搜索宠物 + * @param {Object} searchParams 搜索参数 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const searchPets = (searchParams, config = {}) => { + return uni.$u.http.get('/adoption/pets/search', { + params: searchParams, + custom: { + auth: false, + loading: true, + ...config.custom + }, + ...config + }) +} + +/** + * 筛选宠物 + * @param {Object} filterParams 筛选参数 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const filterPets = (filterParams, config = {}) => { + return uni.$u.http.post('/adoption/pets/filter', filterParams, { + custom: { + auth: false, + loading: true, + ...config.custom + }, + ...config + }) +} + +/** + * 获取宠物详情 + * @param {String|Number} petId 宠物ID + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const getAdoptionPetDetail = (petId, config = {}) => { + return uni.$u.http.get(`/adoption/pets/${petId}`, { + custom: { + auth: false, + loading: true, + ...config.custom + }, + ...config + }) +} + +/** + * 申请领养 + * @param {Object} adoptionData 领养申请数据 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const applyAdoption = (adoptionData, config = {}) => { + return uni.$u.http.post('/adoption/apply', adoptionData, { + custom: { + auth: true, + loading: true, + loadingText: '正在提交申请...', + ...config.custom + }, + ...config + }) +} + +/** + * 获取我的领养申请 + * @param {Object} params 查询参数 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const getMyAdoptionApplications = (params = {}, config = {}) => { + return uni.$u.http.get('/adoption/my-applications', { + params, + custom: { + auth: true, + loading: true, + ...config.custom + }, + ...config + }) +} + +/** + * 取消领养申请 + * @param {String|Number} applicationId 申请ID + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const cancelAdoptionApplication = (applicationId, config = {}) => { + return uni.$u.http.delete(`/adoption/applications/${applicationId}`, {}, { + custom: { + auth: true, + loading: true, + loadingText: '正在取消申请...', + ...config.custom + }, + ...config + }) +} + +/** + * 获取领养机构列表 + * @param {Object} params 查询参数 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const getAdoptionOrganizations = (params = {}, config = {}) => { + return uni.$u.http.get('/adoption/organizations', { + params, + custom: { + auth: false, + loading: true, + ...config.custom + }, + ...config + }) +} + +/** + * 获取领养机构详情 + * @param {String|Number} orgId 机构ID + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const getOrganizationDetail = (orgId, config = {}) => { + return uni.$u.http.get(`/adoption/organizations/${orgId}`, { + custom: { + auth: false, + loading: true, + ...config.custom + }, + ...config + }) +} + +/** + * 收藏宠物 + * @param {String|Number} petId 宠物ID + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const favoritePet = (petId, config = {}) => { + return uni.$u.http.post(`/adoption/pets/${petId}/favorite`, {}, { + custom: { + auth: true, + loading: true, + ...config.custom + }, + ...config + }) +} + +/** + * 取消收藏宠物 + * @param {String|Number} petId 宠物ID + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const unfavoritePet = (petId, config = {}) => { + return uni.$u.http.delete(`/adoption/pets/${petId}/favorite`, {}, { + custom: { + auth: true, + loading: true, + ...config.custom + }, + ...config + }) +} + +/** + * 获取收藏的宠物列表 + * @param {Object} params 查询参数 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const getFavoritePets = (params = {}, config = {}) => { + return uni.$u.http.get('/adoption/favorites', { + params, + custom: { + auth: true, + loading: true, + ...config.custom + }, + ...config + }) +} diff --git a/http/api/assistant.js b/http/api/assistant.js new file mode 100644 index 0000000..3512f5d --- /dev/null +++ b/http/api/assistant.js @@ -0,0 +1,112 @@ +// AI助手相关API接口 +// 注意:所有接口的鉴权配置已在 http/config/config.js 中统一管理 + +/** + * 发送消息给AI助手 + * @param {Object} messageData 消息数据 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const sendMessage = (messageData, config = {}) => { + return uni.$u.http.post('/ai/chat', messageData, { + custom: { + auth: true, + loading: true, + loadingText: 'AI正在思考中...', + ...config.custom + }, + ...config + }) +} + +/** + * 获取AI知识库 + * @param {Object} params 查询参数 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const getKnowledgeBase = (params = {}, config = {}) => { + return uni.$u.http.get('/ai/knowledge', { + params, + custom: { + auth: false, + loading: true, + ...config.custom + }, + ...config + }) +} + +/** + * 获取聊天历史 + * @param {Object} params 查询参数 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const getChatHistory = (params = {}, config = {}) => { + return uni.$u.http.get('/ai/chat/history', { + params, + custom: { + auth: true, + loading: true, + ...config.custom + }, + ...config + }) +} + +/** + * 清除聊天历史 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const clearChatHistory = (config = {}) => { + return uni.$u.http.delete('/ai/chat/history', {}, { + custom: { + auth: true, + loading: true, + loadingText: '正在清除历史记录...', + ...config.custom + }, + ...config + }) +} + +/** + * 获取AI建议 + * @param {Object} petData 宠物数据 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const getAISuggestion = (petData, config = {}) => { + return uni.$u.http.post('/ai/suggestion', petData, { + custom: { + auth: true, + loading: true, + loadingText: '正在分析宠物状况...', + ...config.custom + }, + ...config + }) +} + +/** + * 语音转文字 + * @param {Object} audioData 音频数据 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const speechToText = (audioData, config = {}) => { + return uni.$u.http.upload('/ai/speech-to-text', { + filePath: audioData.filePath, + name: 'audio', + formData: audioData.formData || {}, + custom: { + auth: true, + loading: true, + loadingText: '正在识别语音...', + ...config.custom + }, + ...config + }) +} diff --git a/http/api/common.js b/http/api/common.js new file mode 100644 index 0000000..a963f6e --- /dev/null +++ b/http/api/common.js @@ -0,0 +1,234 @@ +// 通用API接口 + +/** + * 上传图片 + * @param {Object} imageData 图片数据 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const uploadImage = (imageData, config = {}) => { + return uni.$u.http.upload('/upload/image', { + filePath: imageData.filePath, + name: imageData.name || 'file', + formData: imageData.formData || {}, + custom: { + auth: true, + loading: true, + loadingText: '正在上传图片...', + ...config.custom + }, + ...config + }) +} + +/** + * 上传多张图片 + * @param {Array} imageList 图片列表 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const uploadImages = (imageList, config = {}) => { + const uploadPromises = imageList.map(imageData => { + return uploadImage(imageData, { + ...config, + custom: { + loading: false, // 批量上传时不显示单个loading + ...config.custom + } + }) + }) + + return Promise.all(uploadPromises) +} + +/** + * 上传文件 + * @param {Object} fileData 文件数据 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const uploadFile = (fileData, config = {}) => { + return uni.$u.http.upload('/upload/file', { + filePath: fileData.filePath, + name: fileData.name || 'file', + formData: fileData.formData || {}, + custom: { + auth: true, + loading: true, + loadingText: '正在上传文件...', + ...config.custom + }, + ...config + }) +} + +/** + * 下载文件 + * @param {String} url 文件URL + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const downloadFile = (url, config = {}) => { + return uni.$u.http.download(url, { + custom: { + auth: false, + loading: true, + loadingText: '正在下载文件...', + ...config.custom + }, + ...config + }) +} + +/** + * 获取七牛云上传token + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const getQiniuToken = (config = {}) => { + return uni.$u.http.get('/upload/qiniu-token', { + custom: { + auth: true, + loading: false, + ...config.custom + }, + ...config + }) +} + +/** + * 获取阿里云OSS上传签名 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const getOSSSignature = (config = {}) => { + return uni.$u.http.get('/upload/oss-signature', { + custom: { + auth: true, + loading: false, + ...config.custom + }, + ...config + }) +} + +/** + * 获取系统配置 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const getSystemConfig = (config = {}) => { + return uni.$u.http.get('/system/config', { + custom: { + auth: false, + loading: false, + ...config.custom + }, + ...config + }) +} + +/** + * 获取版本信息 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const getVersionInfo = (config = {}) => { + return uni.$u.http.get('/system/version', { + custom: { + auth: false, + loading: false, + ...config.custom + }, + ...config + }) +} + +/** + * 检查更新 + * @param {Object} versionData 版本数据 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const checkUpdate = (versionData, config = {}) => { + return uni.$u.http.post('/system/check-update', versionData, { + custom: { + auth: false, + loading: true, + ...config.custom + }, + ...config + }) +} + +/** + * 发送短信验证码 + * @param {Object} smsData 短信数据 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const sendSmsCode = (smsData, config = {}) => { + return uni.$u.http.post('/sms/send', smsData, { + custom: { + auth: false, + loading: true, + loadingText: '正在发送验证码...', + ...config.custom + }, + ...config + }) +} + +/** + * 验证短信验证码 + * @param {Object} verifyData 验证数据 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const verifySmsCode = (verifyData, config = {}) => { + return uni.$u.http.post('/sms/verify', verifyData, { + custom: { + auth: false, + loading: true, + loadingText: '正在验证...', + ...config.custom + }, + ...config + }) +} + +/** + * 获取地区数据 + * @param {Object} params 查询参数 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const getRegionData = (params = {}, config = {}) => { + return uni.$u.http.get('/common/regions', { + params, + custom: { + auth: false, + loading: false, + ...config.custom + }, + ...config + }) +} + +/** + * 意见反馈 + * @param {Object} feedbackData 反馈数据 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const submitFeedback = (feedbackData, config = {}) => { + return uni.$u.http.post('/feedback', feedbackData, { + custom: { + auth: true, + loading: true, + loadingText: '正在提交反馈...', + ...config.custom + }, + ...config + }) +} diff --git a/http/api/pets.js b/http/api/pets.js new file mode 100644 index 0000000..d8e14a6 --- /dev/null +++ b/http/api/pets.js @@ -0,0 +1,204 @@ +// 宠物管理相关API接口 +// 注意:所有接口的鉴权配置已在 http/config/config.js 中统一管理 + +/** + * 获取宠物列表 + * @param {Object} params 查询参数 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const getPetsList = (params = {}, config = {}) => { + return uni.$u.http.get('/pets', { + params, + custom: { + loading: true, + ...config.custom + }, + ...config + }) +} + +/** + * 获取宠物详情 + * @param {String|Number} petId 宠物ID + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const getPetDetail = (petId, config = {}) => { + return uni.$u.http.get(`/pets/${petId}`, { + custom: { + loading: true, + ...config.custom + }, + ...config + }) +} + +/** + * 添加宠物 + * @param {Object} petData 宠物数据 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const addPet = (petData, config = {}) => { + return uni.$u.http.post('/pets', petData, { + custom: { + loading: true, + loadingText: '正在添加宠物...', + ...config.custom + }, + ...config + }) +} + +/** + * 更新宠物信息 + * @param {String|Number} petId 宠物ID + * @param {Object} petData 宠物数据 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const updatePet = (petId, petData, config = {}) => { + return uni.$u.http.put(`/pets/${petId}`, petData, { + custom: { + auth: true, + loading: true, + loadingText: '正在更新宠物信息...', + ...config.custom + }, + ...config + }) +} + +/** + * 删除宠物 + * @param {String|Number} petId 宠物ID + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const deletePet = (petId, config = {}) => { + return uni.$u.http.delete(`/pets/${petId}`, {}, { + custom: { + auth: true, + loading: true, + loadingText: '正在删除宠物...', + ...config.custom + }, + ...config + }) +} + +/** + * 获取宠物记录列表 + * @param {String|Number} petId 宠物ID + * @param {Object} params 查询参数 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const getPetRecords = (petId, params = {}, config = {}) => { + return uni.$u.http.get(`/pets/${petId}/records`, { + params, + custom: { + auth: true, + loading: true, + ...config.custom + }, + ...config + }) +} + +/** + * 添加宠物记录 + * @param {String|Number} petId 宠物ID + * @param {Object} recordData 记录数据 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const addPetRecord = (petId, recordData, config = {}) => { + return uni.$u.http.post(`/pets/${petId}/records`, recordData, { + custom: { + auth: true, + loading: true, + loadingText: '正在添加记录...', + ...config.custom + }, + ...config + }) +} + +/** + * 更新宠物记录 + * @param {String|Number} petId 宠物ID + * @param {String|Number} recordId 记录ID + * @param {Object} recordData 记录数据 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const updatePetRecord = (petId, recordId, recordData, config = {}) => { + return uni.$u.http.put(`/pets/${petId}/records/${recordId}`, recordData, { + custom: { + auth: true, + loading: true, + loadingText: '正在更新记录...', + ...config.custom + }, + ...config + }) +} + +/** + * 删除宠物记录 + * @param {String|Number} petId 宠物ID + * @param {String|Number} recordId 记录ID + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const deletePetRecord = (petId, recordId, config = {}) => { + return uni.$u.http.delete(`/pets/${petId}/records/${recordId}`, {}, { + custom: { + auth: true, + loading: true, + loadingText: '正在删除记录...', + ...config.custom + }, + ...config + }) +} + +/** + * 获取宠物健康数据 + * @param {String|Number} petId 宠物ID + * @param {Object} params 查询参数 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const getPetHealthData = (petId, params = {}, config = {}) => { + return uni.$u.http.get(`/pets/${petId}/health`, { + params, + custom: { + auth: true, + loading: true, + ...config.custom + }, + ...config + }) +} + +/** + * 获取宠物时间线 + * @param {String|Number} petId 宠物ID + * @param {Object} params 查询参数 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const getPetTimeline = (petId, params = {}, config = {}) => { + return uni.$u.http.get(`/pets/${petId}/timeline`, { + params, + custom: { + auth: true, + loading: true, + ...config.custom + }, + ...config + }) +} diff --git a/http/api/profile.js b/http/api/profile.js new file mode 100644 index 0000000..c3f2dba --- /dev/null +++ b/http/api/profile.js @@ -0,0 +1,227 @@ +// 个人中心相关API接口 + +/** + * 获取用户信息 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const getUserInfo = (config = {}) => { + return uni.$u.http.get('/user/info', { + custom: { + auth: true, + loading: true, + ...config.custom + }, + ...config + }) +} + +/** + * 更新用户信息 + * @param {Object} userInfo 用户信息 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const updateUserInfo = (userInfo, config = {}) => { + return uni.$u.http.put('/user/info', userInfo, { + custom: { + auth: true, + loading: true, + loadingText: '正在更新用户信息...', + ...config.custom + }, + ...config + }) +} + +/** + * 获取用户宠物列表 + * @param {Object} params 查询参数 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const getUserPets = (params = {}, config = {}) => { + return uni.$u.http.get('/user/pets', { + params, + custom: { + auth: true, + loading: true, + ...config.custom + }, + ...config + }) +} + +/** + * 用户登录 + * @param {Object} loginData 登录数据 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const userLogin = (loginData, config = {}) => { + return uni.$u.http.post('/auth/login', loginData, { + custom: { + auth: false, + loading: true, + loadingText: '正在登录...', + ...config.custom + }, + ...config + }) +} + +/** + * 微信登录 + * @param {Object} wxData 微信登录数据 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const wxLogin = (wxData, config = {}) => { + return uni.$u.http.post('/auth/wx-login', wxData, { + custom: { + auth: false, + loading: true, + loadingText: '正在登录...', + ...config.custom + }, + ...config + }) +} + +/** + * 用户注册 + * @param {Object} registerData 注册数据 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const userRegister = (registerData, config = {}) => { + return uni.$u.http.post('/auth/register', registerData, { + custom: { + auth: false, + loading: true, + loadingText: '正在注册...', + ...config.custom + }, + ...config + }) +} + +/** + * 用户登出 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const userLogout = (config = {}) => { + return uni.$u.http.post('/auth/logout', {}, { + custom: { + auth: true, + loading: true, + ...config.custom + }, + ...config + }) +} + +/** + * 刷新token + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const refreshToken = (config = {}) => { + const refreshToken = uni.getStorageSync('refreshToken') + return uni.$u.http.post('/auth/refresh', { refreshToken }, { + custom: { + auth: false, + loading: false, + toast: false, + ...config.custom + }, + ...config + }) +} + +/** + * 修改密码 + * @param {Object} passwordData 密码数据 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const changePassword = (passwordData, config = {}) => { + return uni.$u.http.put('/user/password', passwordData, { + custom: { + auth: true, + loading: true, + loadingText: '正在修改密码...', + ...config.custom + }, + ...config + }) +} + +/** + * 获取用户统计数据 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const getUserStats = (config = {}) => { + return uni.$u.http.get('/user/stats', { + custom: { + auth: true, + loading: true, + ...config.custom + }, + ...config + }) +} + +/** + * 获取用户设置 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const getUserSettings = (config = {}) => { + return uni.$u.http.get('/user/settings', { + custom: { + auth: true, + loading: true, + ...config.custom + }, + ...config + }) +} + +/** + * 更新用户设置 + * @param {Object} settings 设置数据 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const updateUserSettings = (settings, config = {}) => { + return uni.$u.http.put('/user/settings', settings, { + custom: { + auth: true, + loading: true, + loadingText: '正在保存设置...', + ...config.custom + }, + ...config + }) +} + +/** + * 绑定手机号 + * @param {Object} phoneData 手机号数据 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const bindPhone = (phoneData, config = {}) => { + return uni.$u.http.post('/user/bind-phone', phoneData, { + custom: { + auth: true, + loading: true, + loadingText: '正在绑定手机号...', + ...config.custom + }, + ...config + }) +} diff --git a/http/api/review.js b/http/api/review.js new file mode 100644 index 0000000..e6e5f7e --- /dev/null +++ b/http/api/review.js @@ -0,0 +1,202 @@ +// 评价相关API接口 + +/** + * 获取评价列表 + * @param {Object} params 查询参数 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const getReviews = (params = {}, config = {}) => { + return uni.$u.http.get('/reviews', { + params, + custom: { + auth: false, + loading: true, + ...config.custom + }, + ...config + }) +} + +/** + * 获取特定对象的评价列表 + * @param {String} targetType 目标类型 (pet, organization, service) + * @param {String|Number} targetId 目标ID + * @param {Object} params 查询参数 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const getTargetReviews = (targetType, targetId, params = {}, config = {}) => { + return uni.$u.http.get(`/reviews/${targetType}/${targetId}`, { + params, + custom: { + auth: false, + loading: true, + ...config.custom + }, + ...config + }) +} + +/** + * 添加评价 + * @param {Object} reviewData 评价数据 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const addReview = (reviewData, config = {}) => { + return uni.$u.http.post('/reviews', reviewData, { + custom: { + auth: true, + loading: true, + loadingText: '正在提交评价...', + ...config.custom + }, + ...config + }) +} + +/** + * 更新评价 + * @param {String|Number} reviewId 评价ID + * @param {Object} reviewData 评价数据 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const updateReview = (reviewId, reviewData, config = {}) => { + return uni.$u.http.put(`/reviews/${reviewId}`, reviewData, { + custom: { + auth: true, + loading: true, + loadingText: '正在更新评价...', + ...config.custom + }, + ...config + }) +} + +/** + * 删除评价 + * @param {String|Number} reviewId 评价ID + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const deleteReview = (reviewId, config = {}) => { + return uni.$u.http.delete(`/reviews/${reviewId}`, {}, { + custom: { + auth: true, + loading: true, + loadingText: '正在删除评价...', + ...config.custom + }, + ...config + }) +} + +/** + * 获取我的评价列表 + * @param {Object} params 查询参数 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const getMyReviews = (params = {}, config = {}) => { + return uni.$u.http.get('/reviews/my', { + params, + custom: { + auth: true, + loading: true, + ...config.custom + }, + ...config + }) +} + +/** + * 点赞评价 + * @param {String|Number} reviewId 评价ID + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const likeReview = (reviewId, config = {}) => { + return uni.$u.http.post(`/reviews/${reviewId}/like`, {}, { + custom: { + auth: true, + loading: false, + ...config.custom + }, + ...config + }) +} + +/** + * 取消点赞评价 + * @param {String|Number} reviewId 评价ID + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const unlikeReview = (reviewId, config = {}) => { + return uni.$u.http.delete(`/reviews/${reviewId}/like`, {}, { + custom: { + auth: true, + loading: false, + ...config.custom + }, + ...config + }) +} + +/** + * 举报评价 + * @param {String|Number} reviewId 评价ID + * @param {Object} reportData 举报数据 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const reportReview = (reviewId, reportData, config = {}) => { + return uni.$u.http.post(`/reviews/${reviewId}/report`, reportData, { + custom: { + auth: true, + loading: true, + loadingText: '正在提交举报...', + ...config.custom + }, + ...config + }) +} + +/** + * 回复评价 + * @param {String|Number} reviewId 评价ID + * @param {Object} replyData 回复数据 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const replyReview = (reviewId, replyData, config = {}) => { + return uni.$u.http.post(`/reviews/${reviewId}/reply`, replyData, { + custom: { + auth: true, + loading: true, + loadingText: '正在回复评价...', + ...config.custom + }, + ...config + }) +} + +/** + * 获取评价统计 + * @param {String} targetType 目标类型 + * @param {String|Number} targetId 目标ID + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const getReviewStats = (targetType, targetId, config = {}) => { + return uni.$u.http.get(`/reviews/${targetType}/${targetId}/stats`, { + custom: { + auth: false, + loading: true, + ...config.custom + }, + ...config + }) +} diff --git a/http/config/config.js b/http/config/config.js new file mode 100644 index 0000000..e6eb116 --- /dev/null +++ b/http/config/config.js @@ -0,0 +1,125 @@ +// HTTP模块配置文件 + +/** + * 环境配置 + */ +const ENV_CONFIG = { + // 开发环境 + development: { + baseURL: 'https://dev-api.pet-ai.com', + timeout: 30000 + }, + // 测试环境 + testing: { + baseURL: 'https://test-api.pet-ai.com', + timeout: 30000 + }, + // 生产环境 + production: { + baseURL: 'https://api.pet-ai.com', + timeout: 60000 + } +} + +/** + * 当前环境 (可根据实际情况动态设置) + */ +let CURRENT_ENV = 'development' // development | testing | production + +/** + * HTTP基础配置 + */ +export const HTTP_CONFIG = { + // 当前环境配置 + ...ENV_CONFIG[CURRENT_ENV], + + // 登录页面路径 + loginPage: '/pages/login/login', + + // 存储键名配置 + storageKeys: { + token: 'token', + refreshToken: 'refreshToken', + userInfo: 'userInfo' + } +} + +/** + * 不需要鉴权的接口列表 + * 注意:只需要配置不需要token的接口,其他接口默认都需要鉴权 + */ +export const NO_AUTH_APIS = [ + // 用户认证相关 + '/auth/login', + '/auth/register', + '/auth/wx-login', + '/auth/refresh', + + // 公开浏览的接口 + '/ai/knowledge', // AI知识库 + '/adoption/pets', // 浏览待领养宠物 + '/adoption/pets/search', // 搜索宠物 + '/adoption/pets/filter', // 筛选宠物 + '/adoption/organizations', // 领养机构列表 + '/reviews', // 查看评价 + '/system/config', // 系统配置 + '/system/version', // 版本信息 + '/system/check-update', // 检查更新 + '/sms/send', // 发送短信验证码 + '/sms/verify', // 验证短信验证码 + '/common/regions' // 地区数据 +] + +/** + * 检查接口是否需要鉴权 + * @param {String} url 接口URL + * @returns {Boolean} 是否需要鉴权 + */ +export function checkApiAuth(url) { + // 移除查询参数,只保留路径 + const path = url.split('?')[0] + + // 检查是否在不需要鉴权的列表中 + for (const noAuthApi of NO_AUTH_APIS) { + // 支持通配符匹配 + if (noAuthApi.includes('*')) { + const regex = new RegExp('^' + noAuthApi.replace(/\*/g, '.*') + '$') + if (regex.test(path)) { + return false + } + } else if (path === noAuthApi || path.startsWith(noAuthApi + '/')) { + return false + } + } + + // 默认需要鉴权 + return true +} + +/** + * 添加不需要鉴权的接口 + * @param {String|Array} apis 接口路径或接口路径数组 + */ +export function addNoAuthApis(apis) { + if (Array.isArray(apis)) { + NO_AUTH_APIS.push(...apis) + } else { + NO_AUTH_APIS.push(apis) + } +} + +/** + * 设置当前环境 + * @param {String} env 环境名称 (development | testing | production) + */ +export function setEnvironment(env) { + if (ENV_CONFIG[env]) { + CURRENT_ENV = env + // 更新HTTP配置 + Object.assign(HTTP_CONFIG, ENV_CONFIG[env]) + console.log(`HTTP环境已切换到: ${env}`) + console.log(`当前baseURL: ${HTTP_CONFIG.baseURL}`) + } else { + console.error(`无效的环境名称: ${env}`) + } +} diff --git a/http/config/request.js b/http/config/request.js new file mode 100644 index 0000000..8a3d20b --- /dev/null +++ b/http/config/request.js @@ -0,0 +1,159 @@ +// HTTP请求配置和拦截器 +// 基于uView-next的luch-request库实现 + +import { HTTP_CONFIG, checkApiAuth } from './config.js' + +/** + * 初始化HTTP配置 + * @param {Object} vm Vue实例,用于访问vuex等全局状态 + */ +module.exports = (vm) => { + // 初始化请求配置 + uni.$u.http.setConfig((config) => { + config.baseURL = HTTP_CONFIG.baseURL + config.timeout = HTTP_CONFIG.timeout + config.header = { + 'Content-Type': 'application/json;charset=UTF-8' + } + return config + }) + + // 请求拦截器 + uni.$u.http.interceptors.request.use((config) => { + // 初始化请求拦截器时,会执行此方法,此时data为undefined,赋予默认{} + config.data = config.data || {} + config.custom = config.custom || {} + + // 自动检查接口是否需要鉴权(如果没有明确指定) + if (config.custom.auth === undefined) { + config.custom.auth = checkApiAuth(config.url) + } + + // 根据custom参数中配置的是否需要token,添加对应的请求头 + if (config.custom.auth) { + // 从本地存储获取token + const token = uni.getStorageSync('token') + if (token) { + config.header.Authorization = `Bearer ${token}` + } else { + // 如果需要token但没有token,可以跳转到登录页 + console.warn('需要token但未找到,请先登录') + } + } + + // 根据custom参数配置是否显示loading + if (config.custom.loading !== false) { + uni.showLoading({ + title: config.custom.loadingText || '请稍候...', + mask: true + }) + } + + return config + }, config => { + // 请求错误处理 + return Promise.reject(config) + }) + + // 响应拦截器 + uni.$u.http.interceptors.response.use((response) => { + /* 对响应成功做点什么 可使用async await 做异步操作*/ + + // 隐藏loading + uni.hideLoading() + + const data = response.data + const custom = response.config?.custom + + // 统一的响应数据处理 + if (data.code !== undefined) { + // 如果服务端返回的状态码不等于200,则reject() + if (data.code !== 200) { + // 如果没有显式定义custom的toast参数为false的话,默认对报错进行toast弹出提示 + if (custom?.toast !== false) { + uni.$u.toast(data.message || '请求失败') + } + + // 特殊状态码处理 + if (data.code === 401) { + // token过期,清除本地token并跳转到登录页 + uni.removeStorageSync('token') + uni.removeStorageSync('refreshToken') + uni.removeStorageSync('userInfo') + uni.reLaunch({ + url: HTTP_CONFIG.loginPage + }) + return Promise.reject(data) + } + + // 如果需要catch返回,则进行reject + if (custom?.catch) { + return Promise.reject(data) + } else { + // 否则返回一个pending中的promise,请求不会进入catch中 + return new Promise(() => {}) + } + } + } + + // 返回处理后的数据 + return data.data !== undefined ? data.data : data + }, (response) => { + /* 对响应错误做点什么 (statusCode !== 200)*/ + + // 隐藏loading + uni.hideLoading() + + const custom = response.config?.custom + + // 网络错误处理 + let errorMessage = '网络错误,请检查网络连接' + + if (response.statusCode) { + switch (response.statusCode) { + case 400: + errorMessage = '请求参数错误' + break + case 401: + errorMessage = '未授权,请重新登录' + // 清除本地认证信息 + uni.removeStorageSync('token') + uni.removeStorageSync('refreshToken') + uni.removeStorageSync('userInfo') + // 跳转到登录页 + uni.reLaunch({ + url: HTTP_CONFIG.loginPage + }) + break + case 403: + errorMessage = '拒绝访问' + break + case 404: + errorMessage = '请求地址不存在' + break + case 500: + errorMessage = '服务器内部错误' + break + case 502: + errorMessage = '网关错误' + break + case 503: + errorMessage = '服务不可用' + break + case 504: + errorMessage = '网关超时' + break + default: + errorMessage = `连接错误${response.statusCode}` + } + } + + // 显示错误提示 + if (custom?.toast !== false) { + uni.$u.toast(errorMessage) + } + + console.error('请求错误:', response) + return Promise.reject(response) + }) +} diff --git a/http/index.js b/http/index.js new file mode 100644 index 0000000..fa40879 --- /dev/null +++ b/http/index.js @@ -0,0 +1,55 @@ +// HTTP模块统一导出文件 + +// 导入所有API模块 +import * as petsApi from './api/pets.js' +import * as assistantApi from './api/assistant.js' +import * as adoptionApi from './api/adoption.js' +import * as profileApi from './api/profile.js' +import * as reviewApi from './api/review.js' +import * as commonApi from './api/common.js' + +// 导入配置 +export { HTTP_CONFIG, NO_AUTH_APIS, addNoAuthApis, setEnvironment } from './config/config.js' + +// 统一导出所有API +export { + petsApi, + assistantApi, + adoptionApi, + profileApi, + reviewApi, + commonApi +} + +// 也可以按模块导出,便于按需引入 +export default { + pets: petsApi, + assistant: assistantApi, + adoption: adoptionApi, + profile: profileApi, + review: reviewApi, + common: commonApi +} + +// 使用示例: +// 方式1:按模块导入API +// import { petsApi, assistantApi } from '@/http/index.js' +// petsApi.getPetsList() +// assistantApi.sendMessage() + +// 方式2:导入所有API +// import api from '@/http/index.js' +// api.pets.getPetsList() +// api.assistant.sendMessage() + +// 方式3:解构导入特定接口 +// import { petsApi } from '@/http/index.js' +// const { getPetsList, addPet } = petsApi + +// 方式4:配置不需要鉴权的接口 +// import { addNoAuthApis } from '@/http/index.js' +// addNoAuthApis(['/custom/api1', '/custom/api2']) + +// 方式5:切换环境 +// import { setEnvironment } from '@/http/index.js' +// setEnvironment('production') // 切换到生产环境 diff --git a/main.js b/main.js index 6b40832..5744653 100644 --- a/main.js +++ b/main.js @@ -10,6 +10,10 @@ App.mpType = 'app' const app = new Vue({ ...App }) + +// 引入HTTP请求配置,将app参数传递到配置中 +require('./http/config/request.js')(app) + app.$mount() // #endif @@ -18,6 +22,10 @@ import { createSSRApp } from 'vue' export function createApp() { const app = createSSRApp(App) app.use(uViewNext) + + // 引入HTTP请求配置 + require('./http/config/request.js')(app) + return { app }