@qilitt-mickey/vue3-temp-skill 1.1.11 → 1.1.13

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.
@@ -1,319 +1,105 @@
1
1
  ---
2
2
  skill: code-quality
3
- description: 生成后强制质量闸门。写完/改完 Vue/TS 代码后必须重读本清单、对照落盘文件自查、必跑 lint:fix 与 type-check,并在最终回复输出「代码质量审查」结果块。仅把本模块列入命中模块不算完成。
3
+ description: 生成后强制质量闸门。写完/改完代码后重读本清单、对照落盘文件、必跑 lint:fix 与 type-check,最终回复含「代码质量审查」结果块。
4
4
  scope: project
5
5
  tags: [code-review, quality, checklist, lint, typescript, vue3, security, performance, gate]
6
6
  ---
7
7
 
8
- # 代码质量审查清单(生成后强制闸门)
8
+ # 代码质量审查(生成后闸门)
9
9
 
10
- > **何时执行**:任意 `/vue3-temp-skill` 任务在**文件已写入或修改之后**,结束对话前必须执行本闸门。
11
- > **不算完成**:只在「命中模块」里写 `code-quality`;或只跑了 type-check / 未跑 `lint:fix`;或未对照本清单;或最终回复无「代码质量审查」结果块。
12
- > **须按** Skill 功能模块示例 + 本清单审查;不通过必须修正后再收工。
10
+ 写完/改完 Vue/TS 后执行。最终回复须含结果块;只把本模块写入「命中模块」不算完成。
13
11
 
14
- ## 强制执行协议(AI 必须按序做)
12
+ ## 协议(按序)
15
13
 
16
- 1. **重读本文件**(生成后再读,禁止仅凭开场记忆勾选)。
17
- 2. **列出本轮改动文件路径**,逐文件对照下方清单相关项。
18
- 3. **执行命令**(业务项目根目录,**两项均必跑,缺一不可**):
19
- - 必跑:`pnpm lint:fix`(自动修复可修问题;若无该脚本则用 `pnpm lint`,再无则 `pnpm exec eslint . --fix`)
20
- - 必跑:`pnpm type-check`(若无该脚本则用 `pnpm exec vue-tsc --noEmit`)
21
- - 顺序建议:先 `lint:fix`,再 `type-check`(lint 可能改写文件,须以最终落盘结果过类型检查)
22
- 4. **失败则修代码 → 重跑上述两条命令**,直到全部通过或写出明确阻塞(缺依赖、环境等)。`lint:fix` 后仍有无法自动修复的报错,必须手改后再跑,禁止跳过。
23
- 5. **在最终回复追加结果块**(缺此块 = 未完成):
14
+ 1. 重读本文件
15
+ 2. 列出本轮改动路径,对照下方清单
16
+ 3. 业务项目根目录必跑:`pnpm lint:fix` → `pnpm type-check`(无脚本则 `pnpm lint` / `pnpm exec eslint . --fix`;`pnpm exec vue-tsc --noEmit`)
17
+ 4. 失败则修代码并重跑,直至通过或写明阻塞
18
+ 5. 最终回复追加:
24
19
 
25
20
  ```markdown
26
21
  ## 代码质量审查
27
22
  - 闸门:已执行 code-quality(生成后)
28
23
  - 改动文件:`path/a`、`path/b`、…
29
- - 清单:选型 ✅ / 类型 ✅ / 组件 ✅ / API ✅ / 安全 ✅ / 业务 ✅ / 列表布局 ✅或N/A / 风格 ✅
24
+ - 清单:选型 ✅ / 类型 ✅ / 组件 ✅ / API ✅ / 安全 ✅ / 业务 ✅ / 列表→详情 ✅或N/A / 列表布局 ✅或N/A / 风格 ✅
30
25
  - 已修正:…(无则写「无」)
31
- - 命令:`pnpm lint:fix` → 通过 | 失败:…;`pnpm type-check` → 通过 | 失败:…
26
+ - 命令:`pnpm lint:fix` → …;`pnpm type-check` → …
32
27
  - 待确认:…
33
28
  ```
