Files
ks-app-employment-service/utils/request.js

425 lines
11 KiB
JavaScript
Raw Normal View History

2024-11-08 11:55:23 +08:00
import config from "@/config.js"
2026-04-30 13:28:49 +08:00
import { sm4Encrypt, sm4Decrypt } from '@/utils/crypto';
2024-11-08 11:55:23 +08:00
import useUserStore from '@/stores/useUserStore';
2026-04-30 13:28:49 +08:00
2026-05-15 14:16:31 +08:00
let isRefreshing = false;
let refreshSubscribers = [];
2026-04-30 13:28:49 +08:00
const needToEncryptSet = new Set([
'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',
'GET:/app/user/experience/list',
'POST:/app/user/cert',
'POST:/app/user/getUserArchives',
]);
const encryptPathPrefixes = [
2026-05-01 02:48:55 +08:00
// '/app/common/',
2026-04-30 15:12:33 +08:00
'/app/chat/',
2026-05-01 02:48:55 +08:00
// '/app/speech/',
2026-04-30 15:12:33 +08:00
'/app/job/',
'/app/company/',
'/app/companycontact/',
'/app/appskill/',
'/app/userworkexperiences/',
2026-05-01 04:02:50 +08:00
'/app/appWxphoneSmsCode',
2026-05-01 12:23:05 +08:00
'/app/sendSmsAgain',
2026-04-30 15:12:33 +08:00
'/app/user/',
2026-05-02 21:39:41 +08:00
'/registerUser',
2026-04-30 15:12:33 +08:00
'/app/user/resume/',
'/cms/job/recommen/',
2026-05-01 04:02:50 +08:00
'/app/appLoginPhone',
2026-04-30 17:46:19 +08:00
'/app/notice/',
2026-05-01 20:03:11 +08:00
'/app/idCardLogin',
'/app/phoneLogin',
2026-04-30 13:28:49 +08:00
];
2026-05-15 14:16:31 +08:00
const addRefreshSubscriber = (callback) => {
refreshSubscribers.push(callback);
};
const notifyRefreshSubscribers = (token) => {
refreshSubscribers.forEach((callback) => callback(token));
refreshSubscribers = [];
};
2026-05-14 18:35:18 +08:00
const noEncryptSet = new Set([
'DELETE:/app/job/applyJobCencal',
]);
2026-05-21 17:15:47 +08:00
export const isEncryptNeeded = (method, url) => {
2026-05-14 18:35:18 +08:00
const pureUrl = url.split('?')[0];
const key = `${method.toUpperCase()}:${pureUrl}`;
if (noEncryptSet.has(key)) return false;
2026-04-30 13:28:49 +08:00
if (needToEncryptSet.has(key)) return true;
for (const encryptKey of needToEncryptSet) {
const [encryptMethod, encryptUrl] = encryptKey.split(':');
2026-05-14 18:35:18 +08:00
if (encryptMethod === method.toUpperCase() && pureUrl.startsWith(encryptUrl.split('/{')[0])) {
2026-04-30 13:28:49 +08:00
return true;
}
}
for (const prefix of encryptPathPrefixes) {
2026-05-14 18:35:18 +08:00
if (pureUrl.startsWith(prefix)) {
2026-04-30 13:28:49 +08:00
return true;
}
}
return false;
};
2026-05-21 17:15:47 +08:00
export const encryptRequestData = (data) => {
2026-04-30 13:28:49 +08:00
const jsonData = JSON.stringify(data);
// const jsonData = JSON.stringify({a: '1'});
2026-05-14 18:35:18 +08:00
console.log('[请求] 加密前:', jsonData)
2026-04-30 13:28:49 +08:00
return {
encrypted: true,
encryptedData: sm4Encrypt(config.sm4Config.key, jsonData),
timestamp: Date.now(),
};
};
2026-05-21 17:15:47 +08:00
export const handleResponseData = (resData) => {
2026-04-30 13:28:49 +08:00
try {
if (resData?.encrypted) {
const decrypted = sm4Decrypt(config.sm4Config.key, resData.encryptedData);
resData = JSON.parse(decrypted);
2026-05-01 04:02:50 +08:00
// console.log('[请求] 解密后数据:', resData);
2026-04-30 13:28:49 +08:00
}
} catch (e) {
console.error('[请求] 解密失败:', e.message);
}
return resData;
};
2025-03-28 15:19:42 +08:00
export function request({
2025-10-31 17:24:07 +08:00
url,
method = 'GET',
data = {},
load = false,
header = {}
2025-03-28 15:19:42 +08:00
} = {}) {
2024-11-08 11:55:23 +08:00
2025-10-31 17:24:07 +08:00
return new Promise((resolve, reject) => {
if (load) {
uni.showLoading({
title: '请稍候',
mask: true
});
}
let Authorization = ''
if (useUserStore().token) {
Authorization = `Bearer ${useUserStore().token}`
2025-10-31 17:24:07 +08:00
}
uni.request({
url: config.baseUrl + url,
method,
data: data,
header: {
'Authorization': Authorization || '',
},
success: resData => {
// 响应拦截
if (resData.statusCode === 200) {
const {
code,
msg
} = resData.data
if (code === 200) {
resolve(resData.data)
return
}
uni.showToast({
title: msg,
icon: 'none'
})
}
if (resData.data?.code === 401 || resData.data?.code === 402) {
useUserStore().logOut()
uni.showToast({
title: '登录过期,请重新登录',
icon: 'none'
})
return
}
const err = new Error('请求出现异常,请联系工作人员')
err.error = resData
reject(err)
},
2025-11-04 14:31:37 +08:00
fail: err => reject(err) ,
2025-10-31 17:24:07 +08:00
complete() {
if (load) {
uni.hideLoading();
}
}
})
})
2024-11-08 11:55:23 +08:00
}
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
**/
2025-12-18 11:46:39 +08:00
export function createRequest(url, data = {}, method = 'GET', loading = false, headers = {},needHeader = true) {
2025-10-31 17:24:07 +08:00
if (loading) {
uni.showLoading({
title: '请稍后',
mask: true
})
}
const header = headers || {};
2026-05-15 14:16:31 +08:00
const doRequest = () => {
2026-05-21 17:15:47 +08:00
if (needHeader) {
header["Authorization"] = useUserStore().token ? `Bearer ${useUserStore().token}` : '';
}
const requestData = isEncryptNeeded(method, url) ? encryptRequestData(data) : data;
2026-05-15 14:16:31 +08:00
return new Promise((resolve, reject) => {
uni.request({
url: config.baseUrl + url,
method: method,
data: requestData,
header,
success: resData => {
2026-05-20 20:50:51 +08:00
const responseData = handleResponseData(resData.data)
2026-05-22 17:11:06 +08:00
console.log('[请求] 接口地址:', config.baseUrl + url)
console.log('[请求] 解密后数据:', JSON.stringify(responseData))
2026-05-15 14:16:31 +08:00
// 响应拦截
if (resData.statusCode === 200) {
const {
code,
msg
} = responseData
if (code === 200) {
resolve(responseData)
return
}
// 处理业务错误
if (responseData?.code === 401 || responseData?.code === 402) {
handleTokenExpired(resolve, reject, doRequest, loading)
return
}
// 显示具体的错误信息
const errorMsg = msg || '请求出现异常,请联系工作人员'
2026-06-02 18:35:20 +08:00
uni.showToast({
title: errorMsg,
icon: 'none'
})
2026-05-15 14:16:31 +08:00
const err = new Error(errorMsg)
err.error = resData
reject(err)
2025-10-31 17:24:07 +08:00
return
}
2026-05-15 14:16:31 +08:00
// HTTP状态码不是200的情况
2026-06-02 18:35:20 +08:00
const errorMsg = responseData?.msg || '网络请求失败,请检查网络连接'
uni.showToast({
title: errorMsg,
icon: 'none'
})
const err = new Error(errorMsg)
2025-10-31 17:24:07 +08:00
err.error = resData
reject(err)
2026-05-15 14:16:31 +08:00
},
fail: (err) => {
reject(err)
},
complete: () => {
2026-05-21 17:15:47 +08:00
if (loading && !isRefreshing) {
2026-05-15 14:16:31 +08:00
uni.hideLoading();
}
2025-10-31 17:24:07 +08:00
}
2026-05-15 14:16:31 +08:00
});
})
}
return doRequest()
}
const handleTokenExpired = (resolve, reject, retryRequest, loading) => {
2026-05-21 17:15:47 +08:00
return new Promise((innerResolve, innerReject) => {
if (isRefreshing) {
addRefreshSubscriber((token) => {
if (token) {
retryRequest().then(resolve).catch(reject).finally(innerResolve)
} else {
const err = new Error('刷新token失败')
reject(err)
innerReject(err)
}
})
return
}
2026-05-15 14:16:31 +08:00
2026-05-21 17:15:47 +08:00
isRefreshing = true
2026-05-15 14:16:31 +08:00
2026-05-21 17:15:47 +08:00
useUserStore().refreshAccessToken().then((newToken) => {
notifyRefreshSubscribers(newToken)
retryRequest().then(resolve).catch(reject).finally(() => {
isRefreshing = false
refreshSubscribers = []
if (loading) {
uni.hideLoading()
}
innerResolve()
})
}).catch((error) => {
isRefreshing = false
refreshSubscribers = []
uni.showToast({
title: '登录过期,请重新登录',
icon: 'none'
})
reject(error)
innerReject(error)
2026-05-15 14:16:31 +08:00
})
})
2025-03-28 15:19:42 +08:00
}
export function uploadFile(tempFilePaths, loading = false) {
2025-10-31 17:24:07 +08:00
if (loading) {
uni.showLoading({
title: '请稍后',
mask: true
})
}
let Authorization = ''
if (useUserStore().token) {
Authorization = `Bearer ${useUserStore().token}`
2025-10-31 17:24:07 +08:00
}
2025-03-28 15:19:42 +08:00
2025-10-31 17:24:07 +08:00
const header = {};
header["Authorization"] = Authorization;
2025-10-31 17:24:07 +08:00
return new Promise((resolve, reject) => {
uni.uploadFile({
2026-04-09 21:14:25 +08:00
url: config.baseUrl + '/app/file/uploadFile',
2025-10-31 17:24:07 +08:00
filePath: tempFilePaths,
name: 'file',
header,
success: (uploadFileRes) => {
if (uploadFileRes.statusCode === 200) {
return resolve(uploadFileRes.data)
}
},
fail: (err) => {
reject(err)
},
complete: () => {
if (loading) {
uni.hideLoading();
}
}
})
})
}
2026-03-10 17:13:38 +08:00
export function myRequest(url, data = {}, method = 'GET', port = 9100, headers = {}, loading = false,urlType='') {
2025-10-31 17:24:07 +08:00
let LCBaseUrl = config.LCBaseUrl
if (port != 9100) {
LCBaseUrl = config.LCBaseUrlInner
}
2026-03-10 17:13:38 +08:00
if(urlType=='jobRecommend'){
LCBaseUrl=config.jobRecommendUrl
}else if(urlType=='policyRecommend'){
LCBaseUrl=config.policyRecommendUrl
}
2025-10-31 17:24:07 +08:00
const header = headers || {};
// 上下文
// /jobfair-api/jobfair/public 招聘会
// /dashboard-api/dashboard 用户登录相关
// /dashboard-api 获取验证码、登录
if (loading) {
uni.showLoading({
title: '请稍后',
mask: true
})
}
return new Promise((resolve, reject) => {
uni.request({
url: LCBaseUrl + url,
method: method,
data: data,
header,
success: resData => {
if(url=='/dashboard/auth/heart'){
resolve(resData.data)
return
}else{
// 响应拦截
if (resData.statusCode === 200) {
const {
code,
msg
} = resData.data
2025-11-04 14:31:37 +08:00
if(resData.data?.code == undefined){
resolve(resData.data)
return
}
2025-10-31 17:24:07 +08:00
if (code === 200) {
resolve(resData.data)
return
}
2025-12-18 11:46:39 +08:00
// 处理业务错误
if (resData.data?.code === 401 || resData.data?.code === 402) {
const pages = getCurrentPages();
if (pages.length >= 10) {
// 页面栈已满使用redirectTo替代
uni.redirectTo({
url:'/packageB/login?flag=nw',
fail: (err) => {
console.error('页面跳转失败:', err);
}
});
} else {
uni.navigateTo({
url:'/packageB/login?flag=nw',
fail: (err) => {
console.error('页面跳转失败:', err);
// 失败后尝试redirectTo
uni.redirectTo({
url:'/packageB/login?flag=nw',
fail: (err2) => {
console.error('redirectTo也失败:', err2);
}
});
}
});
}
useUserStore().logOut()
2025-10-31 17:24:07 +08:00
}
// 显示具体的错误信息
const errorMsg = msg || '请求出现异常,请联系工作人员'
// uni.showToast({
// title: errorMsg,
// icon: 'none'
// })
2025-10-31 17:24:07 +08:00
const err = new Error(errorMsg)
err.error = resData
reject(err)
return
}
// HTTP状态码不是200的情况
const err = new Error('网络请求失败,请检查网络连接')
err.error = resData
reject(err)
}
},
fail: (err) => {
reject(err)
},
complete: () => {
if (loading) {
uni.hideLoading();
}
}
})
})
}