bohui-vue 1.0.1

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 (104) hide show
  1. package/README.md +121 -0
  2. package/bin/create-vue-template.js +565 -0
  3. package/package.json +28 -0
  4. package/templates/vue-project/.browserslistrc +3 -0
  5. package/templates/vue-project/.editorconfig +28 -0
  6. package/templates/vue-project/.env.development +2 -0
  7. package/templates/vue-project/.env.production +2 -0
  8. package/templates/vue-project/.eslintrc.cjs +76 -0
  9. package/templates/vue-project/.keep +0 -0
  10. package/templates/vue-project/.node-version +1 -0
  11. package/templates/vue-project/.prettierignore +13 -0
  12. package/templates/vue-project/.prettierrc +20 -0
  13. package/templates/vue-project/.prettierrc.txt +130 -0
  14. package/templates/vue-project/.stylelintrc.json +94 -0
  15. package/templates/vue-project/README.md +24 -0
  16. package/templates/vue-project/babel.config.js +5 -0
  17. package/templates/vue-project/index.html +34 -0
  18. package/templates/vue-project/package.json +75 -0
  19. package/templates/vue-project/public/favicon.ico +0 -0
  20. package/templates/vue-project/public/static/img/ai-default.jpg +0 -0
  21. package/templates/vue-project/public/static/img/image.png +0 -0
  22. package/templates/vue-project/public/static/img/ppt1.png +0 -0
  23. package/templates/vue-project/public/static/img/ppt2.png +0 -0
  24. package/templates/vue-project/public/static/img/ppt3.png +0 -0
  25. package/templates/vue-project/public/static/js/config.js +11 -0
  26. package/templates/vue-project/public/static/js/dataConfig.js +1143 -0
  27. package/templates/vue-project/src/App.vue +10 -0
  28. package/templates/vue-project/src/api/error-handler.ts +60 -0
  29. package/templates/vue-project/src/api/http.ts +254 -0
  30. package/templates/vue-project/src/api/services/aicebd.ts +47 -0
  31. package/templates/vue-project/src/api/services/base.ts +18 -0
  32. package/templates/vue-project/src/api/services/umse.ts +17 -0
  33. package/templates/vue-project/src/assets/font/Alibaba-PuHuiTi-Medium.otf +0 -0
  34. package/templates/vue-project/src/assets/font/Alibaba-PuHuiTi-Regular.otf +0 -0
  35. package/templates/vue-project/src/assets/font/DOUYINSANSBOLD.OTF +0 -0
  36. package/templates/vue-project/src/assets/font/Pangmen-Title.TTF +0 -0
  37. package/templates/vue-project/src/assets/font/font.css +25 -0
  38. package/templates/vue-project/src/assets/iconfont/iconfont.css +402 -0
  39. package/templates/vue-project/src/assets/iconfont/iconfont.js +66 -0
  40. package/templates/vue-project/src/assets/iconfont/iconfont.json +688 -0
  41. package/templates/vue-project/src/assets/iconfont/iconfont.ttf +0 -0
  42. package/templates/vue-project/src/assets/iconfont/iconfont.woff +0 -0
  43. package/templates/vue-project/src/assets/iconfont/iconfont.woff2 +0 -0
  44. package/templates/vue-project/src/assets/images/Click-tap.png +0 -0
  45. package/templates/vue-project/src/assets/images/Effects.png +0 -0
  46. package/templates/vue-project/src/assets/images/bg.png +0 -0
  47. package/templates/vue-project/src/assets/images/erCode.png +0 -0
  48. package/templates/vue-project/src/assets/images/header-bg.png +0 -0
  49. package/templates/vue-project/src/assets/images/logo.png +0 -0
  50. package/templates/vue-project/src/assets/scss/common.scss +530 -0
  51. package/templates/vue-project/src/assets/styles/element-overrides.css +53 -0
  52. package/templates/vue-project/src/assets/styles/reset.css +186 -0
  53. package/templates/vue-project/src/assets/styles/theme.css +100 -0
  54. package/templates/vue-project/src/components/BarChart.vue +238 -0
  55. package/templates/vue-project/src/components/echarts/EChart.vue +140 -0
  56. package/templates/vue-project/src/composables/useTheme.ts +84 -0
  57. package/templates/vue-project/src/main.ts +111 -0
  58. package/templates/vue-project/src/mocks/base.ts +37 -0
  59. package/templates/vue-project/src/mocks/umse.ts +31 -0
  60. package/templates/vue-project/src/router/index.ts +32 -0
  61. package/templates/vue-project/src/shims-vue.d.ts +19 -0
  62. package/templates/vue-project/src/store/index.ts +18 -0
  63. package/templates/vue-project/src/store/modules/user.ts +85 -0
  64. package/templates/vue-project/src/types/DTO/aicebd.d.ts +60 -0
  65. package/templates/vue-project/src/types/DTO/base.d.ts +26 -0
  66. package/templates/vue-project/src/types/DTO/global.d.ts +48 -0
  67. package/templates/vue-project/src/types/VO/teachingLog.d.ts +15 -0
  68. package/templates/vue-project/src/types/auto-imports.d.ts +73 -0
  69. package/templates/vue-project/src/types/components.d.ts +17 -0
  70. package/templates/vue-project/src/types/element-plus.d.ts +15 -0
  71. package/templates/vue-project/src/types/js-cookie.d.ts +1 -0
  72. package/templates/vue-project/src/types/unocss.d.ts +2 -0
  73. package/templates/vue-project/src/types/vite-plugins.d.ts +3 -0
  74. package/templates/vue-project/src/types/vue-router.d.ts +1 -0
  75. package/templates/vue-project/src/types/window-config.d.ts +12 -0
  76. package/templates/vue-project/src/utils/com-methods.ts +307 -0
  77. package/templates/vue-project/src/utils/echarts.ts +111 -0
  78. package/templates/vue-project/src/utils/number.ts +99 -0
  79. package/templates/vue-project/src/utils/rem.ts +82 -0
  80. package/templates/vue-project/src/utils/responsive.ts +103 -0
  81. package/templates/vue-project/src/utils/time.ts +314 -0
  82. package/templates/vue-project/src/utils/tracker.ts +527 -0
  83. package/templates/vue-project/src/utils/validators.ts +85 -0
  84. package/templates/vue-project/src/utils/window.ts +132 -0
  85. package/templates/vue-project/src/views/home/Home.vue +60 -0
  86. package/templates/vue-project/src/views/home/composables/useUserAuth.ts +13 -0
  87. package/templates/vue-project/src/views/teachingLog/TeachingLog.vue +40 -0
  88. package/templates/vue-project/src/views/teachingLog/__tests__/TeachingEffect.test.ts +96 -0
  89. package/templates/vue-project/src/views/teachingLog/__tests__/TeachingHighlight.test.ts +66 -0
  90. package/templates/vue-project/src/views/teachingLog/__tests__/TeachingLog.test.ts +34 -0
  91. package/templates/vue-project/src/views/teachingLog/components/TeachingEffect.vue +458 -0
  92. package/templates/vue-project/src/views/teachingLog/components/TeachingHighlight.vue +181 -0
  93. package/templates/vue-project/src/views/teachingLog/composables/useEffectTooltip.ts +88 -0
  94. package/templates/vue-project/src/views/teachingLog/composables/useEffectTrendChart.ts +160 -0
  95. package/templates/vue-project/tests/setup.ts +27 -0
  96. package/templates/vue-project/tsconfig.json +24 -0
  97. package/templates/vue-project/tsconfig.node.json +41 -0
  98. package/templates/vue-project/uno.config.ts +84 -0
  99. package/templates/vue-project/vite.config.ts +216 -0
  100. package/templates/vue-project/vue3_ai_prompt.md +652 -0
  101. package/templates/vue-project/vue3_ai_prompt_basic.md +722 -0
  102. package/templates/vue-project/vue3_ai_prompt_full.md +1021 -0
  103. package/templates/vue-project/vue3_ai_prompt_unocss.md +768 -0
  104. package/templates/vue-project//345/267/245/347/250/213/345/214/226/346/250/241/346/235/277/344/273/213/347/273/215.md +463 -0