34
29
 
35
- ---
36
-
37
- ## 〇、项目选型(最高优先级)
30
+ ## 选型与硬约束
38
31
 
39
- - [ ] 已加载 `core-kernel` + `project-inventory`
40
- - [ ] 复用已有 Re* / Hook / utils;未另起同能力实现
41
- - [ ] 选型表指定库未擅自替换;新依赖已标注待确认
42
- - [ ] 命中 addon 时已核对 `package.json`;缺失包已按第九节**精确版本**安装(或已展示命令并征得确认)
43
- - [ ] Vite 相关插件(FileViewer / vConsole / Vant resolver / Fake Server)版本与接线文件已核对
44
- - [ ] 未使用 `@latest` 或不带版本号安装选型表内的库
45
- - [ ] 列表方法名为 **`onSearch` / `reset`**(不是 handleSearch/handleReset)
46
- - [ ] HTTP 为 `import { http } from '@/utils/http'` + 全局 `Result<T>`
32
+ - [ ] 已读 `core-kernel`;addon/缺依赖时已读 `project-inventory`
33
+ - [ ] 复用已有 Re* / Hook / utils;选型库未擅自替换;新依赖已待确认
34
+ - [ ] addon 缺包按 inventory 第九节精确版本(禁止 `@latest`)
35
+ - [ ] 列表方法名 `onSearch` / `reset`;HTTP 用 `@/utils/http` + `Result<T>`
47
36
  - [ ] 业务路由未二次挂 Layout
