@4399ywkf/cli 1.0.7 → 1.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (254) hide show
  1. package/dist/templates/AntdStaticMethods/index.tsx +20 -0
  2. package/dist/templates/AppTheme.tsx +136 -0
  3. package/dist/templates/DIRECTORY_STRUCTURE.md +141 -0
  4. package/dist/templates/GlobalProvider/AppTheme.tsx +136 -0
  5. package/dist/templates/GlobalProvider/Locale.tsx +84 -0
  6. package/dist/templates/GlobalProvider/Query.tsx +12 -0
  7. package/dist/templates/GlobalProvider/StyleRegistry.tsx +9 -0
  8. package/dist/templates/GlobalProvider/index.tsx +23 -0
  9. package/dist/templates/HarmonyOS_Sans_Bold.woff2 +0 -0
  10. package/dist/templates/HarmonyOS_Sans_Medium.woff2 +0 -0
  11. package/dist/templates/HarmonyOS_Sans_Regular.woff2 +0 -0
  12. package/dist/templates/Locale.tsx +49 -54
  13. package/dist/templates/MainContentWrap.tsx +11 -15
  14. package/dist/templates/Query.tsx +12 -0
  15. package/dist/templates/StyleRegistry.tsx +9 -0
  16. package/dist/templates/ThemeContext.tsx +27 -24
  17. package/dist/templates/analyzeUnusedKeys.ts +506 -0
  18. package/dist/templates/app/.i18nrc.js +57 -0
  19. package/dist/templates/app/config/env/.env.public.tpl +2 -19
  20. package/dist/templates/app/config/jwt/index.ts +4 -4
  21. package/dist/templates/app/config/request/error-handler.ts +67 -0
  22. package/dist/templates/app/config/request/index.ts +127 -129
  23. package/dist/templates/app/config/request/interceptors.ts +118 -0
  24. package/dist/templates/app/config/request/token-manager.ts +23 -0
  25. package/dist/templates/app/config/request/types.ts +63 -0
  26. package/dist/templates/app/config/rspack/rspack.config.mjs +62 -61
  27. package/dist/templates/app/config/rspack/rspack.prod.mjs +41 -62
  28. package/dist/templates/app/docs/DIRECTORY_STRUCTURE.md +141 -0
  29. package/dist/templates/app/docs/glossary.md +11 -0
  30. package/dist/templates/app/locales/zh-CN/common.json +3 -0
  31. package/dist/templates/app/package.json.tpl +8 -25
  32. package/dist/templates/app/public/fonts/HarmonyOS_Sans_Bold.woff2 +0 -0
  33. package/dist/templates/app/public/fonts/HarmonyOS_Sans_Medium.woff2 +0 -0
  34. package/dist/templates/app/public/fonts/HarmonyOS_Sans_Regular.woff2 +0 -0
  35. package/dist/templates/app/react-app-env.d.ts +13 -8
  36. package/dist/templates/app/scripts/i18nWorkflow/analyzeUnusedKeys.ts +506 -0
  37. package/dist/templates/app/scripts/i18nWorkflow/cleanUnusedKeys.ts +344 -0
  38. package/dist/templates/app/scripts/i18nWorkflow/const.ts +18 -0
  39. package/dist/templates/app/scripts/i18nWorkflow/flattenLocaleKeys.ts +139 -0
  40. package/dist/templates/app/scripts/i18nWorkflow/genDefaultLocale.ts +19 -0
  41. package/dist/templates/app/scripts/i18nWorkflow/genDiff.ts +49 -0
  42. package/dist/templates/app/scripts/i18nWorkflow/i18nConfig.ts +7 -0
  43. package/dist/templates/app/scripts/i18nWorkflow/index.ts +11 -0
  44. package/dist/templates/app/scripts/i18nWorkflow/protectedPatterns.ts +91 -0
  45. package/dist/templates/app/scripts/i18nWorkflow/utils.ts +76 -0
  46. package/dist/templates/app/src/bootstrap/index.ts +34 -0
  47. package/dist/templates/app/src/components/AntdStaticMethods/index.tsx +20 -0
  48. package/dist/templates/app/src/config/env.ts +84 -0
  49. package/dist/templates/app/src/index.tsx +13 -51
  50. package/dist/templates/app/src/layout/GlobalProvider/AppTheme.tsx +136 -0
  51. package/dist/templates/app/src/layout/GlobalProvider/Locale.tsx +84 -0
  52. package/dist/templates/app/src/layout/GlobalProvider/Query.tsx +12 -0
  53. package/dist/templates/app/src/layout/GlobalProvider/StyleRegistry.tsx +9 -0
  54. package/dist/templates/app/src/layout/GlobalProvider/index.tsx +23 -0
  55. package/dist/templates/app/src/layout/Locale.tsx +14 -18
  56. package/dist/templates/app/src/layout/MainContentWrap.tsx +11 -15
  57. package/dist/templates/app/src/layout/ThemeContext.tsx +27 -24
  58. package/dist/templates/app/src/locales/default/common.ts +3 -1
  59. package/dist/templates/app/src/locales/utils.ts +23 -0
  60. package/dist/templates/app/src/micro/garfish.ts +53 -0
  61. package/dist/templates/app/src/pages/base/index.tsx +280 -25
  62. package/dist/templates/app/src/routes.tsx +21 -12
  63. package/dist/templates/app/src/types/global.d.ts +19 -0
  64. package/dist/templates/app/src/utils/index.ts +3 -1
  65. package/dist/templates/app/store/middleware/createDevtools.ts +7 -7
  66. package/dist/templates/app/tsconfig.json +19 -3
  67. package/dist/templates/base/index.tsx +280 -25
  68. package/dist/templates/bootstrap/index.ts +34 -0
  69. package/dist/templates/cleanUnusedKeys.ts +344 -0
  70. package/dist/templates/common.json +3 -0
  71. package/dist/templates/common.ts +3 -1
  72. package/dist/templates/components/AntdStaticMethods/index.tsx +20 -0
  73. package/dist/templates/config/env/.env.public.tpl +2 -19
  74. package/dist/templates/config/env.ts +84 -0
  75. package/dist/templates/config/jwt/index.ts +4 -4
  76. package/dist/templates/config/request/error-handler.ts +67 -0
  77. package/dist/templates/config/request/index.ts +127 -129
  78. package/dist/templates/config/request/interceptors.ts +118 -0
  79. package/dist/templates/config/request/token-manager.ts +23 -0
  80. package/dist/templates/config/request/types.ts +63 -0
  81. package/dist/templates/config/rspack/rspack.config.mjs +62 -61
  82. package/dist/templates/config/rspack/rspack.prod.mjs +41 -62
  83. package/dist/templates/const.ts +18 -0
  84. package/dist/templates/createDevtools.ts +7 -7
  85. package/dist/templates/default/common.ts +3 -1
  86. package/dist/templates/docs/DIRECTORY_STRUCTURE.md +141 -0
  87. package/dist/templates/docs/glossary.md +11 -0
  88. package/dist/templates/env/.env.public.tpl +2 -19
  89. package/dist/templates/env.ts +83 -2
  90. package/dist/templates/error-handler.ts +67 -0
  91. package/dist/templates/flattenLocaleKeys.ts +139 -0
  92. package/dist/templates/fonts/HarmonyOS_Sans_Bold.woff2 +0 -0
  93. package/dist/templates/fonts/HarmonyOS_Sans_Medium.woff2 +0 -0
  94. package/dist/templates/fonts/HarmonyOS_Sans_Regular.woff2 +0 -0
  95. package/dist/templates/garfish.ts +53 -0
  96. package/dist/templates/genDefaultLocale.ts +19 -0
  97. package/dist/templates/genDiff.ts +49 -0
  98. package/dist/templates/global.d.ts +19 -0
  99. package/dist/templates/glossary.md +11 -0
  100. package/dist/templates/i18nConfig.ts +7 -0
  101. package/dist/templates/i18nWorkflow/analyzeUnusedKeys.ts +506 -0
  102. package/dist/templates/i18nWorkflow/cleanUnusedKeys.ts +344 -0
  103. package/dist/templates/i18nWorkflow/const.ts +18 -0
  104. package/dist/templates/i18nWorkflow/flattenLocaleKeys.ts +139 -0
  105. package/dist/templates/i18nWorkflow/genDefaultLocale.ts +19 -0
  106. package/dist/templates/i18nWorkflow/genDiff.ts +49 -0
  107. package/dist/templates/i18nWorkflow/i18nConfig.ts +7 -0
  108. package/dist/templates/i18nWorkflow/index.ts +11 -0
  109. package/dist/templates/i18nWorkflow/protectedPatterns.ts +91 -0
  110. package/dist/templates/i18nWorkflow/utils.ts +76 -0
  111. package/dist/templates/index.tsx +280 -25
  112. package/dist/templates/interceptors.ts +118 -0
  113. package/dist/templates/jwt/index.ts +4 -4
  114. package/dist/templates/layout/GlobalProvider/AppTheme.tsx +136 -0
  115. package/dist/templates/layout/GlobalProvider/Locale.tsx +84 -0
  116. package/dist/templates/layout/GlobalProvider/Query.tsx +12 -0
  117. package/dist/templates/layout/GlobalProvider/StyleRegistry.tsx +9 -0
  118. package/dist/templates/layout/GlobalProvider/index.tsx +23 -0
  119. package/dist/templates/layout/Locale.tsx +14 -18
  120. package/dist/templates/layout/MainContentWrap.tsx +11 -15
  121. package/dist/templates/layout/ThemeContext.tsx +27 -24
  122. package/dist/templates/locales/default/common.ts +3 -1
  123. package/dist/templates/locales/utils.ts +23 -0
  124. package/dist/templates/locales/zh-CN/common.json +3 -0
  125. package/dist/templates/micro/garfish.ts +53 -0
  126. package/dist/templates/middleware/createDevtools.ts +7 -7
  127. package/dist/templates/package.json.tpl +8 -25
  128. package/dist/templates/page.tsx +21 -19
  129. package/dist/templates/pages/base/index.tsx +280 -25
  130. package/dist/templates/protectedPatterns.ts +91 -0
  131. package/dist/templates/public/fonts/HarmonyOS_Sans_Bold.woff2 +0 -0
  132. package/dist/templates/public/fonts/HarmonyOS_Sans_Medium.woff2 +0 -0
  133. package/dist/templates/public/fonts/HarmonyOS_Sans_Regular.woff2 +0 -0
  134. package/dist/templates/react-app-env.d.ts +13 -8
  135. package/dist/templates/request/error-handler.ts +67 -0
  136. package/dist/templates/request/index.ts +127 -129
  137. package/dist/templates/request/interceptors.ts +118 -0
  138. package/dist/templates/request/token-manager.ts +23 -0
  139. package/dist/templates/request/types.ts +63 -0
  140. package/dist/templates/routes.tsx +21 -12
  141. package/dist/templates/rspack/rspack.config.mjs +62 -61
  142. package/dist/templates/rspack/rspack.prod.mjs +41 -62
  143. package/dist/templates/rspack.config.mjs +62 -61
  144. package/dist/templates/rspack.prod.mjs +41 -62
  145. package/dist/templates/scripts/i18nWorkflow/analyzeUnusedKeys.ts +506 -0
  146. package/dist/templates/scripts/i18nWorkflow/cleanUnusedKeys.ts +344 -0
  147. package/dist/templates/scripts/i18nWorkflow/const.ts +18 -0
  148. package/dist/templates/scripts/i18nWorkflow/flattenLocaleKeys.ts +139 -0
  149. package/dist/templates/scripts/i18nWorkflow/genDefaultLocale.ts +19 -0
  150. package/dist/templates/scripts/i18nWorkflow/genDiff.ts +49 -0
  151. package/dist/templates/scripts/i18nWorkflow/i18nConfig.ts +7 -0
  152. package/dist/templates/scripts/i18nWorkflow/index.ts +11 -0
  153. package/dist/templates/scripts/i18nWorkflow/protectedPatterns.ts +91 -0
  154. package/dist/templates/scripts/i18nWorkflow/utils.ts +76 -0
  155. package/dist/templates/src/bootstrap/index.ts +34 -0
  156. package/dist/templates/src/components/AntdStaticMethods/index.tsx +20 -0
  157. package/dist/templates/src/config/env.ts +84 -0
  158. package/dist/templates/src/index.tsx +13 -51
  159. package/dist/templates/src/layout/GlobalProvider/AppTheme.tsx +136 -0
  160. package/dist/templates/src/layout/GlobalProvider/Locale.tsx +84 -0
  161. package/dist/templates/src/layout/GlobalProvider/Query.tsx +12 -0
  162. package/dist/templates/src/layout/GlobalProvider/StyleRegistry.tsx +9 -0
  163. package/dist/templates/src/layout/GlobalProvider/index.tsx +23 -0
  164. package/dist/templates/src/layout/Locale.tsx +14 -18
  165. package/dist/templates/src/layout/MainContentWrap.tsx +11 -15
  166. package/dist/templates/src/layout/ThemeContext.tsx +27 -24
  167. package/dist/templates/src/locales/default/common.ts +3 -1
  168. package/dist/templates/src/locales/utils.ts +23 -0
  169. package/dist/templates/src/micro/garfish.ts +53 -0
  170. package/dist/templates/src/pages/base/index.tsx +280 -25
  171. package/dist/templates/src/routes.tsx +21 -12
  172. package/dist/templates/src/types/global.d.ts +19 -0
  173. package/dist/templates/src/utils/index.ts +3 -1
  174. package/dist/templates/store/middleware/createDevtools.ts +7 -7
  175. package/dist/templates/token-manager.ts +23 -0
  176. package/dist/templates/tsconfig.json +19 -3
  177. package/dist/templates/type.ts +23 -24
  178. package/dist/templates/types/global.d.ts +19 -0
  179. package/dist/templates/utils/index.ts +3 -1
  180. package/dist/templates/utils.ts +23 -0
  181. package/dist/templates/zh-CN/common.json +3 -0
  182. package/package.json +19 -21
  183. package/dist/templates/app/config/sentry/sentry.config.ts +0 -188
  184. package/dist/templates/app/src/hooks/useRouteTitle.tsx +0 -36
  185. package/dist/templates/app/src/hooks/useSentry.ts +0 -92
  186. package/dist/templates/app/src/pages/base/layout.tsx +0 -6
  187. package/dist/templates/app/src/pages/base/page.tsx +0 -25
  188. package/dist/templates/app/src/utils/env.ts +0 -3
  189. package/dist/templates/app/src/utils/format.ts +0 -21
  190. package/dist/templates/app/src/utils/getMicroApp.ts +0 -39
  191. package/dist/templates/app/src/utils/sentry.ts +0 -187
  192. package/dist/templates/app/src/utils/sentryDecorators.ts +0 -34
  193. package/dist/templates/app/src/utils/updateVersion.ts +0 -186
  194. package/dist/templates/base/layout.tsx +0 -6
  195. package/dist/templates/base/page.tsx +0 -25
  196. package/dist/templates/config/public/404.png +0 -0
  197. package/dist/templates/config/public/favicon.ico +0 -0
  198. package/dist/templates/config/public/images/banner_market_modal.webp +0 -0
  199. package/dist/templates/config/public/images/chatmode_chat_dark.webp +0 -0
  200. package/dist/templates/config/public/images/chatmode_chat_light.webp +0 -0
  201. package/dist/templates/config/public/images/chatmode_docs_dark.webp +0 -0
  202. package/dist/templates/config/public/images/chatmode_docs_light.webp +0 -0
  203. package/dist/templates/config/public/images/empty_topic_dark.webp +0 -0
  204. package/dist/templates/config/public/images/empty_topic_light.webp +0 -0
  205. package/dist/templates/config/public/images/screenshot_background.webp +0 -0
  206. package/dist/templates/config/public/images/theme_auto.webp +0 -0
  207. package/dist/templates/config/public/images/theme_dark.webp +0 -0
  208. package/dist/templates/config/public/images/theme_light.webp +0 -0
  209. package/dist/templates/config/public/index.html +0 -29
  210. package/dist/templates/config/sentry/sentry.config.ts +0 -188
  211. package/dist/templates/format.ts +0 -21
  212. package/dist/templates/getMicroApp.ts +0 -39
  213. package/dist/templates/hooks/useRouteTitle.tsx +0 -36
  214. package/dist/templates/hooks/useSentry.ts +0 -92
  215. package/dist/templates/layout.tsx +0 -6
  216. package/dist/templates/pages/base/layout.tsx +0 -6
  217. package/dist/templates/pages/base/page.tsx +0 -25
  218. package/dist/templates/sentry/sentry.config.ts +0 -188
  219. package/dist/templates/sentry.config.ts +0 -188
  220. package/dist/templates/sentry.ts +0 -187
  221. package/dist/templates/sentryDecorators.ts +0 -34
  222. package/dist/templates/src/hooks/useRouteTitle.tsx +0 -36
  223. package/dist/templates/src/hooks/useSentry.ts +0 -92
  224. package/dist/templates/src/pages/base/layout.tsx +0 -6
  225. package/dist/templates/src/pages/base/page.tsx +0 -25
  226. package/dist/templates/src/utils/env.ts +0 -3
  227. package/dist/templates/src/utils/format.ts +0 -21
  228. package/dist/templates/src/utils/getMicroApp.ts +0 -39
  229. package/dist/templates/src/utils/sentry.ts +0 -187
  230. package/dist/templates/src/utils/sentryDecorators.ts +0 -34
  231. package/dist/templates/src/utils/updateVersion.ts +0 -186
  232. package/dist/templates/updateVersion.ts +0 -186
  233. package/dist/templates/useRouteTitle.tsx +0 -36
  234. package/dist/templates/useSentry.ts +0 -92
  235. package/dist/templates/utils/env.ts +0 -3
  236. package/dist/templates/utils/format.ts +0 -21
  237. package/dist/templates/utils/getMicroApp.ts +0 -39
  238. package/dist/templates/utils/sentry.ts +0 -187
  239. package/dist/templates/utils/sentryDecorators.ts +0 -34
  240. package/dist/templates/utils/updateVersion.ts +0 -186
  241. /package/dist/templates/app/{config/public → public}/404.png +0 -0
  242. /package/dist/templates/app/{config/public → public}/favicon.ico +0 -0
  243. /package/dist/templates/app/{config/public → public}/images/banner_market_modal.webp +0 -0
  244. /package/dist/templates/app/{config/public → public}/images/chatmode_chat_dark.webp +0 -0
  245. /package/dist/templates/app/{config/public → public}/images/chatmode_chat_light.webp +0 -0
  246. /package/dist/templates/app/{config/public → public}/images/chatmode_docs_dark.webp +0 -0
  247. /package/dist/templates/app/{config/public → public}/images/chatmode_docs_light.webp +0 -0
  248. /package/dist/templates/app/{config/public → public}/images/empty_topic_dark.webp +0 -0
  249. /package/dist/templates/app/{config/public → public}/images/empty_topic_light.webp +0 -0
  250. /package/dist/templates/app/{config/public → public}/images/screenshot_background.webp +0 -0
  251. /package/dist/templates/app/{config/public → public}/images/theme_auto.webp +0 -0
  252. /package/dist/templates/app/{config/public → public}/images/theme_dark.webp +0 -0
  253. /package/dist/templates/app/{config/public → public}/images/theme_light.webp +0 -0
  254. /package/dist/templates/app/{config/public → public}/index.html +0 -0
