minitest2.0 0.0.0

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 (89) hide show
  1. package/.editorconfig +8 -0
  2. package/.env.development +3 -0
  3. package/.env.production +3 -0
  4. package/.env.test +3 -0
  5. package/.gitattributes +1 -0
  6. package/.oxlintrc.json +10 -0
  7. package/.prettierrc.json +6 -0
  8. package/.vscode/extensions.json +9 -0
  9. package/.vscode/settings.json +13 -0
  10. package/README.md +179 -0
  11. package/auto-imports.d.ts +629 -0
  12. package/components.d.ts +21 -0
  13. package/design-qa.md +36 -0
  14. package/docs/MX_API.md +244 -0
  15. package/docs/REQUEST.md +217 -0
  16. package/docs/jsapi.js +515 -0
  17. package/docs/package-json-guide.md +132 -0
  18. package/env.d.ts +15 -0
  19. package/eslint.config.ts +26 -0
  20. package/index.html +16 -0
  21. package/package.json +83 -0
  22. package/plugins/bump-version.ts +61 -0
  23. package/postcss.config.ts +15 -0
  24. package/public/favicon.ico +0 -0
  25. package/public/images/12a73787-86a9-4891-a65f-66104746f6a8.png +0 -0
  26. package/public/images/5798d7aa-ba8b-4605-8079-58b35495ac55.png +0 -0
  27. package/public/images/73fef1e4-0fd0-4a1a-9b8b-a70a5b6acbbc.png +0 -0
  28. package/public/images/bc685b4c-0cca-4a79-924c-a8ee10e6f8eb.png +0 -0
  29. package/public/images/c3dbbd9d-be56-490e-b9f4-6ee17ebefffc.png +0 -0
  30. package/public/images/ea745a10-42aa-4f44-8d7f-3ab02cc0adcd.png +0 -0
  31. package/public/images/f5876785-b927-4347-ba19-999114240649.png +0 -0
  32. package/public/images/img.png +0 -0
  33. package/public/images/opening-reserve-estimate.png +0 -0
  34. package/public/images/position-estimate-report.png +0 -0
  35. package/src/App.vue +131 -0
  36. package/src/api/announcement.ts +405 -0
  37. package/src/api/health.ts +13 -0
  38. package/src/api/pbc-position.ts +178 -0
  39. package/src/api/rmb-position.ts +233 -0
  40. package/src/api/tam.ts +173 -0
  41. package/src/api/user.ts +92 -0
  42. package/src/auto-imports.d.ts +633 -0
  43. package/src/components/AppTitleBar.vue +376 -0
  44. package/src/components.d.ts +33 -0
  45. package/src/config/config.properties +3 -0
  46. package/src/config/env.ts +6 -0
  47. package/src/config/plugin.properties.pro +6 -0
  48. package/src/config/plugin.properties.test +6 -0
  49. package/src/core/mxApi/index.ts +451 -0
  50. package/src/core/request/index.ts +135 -0
  51. package/src/main.ts +40 -0
  52. package/src/router/index.ts +144 -0
  53. package/src/stores/app.ts +103 -0
  54. package/src/stores/counter.ts +12 -0
  55. package/src/stores/user.ts +137 -0
  56. package/src/styles/nprogress.css +22 -0
  57. package/src/styles/vant-overrides.css +42 -0
  58. package/src/types/api.d.ts +14 -0
  59. package/src/types/nprogress.d.ts +8 -0
  60. package/src/utils/auth-token.ts +241 -0
  61. package/src/utils/code-highlight.ts +165 -0
  62. package/src/utils/copy.ts +36 -0
  63. package/src/utils/query.ts +27 -0
  64. package/src/utils/request.ts +238 -0
  65. package/src/utils/rmb-forecast.ts +84 -0
  66. package/src/utils/toast.ts +61 -0
  67. package/src/views/article-detail/index.vue +289 -0
  68. package/src/views/article-edit/index.vue +600 -0
  69. package/src/views/articles/index.vue +293 -0
  70. package/src/views/clearing-detail/index.vue +26 -0
  71. package/src/views/dashboard/index.vue +18 -0
  72. package/src/views/foreign-position/index.vue +26 -0
  73. package/src/views/home/index.vue +213 -0
  74. package/src/views/login/index.vue +275 -0
  75. package/src/views/mine/index.vue +147 -0
  76. package/src/views/net-debit/index.vue +26 -0
  77. package/src/views/opening-reserve-estimate/index.vue +28 -0
  78. package/src/views/pbc-position/index.vue +357 -0
  79. package/src/views/position-estimate/index.vue +67 -0
  80. package/src/views/position-estimate-report/index.vue +28 -0
  81. package/src/views/rmb-position/index.vue +1013 -0
  82. package/src/views/rmb-position-create/index.vue +221 -0
  83. package/src/views/rmb-position-detail/index.vue +355 -0
  84. package/src/views/settings/index.vue +67 -0
  85. package/src/views/warning/index.vue +26 -0
  86. package/tsconfig.app.json +18 -0
  87. package/tsconfig.json +11 -0
  88. package/tsconfig.node.json +28 -0
  89. package/vite.config.ts +100 -0