48
- - [ ] 使用对应 `references/<模块>.md` 示例与约定写法
49
- - [ ] **查询列表布局**:`el-card ref="content"` + 固定 `height`(含 `headerHeight`);查询区 `bg-bg_color p-5` + `ReGrid` `gap`/`cols`;表格绑 `tableHeight`;分页在 `ReTableBar` 内;卡片内查询条件以外的模块包根元素绑 `otherRef`
50
-
51
-
52
- ## 一、TypeScript 类型检查
53
-
54
- ### 必须通过
55
-
56
- - [ ] 所有 `props` 有明确的类型定义,不使用 `any`。
57
- - [ ] 所有 API 返回值声明了泛型类型 `Result<T>`。
58
- - [ ] `ref()` 和 `reactive()` 声明了类型:`ref<string>("")`、`reactive<FormType>({})`。
59
- - [ ] 事件处理函数声明了参数类型:`(e: Event)`、`(row: UserInfo)`。
60
- - [ ] 组件 `defineProps` 使用泛型方式 `defineProps<Props>()`,不使用运行时声明。
61
- - [ ] 不使用 `@ts-ignore` 或 `@ts-nocheck`,除非有注释说明原因。
62
- - [ ] 类型定义放在 `type.ts` 或 `types/` 目录,不内联在组件中。
63
-
64
- ### 常见错误示例
65
-
66
- ```typescript
67
- // ❌ 错误:使用 any
68
- const data = ref<any>(null);
69
- const list = ref([]); // 推断为 any[]
70
-
71
- // ✅ 正确:明确类型
72
- const data = ref<UserInfo | null>(null);
73
- const list = ref<UserListItem[]>([]);
74
-
75
- // ❌ 错误:API 无返回类型
76
- function getList(params) {
77
- return http.request("post", url, { data: params });
78
- }
79
-
80
- // ✅ 正确:声明完整类型
81
- function getListApi(params: ListQuery): Promise<Result<ListResult>> {
82
- return http.request<Result<ListResult>>("post", url, { data: params });
83
- }
84
- ```
85
-
86
- ## 二、Vue 组件规范检查
87
-
88
- ### 必须通过
89
-
90
- - [ ] 使用 `<script setup lang="ts">`,不使用 Options API。
91
- - [ ] 使用 `defineOptions({ name: "ComponentName" })` 声明组件名。
92
- - [ ] Props 和 Emits 类型定义在同目录 `type.ts` 文件中。
93
- - [ ] 样式使用 `<style lang="scss" scoped>`。
94
- - [ ] 组件 class 名使用 `re-` 前缀(自定义组件)或有意义的业务前缀。
95
- - [ ] 没有硬编码中文文案(应使用 `$t()` 或配置化)。
96
-
97
- ### 常见错误示例
98
-
99
- ```vue
100
- <!-- ❌ 错误:Options API -->
101
- <script>
102
- export default {
103
- data() { return { count: 0 } },
104
- methods: { increment() { this.count++ } }
105
- }
106
- </script>
107
-
108
- <!-- ✅ 正确:Composition API + script setup -->
109
- <script setup lang="ts">
110
- import type { MyComponentProps } from "./type";
111
- defineOptions({ name: "MyComponent" });
112
- const props = defineProps<MyComponentProps>();
113
- const count = ref(0);
114
- function increment() { count.value++; }
115
- </script>
116
- ```
117
-
118
- ## 三、API 调用规范检查
119
-
120
- ### 必须通过
121
-
122
- - [ ] API 调用封装在 `src/api/` 目录的函数中,不在组件中直接写 `http.request`。
123
- - [ ] 请求方法与后端文档一致(**允许 GET / POST**);POST 用 `data`,GET 用 `params`。
124
- - [ ] 真实接口 URL 使用 `import.meta.env.VITE_API_BASE_URL` 拼接;未硬编码域名。
125
- - [ ] 未把 `/mock/...` 或虚构的 `/api/...` 当成前后端标准前缀。
126
- - [ ] 返回类型为 `Result<T>`(`status` / `statusText` / `data`);分页用 `content` / `totalCount` / `pageNo` / `pageSize`。
127
- - [ ] 字段命名为驼峰(如 `userName`),与后端一致;`Long` / `BigDecimal` 用 `string`。
128
- - [ ] 下载请求设置了 `responseType: "blob"`。
129
- - [ ] 加解密依赖环境变量 `VITE_ENCODE_SWITCH`(无单请求 `crypto: true`)。
130
- - [ ] 组件中 API 调用有 `try/finally` 或 `try/catch` 处理异常。
131
-
132
- ### 常见错误示例
133
-
134
- ```typescript
135
- import { http } from "@/utils/http";
37
+ - [ ] 独立详情:`showLink:false` + `activePath` + `toDetail` + `initToDetail`(细则 `detail-page`)
38
+ - [ ] 列表布局按 `crud-pages` 黄金样板(`el-card.vts-page-card`+`content`+固定 height、`tableHeight`、`otherRef`、分页在 ReTableBar 内;内容区无外层滚动条)
136
39
 
137
- // ❌ 错误:在组件中直接调用 http,且使用虚构 /api 前缀
138
- const res = await http.request("post", "/api/user/list", { data: params });
40
+ ## TypeScript
139
41
 
140
- // ✅ 正确:封装到 api/,真实地址走环境变量
141
- export function getUserListApi(data: CombinedQueryData) {
142
- return http.request<Result<Data>>(
143
- "post",
144
- `${import.meta.env.VITE_API_BASE_URL}/console/user/list`,
145
- { data },
146
- );
147
- }
42
+ - [ ] props / API / `ref` / `reactive` / 事件参数有明确类型,忌 `any`
43
+ - [ ] `defineProps<Props>()`;忌 `@ts-ignore` / `@ts-nocheck`(除非注释原因)
44
+ - [ ] 类型放 `type.ts` 或 `types/`
148
45
 
149
- // ❌ 错误:方法与参数位置错配(POST 却用 params)
150
- http.request("post", `${import.meta.env.VITE_API_BASE_URL}/console/user/list`, { params });
46
+ ## Vue 组件
151
47
 
152
- // ✅ 正确:POST → data;后端约定 GET → params(项目允许)
153
- http.request("post", `${import.meta.env.VITE_API_BASE_URL}/console/user/list`, { data: params });
154
- http.request("get", `${import.meta.env.VITE_API_BASE_URL}/console/common/downLoadTemplate`, {
155
- params: { fileName: name },
156
- responseType: "blob",
157
- });
48
+ - [ ] `<script setup lang="ts">` + `defineOptions({ name })`
49
+ - [ ] Props/Emits 在同目录 `type.ts`;`<style lang="scss" scoped>`
50
+ - [ ] 文案用 `$t('中文')`
158
51
 
159
- // ❌ 错误:不存在的单请求加密开关
160
- http.request("post", url, { data: params, crypto: true });
161
- ```
162
-
163
- ## 四、安全规范检查
164
-
165
- ### 必须通过
166
-
167
- - [ ] 不在前端代码中硬编码密钥、Token、密码。
168
- - [ ] 用户输入在提交前做了前端校验(必填、格式、长度)。
169
- - [ ] XSS 防护:用户输入展示使用 `v-text` 而非 `v-html`,除非已做消毒处理。
170
- - [ ] 权限按钮使用 `v-auth` 指令控制,不手动判断角色。
171
- - [ ] 敏感操作(删除、提交)有二次确认弹窗。
172
- - [ ] 不在前端做安全校验(前端校验仅为体验优化,后端必须同步校验)。
173
-
174
- ### 安全检查清单
175
-
176
- ```typescript
177
- // ❌ 危险:v-html 直接渲染用户输入
178
- <div v-html="userInput" />
179
-
180
- // ✅ 安全:使用 v-text 或 {{ }} 插值
181
- <span v-text="userInput" />
182
- <span>{{ userInput }}</span>
183
-
184
- // ❌ 危险:硬编码密钥
185
- const apiKey = "sk-abc123456";
186
-
187
- // ✅ 安全:从环境变量或后端获取
188
- const apiKey = import.meta.env.VITE_API_KEY;
189
- ```
190
-
191
- ## 五、性能检查
192
-
193
- ### 必须通过
52
+ ## API
194
53
 
