import config from "@/config.js" import { sm2_Decrypt, sm2_Encrypt, sm4Decrypt, sm4Encrypt } from '@/common/globalFunction'; import IndexedDBHelper from '@/common/IndexedDBHelper'; import useUserStore from '@/stores/useUserStore'; import baseDB from '@/utils/db.js'; const CACHE_STORE_NAME = 'api_cache'; const needToEncrypt = [ ["post", "/app/login"], ["get", "/app/user/resume"], ["post", "/app/user/resume"], ["post", "/app/user/experience/edit"], ["post", "/app/user/experience/delete"], ["get", "/app/user/experience/getSingle/{value}"], ["get", "/app/user/experience/list"] ] /** * 带缓存的请求方法 */ export async function createRequestWithCache(url, data = {}, method = 'GET', loading = false, headers = {}, onCacheLoad = null) { // 是分页接口的话, 只缓存第一页的数据 if (data.current && data.current > 1) { return createRequest(url, data, method, loading, headers); } const cacheKey = `${method.toUpperCase()}:${url}:${JSON.stringify(data)}`; baseDB.getDB().then(async (dbHelper) => { try { const cachedRecord = await dbHelper.get(CACHE_STORE_NAME, cacheKey); if (cachedRecord && cachedRecord.response && typeof onCacheLoad === 'function') { onCacheLoad(cachedRecord.response); } } catch (e) { console.error('读取缓存失败', e); } }); // 3. 发起网络请求 try { const networkResponse = await createRequest(url, data, method, loading, headers); baseDB.getDB().then(async (dbHelper) => { try { await dbHelper.update(CACHE_STORE_NAME, { cacheKey: cacheKey, response: networkResponse, timestamp: Date.now() }); console.log('💾 [BaseDB] 缓存更新:', url); } catch (e) { console.error('更新缓存失败', e); } }); return networkResponse; } catch (error) { throw error; } } /** * @param url String,请求的地址,默认:none * @param data Object,请求的参数,默认:{} * @param method String,请求的方式,默认:GET * @param loading Boolean,是否需要loading ,默认:false * @param header Object,headers,默认:{} * @returns promise **/ export function createRequest(url, data = {}, method = 'GET', loading = false, headers = {}) { if (loading) { uni.showLoading({ title: '请稍后', mask: true }) } let header = { ...headers }; const userStore = useUserStore(); const token = userStore.token; if (token) { // 确保 Authorization 不会被覆盖,且进行编码 header["Authorization"] = encodeURIComponent(token); } // ------------------------------------------------------------------ // 检查当前请求是否需要加密 const isEncrypt = needToEncrypt.some(item => { const matchMethod = item[0].toLowerCase() === method.toLowerCase(); const matchUrl = item[1].includes('{') ? url.startsWith(item[1].split('/{')[0]) // 检查动态路径的前缀 : item[1] === url; // 检查静态路径 return matchMethod && matchUrl; }); let requestData = data; if (isEncrypt) { const jsonData = JSON.stringify(data); const encryptedBody = sm4Encrypt(config.sm4Config.key, jsonData); requestData = { encrypted: true, encryptedData: encryptedBody, timestamp: Date.now() }; } // ------------------------------------------------------------------ return new Promise((resolve, reject) => { uni.request({ url: config.baseUrl + url, method: method, data: requestData, header, success: resData => { // 响应拦截 if (resData.statusCode === 200) { if (resData.data.encrypted) { const decryptedData = sm4Decrypt(config.sm4Config.key, resData.data .encryptedData) resData.data = JSON.parse(decryptedData) } const { code, msg } = resData.data if (code === 200) { resolve(resData.data) return } if (msg) { uni.showToast({ title: msg, icon: 'none' }) } } if (resData.data?.code === 401 || resData.data?.code === 402) { useUserStore().logOut() } const err = new Error('请求出现异常,请联系工作人员') err.error = resData reject(err) }, fail: (err) => { reject(err) }, complete: () => { if (loading) { uni.hideLoading(); } } }); }) } export function uploadFile(tempFilePaths, loading = false) { if (loading) { uni.showLoading({ title: '请稍后', mask: true }) } let Authorization = '' if (useUserStore().token) { Authorization = `${useUserStore().token}` } const header = {}; header["Authorization"] = encodeURIComponent(Authorization); return new Promise((resolve, reject) => { uni.uploadFile({ url: config.baseUrl + '/app/file/upload', filePath: tempFilePaths, name: 'file', header, success: (uploadFileRes) => { if (uploadFileRes.statusCode === 200) { return resolve(uploadFileRes.data) } }, fail: (err) => { reject(err) }, complete: () => { if (loading) { uni.hideLoading(); } } }) }) }