From 10b714e4415142d65902ae040ba3d8a41429a0be Mon Sep 17 00:00:00 2001 From: yvan <8574526@qq.com> Date: Fri, 15 Aug 2025 16:55:43 +0800 Subject: [PATCH] 1 --- http/api/adoption.js | 1 + http/api/pets.js | 1 - http/api/profile.js | 33 +++++++++++++++-- http/config/config.js | 7 ++++ http/config/request.js | 14 ++++---- http/index.js | 3 ++ http/utils/validator.js | 80 +++++++++++++++++++++++++++++++++++++++++ 7 files changed, 129 insertions(+), 10 deletions(-) create mode 100644 http/utils/validator.js diff --git a/http/api/adoption.js b/http/api/adoption.js index 10b730d..dd67a15 100644 --- a/http/api/adoption.js +++ b/http/api/adoption.js @@ -1,4 +1,5 @@ // 领养专区相关API接口 +// 注意:所有接口的鉴权配置已在 http/config/config.js 中统一管理 /** * 获取待领养宠物列表 diff --git a/http/api/pets.js b/http/api/pets.js index d8e14a6..3bc5a1e 100644 --- a/http/api/pets.js +++ b/http/api/pets.js @@ -61,7 +61,6 @@ export const addPet = (petData, config = {}) => { export const updatePet = (petId, petData, config = {}) => { return uni.$u.http.put(`/pets/${petId}`, petData, { custom: { - auth: true, loading: true, loadingText: '正在更新宠物信息...', ...config.custom diff --git a/http/api/profile.js b/http/api/profile.js index c3f2dba..89b9be5 100644 --- a/http/api/profile.js +++ b/http/api/profile.js @@ -131,7 +131,6 @@ 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 @@ -217,7 +216,6 @@ export const updateUserSettings = (settings, config = {}) => { export const bindPhone = (phoneData, config = {}) => { return uni.$u.http.post('/user/bind-phone', phoneData, { custom: { - auth: true, loading: true, loadingText: '正在绑定手机号...', ...config.custom @@ -225,3 +223,34 @@ export const bindPhone = (phoneData, config = {}) => { ...config }) } + +/** + * 获取用户权限 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const getUserPermissions = (config = {}) => { + return uni.$u.http.get('/user/permissions', { + custom: { + loading: false, + ...config.custom + }, + ...config + }) +} + +/** + * 注销账户 + * @param {Object} config 自定义配置 + * @returns {Promise} + */ +export const deleteAccount = (config = {}) => { + return uni.$u.http.delete('/user/account', {}, { + custom: { + loading: true, + loadingText: '正在注销账户...', + ...config.custom + }, + ...config + }) +} diff --git a/http/config/config.js b/http/config/config.js index e6eb116..513b1f8 100644 --- a/http/config/config.js +++ b/http/config/config.js @@ -41,6 +41,13 @@ export const HTTP_CONFIG = { token: 'token', refreshToken: 'refreshToken', userInfo: 'userInfo' + }, + + // 请求重试配置 + retry: { + times: 2, // 重试次数 + delay: 1000, // 重试延迟(毫秒) + statusCodes: [500, 502, 503, 504] // 需要重试的状态码 } } diff --git a/http/config/request.js b/http/config/request.js index 8a3d20b..c207768 100644 --- a/http/config/request.js +++ b/http/config/request.js @@ -32,7 +32,7 @@ module.exports = (vm) => { // 根据custom参数中配置的是否需要token,添加对应的请求头 if (config.custom.auth) { // 从本地存储获取token - const token = uni.getStorageSync('token') + const token = uni.getStorageSync(HTTP_CONFIG.storageKeys.token) if (token) { config.header.Authorization = `Bearer ${token}` } else { @@ -77,9 +77,9 @@ module.exports = (vm) => { // 特殊状态码处理 if (data.code === 401) { // token过期,清除本地token并跳转到登录页 - uni.removeStorageSync('token') - uni.removeStorageSync('refreshToken') - uni.removeStorageSync('userInfo') + uni.removeStorageSync(HTTP_CONFIG.storageKeys.token) + uni.removeStorageSync(HTTP_CONFIG.storageKeys.refreshToken) + uni.removeStorageSync(HTTP_CONFIG.storageKeys.userInfo) uni.reLaunch({ url: HTTP_CONFIG.loginPage }) @@ -117,9 +117,9 @@ module.exports = (vm) => { case 401: errorMessage = '未授权,请重新登录' // 清除本地认证信息 - uni.removeStorageSync('token') - uni.removeStorageSync('refreshToken') - uni.removeStorageSync('userInfo') + uni.removeStorageSync(HTTP_CONFIG.storageKeys.token) + uni.removeStorageSync(HTTP_CONFIG.storageKeys.refreshToken) + uni.removeStorageSync(HTTP_CONFIG.storageKeys.userInfo) // 跳转到登录页 uni.reLaunch({ url: HTTP_CONFIG.loginPage diff --git a/http/index.js b/http/index.js index fa40879..3285ead 100644 --- a/http/index.js +++ b/http/index.js @@ -11,6 +11,9 @@ import * as commonApi from './api/common.js' // 导入配置 export { HTTP_CONFIG, NO_AUTH_APIS, addNoAuthApis, setEnvironment } from './config/config.js' +// 导入工具 +export { validateRequired, validateId, validatePagination, validateFileUpload } from './utils/validator.js' + // 统一导出所有API export { petsApi, diff --git a/http/utils/validator.js b/http/utils/validator.js new file mode 100644 index 0000000..3adb729 --- /dev/null +++ b/http/utils/validator.js @@ -0,0 +1,80 @@ +// HTTP请求参数验证工具 + +/** + * 验证必需参数 + * @param {Object} params 参数对象 + * @param {Array} requiredFields 必需字段数组 + * @param {String} apiName API名称(用于错误提示) + * @throws {Error} 参数验证失败时抛出错误 + */ +export function validateRequired(params, requiredFields, apiName = 'API') { + if (!params || typeof params !== 'object') { + throw new Error(`${apiName}: 参数不能为空`) + } + + for (const field of requiredFields) { + if (params[field] === undefined || params[field] === null || params[field] === '') { + throw new Error(`${apiName}: 缺少必需参数 ${field}`) + } + } +} + +/** + * 验证ID参数 + * @param {String|Number} id ID值 + * @param {String} fieldName 字段名称 + * @param {String} apiName API名称 + * @throws {Error} ID验证失败时抛出错误 + */ +export function validateId(id, fieldName = 'id', apiName = 'API') { + if (!id || (typeof id !== 'string' && typeof id !== 'number')) { + throw new Error(`${apiName}: ${fieldName} 不能为空且必须是字符串或数字`) + } + + if (typeof id === 'string' && id.trim() === '') { + throw new Error(`${apiName}: ${fieldName} 不能为空字符串`) + } + + if (typeof id === 'number' && (id <= 0 || !Number.isInteger(id))) { + throw new Error(`${apiName}: ${fieldName} 必须是正整数`) + } +} + +/** + * 验证分页参数 + * @param {Object} params 分页参数 + * @param {String} apiName API名称 + */ +export function validatePagination(params, apiName = 'API') { + if (params.page !== undefined) { + if (!Number.isInteger(params.page) || params.page < 1) { + throw new Error(`${apiName}: page 必须是大于0的整数`) + } + } + + if (params.limit !== undefined) { + if (!Number.isInteger(params.limit) || params.limit < 1 || params.limit > 100) { + throw new Error(`${apiName}: limit 必须是1-100之间的整数`) + } + } +} + +/** + * 验证文件上传参数 + * @param {Object} fileData 文件数据 + * @param {String} apiName API名称 + */ +export function validateFileUpload(fileData, apiName = 'API') { + if (!fileData || typeof fileData !== 'object') { + throw new Error(`${apiName}: 文件数据不能为空`) + } + + if (!fileData.filePath || typeof fileData.filePath !== 'string') { + throw new Error(`${apiName}: filePath 不能为空且必须是字符串`) + } + + // 验证文件路径格式(简单验证) + if (!fileData.filePath.includes('/') && !fileData.filePath.includes('\\')) { + throw new Error(`${apiName}: filePath 格式不正确`) + } +}