Files

202 lines
6.4 KiB
JavaScript
Raw Permalink Normal View History

2024-11-08 11:55:23 +08:00
import config from "@/config.js"
2025-11-18 17:25:39 +08:00
import {
sm2_Decrypt,
sm2_Encrypt,
2025-11-20 09:17:29 +08:00
sm4Decrypt,
sm4Encrypt
} from '@/common/globalFunction';
import IndexedDBHelper from '@/common/IndexedDBHelper';
import useUserStore from '@/stores/useUserStore';
import baseDB from '@/utils/db.js';
2024-11-08 11:55:23 +08:00
const CACHE_STORE_NAME = 'api_cache';
2024-11-08 11:55:23 +08:00
2025-11-20 09:17:29 +08:00
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"]
]
2025-03-28 15:19:42 +08:00
/**
* 带缓存的请求方法
*/
export async function createRequestWithCache(url, data = {}, method = 'GET', loading = false, headers = {},
onCacheLoad = null) {
2025-11-30 16:47:06 +08:00
// 是分页接口的话, 只缓存第一页的数据
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;
}
}
2025-03-28 15:19:42 +08:00
/**
* @param url String请求的地址默认none
* @param data Object请求的参数默认{}
* @param method String请求的方式默认GET
* @param loading Boolean是否需要loading 默认false
* @param header Objectheaders默认{}
* @returns promise
**/
export function createRequest(url, data = {}, method = 'GET', loading = false, headers = {}) {
if (loading) {
uni.showLoading({
title: '请稍后',
mask: true
})
}
2025-11-30 16:47:06 +08:00
let header = {
...headers
};
const userStore = useUserStore();
const token = userStore.token;
2025-03-28 15:19:42 +08:00
2025-11-30 16:47:06 +08:00
if (token) {
// 确保 Authorization 不会被覆盖,且进行编码
header["Authorization"] = encodeURIComponent(token);
}
2025-11-20 09:17:29 +08:00
// ------------------------------------------------------------------
// 检查当前请求是否需要加密
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()
};
}
// ------------------------------------------------------------------
2025-03-28 15:19:42 +08:00
return new Promise((resolve, reject) => {
uni.request({
url: config.baseUrl + url,
method: method,
2025-11-20 09:17:29 +08:00
data: requestData,
2025-03-28 15:19:42 +08:00
header,
success: resData => {
// 响应拦截
if (resData.statusCode === 200) {
2025-11-20 09:17:29 +08:00
if (resData.data.encrypted) {
2025-11-24 14:33:23 +08:00
const decryptedData = sm4Decrypt(config.sm4Config.key, resData.data
.encryptedData)
2025-11-20 09:17:29 +08:00
resData.data = JSON.parse(decryptedData)
}
2025-03-28 15:19:42 +08:00
const {
code,
msg
} = resData.data
if (code === 200) {
resolve(resData.data)
return
}
if (msg) {
uni.showToast({
title: msg,
icon: 'none'
})
}
2025-03-28 15:19:42 +08:00
}
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();
}
}
})
})
}