@@ -1,174 +1,172 @@
1
- import jwt from "@config/jwt";
2
- import axios, {
3
- type AxiosInstance,
4
- type AxiosRequestConfig,
5
- type AxiosResponse,
6
- } from "axios";
1
+ import axios, { type AxiosInstance } from "axios";
7
2
  import qs from "qs";
8
-
9
- type Result<T> = {
10
- code: number;
11
- message: string;
12
- data: T;
13
- suppressErrorNotification?: boolean;
14
- };
15
-
16
- const baseURL = process.env.API_PREFIX;
17
- const timeout = process.env.API_TIMEOUT;
18
- const accessTokenKey = process.env.COOKIE_NAME;
19
-
20
- let flag = false; // 设置开关,保证一次只能请求一次刷新token,防止客户端多次操作,多次请求
21
- let subSequest: any[] = [];
22
-
23
- // 把过期请求添加在数组中
24
- function addRequest(request: () => any) {
25
- subSequest.push(request);
26
- }
27
-
28
- // 重新调用过期请求列表
29
- function retryRequest() {
30
- subSequest.forEach((request) => request());
31
- subSequest = [];
32
- }
33
-
34
- function getRefreshToken(token: string) {
35
- return fetch(`${baseURL}/dns/auth/login/token/refresh`, {
36
- headers: {
37
- authorization: token,
38
- },
39
- });
40
- }
41
-
42
- function redirectToLogin() {
43
- // 记录当前的url,并且实现跳转
44
- if (window.location.pathname === "/login") {
45
- return;
46
- }
47
- jwt.clearAccessToken(accessTokenKey as string);
48
- jwt.clearAccessToken("refresh_token");
49
- const href = encodeURIComponent(window.location.href);
50
- window.location.href = `${window.location.origin}/login?redirect=${href}`;
51
- }
52
-
53
- // 刷新token
54
- function refreshToken() {
55
- if (!flag) {
56
- flag = true;
57
- // 获取刷新token
58
- const r_tk = jwt.getAccessToken("refresh_token");
59
- if (r_tk) {
60
- // 判断刷新token是否过期
61
- getRefreshToken(r_tk)
62
- .then((v) => v.json())
63
- .then((v) => {
64
- flag = false;
65
- if (!v?.data?.accessToken) {
66
- redirectToLogin();
67
- return;
68
- }
69
- jwt.setAccessToken({
70
- token_type: v.data?.tokenType ?? "JWT",
71
- access_token: v.data?.accessToken,
72
- expires_at: v.data?.expires_at * 1000,
73
- });
74
- // 重新发送请求
75
- retryRequest();
76
- })
77
- .catch(() => {
78
- redirectToLogin();
79
- });
80
- } else {
81
- redirectToLogin();
3
+ import { env } from "@/config/env";
4
+ import type { RequestConfig, ApiResponse, TokenManager } from "./types";
5
+ import { tokenManager as defaultTokenManager } from "./token-manager";
6
+ import {
7
+ errorHandler as defaultErrorHandler,
8
+ type ErrorHandler,
9
+ } from "./error-handler";
10
+ import {
11
+ setupRequestInterceptor,
12
+ setupResponseInterceptor,
13
+ } from "./interceptors";
14
+
15
+ /**
16
+ * 参数序列化器
17
+ */
18
+ export function paramsSerializer(params: Record<string, any>): string {
19
+ const result: Record<string, any> = {};
20
+
21
+ Object.keys(params).forEach((key) => {
22
+ const value = params[key];
23
+ if (value === null || value === undefined) {
24
+ // 跳过 null 和 undefined
25
+ return;
82
26
  }
83
- }
84
- }
85
-
86
- export function paramsSerializer(params) {
87
- const result = {};
88
- Object.keys(params).forEach((p) => {
89
- const value = params[p];
90
27
  if (Array.isArray(value)) {
91
- result[p] = value;
92
- } else if (value === null || value === undefined) {
93
- result[p] = value;
28
+ result[key] = value;
94
29
  } else if (typeof value === "object") {
95
- result[p] = JSON.stringify(value);
30
+ result[key] = JSON.stringify(value);
96
31
  } else {
97
- result[p] = value;
32
+ result[key] = value;
98
33
  }
99
34
  });
35
+
100
36
  return qs.stringify(result, { arrayFormat: "repeat", skipNulls: true });
101
37
  }
102
38
 
103
- // 导出Request类,可以用来自定义传递配置来创建实例
39
+ /**
40
+ * Request 配置选项
41
+ */
42
+ export interface RequestOptions {
43
+ baseURL?: string;
44
+ timeout?: number;
45
+ tokenManager?: TokenManager;
46
+ errorHandler?: ErrorHandler;
47
+ onUnauthorized?: () => void;
48
+ }
49
+
50
+ /**
51
+ * HTTP 请求类
52
+ */
104
53
  export class Request {
105
- // axios 实例
106
54
  private instance: AxiosInstance;
107
- // 基础配置,url和超时时间
108
- private baseConfig: AxiosRequestConfig = {
109
- baseURL: baseURL,
110
- timeout: Number(timeout),
111
- withCredentials: true,
112
- };
113
-
114
- constructor(config: AxiosRequestConfig) {
115
- // 使用axios.create创建axios实例
116
- this.instance = axios.create(Object.assign(this.baseConfig, config));
117
-
118
- this.instance.interceptors.request.use(
119
- (config: any) => {
120
- // 一般会请求拦截里面加token,用于后端的验证
121
- config.headers = config.headers || {};
122
- config.headers.Authorization =
123
- jwt.getAccessToken(accessTokenKey as string) || "";
124
- return config;
125
- },
126
- (err: any) => {
127
- return Promise.reject(err);
128
- }
55
+ public tokenManager: TokenManager;
56
+ public errorHandler: ErrorHandler;
57
+
58
+ constructor(options: RequestOptions = {}) {
59
+ const {
60
+ baseURL = env.API_PREFIX,
61
+ timeout = env.API_TIMEOUT,
62
+ tokenManager = defaultTokenManager,
63
+ errorHandler = defaultErrorHandler,
64
+ onUnauthorized,
65
+ } = options;
66
+
67
+ this.tokenManager = tokenManager;
68
+ this.errorHandler = errorHandler;
69
+
70
+ // 创建 axios 实例
71
+ this.instance = axios.create({
72
+ baseURL,
73
+ timeout,
74
+ withCredentials: true,
75
+ });
76
+
77
+ // 设置拦截器
78
+ setupRequestInterceptor(this.instance, tokenManager);
79
+ setupResponseInterceptor(
80
+ this.instance,
81
+ tokenManager,
82
+ errorHandler,
83
+ onUnauthorized
129
84
  );
130
85
  }
131
86
 
132
- // 定义请求方法
133
- public request(config: AxiosRequestConfig): Promise<AxiosResponse> {
87
+ /**
88
+ * 通用请求方法
89
+ */
90
+ public request<T = any>(config: RequestConfig): Promise<ApiResponse<T>> {
134
91
  return this.instance.request(config);
135
92
  }
136
93
 
94
+ /**
95
+ * GET 请求
96
+ */
137
97
  public get<T = any>(
138
98
  url: string,
139
99
  params?: any,
140
- config?: AxiosRequestConfig & { suppressErrorNotification?: boolean }
141
- ): Promise<Result<T>> {
100
+ config?: RequestConfig
101
+ ): Promise<ApiResponse<T>> {
142
102
  return this.instance.get(url, {
143
103
  ...config,
144
- params: params,
104
+ params,
145
105
  paramsSerializer,
146
106
  });
147
107
  }
148
108
 
109
+ /**
110
+ * POST 请求
111
+ */
149
112
  public post<T = any>(
150
113
  url: string,
151
114
  data?: any,
152
- config?: AxiosRequestConfig & { suppressErrorNotification?: boolean }
153
- ): Promise<Result<T>> {
115
+ config?: RequestConfig
116
+ ): Promise<ApiResponse<T>> {
154
117
  return this.instance.post(url, data, config);
155
118
  }
156
119
 
120
+ /**
121
+ * PUT 请求
122
+ */
157
123
  public put<T = any>(
158
124
  url: string,
159
125
  data?: any,
160
- config?: AxiosRequestConfig & { suppressErrorNotification?: boolean }
161
- ): Promise<Result<T>> {
126
+ config?: RequestConfig
127
+ ): Promise<ApiResponse<T>> {
162
128
  return this.instance.put(url, data, config);
163
129
  }
164
130
 
131
+ /**
132
+ * DELETE 请求
133
+ */
165
134
  public delete<T = any>(
166
135
  url: string,
167
- config?: AxiosRequestConfig & { suppressErrorNotification?: boolean }
168
- ): Promise<Result<T>> {
136
+ config?: RequestConfig
137
+ ): Promise<ApiResponse<T>> {
169
138
  return this.instance.delete(url, config);
170
139
  }
140
+
141
+ /**
142
+ * PATCH 请求
143
+ */
144
+ public patch<T = any>(
145
+ url: string,
146
+ data?: any,
147
+ config?: RequestConfig
148
+ ): Promise<ApiResponse<T>> {
149
+ return this.instance.patch(url, data, config);
150
+ }
151
+
152
+ /**
153
+ * 获取 axios 实例(用于高级用法)
154
+ */
155
+ public getAxiosInstance(): AxiosInstance {
156
+ return this.instance;
157
+ }
171
158
  }
172
159
 
173
- // 默认导出Request实例
174
- export default new Request({});
160
+ // 导出默认实例
161
+ export const request = new Request();
162
+
163
+ // 导出类型
164
+ export type {
165
+ RequestConfig,
166
+ ApiResponse,
167
+ MessageConfig,
168
+ TokenManager,
169
+ } from "./types";
170
+
171
+ // 默认导出
172
+ export default request;
@@ -0,0 +1,118 @@
1
+ import type {
2
+ AxiosInstance,
3
+ InternalAxiosRequestConfig,
4
+ AxiosResponse,
5
+ } from "axios";
6
+ import { message as antdMessage } from "antd";
7
+ import type { TokenManager, RequestConfig, ApiResponse } from "./types";
8
+ import type { ErrorHandler } from "./error-handler";
9
+
10
+ /**
11
+ * 设置请求拦截器
12
+ */
13
+ export function setupRequestInterceptor(
14
+ instance: AxiosInstance,
15
+ tokenManager: TokenManager
16
+ ): void {
17
+ instance.interceptors.request.use(
18
+ (config: InternalAxiosRequestConfig) => {
19
+ const requestConfig = config as RequestConfig;
20
+
21
+ // 添加 Token(如果需要认证,默认为 true)
22
+ if (requestConfig.requireAuth !== false) {
23
+ const token = tokenManager.getToken();
24
+ if (token && config.headers) {
25
+ config.headers.Authorization = token;
26
+ }
27
+ }
28
+
29
+ // 添加自定义 Headers
30
+ if (requestConfig.customHeaders && config.headers) {
31
+ Object.entries(requestConfig.customHeaders).forEach(([key, value]) => {
32
+ config.headers[key] = value;
33
+ });
34
+ }
35
+
36
+ return config;
37
+ },
38
+ (error) => {
39
+ return Promise.reject(error);
40
+ }
41
+ );
42
+ }
43
+
44
+ /**
45
+ * 设置响应拦截器
46
+ */
47
+ export function setupResponseInterceptor(
48
+ instance: AxiosInstance,
49
+ tokenManager: TokenManager,
50
+ errorHandler: ErrorHandler,
51
+ onUnauthorized?: () => void
52
+ ): void {
53
+ instance.interceptors.response.use(
54
+ (response: AxiosResponse<ApiResponse>) => {
55
+ const config = response.config as RequestConfig;
56
+ const messageConfig = config.message;
57
+
58
+ const { code, message: msg, data } = response.data;
59
+
60
+ // 业务成功(根据实际后端约定调整)
61
+ if (code === 0 || code === 200) {
62
+ // 显示成功消息
63
+ if (messageConfig?.showSuccess) {
64
+ const successMsg = messageConfig.successMessage || msg || "操作成功";
65
+ antdMessage.success(successMsg);
66
+ }
67
+
68
+ // 直接返回 data,简化调用
69
+ return response.data;
70
+ }
71
+
72
+ // 业务失败
73
+ const errorMsg = messageConfig?.errorMessage || msg || "操作失败";
74
+
75
+ if (messageConfig?.showError !== false) {
76
+ antdMessage.error(errorMsg);
77
+ }
78
+
79
+ return Promise.reject(new Error(errorMsg));
80
+ },
81
+ async (error) => {
82
+ const config = error.config as RequestConfig;
83
+
84
+ // 401 未授权
85
+ if (error.response?.status === 401) {
86
+ tokenManager.clearToken();
87
+
88
+ // 执行自定义的未授权回调
89
+ if (onUnauthorized) {
90
+ onUnauthorized();
91
+ } else {
92
+ // 默认跳转到登录页
93
+ redirectToLogin();
94
+ }
95
+
96
+ return Promise.reject(error);
97
+ }
98
+
99
+ // 其他错误统一处理
100
+ errorHandler.handle(error, config);
101
+
102
+ return Promise.reject(error);
103
+ }
104
+ );
105
+ }
106
+
107
+ /**
108
+ * 重定向到登录页
109
+ */
110
+ function redirectToLogin(): void {
111
+ if (typeof window === "undefined") return;
112
+
113
+ const currentPath = window.location.pathname;
114
+ if (currentPath === "/login") return;
115
+
116
+ const redirectUrl = encodeURIComponent(window.location.href);
117
+ window.location.href = `${window.location.origin}/login?redirect=${redirectUrl}`;
118
+ }
@@ -0,0 +1,23 @@
1
+ import jwt from "@config/jwt";
2
+ import type { TokenManager as TokenManagerType } from "./types";
3
+ /**
4
+ * Token 刷新管理器
5
+ * 使用 Promise 避免并发刷新问题
6
+ */
7
+ export class TokenManager implements TokenManagerType {
8
+ getToken(token?: string): string | undefined {
9
+ return jwt.getAccessToken(token);
10
+ }
11
+ setToken(token: {
12
+ token_type: any;
13
+ access_token: any;
14
+ expires_at: number;
15
+ }): void {
16
+ jwt.setAccessToken(token);
17
+ }
18
+ clearToken(token?: string): void {
19
+ jwt.clearAccessToken(token);
20
+ }
21
+ }
22
+
23
+ export const tokenManager = new TokenManager();
@@ -0,0 +1,63 @@
1
+ import type { AxiosRequestConfig } from "axios";
2
+
3
+ /**
4
+ * 后端统一响应格式
5
+ */
6
+ export interface ApiResponse<T = any> {
7
+ code: number;
8
+ message: string;
9
+ data: T;
10
+ }
11
+
12
+ /**
13
+ * 消息提示配置
14
+ */
15
+ export interface MessageConfig {
16
+ /** 是否显示成功消息 */
17
+ showSuccess?: boolean;
18
+ /** 自定义成功消息 */
19
+ successMessage?: string;
20
+ /** 是否显示错误消息 */
21
+ showError?: boolean;
22
+ /** 自定义错误消息 */
23
+ errorMessage?: string;
24
+ }
25
+
26
+ /**
27
+ * 扩展的请求配置
28
+ */
29
+ export interface RequestConfig extends AxiosRequestConfig {
30
+ /** 消息提示配置 */
31
+ message?: MessageConfig;
32
+ /** 自定义请求头 */
33
+ customHeaders?: Record<string, string>;
34
+ /** 是否需要认证(默认 true) */
35
+ requireAuth?: boolean;
36
+ /** 请求元数据(用于日志、监控等) */
37
+ metadata?: Record<string, any>;
38
+ }
39
+
40
+ /**
41
+ * Token 信息
42
+ */
43
+ export interface TokenInfo {
44
+ token_type: string;
45
+ access_token: string;
46
+ expires_at: number;
47
+ }
48
+
49
+ /**
50
+ * Token 管理器接口
51
+ */
52
+ export interface TokenManager {
53
+ getToken(key?: string): string | undefined;
54
+ setToken(token: TokenInfo): void;
55
+ clearToken(key?: string): void;
56
+ }
57
+
58
+ /**
59
+ * 错误处理器接口
60
+ */
61
+ export interface ErrorHandler {
62
+ handle(error: any, config?: RequestConfig): void;
63
+ }