195
- - [ ] 页面组件使用 `() => import()` 懒加载。
196
- - [ ] 列表数据量超过 100 行时使用了分页或虚拟滚动。
197
- - [ ] 图表组件在 `onUnmounted` 中调用了 `dispose()`。
198
- - [ ] 没有不必要的 `watch`(能用 `computed` 的场景不用 `watch`)。
199
- - [ ] `v-for` 循环使用了唯一且稳定的 `:key`,不使用 `index` 作为 key(列表会变动时)。
200
- - [ ] 大数组操作使用 `computed` 缓存结果,不在 template 中直接调用方法。
201
- - [ ] 图片使用了懒加载(移动端 `van-image lazy-load`)。
202
- - [ ] 事件监听器在组件卸载时正确移除(`onUnmounted` 中 `removeEventListener`)。
54
+ - [ ] 调用在 `src/api/`;方法跟后端;POST→`data`,GET→`params`
55
+ - [ ] URL:`VITE_API_BASE_URL` + path;忌硬编码域名 / 虚构 `/api` 前缀
56
+ - [ ] `Result<T>`;分页 `content` / `totalCount` / `pageNo` / `pageSize`
57
+ - [ ] 驼峰字段;`Long`/`BigDecimal`→`string`;下载 `responseType: "blob"`
58
+ - [ ] 加解密靠 `VITE_ENCODE_SWITCH`;无单请求 `crypto: true`
59
+ - [ ] 组件调用有 `try/finally` 或 `try/catch`
203
60
 
204
- ### 常见错误示例
61
+ ## 安全
205
62
 
