解决跨域问题
This commit is contained in:
+5
-15
@@ -8,7 +8,6 @@
|
||||
*/
|
||||
|
||||
/** ai-server 统一响应 */
|
||||
import { request } from '../request/ai';
|
||||
interface AiResp<T = any> {
|
||||
code: number;
|
||||
message: string;
|
||||
@@ -181,22 +180,13 @@ export interface RecognizeResult {
|
||||
materials_suggest: string[];
|
||||
}
|
||||
|
||||
export function aiRecognize(content: string, deviceTags: string[] = []){
|
||||
return request({
|
||||
url: '/open/v1/moc/change/recognize',
|
||||
method: 'post',
|
||||
params: {
|
||||
request_id: nextRequestId('rec'),
|
||||
content,
|
||||
device_tags: deviceTags
|
||||
}
|
||||
export function aiRecognize(content: string, deviceTags: string[] = []) {
|
||||
return aiFetch<RecognizeResult>('/open/v1/moc/change/recognize', {
|
||||
request_id: nextRequestId('rec'),
|
||||
content,
|
||||
device_tags: deviceTags
|
||||
});
|
||||
}
|
||||
// aiFetch<RecognizeResult>('/open/v1/moc/change/recognize', {
|
||||
// request_id: nextRequestId('rec'),
|
||||
// content,
|
||||
// device_tags: deviceTags
|
||||
// });
|
||||
|
||||
|
||||
|
||||
|
||||
+68
-68
@@ -1,68 +1,68 @@
|
||||
import { request } from '../request';
|
||||
|
||||
/** 变更预识别查询
|
||||
*
|
||||
*/
|
||||
export function precheckApi(id: number) {
|
||||
return request({
|
||||
url: `/api/changes/${id}/precheck`,
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 变更预识别保存
|
||||
*
|
||||
*/
|
||||
export function precheckSaveApi(params: {
|
||||
change_id: number,
|
||||
title: string,
|
||||
description: string,
|
||||
severity: string,
|
||||
probability: string,
|
||||
protection: string,
|
||||
compare_rows: {item: string, before_text: string, after_text: string}[]
|
||||
}) {
|
||||
return request({
|
||||
url: '/api/changes/precheck',
|
||||
method: 'post',
|
||||
data: params
|
||||
});
|
||||
}
|
||||
|
||||
/** 变更申请表查询
|
||||
*
|
||||
*/
|
||||
export function applicationApi(id: number) {
|
||||
return request({
|
||||
url: `/api/changes/${id}/apply-form`,
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 变更申请表保存
|
||||
*
|
||||
*/
|
||||
export function applicationSaveApi(id: number, params: {
|
||||
change_type: number,
|
||||
change_level: number,
|
||||
duration_type: number,
|
||||
restore_deadline: string,
|
||||
org_id: number,
|
||||
urgent: number,
|
||||
purposes: string[],
|
||||
effect: string,
|
||||
main_changes: string[],
|
||||
related_changes: string[],
|
||||
materials: string,
|
||||
update_docs: string[],
|
||||
disciplines: string[],
|
||||
manage_dept: string,
|
||||
plan_use_date: string,
|
||||
risk_tools: string[],
|
||||
}) {
|
||||
return request({
|
||||
url: `/api/changes/${id}/apply-form`,
|
||||
method: 'post',
|
||||
data: params
|
||||
});
|
||||
}
|
||||
import { request } from '../request';
|
||||
|
||||
/** 变更预识别查询
|
||||
*
|
||||
*/
|
||||
export function precheckApi(id: number) {
|
||||
return request({
|
||||
url: `/api/changes/${id}/precheck`,
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 变更预识别保存
|
||||
*
|
||||
*/
|
||||
export function precheckSaveApi(params: {
|
||||
change_id: number,
|
||||
title: string,
|
||||
description: string,
|
||||
severity: string,
|
||||
probability: string,
|
||||
protection: string,
|
||||
compare_rows: {item: string, before_text: string, after_text: string}[]
|
||||
}) {
|
||||
return request({
|
||||
url: '/api/changes/precheck',
|
||||
method: 'post',
|
||||
data: params
|
||||
});
|
||||
}
|
||||
|
||||
/** 变更申请表查询
|
||||
*
|
||||
*/
|
||||
export function applicationApi(id: number) {
|
||||
return request({
|
||||
url: `/api/changes/${id}/apply-form`,
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 变更申请表保存
|
||||
*
|
||||
*/
|
||||
export function applicationSaveApi(id: number, params: {
|
||||
change_type: number,
|
||||
change_level: number,
|
||||
duration_type: number,
|
||||
restore_deadline: string,
|
||||
org_id: number,
|
||||
urgent: number,
|
||||
purposes: string[],
|
||||
effect: string,
|
||||
main_changes: string[],
|
||||
related_changes: string[],
|
||||
materials: string,
|
||||
update_docs: string[],
|
||||
disciplines: string[],
|
||||
manage_dept: string,
|
||||
plan_use_date: string,
|
||||
risk_tools: string[],
|
||||
}) {
|
||||
return request({
|
||||
url: `/api/changes/${id}/apply-form`,
|
||||
method: 'post',
|
||||
data: params
|
||||
});
|
||||
}
|
||||
|
||||
+96
-96
@@ -1,96 +1,96 @@
|
||||
import { request } from '../request';
|
||||
|
||||
// 获取配置
|
||||
export function systemConfigApi() {
|
||||
return request({
|
||||
url: '/api/system-config',
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
// 添加配置项
|
||||
export function addSystemConfigApi(data:{group_key:string, label:string,color:string,remark?:string,value:string}) {
|
||||
return request({
|
||||
url: '/api/system-config',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
}
|
||||
// 编辑配置项
|
||||
export function editSystemConfigApi(id:number, data:{group_key:string, label:string,color:string,remark?:string,value:string}) {
|
||||
return request({
|
||||
url: `/api/system-config/${id}`,
|
||||
method: 'put',
|
||||
data,
|
||||
});
|
||||
}
|
||||
// 批量修改ai配置项和变更编号规则
|
||||
export function updateConfigApi(data:{items:any[]}) {
|
||||
return request({
|
||||
url: '/api/system-config/batch',
|
||||
method: 'put',
|
||||
data,
|
||||
});
|
||||
}
|
||||
// 删除配置项
|
||||
export function deleteSystemConfigApi(id:number) {
|
||||
return request({
|
||||
url: `/api/system-config/${id}`,
|
||||
method: 'delete',
|
||||
});
|
||||
}
|
||||
|
||||
// 审批模板列表
|
||||
export function templateListApi() {
|
||||
return request({
|
||||
url: '/api/approval-templates',
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
// 审批用户列表
|
||||
export function peopleListApi() {
|
||||
return request({
|
||||
url: '/api/approval-flow/users',
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
// 新增审批模板
|
||||
export function addTemplateApi(data:any) {
|
||||
return request({
|
||||
url: '/api/approval-templates',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
}
|
||||
// 编辑审批模板
|
||||
export function editTemplateApi(id:number,data:any) {
|
||||
return request({
|
||||
url: `/api/approval-templates/${id}`,
|
||||
method: 'put',
|
||||
data,
|
||||
});
|
||||
}
|
||||
// 删除审批模板
|
||||
export function deleteTemplateApi(id:number) {
|
||||
return request({
|
||||
url: `/api/approval-templates/${id}`,
|
||||
method: 'delete',
|
||||
});
|
||||
}
|
||||
|
||||
// 获取风险矩阵配置
|
||||
export function matrixConfigApi(bizType:string) {
|
||||
return request({
|
||||
url: `/api/risk-matrix/${bizType}`,
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
// 保存风险矩阵配置
|
||||
export function saveMatrixConfigApi(bizType:string,data:any) {
|
||||
return request({
|
||||
url: `/api/risk-matrix/${bizType}`,
|
||||
method: 'put',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
import { request } from '../request';
|
||||
|
||||
// 获取配置
|
||||
export function systemConfigApi() {
|
||||
return request({
|
||||
url: '/api/system-config',
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
// 添加配置项
|
||||
export function addSystemConfigApi(data:{group_key:string, label:string,color:string,remark?:string,value:string}) {
|
||||
return request({
|
||||
url: '/api/system-config',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
}
|
||||
// 编辑配置项
|
||||
export function editSystemConfigApi(id:number, data:{group_key:string, label:string,color:string,remark?:string,value:string}) {
|
||||
return request({
|
||||
url: `/api/system-config/${id}`,
|
||||
method: 'put',
|
||||
data,
|
||||
});
|
||||
}
|
||||
// 批量修改ai配置项和变更编号规则
|
||||
export function updateConfigApi(data:{items:any[]}) {
|
||||
return request({
|
||||
url: '/api/system-config/batch',
|
||||
method: 'put',
|
||||
data,
|
||||
});
|
||||
}
|
||||
// 删除配置项
|
||||
export function deleteSystemConfigApi(id:number) {
|
||||
return request({
|
||||
url: `/api/system-config/${id}`,
|
||||
method: 'delete',
|
||||
});
|
||||
}
|
||||
|
||||
// 审批模板列表
|
||||
export function templateListApi() {
|
||||
return request({
|
||||
url: '/api/approval-templates',
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
// 审批用户列表
|
||||
export function peopleListApi() {
|
||||
return request({
|
||||
url: '/api/approval-flow/users',
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
// 新增审批模板
|
||||
export function addTemplateApi(data:any) {
|
||||
return request({
|
||||
url: '/api/approval-templates',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
}
|
||||
// 编辑审批模板
|
||||
export function editTemplateApi(id:number,data:any) {
|
||||
return request({
|
||||
url: `/api/approval-templates/${id}`,
|
||||
method: 'put',
|
||||
data,
|
||||
});
|
||||
}
|
||||
// 删除审批模板
|
||||
export function deleteTemplateApi(id:number) {
|
||||
return request({
|
||||
url: `/api/approval-templates/${id}`,
|
||||
method: 'delete',
|
||||
});
|
||||
}
|
||||
|
||||
// 获取风险矩阵配置
|
||||
export function matrixConfigApi(bizType:string) {
|
||||
return request({
|
||||
url: `/api/risk-matrix/${bizType}`,
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
// 保存风险矩阵配置
|
||||
export function saveMatrixConfigApi(bizType:string,data:any) {
|
||||
return request({
|
||||
url: `/api/risk-matrix/${bizType}`,
|
||||
method: 'put',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
+111
-111
@@ -1,111 +1,111 @@
|
||||
import { request } from '../request';
|
||||
|
||||
// 组织列表
|
||||
export function orgListApi() {
|
||||
return request({
|
||||
url: '/api/organization/tree',
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
// 新增组织
|
||||
export function addOrgApi(params: { label: string, parent_id: number, sort: number, is_bottom: number, org_code: string }) {
|
||||
return request({
|
||||
url: '/api/organization',
|
||||
method: 'post',
|
||||
data: params
|
||||
});
|
||||
}
|
||||
// 编辑组织
|
||||
export function editOrgApi(id: number, params: { label: string, parent_id: number, sort: number, is_bottom: number, org_code: string }) {
|
||||
return request({
|
||||
url: `/api/organization/${id}`,
|
||||
method: 'put',
|
||||
data: params
|
||||
});
|
||||
}
|
||||
// 删除组织
|
||||
export function deleteOrgApi(id: number) {
|
||||
return request({
|
||||
url: `/api/organization/${id}`,
|
||||
method: 'delete',
|
||||
});
|
||||
}
|
||||
|
||||
// 获取用户列表
|
||||
export function userListApi(params: {org_id: number, keyword: string, page: number, limit: number }) {
|
||||
return request({
|
||||
url: '/api/user',
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 新增用户
|
||||
export function addUserApi(params: { real_name: string, username: string, gender: number, mobile?: string, email?: string, dept_ids: number[], role_id: number | null, org_ids: number[], enabled: boolean }) {
|
||||
return request({
|
||||
url: '/api/user',
|
||||
method: 'post',
|
||||
data: params
|
||||
});
|
||||
}
|
||||
|
||||
// 编辑用户
|
||||
export function editUserApi(id: number, params: { real_name: string, username: string, gender: number, mobile?: string, email?: string, dept_ids: number[], role_id: number | null, org_ids: number[], enabled: boolean }) {
|
||||
return request({
|
||||
url: `/api/user/${id}`,
|
||||
method: 'put',
|
||||
data: params
|
||||
});
|
||||
}
|
||||
|
||||
// 删除用户
|
||||
export function deleteUserApi(params: { id: number, type: number }) {
|
||||
return request({
|
||||
url: '/api/user/operation',
|
||||
method: 'post',
|
||||
data: params
|
||||
});
|
||||
}
|
||||
|
||||
// 重置数据权限
|
||||
export function resetDataApi() {
|
||||
return request({
|
||||
url: `/api/user/reset-data-permission`,
|
||||
method: 'post',
|
||||
});
|
||||
}
|
||||
|
||||
// 下载用户导入模板
|
||||
export function downloadTemplateApi() {
|
||||
return request({
|
||||
url: `/api/user/template`,
|
||||
method: 'get',
|
||||
responseType: 'blob',
|
||||
});
|
||||
}
|
||||
|
||||
// 导入用户
|
||||
export function importUserApi(params: FormData) {
|
||||
return request({
|
||||
url: `/api/user/import`,
|
||||
method: 'post',
|
||||
data: params
|
||||
});
|
||||
}
|
||||
// 重置用户密码
|
||||
export function resetPasswordApi(id: number) {
|
||||
return request({
|
||||
url: `/api/user/${id}/reset-password`,
|
||||
method: 'post',
|
||||
});
|
||||
}
|
||||
|
||||
// 修改用户密码
|
||||
export function changePasswordApi(params: { oldPassword: string, password: string }) {
|
||||
return request({
|
||||
url: `/api/user/change-password`,
|
||||
method: 'post',
|
||||
data: params
|
||||
});
|
||||
}
|
||||
|
||||
import { request } from '../request';
|
||||
|
||||
// 组织列表
|
||||
export function orgListApi() {
|
||||
return request({
|
||||
url: '/api/organization/tree',
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
// 新增组织
|
||||
export function addOrgApi(params: { label: string, parent_id: number, sort: number, is_bottom: number, org_code: string }) {
|
||||
return request({
|
||||
url: '/api/organization',
|
||||
method: 'post',
|
||||
data: params
|
||||
});
|
||||
}
|
||||
// 编辑组织
|
||||
export function editOrgApi(id: number, params: { label: string, parent_id: number, sort: number, is_bottom: number, org_code: string }) {
|
||||
return request({
|
||||
url: `/api/organization/${id}`,
|
||||
method: 'put',
|
||||
data: params
|
||||
});
|
||||
}
|
||||
// 删除组织
|
||||
export function deleteOrgApi(id: number) {
|
||||
return request({
|
||||
url: `/api/organization/${id}`,
|
||||
method: 'delete',
|
||||
});
|
||||
}
|
||||
|
||||
// 获取用户列表
|
||||
export function userListApi(params: {org_id: number, keyword: string, page: number, limit: number }) {
|
||||
return request({
|
||||
url: '/api/user',
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 新增用户
|
||||
export function addUserApi(params: { real_name: string, username: string, gender: number, mobile?: string, email?: string, dept_ids: number[], role_id: number | null, org_ids: number[], enabled: boolean }) {
|
||||
return request({
|
||||
url: '/api/user',
|
||||
method: 'post',
|
||||
data: params
|
||||
});
|
||||
}
|
||||
|
||||
// 编辑用户
|
||||
export function editUserApi(id: number, params: { real_name: string, username: string, gender: number, mobile?: string, email?: string, dept_ids: number[], role_id: number | null, org_ids: number[], enabled: boolean }) {
|
||||
return request({
|
||||
url: `/api/user/${id}`,
|
||||
method: 'put',
|
||||
data: params
|
||||
});
|
||||
}
|
||||
|
||||
// 删除用户
|
||||
export function deleteUserApi(params: { id: number, type: number }) {
|
||||
return request({
|
||||
url: '/api/user/operation',
|
||||
method: 'post',
|
||||
data: params
|
||||
});
|
||||
}
|
||||
|
||||
// 重置数据权限
|
||||
export function resetDataApi() {
|
||||
return request({
|
||||
url: `/api/user/reset-data-permission`,
|
||||
method: 'post',
|
||||
});
|
||||
}
|
||||
|
||||
// 下载用户导入模板
|
||||
export function downloadTemplateApi() {
|
||||
return request({
|
||||
url: `/api/user/template`,
|
||||
method: 'get',
|
||||
responseType: 'blob',
|
||||
});
|
||||
}
|
||||
|
||||
// 导入用户
|
||||
export function importUserApi(params: FormData) {
|
||||
return request({
|
||||
url: `/api/user/import`,
|
||||
method: 'post',
|
||||
data: params
|
||||
});
|
||||
}
|
||||
// 重置用户密码
|
||||
export function resetPasswordApi(id: number) {
|
||||
return request({
|
||||
url: `/api/user/${id}/reset-password`,
|
||||
method: 'post',
|
||||
});
|
||||
}
|
||||
|
||||
// 修改用户密码
|
||||
export function changePasswordApi(params: { oldPassword: string, password: string }) {
|
||||
return request({
|
||||
url: `/api/user/change-password`,
|
||||
method: 'post',
|
||||
data: params
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+124
-124
@@ -1,124 +1,124 @@
|
||||
import type { AxiosResponse } from 'axios';
|
||||
import { BACKEND_ERROR_CODE, createFlatRequest } from '@sa/axios';
|
||||
import { useAuthStore } from '@/store/modules/auth';
|
||||
import { getServiceAiURL } from '@/utils/service';
|
||||
import { $t } from '@/locales';
|
||||
import { getAiAuthorization, handleExpiredRequest, showErrorMsg } from './shared';
|
||||
import type { RequestInstanceState } from './type';
|
||||
|
||||
const isHttpProxy = import.meta.env.DEV && import.meta.env.VITE_HTTP_PROXY === 'Y';
|
||||
const { baseURL } = getServiceAiURL(import.meta.env, isHttpProxy);
|
||||
|
||||
export const request = createFlatRequest(
|
||||
{
|
||||
baseURL,
|
||||
headers: {}
|
||||
},
|
||||
{
|
||||
defaultState: {
|
||||
errMsgStack: [],
|
||||
refreshTokenPromise: null
|
||||
} as RequestInstanceState,
|
||||
transform(response: AxiosResponse<App.Service.Response<any>>) {
|
||||
return response.data.data;
|
||||
},
|
||||
async onRequest(config) {
|
||||
const Authorization = getAiAuthorization();
|
||||
Object.assign(config.headers, { Authorization });
|
||||
|
||||
return config;
|
||||
},
|
||||
isBackendSuccess(response) {
|
||||
// when the backend response code is "0000"(default), it means the request is success
|
||||
// to change this logic by yourself, you can modify the `VITE_SERVICE_SUCCESS_CODE` in `.env` file
|
||||
return String(response.data.code) === import.meta.env.VITE_SERVICE_SUCCESS_CODE;
|
||||
},
|
||||
async onBackendFail(response, instance) {
|
||||
const authStore = useAuthStore();
|
||||
const responseCode = String(response.data.code);
|
||||
|
||||
function handleLogout() {
|
||||
authStore.resetStore();
|
||||
}
|
||||
|
||||
function logoutAndCleanup() {
|
||||
handleLogout();
|
||||
window.removeEventListener('beforeunload', handleLogout);
|
||||
|
||||
request.state.errMsgStack = request.state.errMsgStack.filter(msg => msg !== response.data.msg);
|
||||
}
|
||||
|
||||
// when the backend response code is in `logoutCodes`, it means the user will be logged out and redirected to login page
|
||||
const logoutCodes = import.meta.env.VITE_SERVICE_LOGOUT_CODES?.split(',') || [];
|
||||
if (logoutCodes.includes(responseCode)) {
|
||||
handleLogout();
|
||||
return null;
|
||||
}
|
||||
|
||||
// when the backend response code is in `modalLogoutCodes`, it means the user will be logged out by displaying a modal
|
||||
const modalLogoutCodes = import.meta.env.VITE_SERVICE_MODAL_LOGOUT_CODES?.split(',') || [];
|
||||
if (modalLogoutCodes.includes(responseCode) && !request.state.errMsgStack?.includes(response.data.msg)) {
|
||||
request.state.errMsgStack = [...(request.state.errMsgStack || []), response.data.msg];
|
||||
|
||||
// prevent the user from refreshing the page
|
||||
window.addEventListener('beforeunload', handleLogout);
|
||||
|
||||
window.$dialog?.error({
|
||||
title: $t('common.error'),
|
||||
content: response.data.msg,
|
||||
positiveText: $t('common.confirm'),
|
||||
maskClosable: false,
|
||||
closeOnEsc: false,
|
||||
onPositiveClick() {
|
||||
logoutAndCleanup();
|
||||
},
|
||||
onClose() {
|
||||
logoutAndCleanup();
|
||||
}
|
||||
});
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// when the backend response code is in `expiredTokenCodes`, it means the token is expired, and refresh token
|
||||
// the api `refreshToken` can not return error code in `expiredTokenCodes`, otherwise it will be a dead loop, should return `logoutCodes` or `modalLogoutCodes`
|
||||
const expiredTokenCodes = import.meta.env.VITE_SERVICE_EXPIRED_TOKEN_CODES?.split(',') || [];
|
||||
if (expiredTokenCodes.includes(responseCode)) {
|
||||
const success = await handleExpiredRequest(request.state);
|
||||
if (success) {
|
||||
const Authorization = getAuthorization();
|
||||
Object.assign(response.config.headers, { Authorization });
|
||||
|
||||
return instance.request(response.config) as Promise<AxiosResponse>;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
onError(error) {
|
||||
// when the request is fail, you can show error message
|
||||
let message = error.message;
|
||||
let backendErrorCode = '';
|
||||
|
||||
// get backend error message and code
|
||||
if (error.code === BACKEND_ERROR_CODE) {
|
||||
message = error.response?.data?.message || message;
|
||||
backendErrorCode = String(error.response?.data?.code || '');
|
||||
}
|
||||
|
||||
// the error message is displayed in the modal
|
||||
const modalLogoutCodes = import.meta.env.VITE_SERVICE_MODAL_LOGOUT_CODES?.split(',') || [];
|
||||
if (modalLogoutCodes.includes(backendErrorCode)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// when the token is expired, refresh token and retry request, so no need to show error message
|
||||
const expiredTokenCodes = import.meta.env.VITE_SERVICE_EXPIRED_TOKEN_CODES?.split(',') || [];
|
||||
if (expiredTokenCodes.includes(backendErrorCode)) {
|
||||
return;
|
||||
}
|
||||
|
||||
showErrorMsg(request.state, message);
|
||||
}
|
||||
}
|
||||
);
|
||||
import type { AxiosResponse } from 'axios';
|
||||
import { BACKEND_ERROR_CODE, createFlatRequest } from '@sa/axios';
|
||||
import { useAuthStore } from '@/store/modules/auth';
|
||||
import { getServiceAiURL } from '@/utils/service';
|
||||
import { $t } from '@/locales';
|
||||
import { getAiAuthorization, handleExpiredRequest, showErrorMsg } from './shared';
|
||||
import type { RequestInstanceState } from './type';
|
||||
|
||||
const isHttpProxy = import.meta.env.DEV && import.meta.env.VITE_HTTP_PROXY === 'Y';
|
||||
const { baseURL } = getServiceAiURL(import.meta.env, isHttpProxy);
|
||||
|
||||
export const request = createFlatRequest(
|
||||
{
|
||||
baseURL,
|
||||
headers: {}
|
||||
},
|
||||
{
|
||||
defaultState: {
|
||||
errMsgStack: [],
|
||||
refreshTokenPromise: null
|
||||
} as RequestInstanceState,
|
||||
transform(response: AxiosResponse<App.Service.Response<any>>) {
|
||||
return response.data.data;
|
||||
},
|
||||
async onRequest(config) {
|
||||
const Authorization = getAiAuthorization();
|
||||
Object.assign(config.headers, { Authorization });
|
||||
|
||||
return config;
|
||||
},
|
||||
isBackendSuccess(response) {
|
||||
// when the backend response code is "0000"(default), it means the request is success
|
||||
// to change this logic by yourself, you can modify the `VITE_SERVICE_SUCCESS_CODE` in `.env` file
|
||||
return String(response.data.code) === import.meta.env.VITE_SERVICE_SUCCESS_CODE;
|
||||
},
|
||||
async onBackendFail(response, instance) {
|
||||
const authStore = useAuthStore();
|
||||
const responseCode = String(response.data.code);
|
||||
|
||||
function handleLogout() {
|
||||
authStore.resetStore();
|
||||
}
|
||||
|
||||
function logoutAndCleanup() {
|
||||
handleLogout();
|
||||
window.removeEventListener('beforeunload', handleLogout);
|
||||
|
||||
request.state.errMsgStack = request.state.errMsgStack.filter(msg => msg !== response.data.msg);
|
||||
}
|
||||
|
||||
// when the backend response code is in `logoutCodes`, it means the user will be logged out and redirected to login page
|
||||
const logoutCodes = import.meta.env.VITE_SERVICE_LOGOUT_CODES?.split(',') || [];
|
||||
if (logoutCodes.includes(responseCode)) {
|
||||
handleLogout();
|
||||
return null;
|
||||
}
|
||||
|
||||
// when the backend response code is in `modalLogoutCodes`, it means the user will be logged out by displaying a modal
|
||||
const modalLogoutCodes = import.meta.env.VITE_SERVICE_MODAL_LOGOUT_CODES?.split(',') || [];
|
||||
if (modalLogoutCodes.includes(responseCode) && !request.state.errMsgStack?.includes(response.data.msg)) {
|
||||
request.state.errMsgStack = [...(request.state.errMsgStack || []), response.data.msg];
|
||||
|
||||
// prevent the user from refreshing the page
|
||||
window.addEventListener('beforeunload', handleLogout);
|
||||
|
||||
window.$dialog?.error({
|
||||
title: $t('common.error'),
|
||||
content: response.data.msg,
|
||||
positiveText: $t('common.confirm'),
|
||||
maskClosable: false,
|
||||
closeOnEsc: false,
|
||||
onPositiveClick() {
|
||||
logoutAndCleanup();
|
||||
},
|
||||
onClose() {
|
||||
logoutAndCleanup();
|
||||
}
|
||||
});
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// when the backend response code is in `expiredTokenCodes`, it means the token is expired, and refresh token
|
||||
// the api `refreshToken` can not return error code in `expiredTokenCodes`, otherwise it will be a dead loop, should return `logoutCodes` or `modalLogoutCodes`
|
||||
const expiredTokenCodes = import.meta.env.VITE_SERVICE_EXPIRED_TOKEN_CODES?.split(',') || [];
|
||||
if (expiredTokenCodes.includes(responseCode)) {
|
||||
const success = await handleExpiredRequest(request.state);
|
||||
if (success) {
|
||||
const Authorization = getAuthorization();
|
||||
Object.assign(response.config.headers, { Authorization });
|
||||
|
||||
return instance.request(response.config) as Promise<AxiosResponse>;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
onError(error) {
|
||||
// when the request is fail, you can show error message
|
||||
let message = error.message;
|
||||
let backendErrorCode = '';
|
||||
|
||||
// get backend error message and code
|
||||
if (error.code === BACKEND_ERROR_CODE) {
|
||||
message = error.response?.data?.message || message;
|
||||
backendErrorCode = String(error.response?.data?.code || '');
|
||||
}
|
||||
|
||||
// the error message is displayed in the modal
|
||||
const modalLogoutCodes = import.meta.env.VITE_SERVICE_MODAL_LOGOUT_CODES?.split(',') || [];
|
||||
if (modalLogoutCodes.includes(backendErrorCode)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// when the token is expired, refresh token and retry request, so no need to show error message
|
||||
const expiredTokenCodes = import.meta.env.VITE_SERVICE_EXPIRED_TOKEN_CODES?.split(',') || [];
|
||||
if (expiredTokenCodes.includes(backendErrorCode)) {
|
||||
return;
|
||||
}
|
||||
|
||||
showErrorMsg(request.state, message);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user