package/docs/jsapi.js ADDED
@@ -0,0 +1,515 @@
1
+ function MXApi(callbacks = {}) {
2
+ let deviceReady = false
3
+ const taskQueue = []
4
+
5
+ document.addEventListener(
6
+ 'deviceready',
7
+ function deviceReadyHandler() {
8
+ deviceReady = true
9
+
10
+ taskQueue.forEach(function (task) {
11
+ applyApi.apply(null, task)
12
+ })
13
+
14
+ taskQueue.length = 0
15
+
16
+ callbacks.ready && callbacks.ready()
17
+ document.removeEventListener('deviceready', deviceReadyHandler, false)
18
+ },
19
+ false,
20
+ )
21
+
22
+ function applyApi(namespace, api, args = []) {
23
+ if (window[namespace] && window[namespace][api]) {
24
+ callbacks.beforeApply && callbacks.beforeApply(namespace, api, args)
25
+ return window[namespace][api].apply(null, args)
26
+ }
27
+
28
+ if (!deviceReady) {
29
+ taskQueue.push([namespace, api, args])
30
+ return
31
+ }
32
+
33
+ const message = ['该终端没有', namespace, '.', api, '方法!'].join('')
34
+ callbacks.error && callbacks.error(message, namespace, api)
35
+ throw new Error(message)
36
+ }
37
+
38
+ return applyApi
39
+ }
40
+
41
+ const applyApi = MXApi({
42
+ ready() {
43
+ console.log('device ready!!')
44
+ },
45
+ error(err) {
46
+ console.log(err)
47
+ },
48
+ beforeApply(namespace, api, args) {
49
+ // do nothing
50
+ },
51
+ })
52
+
53
+ const makeApi =
54
+ (namespace) =>
55
+ (api, ...args) =>
56
+ applyApi(namespace, api, args)
57
+
58
+ const MXCommon = makeApi('MXCommon')
59
+ const MXWebui = makeApi('MXWebui')
60
+ const MXContacts = makeApi('MXContacts')
61
+ const MXLocation = makeApi('MXLocation')
62
+ const MXCloudWalkFace = makeApi('MXCloudWalkFace')
63
+ const MXMedal = makeApi('MXMedal')
64
+ const MXChat = makeApi('MXChat')
65
+ const MXCircle = makeApi('MXCircle')
66
+ const MXShare = makeApi('MXShare')
67
+
68
+ export const showOptionMenu = () => MXWebui('showOptionMenu')
69
+
70
+ export const iphoneXBottomSetAside = (...args) => {
71
+ return MXWebui('iphoneXBottomSetAside', ...args)
72
+ }
73
+
74
+ export const hideOptionMenu = () => {
75
+ return MXWebui('hideOptionMenu')
76
+ }
77
+
78
+ export const setCustomHeaderMenu = (...args) => {
79
+ return MXWebui('setCustomHeaderMenu', ...args)
80
+ }
81
+
82
+ export const setWebViewTitle = (...args) => {
83
+ return MXWebui('setWebViewTitle', ...args)
84
+ }
85
+
86
+ export const showWebViewTitle = (...args) => {
87
+ return MXWebui('showWebViewTitle', ...args)
88
+ }
89
+
90
+ export const closeWindow = (...args) => {
91
+ return MXWebui('closeWindow', ...args)
92
+ }
93
+
94
+ export const call = (...args) => {
95
+ return MXCommon('call', ...args)
96
+ }
97
+
98
+ export const hideWebViewTitle = (...args) => {
99
+ return MXWebui('hideWebViewTitle', ...args)
100
+ }
101
+
102
+ // 沉浸式头部
103
+ export const enableTranslucentHeader = (...args) => {
104
+ return MXWebui('enableTranslucentHeader', ...args)
105
+ }
106
+
107
+ export const getCurrentUser = () => {
108
+ return new Promise((resolve, reject) => {
109
+ MXCommon('getCurrentUser', resolve, reject)
110
+ })
111
+ }
112
+
113
+ export const MXSelectUsers = (userIds) => {
114
+ return new Promise((resolve, reject) => {
115
+ MXContacts(
116
+ 'selectUsers',
117
+ resolve,
118
+ {
119
+ customUserIDS: userIds,
120
+ enableSelectDept: false,
121
+ canSelectSelf: true,
122
+ },
123
+ reject,
124
+ )
125
+ })
126
+ }
127
+
128
+ export const MXSelectUser = () => {
129
+ return new Promise((resolve, reject) => {
130
+ MXContacts('selectUser', resolve, {}, reject)
131
+ })
132
+ }
133
+
134
+ export const MXBrowseImages = (...args) => {
135
+ return MXCommon('browseImages', ...args)
136
+ }
137
+
138
+ export const MXDownload = (...args) => {
139
+ return MXCommon('download', ...args)
140
+ }
141
+
142
+ export const MXOpenUrlPage = (...args) => {
143
+ return MXCommon('openUrlPage', ...args)
144
+ }
145
+
146
+ const safeJsonParse = (data) => {
147
+ if (typeof data !== 'string') return data
148
+
149
+ try {
150
+ return JSON.parse(data)
151
+ } catch (error) {
152
+ return data
153
+ }
154
+ }
155
+
156
+ export const ajax = (params) => {
157
+ return new Promise((resolve, reject) => {
158
+ params = Object.assign({}, params, {
159
+ url: `${params.url}`,
160
+ async: true,
161
+ success(data, status, xhr) {
162
+ console.log(data, status, xhr)
163
+ resolve({
164
+ data: safeJsonParse(data),
165
+ status,
166
+ xhr,
167
+ })
168
+ },
169
+ error(data, status, xhr) {
170
+ reject({
171
+ data,
172
+ status,
173
+ xhr,
174
+ })
175
+ },
176
+ })
177
+
178
+ console.log('params_url==>>', params.url)
179
+ console.log('params_data==>>', params.data)
180
+
181
+ MXCommon('ajax', params)
182
+ })
183
+ }
184
+
185
+ const queryString = (obj) => {
186
+ if (!obj) return ''
187
+
188
+ return Object.keys(obj)
189
+ .map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(obj[key])}`)
190
+ .join('&')
191
+ }
192
+
193
+ export const ajaxGet = (url, query) => {
194
+ url = query ? `${url}?${queryString(query)}` : url
195
+
196
+ return ajax({
197
+ type: 'GET',
198
+ url,
199
+ })
200
+ }
201
+
202
+ export const ajaxPost = (url, data, param = {}) => {
203
+ return ajax({
204
+ type: 'POST',
205
+ url,
206
+ data,
207
+ ...param,
208
+ })
209
+ }
210
+
211
+ export const ajaxPut = (url, data) => {
212
+ return ajax({
213
+ type: 'PUT',
214
+ url,
215
+ data,
216
+ })
217
+ }
218
+
219
+ export const ajaxDelete = (url, id) => {
220
+ return ajax({
221
+ type: 'DELETE',
222
+ url: `${url}/${id}`,
223
+ })
224
+ }
225
+
226
+ export const chooseFile = (count, options) => {
227
+ return new Promise((resolve, reject) => {
228
+ MXCommon('chooseFile', count, options, resolve, reject)
229
+ })
230
+ }
231
+
232
+ export const chooseImage = (count, options) => {
233
+ return new Promise((resolve, reject) => {
234
+ MXCommon('chooseImage', count, options, resolve, reject)
235
+ })
236
+ }
237
+
238
+ export const getLocation = (gpsOnly) => {
239
+ return new Promise((resolve, reject) => {
240
+ MXLocation('getLocation', resolve, reject, gpsOnly)
241
+ })
242
+ }
243
+
244
+ export const getMapScreenShot = () => {
245
+ return new Promise((resolve, reject) => {
246
+ MXLocation('getMapScreenShot', {
247
+ onSuccess: resolve,
248
+ onFail: reject,
249
+ })
250
+ })
251
+ }
252
+
253
+ // 获取服务器地址
254
+ export const getServerUrl = () => {
255
+ return new Promise((resolve, reject) => {
256
+ MXCommon('getServerUrl', resolve, reject)
257
+ })
258
+ }
259
+
260
+ // 获取水印
261
+ export const getWaterMarkUrl = () => {
262
+ return new Promise((resolve, reject) => {
263
+ MXCommon('getWaterMarkUrl', resolve, reject)
264
+ })
265
+ }
266
+
267
+ // 身份证读取
268
+ export const iDCardRecognize = (params) => {
269
+ return new Promise((resolve, reject) => {
270
+ MXCloudWalkFace('iDCardRecognize', {
271
+ type: params.type,
272
+ onSuccess: resolve,
273
+ onFail: reject,
274
+ })
275
+ })
276
+ }
277
+
278
+ // 人脸识别
279
+ export const faceRecognize = () => {
280
+ return new Promise((resolve, reject) => {
281
+ MXCloudWalkFace('faceRecognize', {
282
+ onSuccess: resolve,
283
+ onFail: reject,
284
+ })
285
+ })
286
+ }
287
+
288
+ // base64图片保存到本地
289
+ export const saveImageToAlbum = (url) => {
290
+ return MXMedal('saveImageToAlbum', {
291
+ base64: url,
292
+ })
293
+ }
294
+
295
+ // 根据appid获取sso_token
296
+ export const getSSOToken = (appId) => {
297
+ return new Promise((resolve, reject) => {
298
+ MXCommon('getSSOToken', appId, resolve, reject)
299
+ })
300
+ }
301
+
302
+ // 佩戴取消佩戴头饰
303
+ export const mxWearMedal = (param) => {
304
+ return new Promise((resolve, reject) => {
305
+ MXMedal('wearMedal', {
306
+ onSuccess: resolve,
307
+ onFail: reject,
308
+ isWear: param.isWear,
309
+ isCancelWear: param.isCancelWear,
310
+ ornamentUrl: param.ornamentUrl,
311
+ })
312
+ })
313
+ }
314
+
315
+ /**
316
+ * 判断是否是PC端
317
+ */
318
+ export const judgePlat = () => {
319
+ const userAgentInfo = navigator.userAgent
320
+ const agents = ['Android', 'iPhone', 'SymbianOS', 'Windows Phone']
321
+
322
+ for (let v = 0; v < agents.length; v++) {
323
+ if (userAgentInfo.indexOf(agents[v]) > 0) {
324
+ return false
325
+ }
326
+ }
327
+
328
+ return true
329
+ }
330
+
331
+ // 根据用户id获取头像
332
+ export const getUserAvatars = (param) => {
333
+ return new Promise((resolve, reject) => {
334
+ MXCommon('getUserAvatars', {
335
+ userIds: param.userIds,
336
+ onSuccess: resolve,
337
+ onFail: reject,
338
+ })
339
+ })
340
+ }
341
+
342
+ // base64图片分享到聊天
343
+ export const shareImageToChat = (url) => {
344
+ return MXChat('chat', {
345
+ message: {
346
+ message_type: 'image',
347
+ body: {
348
+ base64: url,
349
+ },
350
+ },
351
+ })
352
+ }
353
+
354
+ // base64图片分享到朋友圈
355
+ export const shareImageToCircle = (url) => {
356
+ return MXCircle('send', {
357
+ attachments: [
358
+ {
359
+ type: 'image',
360
+ url,
361
+ },
362
+ ],
363
+ })
364
+ }
365
+
366
+ // 客户端登出
367
+ export const jumpLogin = () => {
368
+ return MXCommon('jumpLogin')
369
+ }
370
+
371
+ // 客户端登录
372
+ export const loginWithToken = (...args) => {
373
+ return MXCommon('loginWithToken', ...args)
374
+ }
375
+
376
+ // MXCommon.ajaxFormData
377
+ export const ajaxFormData = (params) => {
378
+ return new Promise((resolve, reject) => {
379
+ params = Object.assign({}, params, {
380
+ url: `${params.url}`,
381
+ async: true,
382
+ success(data, status, xhr) {
383
+ console.log(data, status, xhr)
384
+ resolve({
385
+ data: safeJsonParse(data),
386
+ status,
387
+ xhr,
388
+ })
389
+ },
390
+ error(data, status, xhr) {
391
+ reject({
392
+ data,
393
+ status,
394
+ xhr,
395
+ })
396
+ },
397
+ })
398
+
399
+ console.log('params_url==>>', params.url)
400
+ console.log('params_data==>>', params.data)
401
+
402
+ MXCommon('ajaxFormData', params)
403
+ })
404
+ }
405
+
406
+ export const addEventListener = (params) => {
407
+ return MXCommon('addEventListener', params)
408
+ }
409
+
410
+ export const removeEventListener = (params) => {
411
+ return MXCommon('removeEventListener', params)
412
+ }
413
+
414
+ // 允许截屏
415
+ export const enableWebViewScreenShot = (params) => {
416
+ return MXCommon('enableWebViewScreenShot', params)
417
+ }
418
+
419
+ // 禁止截屏
420
+ export const disableWebViewScreenShot = (params) => {
421
+ return MXCommon('disableWebViewScreenShot', params)
422
+ }
423
+
424
+ // 开始录音
425
+ export const startRecord = (params) => {
426
+ return MXCommon('startRecord', params)
427
+ }
428
+
429
+ // 暂停录音
430
+ export const pauseRecord = (params) => {
431
+ return MXCommon('pauseRecord', params)
432
+ }
433
+
434
+ // 停止录音
435
+ export const stopRecord = (...params) => {
436
+ return MXCommon('stopRecord', ...params)
437
+ }
438
+
439
+ // 获取录音时长
440
+ export const getRecordDuration = (params) => {
441
+ return MXCommon('getRecordDuration', params)
442
+ }
443
+
444
+ // 播放录音
445
+ export const playVoice = (...params) => {
446
+ return MXCommon('playVoice', ...params)
447
+ }
448
+
449
+ // 暂停播放
450
+ export const pauseVoice = (...params) => {
451
+ return MXCommon('pauseVoice', ...params)
452
+ }
453
+
454
+ // 停止播放
455
+ export const stopVoice = (...params) => {
456
+ return MXCommon('stopVoice', ...params)
457
+ }
458
+
459
+ // 身份证拍照
460
+ export const onlyTakeIdCardPhoto = (params) => {
461
+ return MXCommon('onlyTakeIdCardPhoto', params)
462
+ }
463
+
464
+ // base64 分享到工作圈
465
+ export const base64SendToCircle = (params) => {
466
+ return MXCommon('base64SendToCircle', params)
467
+ }
468
+
469
+ // 地理逆编码
470
+ export const regeocode = (params) => {
471
+ return MXLocation('regeocode', params)
472
+ }
473
+
474
+ export const newChooseFile = (params) => {
475
+ return MXCommon('chooseFile', params)
476
+ }
477
+
478
+ export const newChooseFile02 = (...params) => {
479
+ return MXCommon('chooseFile', ...params)
480
+ }
481
+
482
+ // 根据appid启动应用
483
+ export const lanuchApp = (...params) => {
484
+ return MXCommon('launchApp', ...params)
485
+ }
486
+
487
+ // 打开协议
488
+ export const launchAnyUrl = (params) => {
489
+ return MXCommon('launchAnyUrl', params)
490
+ }
491
+
492
+ // 设置应用未读数
493
+ export const setAppUnreadCount = (...params) => {
494
+ return MXCommon('setAppUnreadCount', ...params)
495
+ }
496
+
497
+ // 设置应用在聊天列表中的未读数
498
+ export const setAppChatUnreadCount = (...params) => {
499
+ return MXCommon('setAppChatUnreadCount', ...params)
500
+ }
501
+
502
+ // 设置导航栏背景颜色
503
+ export const setNavBgColor = (...params) => {
504
+ return MXWebui('setNavBgColor', ...params)
505
+ }
506
+
507
+ // 设置右上角菜单颜色
508
+ export const setPopupMenuBgColor = (...params) => {
509
+ return MXWebui('setPopupMenuBgColor', ...params)
510
+ }
511
+
512
+ // 分享到微信或者微信朋友圈
513
+ export const share = (params) => {
514
+ return MXShare('share', params)
515
+ }
@@ -0,0 +1,132 @@
1
+ # package.json 说明
2
+
3
+ ## 项目信息
4
+
5
+ | 字段 | 值 | 说明 |
6
+ |------|-----|------|
7
+ | `name` | `mini2.0` | 项目名称 |
8
+ | `version` | `0.0.0` | 当前版本(开发初期未正式定版) |
9
+ | `private` | `true` | 私有项目,禁止发布到 npm |
10
+ | `type` | `module` | 使用 ES Module 规范(`import/export`) |
11
+ | `engines.node` | `^20.19.0 \|\| >=22.12.0` | 要求 Node.js 20.19+ 或 22.12+ |
12
+
13
+ ---
14
+
15
+ ## 脚本命令(scripts)
16
+
17
+ ### 开发
18
+
19
+ | 命令 | 作用 |
20
+ |------|------|
21
+ | `npm run dev` | 启动 Vite 开发服务器(默认 `.env.development` 环境变量) |
22
+ | `npm run dev:test` | 以 test 模式启动开发服务器,加载 `.env.test` 环境变量,用于本地联调测试环境接口 |
23
+
24
+ ### 构建
25
+
26
+ | 命令 | 作用 |
27
+ |------|------|
28
+ | `npm run build` | 生产构建,先运行 TypeScript 类型检查(`vue-tsc --build`),再执行 Vite 构建 |
29
+ | `npm run build:test` | 测试环境构建,串行执行类型检查 + Vite 构建(`--mode test`) |
30
+ | `npm run build:prod` | 生产环境构建,串行执行类型检查 + Vite 构建(`--mode production`) |
31
+ | `npm run build-only` | **仅**执行 Vite 构建,不做类型检查,适合快速出包调试 |
32
+ | `npm run build-only:test` | 仅构建,使用 test 模式 |
33
+ | `npm run build-only:prod` | 仅构建,使用 production 模式 |
34
+ | `npm run preview` | 启动 Vite 静态文件预览服务器,用于本地查看构建产物 |
35
+
36
+ > `build` 命令使用 `npm-run-all2` 的 `run-p`(并行)执行类型检查和构建;`build:test` / `build:prod` 使用 `run-s`(串行)先类型检查再构建。
37
+
38
+ ### 代码质量
39
+
40
+ | 命令 | 作用 |
41
+ |------|------|
42
+ | `npm run lint` | 串行执行所有 `lint:*` 子命令 |
43
+ | `npm run lint:oxlint` | 使用 OxLint 对代码做快速 lint 检查并自动修复 |
44
+ | `npm run lint:eslint` | 使用 ESLint 做完整 lint 检查并自动修复,结果会缓存(`--cache`) |
45
+ | `npm run format` | 使用 Prettier 格式化 `src/` 目录下的代码 |
46
+
47
+ > `npm run lint` 会先执行 oxlint 再执行 eslint,两者分工:oxlint 速度快,适合捕获常见错误;eslint 规则更全面,特别是 Vue/TypeScript 相关规则。
48
+
49
+ ---
50
+
51
+ ## 生产依赖(dependencies)
52
+
53
+ 这些包会被打包到最终产物中,直接影响用户侧。
54
+
55
+ | 包名 | 版本 | 作用 |
56
+ |------|------|------|
57
+ | `vue` | `^3.5.32` | Vue 3 核心框架,提供响应式系统、组件系统和模板编译 |
58
+ | `vue-router` | `^5.0.4` | Vue 官方路由,管理页面导航和 URL 映射 |
59
+ | `pinia` | `^3.0.4` | Vue 官方状态管理库,替代 Vuex,支持组合式 API |
60
+ | `vant` | `^4.9.24` | 有赞出品的移动端 Vue 3 组件库,提供丰富的 UI 组件(按钮、弹窗、表单等) |
61
+ | `axios` | `^1.16.1` | HTTP 客户端,用于发起 API 请求,支持拦截器、取消请求等 |
62
+ | `@iconify/vue` | `^5.0.1` | Iconify 图标库的 Vue 组件封装,可使用数千个图标集(如 Material Design、Tabler 等) |
63
+ | `@vueuse/core` | `^14.3.0` | Vue 组合式工具函数集,提供 `useStorage`、`useDebounceFn`、`useClipboard` 等常用 hooks |
64
+ | `dayjs` | `^1.11.21` | 轻量级日期时间处理库(仅 2KB),Moment.js 的替代品 |
65
+ | `crypto-js` | `^4.2.0` | 加密算法库,支持 AES、MD5、SHA 等,用于前端数据加密/签名 |
66
+ | `clipboard` | `^2.0.11` | 剪贴板操作库,实现一键复制文本到系统剪贴板 |
67
+ | `nprogress` | `^0.2.0` | 页面顶部细线进度条,常用于路由切换或接口请求时的加载反馈 |
68
+ | `qrcode` | `^1.5.4` | 二维码生成库,可在 Canvas/SVG/Node.js 中生成二维码图片 |
69
+
70
+ ---
71
+
72
+ ## 开发依赖(devDependencies)
73
+
74
+ 这些包仅在开发/构建阶段使用,不会进入最终产物。
75
+
76
+ ### 构建工具
77
+
78
+ | 包名 | 版本 | 作用 |
79
+ |------|------|------|
80
+ | `vite` | `^8.0.8` | 下一代前端构建工具,提供极快的冷启动和热更新 |
81
+ | `@vitejs/plugin-vue` | `^6.0.6` | Vite 官方 Vue 插件,处理 `.vue` 单文件组件的编译 |
82
+ | `vite-plugin-vue-devtools` | `^8.1.1` | Vue DevTools 的 Vite 插件集成,开发时提供组件树、状态检查等调试能力 |
83
+ | `unplugin-vue-components` | `^32.1.0` | 组件自动导入插件,无需手动 `import` 即可使用 Vant 等组件(按需引入) |
84
+ | `postcss-px-to-viewport-8-plugin` | `^1.2.5` | PostCSS 插件,自动将 CSS 中的 `px` 单位转换为 `vw`,实现移动端视口适配 |
85
+ | `less` | `^4.6.4` | Less CSS 预处理器,支持变量、嵌套、混入等语法 |
86
+ | `npm-run-all2` | `^8.0.4` | 提供 `run-s`(串行)和 `run-p`(并行)命令,用于组合多个 npm scripts |
87
+ | `jiti` | `^2.6.1` | 运行时 TypeScript/ESM 模块加载器,部分工具链(如 ESLint flat config)依赖它在 Node 中直接解析 TS 配置文件 |
88
+
89
+ ### TypeScript
90
+
91
+ | 包名 | 版本 | 作用 |
92
+ |------|------|------|
93
+ | `typescript` | `~6.0.0` | TypeScript 编译器,提供静态类型检查 |
94
+ | `vue-tsc` | `^3.2.6` | Vue 单文件组件的 TypeScript 类型检查工具(基于 `tsc`,支持 `.vue` 文件) |
95
+ | `@tsconfig/node24` | `^24.0.4` | Node.js 24 的 `tsconfig.json` 基础配置预设 |
96
+ | `@types/node` | `^24.12.2` | Node.js 内置模块(`fs`、`path` 等)的类型声明 |
97
+ | `@vue/tsconfig` | `^0.9.1` | Vue 项目的 `tsconfig.json` 基础配置预设 |
98
+
99
+ ### 代码规范
100
+
101
+ | 包名 | 版本 | 作用 |
102
+ |------|------|------|
103
+ | `eslint` | `^10.2.1` | JavaScript/TypeScript 代码静态分析工具,检测代码风格和潜在错误 |
104
+ | `eslint-plugin-vue` | `~10.8.0` | ESLint 的 Vue 规则插件,检查 `.vue` 文件的模板和脚本 |
105
+ | `@vue/eslint-config-typescript` | `^14.7.0` | Vue 官方的 TypeScript ESLint 配置预设 |
106
+ | `eslint-plugin-oxlint` | `~1.60.0` | 让 ESLint 跳过 OxLint 已覆盖的规则,避免重复检查 |
107
+ | `eslint-config-prettier` | `^10.1.8` | 关闭 ESLint 中与 Prettier 冲突的格式化规则,保证两者不打架 |
108
+ | `oxlint` | `~1.60.0` | Rust 编写的超快 linter(比 ESLint 快 50-100 倍),用于替代部分 ESLint 规则 |
109
+ | `prettier` | `3.8.3` | 代码格式化工具,统一缩进、引号、分号等风格,只管格式不管逻辑 |
110
+
111
+ ---
112
+
113
+ ## 依赖关系速览
114
+
115
+ ```
116
+ 开发流程
117
+ ├── 代码编写阶段
118
+ │ ├── TypeScript (类型检查)
119
+ │ ├── ESLint + OxLint (代码规范)
120
+ │ └── Prettier (代码格式化)
121
+
122
+ ├── 开发调试阶段
123
+ │ ├── Vite (开发服务器 + HMR)
124
+ │ ├── Vue / Vant (UI 开发)
125
+ │ └── vite-plugin-vue-devtools (调试工具)
126
+
127
+ └── 构建部署阶段
128
+ ├── vue-tsc (类型检查)
129
+ ├── Vite (打包构建)
130
+ ├── postcss-px-to-viewport-8-plugin (移动端适配)
131
+ └── unplugin-vue-components (按需引入)
132
+ ```
package/env.d.ts ADDED
@@ -0,0 +1,15 @@
1
+ /// <reference types="vite/client" />
2
+
3
+ interface ImportMetaEnv {
4
+ readonly BASE_URL: string
5
+ readonly VITE_APP_ENV: 'development' | 'test' | 'production'
6
+ readonly VITE_API_BASE_URL: string
7
+ readonly VITE_PROXY_TARGET?: string
8
+ readonly VITE_API_TIMEOUT: string
9
+ }
10
+
11
+ interface ImportMeta {
12
+ readonly env: ImportMetaEnv
13
+ }
14
+
15
+ declare const __APP_VERSION__: string
@@ -0,0 +1,26 @@
1
+ import { globalIgnores } from 'eslint/config'
2
+ import { defineConfigWithVueTs, vueTsConfigs } from '@vue/eslint-config-typescript'
3
+ import pluginVue from 'eslint-plugin-vue'
4
+ import pluginOxlint from 'eslint-plugin-oxlint'
5
+ import skipFormatting from 'eslint-config-prettier/flat'
6
+
7
+ // To allow more languages other than `ts` in `.vue` files, uncomment the following lines:
8
+ // import { configureVueProject } from '@vue/eslint-config-typescript'
9
+ // configureVueProject({ scriptLangs: ['ts', 'tsx'] })
10
+ // More info at https://github.com/vuejs/eslint-config-typescript/#advanced-setup
11
+
12
+ export default defineConfigWithVueTs(
13
+ {
14
+ name: 'app/files-to-lint',
15
+ files: ['**/*.{vue,ts,mts,tsx}'],
16
+ },
17
+
18
+ globalIgnores(['**/dist/**', '**/dist-ssr/**', '**/coverage/**']),
19
+
20
+ ...pluginVue.configs['flat/essential'],
21
+ vueTsConfigs.recommended,
22
+
23
+ ...pluginOxlint.buildFromOxlintConfigFile('.oxlintrc.json'),
24
+
25
+ skipFormatting,
26
+ )
package/index.html ADDED
@@ -0,0 +1,16 @@
1
+ <!DOCTYPE html>
2
+ <html lang="">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <link rel="icon" href="/favicon.ico">
6
+ <meta
7
+ name="viewport"
8
+ content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no"
9
+ />
10
+ <title>平台</title>
11
+ </head>
12
+ <body>
13
+ <div id="app"></div>
14
+ <script type="module" src="/src/main.ts"></script>
15
+ </body>
16
+ </html>