206
- ```typescript
207
- // ❌ 错误:watch 可以用 computed 替代
208
- watch(searchText, () => {
209
- filteredList.value = list.value.filter(item => item.name.includes(searchText.value));
210
- });
63
+ - [ ] 无硬编码密钥/Token/密码
64
+ - [ ] 提交前校验;忌不可信内容 `v-html`
65
+ - [ ] 权限用 `v-auth` / `ReAuth`;敏感操作有确认框
211
66
 
212
- // ✅ 正确:使用 computed
213
- const filteredList = computed(() =>
214
- list.value.filter(item => item.name.includes(searchText.value))
215
- );
67
+ ## 性能
216
68
 
217
- // ❌ 错误:template 中调用方法(每次渲染都执行)
218
- <template>{{ getFullName(user) }}</template>
69
+ - [ ] 路由组件 `() => import()`;大列表分页或虚拟滚动
70
+ - [ ] 图表 `onUnmounted` → `dispose()`;`v-for` 稳定 `:key`
71
+ - [ ] 能 `computed` 不用多余 `watch`;监听器卸载时移除
219
72
 
220
- // ✅ 正确:使用 computed 缓存
221
- const fullName = computed(() => `${user.firstName} ${user.lastName}`);
222
- ```
223
-
224
- ## 六、样式规范检查
225
-
226
- ### 必须通过
227
-
228
- - [ ] 样式使用 `scoped`,不会污染全局。
229
- - [ ] 颜色使用 CSS 变量(`var(--el-color-primary)`),不硬编码。
230
- - [ ] 优先使用 UnoCSS 原子类(`flex-center`、`mb-4`)。
231
- - [ ] UnoCSS 类名为连字符形态:`p-5` / `w-full` / `px-5` / `gap-10`;禁止 `p5` / `w100%` / `px5` / `gap10`(无 CSS 产出,样式静默失效)。
232
- - [ ] 背景/文字色按语义取变量:`bg-bg_color` / `var(--el-text-color-*)`;禁止 `bg-[#fff]` + `dark:bg-[#303030]` 成对硬编码。
233
- - [ ] 组件尺寸按场景档位:查询区与 `ReTableBar` 工具栏按钮 `size="small"`;表格 `:size="size"`(禁写死);弹窗表单 default;整屏主表单 `large`(细则见 `core-kernel`「四之二、样式契约」)。
234
- - [ ] 业务图标优先 `<svg-icon name="..." />`(本地无冒号 / Iconify 含 `:`);菜单 `meta.icon` 为 string;细则见 `icons`。
235
- - [ ] 不使用 `!important`,除非覆盖第三方组件样式且有注释说明。
236
- - [ ] 不使用深层嵌套选择器(不超过 3 层)。
237
- - [ ] 移动端不使用固定 `px` 宽度,使用 `rem` 或百分比。
238
- - [ ] 新增全局样式时,同步在 `dark.scss` 中添加暗黑模式覆盖。
239
- - [ ] 不直接修改 `--el-color-primary`,而是通过 `setEpThemeColor()` 设置(保证色阶同步更新)。
240
- - [ ] 使用 `chroma-js` 处理颜色,不使用 `color`、`polished` 等其他库。
241
- - [ ] 侧边栏相关样式通过 `html[data-theme]` 选择器设置,不写在 `:root` 中。
242
- - [ ] 覆盖 Element Plus 组件的全局样式放在 `src/styles/element-plus.scss`,不在组件内写。
243
-
244
- ### 设计规范遵从(命中 design-system 时必查,细则见 `design-system.md`)
245
-
246
- - [ ] 已输出「规范识别回执」,且规范 ID / 主色在令牌层、`platform-config.json`、侧栏主题三处一致(防识别漂移)。
247
- - [ ] 已建立令牌层 `design-tokens.scss`(**唯一新增文件**,纯 `:root` 数据无选择器;含用户可自定义区块 + 模版桥接令牌 + `--el-*` 映射);组件几何重写已并入 `element-plus.scss`(令牌引用 + 规范注释);文件名不得漂移成 `tokens.scss` 等变体,无独立重写层文件残留。
248
- - [ ] `index.scss` 中 `design-tokens` 位于 `@use` 最前;模版其余顺序未动。
249
- - [ ] `design-system.md` 第四节「模版硬编码冲突清单」逐条处理并在回复中逐条回填(重点:通配符 font-family、reset.scss body 字体与 `label { font-weight: 700 }`、`.el-card__body` padding 5px、弹窗渐变蓝底、表头硬编码色)。
250
- - [ ] 主色三态(hover/active)、字体、控件高度、圆角、卡片内边距、表单标签字重、表头视觉均符合目标规范(按第二节验证清单核验)。
251
- - [ ] 业务代码无裸控件高度/内边距/字号/圆角;组件几何覆盖只集中在 `element-plus.scss`;存量裸值扫描已执行。
252
- - [ ] 公共区域已按规范落地:`theme.scss` 侧栏配色(激活条 = 规范主色)、`index.scss` 壳变量(导航高/内容边距/弹窗底)、`HeaderHeight` 一致。
253
- - [ ] `platform-config.json` 的 `EpThemeColor` 与规范主色一致,已提醒清理 localStorage 缓存;新增令牌已在 `dark.scss` 补暗色覆盖。
73
+ ## 样式
254
74
 
