api.ts 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. import axios, { AxiosResponse } from 'axios';
  2. import { message } from 'antd';
  3. import config, { getHeaders } from './config';
  4. import LocalStorage from '@/LocalStorage';
  5. import { encryptBase64, encryptWithAes, generateAesKey, decryptWithAes, decryptBase64 } from '@/utils/crypto';
  6. import { encrypt, decrypt } from '@/utils/jsencrypt';
  7. import {
  8. mockFetchKnowledgeLibList,
  9. mockFetchKnowledgeLibDetail,
  10. mockCreateKnowledgeLib,
  11. mockModifyKnowledgeLib,
  12. mockDeleteKnowledgeLib,
  13. mockFetchEmbeddingList,
  14. mockFetchDocumentLibList,
  15. mockFetchDocumentLibDetail,
  16. mockModifyDocumentLib,
  17. mockDeleteDocumentLib,
  18. mockUploadDocument,
  19. mockFetchDocumentSetting,
  20. mockModifyDocumentSetting,
  21. mockFetchSliceList,
  22. mockFetchSliceDetail,
  23. mockAddSlice,
  24. mockModifySlice,
  25. mockDeleteSlice,
  26. mockFetchReviseToolList,
  27. mockFetchReviseToolAllList,
  28. mockFetchReviseToolSliceList,
  29. mockSubmitReviseSlice,
  30. mockFetchReviseHistoryList,
  31. mockFetchTakaiAppTypeList,
  32. mockFetchChatHistoryList,
  33. mockExportChatHistory,
  34. } from '@/mock/knowledgeApi';
  35. import { applicationMockHandlers } from '@/mock/applicationApi';
  36. import { authMockHandlers } from '@/mock/authApi';
  37. import { auditMockHandlers } from '@/mock/auditApi';
  38. import { overviewMockHandlers } from '@/mock/overviewApi';
  39. const encryptHeader = 'encrypt-key';
  40. // 是否启用 Mock 模式
  41. const USE_MOCK = true;
  42. // 创建 axios 实例
  43. const axiosInstance = axios.create({
  44. baseURL: config.baseURL,
  45. timeout: 600000 * 2,// 请求超时 20 分钟
  46. });
  47. // Mock 请求处理映射
  48. const mockHandlerMap: Record<string, Function> = {
  49. // 知识库相关
  50. 'POST /bigmodel/api/knowledgeList': mockFetchKnowledgeLibList,
  51. 'GET /bigmodel/api/detailKnowledge': mockFetchKnowledgeLibDetail,
  52. 'POST /bigmodel/api/createKnowledge': mockCreateKnowledgeLib,
  53. 'PUT /bigmodel/api/updateKnowledge': mockModifyKnowledgeLib,
  54. 'DELETE /bigmodel/api/delKnowledge': mockDeleteKnowledgeLib,
  55. 'GET /bigmodel/api/embedding': mockFetchEmbeddingList,
  56. // 文档管理相关
  57. 'POST /bigmodel/api/documentList': mockFetchDocumentLibList,
  58. 'GET /bigmodel/api/documentDetail': mockFetchDocumentLibDetail,
  59. 'PUT /bigmodel/api/updateDocument': mockModifyDocumentLib,
  60. 'DELETE /bigmodel/api/delDocument': mockDeleteDocumentLib,
  61. 'POST /bigmodel/api/uploadDocument': mockUploadDocument,
  62. 'GET /bigmodel/api/documentSetting': mockFetchDocumentSetting,
  63. 'PUT /bigmodel/api/updateDocumentSetting': mockModifyDocumentSetting,
  64. // 切片管理相关
  65. 'POST /bigmodel/api/getSliceList': mockFetchSliceList,
  66. 'GET /bigmodel/api/getSliceDetail': mockFetchSliceDetail,
  67. 'POST /bigmodel/api/add/slice': mockAddSlice,
  68. 'PUT /bigmodel/api/updateSliceInfo': mockModifySlice,
  69. 'DELETE /bigmodel/api/deleteSlice': mockDeleteSlice,
  70. // 修订工具相关
  71. 'GET /deepseek/revise/pageList': mockFetchReviseToolList,
  72. 'GET /deepseek/revise/list': mockFetchReviseToolAllList,
  73. 'GET /deepseek/revise/sliceList': mockFetchReviseToolSliceList,
  74. 'PUT /deepseek/revise/reviseSlice': mockSubmitReviseSlice,
  75. 'GET /deepseek/revise/reviseHistoryList': mockFetchReviseHistoryList,
  76. // 字典数据相关
  77. 'GET /deepseek/api/standard_classification': () => mockFetchTakaiAppTypeList('standard_classification'),
  78. 'GET /deepseek/api/parsing_type': () => mockFetchTakaiAppTypeList('parsing_type'),
  79. 'GET /deepseek/api/splitting_type': () => mockFetchTakaiAppTypeList('splitting_type'),
  80. 'GET /deepseek/api/revision_status': () => mockFetchTakaiAppTypeList('revision_status'),
  81. // 聊天记录相关
  82. 'POST /bigmodel/api/chatHistory/list': mockFetchChatHistoryList,
  83. 'POST /bigmodel/api/dialog/export': mockExportChatHistory,
  84. // 应用管理相关
  85. ...applicationMockHandlers,
  86. // 认证与用户相关
  87. ...authMockHandlers,
  88. // 审核管理相关
  89. ...auditMockHandlers,
  90. // 首页统计相关
  91. ...overviewMockHandlers,
  92. };
  93. // 请求拦截器
  94. axiosInstance.interceptors.request.use(
  95. (config: any) => {
  96. const isEncrypt = config.headers?.isEncrypt === 'true';
  97. config.headers = {
  98. 'Content-Language': 'zh_CN',
  99. clientid:'e5cd7e4891bf95d1d19206ce24a7b32e',
  100. ...config.headers,
  101. ...getHeaders(),
  102. };
  103. if (!navigator.onLine) {
  104. message.error('网络故障');
  105. }
  106. // 当开启参数加密
  107. if (isEncrypt && (config.method === 'post' || config.method === 'put')) {
  108. // 生成一个 AES 密钥
  109. const aesKey = generateAesKey();
  110. config.headers[encryptHeader] = encrypt(encryptBase64(aesKey));
  111. config.data = typeof config.data === 'object' ? encryptWithAes(JSON.stringify(config.data), aesKey) : encryptWithAes(config.data, aesKey);
  112. }
  113. return config;
  114. }
  115. );
  116. // 响应拦截器 - 添加 Mock 支持
  117. axiosInstance.interceptors.request.use(
  118. (config: any) => {
  119. if (USE_MOCK) {
  120. const method = (config.method || 'GET').toUpperCase();
  121. const url = config.url || '';
  122. // 构建匹配键
  123. const matchKey = `${method} ${url.split('?')[0]}`;
  124. // 查找匹配的 Mock 处理器
  125. for (const [key, handler] of Object.entries(mockHandlerMap)) {
  126. if (matchKey.includes(key.replace(`${method} `, ''))) {
  127. // 找到匹配的 Mock 处理器,返回 Mock 数据
  128. return Promise.resolve({
  129. config,
  130. data: null,
  131. headers: config.headers,
  132. status: 200,
  133. statusText: 'OK',
  134. mockHandler: handler,
  135. mockParams: config.data || config.params,
  136. mockUrl: url,
  137. });
  138. }
  139. }
  140. }
  141. return config;
  142. }
  143. );
  144. // 响应拦截器
  145. axiosInstance.interceptors.response.use(
  146. (response: AxiosResponse) => {
  147. // 处理 Mock 响应
  148. if (response.mockHandler) {
  149. const handler = response.mockHandler;
  150. const params = response.mockParams;
  151. const url = response.mockUrl;
  152. // 从 URL 提取 ID 参数(用于详情接口)
  153. const urlParts = url.split('/');
  154. const idParam = urlParts[urlParts.length - 1];
  155. return handler(params || {}, idParam);
  156. }
  157. // 正常响应处理
  158. const { config, data } = response;
  159. if (config.responseType === 'blob') {
  160. return Promise.resolve(data);
  161. } else {
  162. if (data.code === 200) {// 成功
  163. return Promise.resolve(data);
  164. } else {// 失败
  165. if (data.code === 401) {
  166. LocalStorage.clear();
  167. message.error('登录过期');
  168. // 使用 window.location 确保跳转生效
  169. window.location.replace('/login');
  170. return Promise.reject();
  171. } else {
  172. message.error(data.msg||'请求失败');
  173. return Promise.reject(data);
  174. }
  175. }
  176. }
  177. },
  178. (error) => {// 错误信息
  179. // HTTP 状态码
  180. const statusCode = error.response?.status;
  181. if (String(error).includes('timeout')) {
  182. message.error('请求超时');
  183. } else {
  184. if (statusCode === 401) {
  185. LocalStorage.clear();
  186. message.error('登录过期');
  187. // 使用 window.location 确保跳转生效
  188. window.location.replace('/login');
  189. } else if (statusCode && statusCode < 500) {
  190. message.error('请求失败');
  191. } else {
  192. message.error('服务异常');
  193. }
  194. }
  195. return Promise.reject();
  196. }
  197. );
  198. export default axiosInstance;