request.ts 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. import axios from "axios";
  2. import { download } from "@/utils/tool";
  3. import { get, isEmpty } from "lodash-es";
  4. import qs from "qs";
  5. // import { h } from 'vue';
  6. import { getAuthorization, getMD5 } from "./crypto";
  7. import router from "@/router";
  8. import { initSyncTime, fetchTime } from "./syncServerTime";
  9. import { local } from "@/utils/tool";
  10. import { useAppStore } from "@/store";
  11. import { message } from "@qmth/ui";
  12. function getDeviceId() {
  13. let deviceId = local.get("deviceId");
  14. if (deviceId) return deviceId;
  15. if (!deviceId) {
  16. deviceId = getMD5(Math.random() + "-" + Date.now());
  17. local.set("deviceId", deviceId);
  18. return deviceId;
  19. }
  20. }
  21. function setAuth(config: any) {
  22. let userSession = sessionStorage.getItem("user");
  23. if (userSession && !config.noAuth) {
  24. let user = JSON.parse(userSession).userInfo;
  25. if (!user) {
  26. return;
  27. }
  28. const timestamp = fetchTime();
  29. const authorization = getAuthorization(
  30. {
  31. method: config.method,
  32. uri: config.url.split("?")[0].trim(),
  33. timestamp,
  34. sessionId: user.sessionId,
  35. token: user.accessToken,
  36. },
  37. "token"
  38. );
  39. config.headers["Authorization"] = authorization;
  40. config.headers["time"] = timestamp;
  41. }
  42. }
  43. function createService() {
  44. // 创建一个 axios 实例
  45. const service = axios.create();
  46. // HTTP request 拦截器
  47. service.interceptors.request.use(
  48. (config: any) => {
  49. setAuth(config);
  50. const appStore = useAppStore();
  51. if (config.loading) {
  52. appStore.setLoading(true);
  53. }
  54. if (config.download) {
  55. config.responseType ??= "blob";
  56. }
  57. return config;
  58. },
  59. (error) => {
  60. // 失败
  61. return Promise.reject(error);
  62. }
  63. );
  64. const rejectWhiteList: string[] = [];
  65. // HTTP response 拦截器
  66. service.interceptors.response.use(
  67. (response: any) => {
  68. initSyncTime(new Date(response.headers.date).getTime());
  69. const appStore = useAppStore();
  70. if (response.config.loading) {
  71. appStore.setLoading(false);
  72. }
  73. // 以下代码看后端是否有统一在接口里增加外层code的规范
  74. if (response.data?.code && response.data?.code !== 200) {
  75. message.error(response.data?.message);
  76. }
  77. if (response.config.download && response.config.responseType === "blob") {
  78. download(response);
  79. }
  80. return response.data;
  81. },
  82. (error) => {
  83. if (error.response) {
  84. initSyncTime(new Date(error.response.headers.date).getTime());
  85. }
  86. const appStore = useAppStore();
  87. if (error.config?.loading) {
  88. appStore.setLoading(false);
  89. }
  90. const err = (text: string) => {
  91. !rejectWhiteList.includes(error.config?.url) &&
  92. message.error(
  93. error.response && error.response.data && error.response.data.message
  94. ? error.response.data.message
  95. : text
  96. );
  97. };
  98. if (error.response) {
  99. switch (error.response.status) {
  100. case 404:
  101. err(`服务器资源不存在`);
  102. break;
  103. case 500:
  104. err(`服务器内部错误`);
  105. break;
  106. case 401:
  107. message.error("登录状态已过期");
  108. router.replace({ name: "Login" });
  109. break;
  110. case 403:
  111. err(`没有权限访问该资源`);
  112. break;
  113. default:
  114. err(JSON.stringify(error?.response || "未知错误"));
  115. }
  116. } else {
  117. err("请求超时,服务器无响应!");
  118. }
  119. return Promise.reject(
  120. error.response && error.response.data ? error.response.data : null
  121. );
  122. }
  123. );
  124. return service;
  125. }
  126. /**
  127. * @description 创建请求方法
  128. * @param {Object} service axios 实例
  129. */
  130. function createRequest(service: any) {
  131. return function (config: any) {
  132. const env = process.env;
  133. let headers = {
  134. platform: "WEB",
  135. deviceId: getDeviceId(),
  136. ...(config.headers || {}),
  137. "Content-Type": get(
  138. config,
  139. "headers.Content-Type",
  140. // "application/json;charset=UTF-8"
  141. "application/x-www-form-urlencoded"
  142. ),
  143. };
  144. const configDefault = {
  145. method: "post",
  146. timeout: 120000,
  147. // baseURL: env.VITE_APP_PROXY_URL ? "" : env.VITE_APP_BASE_URL,
  148. baseURL: env.VITE_APP_PROXY_URL ? "" : local.get("baseUrl") || "/",
  149. data: {},
  150. };
  151. const option = Object.assign(configDefault, config, { headers: headers });
  152. return service(option);
  153. };
  154. }
  155. export function paramsSerializer(params: any) {
  156. return qs.stringify(params);
  157. }
  158. // 用于真实网络请求的实例和请求方法
  159. export const service = createService();
  160. export const request = createRequest(service);