255
- ## 七、业务逻辑检查
75
+ - [ ] `scoped`;色用 CSS 变量;优先 UnoCSS 连字符类(`p-5` 非 `p5`)
76
+ - [ ] 语义色 `bg-bg_color` / `--el-*`;尺寸档位见 `core-kernel` 样式契约
77
+ - [ ] 图标见 `icons`;忌滥 `!important`;选择器 ≤3 层
78
+ - [ ] 全局 EP 覆盖在 `element-plus.scss`;侧栏色用 `html[data-theme]`
79
+ - [ ] 主色经 `setEpThemeColor()`;颜色处理用 `chroma-js`
256
80
 
257
- ### 必须通过
81
+ ### design-system(命中时)
258
82
 
259
- - [ ] 表单提交前调用了 `validate()`。
260
- - [ ] 删除操作有确认弹窗(`ElMessageBox.confirm` 或 `showConfirmDialog`)。
261
- - [ ] 提交按钮有 `loading` 状态防止重复提交。
262
- - [ ] 列表页有加载状态(`v-loading`)。
263
- - [ ] 空数据有占位提示(`el-empty` 或 `van-empty`)。
264
- - [ ] 编辑页正确加载并回显了已有数据。
265
- - [ ] 路由跳转使用了正确的参数传递方式(`query` 而非 `params`)。
266
- - [ ] 分页切换正确触发了数据加载。
83
+ - [ ] 规范识别回执;令牌 / `platform-config.json` / 侧栏主题一致
84
+ - [ ] 已建 `design-tokens.scss`;`index.scss` 中其 `@use` 最前
85
+ - [ ] 冲突清单已逐条处理(见 `design-system`)
86
+ - [ ] 有上游设计产出时已读 `design-handoff`;`EpThemeColor`/`Theme`/侧栏桥接/`Version` 一致
267
87
 
268
- ### 查询列表页布局(命中 crud-pages / 列表需求时必查)
88
+ ## 业务
269
89
 