@@ -0,0 +1,463 @@
1
+ # 工程化模板介绍(Vue 3 + TypeScript + Vite + Element Plus)
2
+
3
+ 本仓库是一个可复用的前端工程化模板,后续业务项目建议在此模板基础上进行二次开发与持续演进。文档目标是让新成员在最短时间内理解:项目如何启动、代码如何组织、工程规范如何落地、以及新增模块应遵循的约定。
4
+
5
+ ## 1. 技术栈与能力边界
6
+
7
+ - 框架:Vue 3(SFC + `<script setup>`)+ TypeScript(`strict: true`)
8
+ - 构建:Vite
9
+ - 原子化 CSS:UnoCSS(含 reset 与主题映射)
10
+ - UI:Element Plus(按需自动引入 + 部分手动注册)
11
+ - 状态管理:Pinia
12
+ - 路由:Vue Router(Hash 模式)
13
+ - 请求:Axios(统一封装 `http` / `formDataHttp`)
14
+ - Mock:vite-plugin-mock(开发环境可开关)
15
+ - 质量:ESLint + Prettier + Stylelint + EditorConfig + VS Code 工作区设置
16
+
17
+ ## 2. 环境要求与包管理
18
+
19
+ - Node:`>= 22.0.0`(见 `.node-version` 与 `package.json#engines`)
20
+ - pnpm:`>= 10.28.0`(见 `package.json#engines`)
21
+ - 包管理强制:`preinstall` 使用 `only-allow pnpm`,禁止 npm/yarn 安装依赖
22
+
23
+ 建议统一使用:
24
+
25
+ ```bash
26
+ pnpm install
27
+ pnpm serve
28
+ ```
29
+
30
+ ## 3. 常用脚本
31
+
32
+ 见 `package.json#scripts`:
33
+
34
+ ```bash
35
+ pnpm serve # 本地开发
36
+ pnpm build # 生产构建
37
+ pnpm preview # 本地预览构建产物
38
+ pnpm test # 单元测试(watch)
39
+ pnpm test:run # 单元测试(run)
40
+ pnpm test:ui # 单元测试 UI
41
+ pnpm test:coverage # 单元测试覆盖率
42
+ pnpm lint # ESLint 修复(--fix)
43
+ pnpm lint:check # ESLint 仅检查
44
+ pnpm format # Prettier 格式化
45
+ pnpm format:check # Prettier 仅检查
46
+ ```
47
+
48
+ 说明:
49
+
50
+ - `format/format:check` 依赖 `prettier` 命令;若在命令行执行提示 “prettier 不是内部或外部命令”,请在 `devDependencies` 中补充安装 `prettier`(或仅使用编辑器 Prettier 插件进行格式化)。
51
+
52
+ ## 4. 目录结构与职责边界
53
+
54
+ 项目核心代码位于 `src/`,其余为工程配置与静态资源。
55
+
56
+ ```text
57
+ public/ # 静态资源(不参与构建处理,原样拷贝)
58
+ static/js/config.js # 运行时配置注入(window.ConfigInfo)
59
+ static/js/dataConfig.js # 运行时数据注入(window.DataConfig)
60
+
61
+ src/
62
+ api/ # 请求层(统一封装与业务接口)
63
+ services/ # 按后端域/模块拆分的接口文件
64
+ http.ts # axios 实例、拦截器、取消请求
65
+ error-handler.ts # 错误解析与提示文案
66
+ assets/ # 静态资源(参与构建)
67
+ styles/ # reset / 主题 / element-plus 覆盖
68
+ scss/ # 全局 scss(变量/公共样式)
69
+ images/ font/ iconfont/ # 图片/字体/iconfont
70
+ components/ # 全局可复用组件(与具体页面解耦)
71
+ composables/ # 全局可复用组合式函数(hooks)
72
+ mocks/ # 本地 Mock(vite-plugin-mock 扫描)
73
+ router/ # 路由配置
74
+ store/ # Pinia store(按模块拆分)
75
+ types/ # 全局类型声明、DTO/VO、插件类型补充
76
+ utils/ # 工具函数(与业务解耦)
77
+ views/ # 页面与页面级模块(建议按业务域拆分)
78
+ App.vue # 根组件
79
+ main.ts # 应用入口(插件注册、全局样式引入)
80
+ ```
81
+
82
+ ### 4.1 `components/`(全局复用组件)
83
+
84
+ 用于沉淀“跨页面可复用”的组件,避免被单个页面目录绑定(例如 ECharts 封装、通用图表组件等)。
85
+
86
+ 约定建议:
87
+
88
+ - 组件目录按领域拆分(如 `components/echarts/`)
89
+ - 组件尽量“纯展示 + 明确输入输出”,避免直接依赖某个页面的 store/router
90
+
91
+ #### 4.1.1 图表(ECharts)使用规范
92
+
93
+ 模板内对 ECharts 做了“按需引入 + 统一渲染容器”的工程化封装,目标是:减少打包体积、统一初始化/销毁、降低业务图表组件的复杂度。
94
+
95
+ - 按需引入入口:`src/utils/echarts.ts`
96
+ - 业务代码不要直接从 `echarts` 顶层包导入(避免全量引入)
97
+ - 如需新增图表类型/组件能力,在该文件中从 `echarts/charts`、`echarts/components` 引入并注册到 `echarts.use([...])`
98
+ - 统一渲染容器组件:`src/components/echarts/EChart.vue`
99
+ - Props 约定:`option: EChartsOption`,可选 `theme/autoResize/autoRefresh`
100
+ - 生命周期约定:组件负责 `init -> setOption -> resize/observe -> dispose`
101
+ - 事件约定:对外抛出 `chart-click`(图形元素点击)与 `zr-click`(画布点击)
102
+ - 能力暴露:通过 `defineExpose` 暴露 `getInstance/resize/clear/updateChart`,便于父级在必要时做高级控制
103
+ - 业务图表组件写法(推荐沉淀到 `src/components/`)
104
+ - 以 `src/components/BarChart.vue` 为参考:组件接收“数据源(source)”作为 props,在组件内部 `computed<EChartsOption>` 生成 option
105
+ - 建议把“数据整形/派生值计算”与“布局/样式”分离:例如 `buildChartModel(source)` 只做计算,不关心 UI
106
+ - 响应式:如需字号/布局随容器变化重算,可使用 `src/utils/com-methods.ts` 的 `useResizeTrigger()` 触发 option 重新计算
107
+ - 工具函数复用:通用的数值钳制/换行/文本处理等,统一放在 `src/utils/`(示例:`wrapLabel`、`clamp`)
108
+ - 页面使用方式
109
+ - 页面只做数据准备与组件编排,不直接 `echarts.init`
110
+ - 示例(`src/views/home/Home.vue`):
111
+
112
+ ```vue
113
+ <BarChart :bar-chart-data="BarChartTestData" />
114
+ ```
115
+
116
+ 数据约定(以 `BarChartSource` 为例):
117
+
118
+ - `categories.length` 必须与 `series[].values.length` 一一对应
119
+ - `values` 建议约束在 `0~100`(如百分比口径),超出范围需要在组件内部做钳制或规则说明
120
+
121
+ ### 4.2 `views/`(页面组织规范)
122
+
123
+ 建议按“业务域 / 页面模块”拆分:
124
+
125
+ - 每个页面一个目录:`src/views/<feature>/`
126
+ - 页面入口:`<Feature>.vue`
127
+ - 页面内组件:`components/`
128
+ - 页面内组合式逻辑:`composables/`
129
+
130
+ 示例:`src/views/teachingLog/`。
131
+
132
+ ### 4.3 `api/`(请求层规范)
133
+
134
+ - `src/api/http.ts`:提供两个实例
135
+ - `http`:`application/json`
136
+ - `formDataHttp`:`application/x-www-form-urlencoded`
137
+ - `src/api/services/`:按后端模块拆分文件(如 `aicebd.ts`、`base.ts`、`umse.ts`)
138
+ - 返回值类型建议统一走 `src/types/DTO/` 中声明的 DTO
139
+
140
+ ### 4.4 `types/`(类型组织规范)
141
+
142
+ `tsconfig.json` 配置了:
143
+
144
+ - `typeRoots: ["./node_modules/@types", "./src/types"]`
145
+ - `paths: { "@/*": ["src/*"] }`
146
+
147
+ 因此 `src/types/**.d.ts` 的声明会被全局识别。当前约定:
148
+
149
+ - `types/DTO/`:接口传输对象(字段与后端返回保持一致)
150
+ - `types/VO/`:视图层对象(更贴近前端使用形态,可与 DTO 不同)
151
+ - `types/global.d.ts`:全局通用响应结构 `globalDto.ResponseType<T>`
152
+ - `types/element-plus.d.ts`:Element Plus 常用实例类型别名(供 `ref<...>` 使用)
153
+ - `types/auto-imports.d.ts` / `types/components.d.ts`:由插件自动生成(不要手改)
154
+
155
+ ### 4.5 `store/`(状态管理规范)
156
+
157
+ - 使用 Pinia 的组合式写法:`defineStore("moduleName", () => { ... })`
158
+ - `src/store/index.ts` 作为统一出口:默认导出 `pinia`,并 `export * from "./modules/*"`
159
+ - 模块文件放在 `src/store/modules/`
160
+
161
+ 建议:跨页面共享且有明确生命周期的数据进入 store;纯页面状态尽量留在页面内部。
162
+
163
+ ### 4.6 `utils/`(工具函数规范)
164
+
165
+ 工具函数应满足:
166
+
167
+ - 与具体业务无关
168
+ - 输入输出明确、易测试
169
+ - 不直接操作 UI(比如弹窗提示)与路由(除非工具目标就是封装这些)
170
+
171
+ #### 4.6.1 数据埋点(Tracker)使用规范
172
+
173
+ 模板提供了轻量级埋点/采集工具:`src/utils/tracker.ts`,并已在入口 `src/main.ts` 完成初始化接入,目标是统一采集页面访问、点击、接口请求结果等事件。
174
+
175
+ - 上报地址
176
+ - 默认读取 `window.ConfigInfo.baseUrl` 拼接 `${baseUrl}/analytics/collect`
177
+ - 若未注入 `baseUrl`,回退到相对路径 `/analytics/collect`
178
+ - 可在初始化时通过 `createTrackerPlugin({ endpoint })` 覆盖
179
+ - 接入方式(项目入口)
180
+ - Vue 插件:`createTrackerPlugin({ appId: "vue3-template" })` 注册全局能力
181
+ - 路由埋点:`getTracker().bindRouter(router)` 采集 `page_view`
182
+ - 页面曝光:`getTracker().bindRouterExposure(router)` 采集 `page_exposure`(仅统计页面可见时长)
183
+ - 接口埋点:`getTracker().attachAxios([http, formDataHttp])` 采集 `api_success/api_error`
184
+ - 用户关联:监听用户信息变化后 `getTracker().setUserId(u?.id ?? null)`,将后续事件与用户关联
185
+ - 事件采集调用规范
186
+ - `$track(name, data)`:入队缓冲,适合高频/非关键事件(减少上报频率)
187
+ - `v-track` 指令:点击事件立即上报(避免跳转/关闭页面导致丢失)
188
+ - 手动即时上报:`getTracker().trackNow(name, data)`,适合关键动作
189
+
190
+ 组件内用法示例:
191
+
192
+ ```ts
193
+ import { getTracker } from "@/utils/tracker";
194
+
195
+ getTracker().track("search_submit", { keyword: "xxx" });
196
+ getTracker().trackNow("pay_click", { orderId: "o_001" });
197
+ ```
198
+
199
+ 模板内置事件语义(建议统一沿用):
200
+
201
+ - `page_view`:路由切换后的页面访问
202
+ - `page_exposure`:页面曝光时长结算(route_change / hidden / beforeunload)
203
+ - `api_success` / `api_error`:接口成功/失败与耗时(自动从 axios 拦截器采集)
204
+ - `click` / 自定义 click 事件:通过 `v-track` 或 `trackNow` 采集
205
+
206
+ 数据约定建议:
207
+
208
+ - `name` 统一使用 `snake_case` 或 `kebab-case`,并在团队内固定一种风格
209
+ - `data` 不写入敏感信息(token、密码、身份证号等),用户标识使用 `setUserId` 管理
210
+
211
+ ### 4.7 `assets/`(样式与主题规范)
212
+
213
+ 入口在 `src/main.ts` 中统一引入(顺序也体现了层级):
214
+
215
+ 1. `@unocss/reset/tailwind.css`:UnoCSS reset(基础归一)
216
+ 2. `uno.css`:UnoCSS 编译产物(工具类)
217
+ 3. `reset.css`:项目级 reset(按需覆盖)
218
+ 4. `theme.css`:项目主题变量(业务主色、字体、边框等)
219
+ 5. `element-overrides.css`:将主题变量映射到 Element Plus CSS 变量
220
+ 6. `common.scss`:全局公共样式与布局片段
221
+
222
+ 另有:
223
+
224
+ - `src/utils/rem.ts`:基于屏幕宽度动态设置根字号,整体使用 `rem` 做响应式
225
+ - `src/composables/useTheme.ts`:通过给 `html` 设置 `data-theme` 切换明暗主题
226
+
227
+ ## 5. 工程规范(格式化、校验、样式)
228
+
229
+ ### 5.1 ESLint(代码质量与一致性)
230
+
231
+ - 配置:`.eslintrc.cjs`
232
+ - 继承:`eslint:recommended`、`plugin:vue/vue3-recommended`、`plugin:@typescript-eslint/recommended`、`prettier`
233
+ - 重点规则(约定意义):
234
+ - 允许单词组件名(便于业务组件命名):`vue/multi-word-component-names: off`
235
+ - `any` 允许但会告警:`@typescript-eslint/no-explicit-any: warn`
236
+ - 未使用变量告警,以下划线开头可忽略:`@typescript-eslint/no-unused-vars`
237
+ - 生产环境限制 `console/debugger`
238
+
239
+ 建议:本地开发用 `pnpm lint` 修复;CI 用 `pnpm lint:check` 卡质量。
240
+
241
+ ### 5.2 Prettier(统一格式化)
242
+
243
+ - 配置:`.prettierrc`
244
+ - 关键约定:`tabWidth: 4`、`printWidth: 100`、`semi: true`、双引号
245
+
246
+ 建议:格式化以 Prettier 为准;VS Code 已开启保存自动格式化与 ESLint 修复(见 `.vscode/settings.json`)。
247
+
248
+ ### 5.3 Stylelint(样式规范)
249
+
250
+ - 配置:`.stylelintrc.json`
251
+ - 作用:统一 CSS/SCSS 规则,并使用 `stylelint-order` 约束属性顺序(布局/盒模型/外观文字)
252
+ - 对 `.vue` 使用 `postcss-html` 解析 `<style>`
253
+
254
+ ### 5.4 自动化测试(单元/集成/E2E)
255
+
256
+ 当前模板已接入并提供“单元测试示例”,基于 Vitest + Vue Test Utils。集成测试与端到端测试目前先按约定留出占位规范,后续可逐步补齐。
257
+
258
+ #### 5.4.1 单元测试(Unit Test)
259
+
260
+ - 工具链
261
+ - 运行器:Vitest
262
+ - DOM 环境:jsdom
263
+ - Vue 组件测试:@vue/test-utils
264
+ - 覆盖率:@vitest/coverage-v8
265
+ - 配置位置
266
+ - `vite.config.ts` 的 `test` 字段:基础配置、include、setupFiles、coverage
267
+ - `tests/setup.ts`:全局测试初始化(Element Plus 全局注册、matchMedia 等 polyfill)
268
+ - 用例组织约定
269
+ - 推荐目录:就近放置在模块下:`src/views/<feature>/__tests__/`
270
+ - 文件命名:`*.test.ts` 或 `*.spec.ts`
271
+ - 当前示例:`src/views/teachingLog/__tests__/`
272
+ - 编写原则(建议沿用)
273
+ - 组件类测试优先断言“渲染结果 + 关键交互 + 关键派生计算”,避免过度关注实现细节
274
+ - 对第三方能力(如 ECharts init)优先用 `vi.mock(...)` 替身,避免依赖真实 DOM 渲染与外部库复杂行为
275
+ - 业务分支可用 `window.DataConfig` 注入 mock 数据,覆盖「无 lessonCode 的 fallback」逻辑
276
+
277
+ 运行方式(对应 `package.json#scripts`):
278
+
279
+ ```bash
280
+ pnpm test # watch 模式(开发时推荐)
281
+ pnpm test:run # CI/本地一次性跑完
282
+ pnpm test:ui # 打开 Vitest UI
283
+ pnpm test:coverage # 生成覆盖率报告
284
+ ```
285
+
286
+ #### 5.4.2 集成测试(Integration Test,占位)
287
+
288
+ 集成测试用于覆盖“多个模块/层级组合后的行为”,例如:
289
+
290
+ - 页面 + 路由跳转 + 请求层拦截器 + store 联动
291
+ - 真实接口不可用时,用 Mock Server 模拟后端响应
292
+
293
+ 当前模板预留方向:
294
+
295
+ - 推荐放置:`tests/integration/` 或 `src/**/__tests__/integration/`
296
+ - Mock Server:可选 MSW(当前 `tests/setup.ts` 预留了初始化位置)
297
+
298
+ #### 5.4.3 端到端测试(E2E,占位)
299
+
300
+ E2E 用于覆盖“用户真实操作路径”,验证构建产物/运行环境下的整体可用性,例如:
301
+
302
+ - 登录/退出、关键表单提交、关键页面跳转与权限拦截
303
+ - 样式/布局在不同分辨率下的关键断言(必要时)
304
+
305
+ 当前模板预留方向:
306
+
307
+ - 工具候选:Playwright 或 Cypress(后续根据团队习惯选型接入)
308
+ - 目录建议:`tests/e2e/`
309
+ - 运行策略:本地可跑;CI 在 nightly 或发布前跑全量关键路径
310
+
311
+ ## 6. Vite 配置约定(开发、构建、Mock)
312
+
313
+ 见 `vite.config.ts`:
314
+
315
+ ### 6.1 路径与别名
316
+
317
+ - `@` -> `src`
318
+ - 可省略扩展名:`.ts/.tsx/.js/.jsx/.vue/.json`
319
+
320
+ ### 6.2 自动引入(减少样板代码)
321
+
322
+ - `unplugin-auto-import`:
323
+ - 自动引入 `vue` 的常用 API(`ref/computed/onMounted/...`)
324
+ - 自动引入 Pinia:`defineStore`、`storeToRefs`
325
+ - `unplugin-vue-components`:
326
+ - 通过 `ElementPlusResolver` 自动注册 Element Plus 组件
327
+
328
+ 注意:自动生成的类型文件在 `src/types/auto-imports.d.ts` 与 `src/types/components.d.ts`。
329
+
330
+ ### 6.3 UnoCSS(原子化 CSS)规范
331
+
332
+ 模板已接入 UnoCSS:
333
+
334
+ - Vite 插件:`vite.config.ts` 注册 `UnoCSS()`
335
+ - 配置文件:`uno.config.ts`
336
+ - 全局引入:`src/main.ts` 引入 `@unocss/reset/tailwind.css` 与 `uno.css`
337
+
338
+ 使用约定:
339
+
340
+ - 优先用 UnoCSS 处理布局/间距/排版等“通用样式”,减少页面级 SCSS 的重复
341
+ - 复杂组件(图表、复杂交互)仍建议保留 scoped SCSS,但布局间距可用工具类表达
342
+ - 使用 `presetAttributify`:允许在标签上用属性方式写工具类(例如 `p="4"`、`text="t-primary 14"`)
343
+ - 使用 `transformerVariantGroup`:支持分组写法(例如 `hover:(bg-b-brand text-t-inverse)`)
344
+
345
+ 本模板对 `spacing`/`fontSize` 做了 rem 映射(见 `uno.config.ts`):
346
+
347
+ - 数值刻度与 rem 一一对应:`1 -> 1rem, 2 -> 2rem ...`
348
+ - 影响:`p-4 / m-8 / gap-2 / text-14` 等数值类,单位都是 `rem`
349
+
350
+ 颜色规范(建议沿用):
351
+
352
+ - 颜色已映射到 CSS 变量:`brand/success/warning/danger/info` 及 `t-*`(文字)、`b-*`(背景)、`border/divider` 等
353
+ - 推荐使用语义化类名组合,例如:`text-t-primary bg-b-base border-border`
354
+
355
+ ### 6.4 Mock 机制
356
+
357
+ - 插件:`vite-plugin-mock`
358
+ - Mock 文件目录:`src/mocks`
359
+ - 开关:`.env.development` / `.env.production` 中的 `VITE_USE_MOCK`
360
+ - 场景:`VITE_MOCK_SCENARIO`(并且 `http.ts` 会把 `scenario` 追加到请求 query 上,便于同一路径模拟多场景)
361
+
362
+ ### 6.5 构建产物与性能
363
+
364
+ - `base: "/teaching"`:部署基础路径(若部署路径变化,需要同步调整)
365
+ - 输出目录:`dist/`
366
+ - 静态资源目录:`static/`
367
+ - gzip:`vite-plugin-compression` 生成 `.gz`
368
+ - 压缩:`terser`,生产环境移除 `console/debugger`
369
+ - 分包:`manualChunks` 将 `vue`、`element-plus` 拆出
370
+
371
+ ## 7. 请求封装与接口编写规范
372
+
373
+ ### 7.1 统一响应结构
374
+
375
+ `src/types/DTO/global.d.ts` 定义了:
376
+
377
+ - `globalDto.ResponseType<T>`:接口第一层包装(`status/code/message/data/result`)
378
+
379
+ `src/api/http.ts` 的响应拦截器会把第一层结构解包,成功时直接返回 `data.data`,业务侧拿到的是 `T`。
380
+
381
+ ### 7.2 重复请求与页面切换
382
+
383
+ 模板内置了“取消请求”的工程化约定:
384
+
385
+ - 同一请求(同 method + url)重复触发:会 abort 上一个
386
+ - 路由切换前:`router.beforeEach` 调用 `abortAllRequests()`
387
+ - 页面刷新/关闭:`beforeunload` 调用 `abortAllRequests()`
388
+
389
+ 这类约定用于避免:
390
+
391
+ - 组件销毁后异步回写导致的状态污染
392
+ - 高频交互下的请求堆积
393
+
394
+ ### 7.3 新增接口的推荐写法
395
+
396
+ 1. 在 `src/types/DTO/<module>.d.ts` 声明后端返回 DTO
397
+ 2. 在 `src/api/services/<module>.ts` 中新增函数
398
+ 3. 在页面或 store 中调用,避免页面内直接写 axios
399
+
400
+ 建议命名:`xxxAPI`,入参显式(`lessonCode: string`),返回值显式(`Promise<DtoType>`)。
401
+
402
+ ## 8. 路由与页面开发约定
403
+
404
+ - 路由统一在 `src/router/index.ts` 维护
405
+ - 页面采用懒加载:`component: () => import("@/views/...")`
406
+ - 路由模式:`createWebHashHistory()`(适合静态资源部署/无服务端重写场景)
407
+
408
+ 新增页面步骤(推荐):
409
+
410
+ 1. 新建 `src/views/<feature>/<Feature>.vue`
411
+ 2. 如有子组件,新建 `src/views/<feature>/components/*`
412
+ 3. 如有可复用逻辑,新建 `src/views/<feature>/composables/useXxx.ts`
413
+ 4. 在 `router/index.ts` 增加路由并配置 `name`
414
+
415
+ ## 9. 运行时配置注入规范(public/static)
416
+
417
+ 模板通过 `index.html` 额外引入:
418
+
419
+ - `/static/js/config.js`:`window.ConfigInfo`
420
+ - `/static/js/dataConfig.js`:`window.DataConfig`
421
+
422
+ 配套类型声明在 `src/types/window-config.d.ts`。
423
+
424
+ 约定建议:
425
+
426
+ - `ConfigInfo` 存放“环境相关”的运行时配置(如后端地址、开关),用于不重新构建即可切换
427
+ - `DataConfig` 存放“演示/注入数据”(或外部系统注入的上下文)
428
+ - 不要在仓库中写入敏感凭证;运行时注入也要注意脱敏与权限控制
429
+
430
+ ## 10. 代码风格与命名约定(建议作为团队规范)
431
+
432
+ - 文件/目录:
433
+ - 页面目录:`views/featureName`(小驼峰或语义化英文)
434
+ - 组件:`PascalCase.vue`(如 `TeachingEffect.vue`)
435
+ - 组合式函数:`useXxx.ts`
436
+ - 导入:
437
+ - 优先使用别名 `@/`,避免深层相对路径
438
+ - 工具函数用具名导出,避免默认导出(统一可读性)
439
+ - 组件:
440
+ - 统一使用 `<script setup lang="ts">`
441
+ - props 使用 `defineProps`,并为复杂 props 提供明确类型
442
+ - 类型:
443
+ - DTO 与 VO 分层,避免在视图层直接扩展后端 DTO 导致“类型污染”
444
+
445
+ ## 11. 推荐的新增模块清单(复制即可执行)
446
+
447
+ 新增一个业务模块 `<feature>` 时,推荐一次性补齐以下结构:
448
+
449
+ ```text
450
+ src/views/<feature>/
451
+ <Feature>.vue
452
+ components/
453
+ composables/
454
+
455
+ src/api/services/<feature>.ts
456
+ src/types/DTO/<feature>.d.ts
457
+ ```
458
+
459
+ 如果需要跨页面共享状态:
460
+
461
+ ```text
462
+ src/store/modules/<feature>.ts
463
+ ```