270
- - [ ] `ref="content"` 挂在 **`el-card`**(组件),不是原生 `div`。
271
- - [ ] 卡片样式为固定 **`height: calc(100vh - 2 * var(--vts-margin) - ${headerHeight}px)`**,不是 `minHeight`。
272
- - [ ] 查询 `el-form`:`inline` + `class="bg-bg_color p-5"`;`ReGrid` 有 `:gap="[0, 20]"` 与响应式 `cols`。
273
- - [ ] 表单项有 `class="w-[100%] !mr-0"`;操作按钮用 `<ReGridItem suffix>`。
274
- - [ ] 折叠事件为 `@should-show-collapse`(不是 `@show-collapse`)。
275
- - [ ] 展示区用 `ReTableBar class="bg-bg_color"`,与查询区视觉分离。
276
- - [ ] 表格 `:style="{ height: \`${tableHeight}px\` }"`;`paginationRef` 在表格下方且同属 `ReTableBar` `#default`。
277
- - [ ] 卡片内除查询表单、表格+分页外还有其他模块(统计块/页签/提示条等)时,已包进一个根元素并绑 `ref="otherRef"`(从 `useTableSearch` 解构);未绑则 `tableHeight` 漏减该模块高度。
278
- - [ ] `RePagination` 使用 `:pagination` + `@handle-current-change` / `@handle-size-change`。
279
- - [ ] `ReTableOperate` 使用 `:list`(不是 `:buttons`)。
90
+ - [ ] 提交前 `validate()`;删除有确认;提交有 loading;列表有 `v-loading`
91
+ - [ ] 编辑回显正确;分页切换会拉数
280
92
 
281
- ## 八、代码风格检查
93
+ ### 列表→详情(命中 detail-page 时)
282
94
 
283
- ### 必须通过
95
+ - [ ] 兄弟绝对 path;`showLink:false`;`activePath`=列表 path;非空 `title`
96
+ - [ ] 仅 `toDetail`;详情 `initToDetail`;`name` 对齐
97
+ - [ ] 按需 `keepAlive` / `moreTags`
284
98
 
285
- - [ ] 使用 `const` / `let`,不使用 `var`。
286
- - [ ] 字符串使用双引号(遵循 ESLint 配置),模板字符串用于变量拼接。
287
- - [ ] 函数和变量使用驼峰命名。
288
- - [ ] 组件名使用大驼峰(`UserList`),文件名使用短横线(`user-list.vue`)。
289
- - [ ] 常量使用全大写下划线分隔(`MAX_PAGE_SIZE`)。
290
- - [ ] 没有未使用的变量、导入或参数。
291
- - [ ] 没有 `console.log` 残留(生产代码中)。
99
+ ### 列表布局(命中 crud-pages 时)
292
100
 
293
- ## 审查流程
101
+ - [ ] 对照 `crud-pages` L1–L8(不在此复述示例)
294
102
 
295
- 1. **生成/改码落盘之后**(不是生成前):执行上方「强制执行协议」。
296
- 2. **发现问题**:立即修正并重跑 `pnpm lint:fix` + `pnpm type-check`,不要带着已知问题收工。
297
- 3. **不确定项**:写入结果块「待确认」,必要时在代码加 `// TODO: 需要确认`。
298
- 4. **严重问题**(安全 / 类型错误 / lint 报错 / 列表布局硬约束违反):必须修正后再输出最终回复。
299
- 5. **最终回复**:必须含「代码质量审查」结果块;禁止只用「命中模块含 code-quality」代替。
103
+ ## 代码风格
300
104
 
301
- ## 快速自检命令
302
-
303
- 完成代码修改后,运行以下命令验证(**均必跑**):
304
-
305
- ```bash
306
- # 必跑:Lint 自动修复(优先用项目脚本)
307
- pnpm lint:fix
308
-
309
- # 必跑:TypeScript 类型检查(优先用项目脚本)
310
- pnpm type-check
311
-
312
- # 无 lint:fix 时的回退
313
- pnpm lint
314
- # 或
315
- pnpm exec eslint . --fix
316
-
317
- # 无 type-check 脚本时的回退
318
- pnpm exec vue-tsc --noEmit
319
- ```
105
+ - [ ] `const`/`let`;驼峰;组件大驼峰;无未使用导入;无残留 `console.log`