@agile-team/wl-skills-ui 1.6.2
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.
- package/CHANGELOG.md +207 -0
- package/README.md +623 -0
- package/SKILL.md +632 -0
- package/bin/wl-ui.js +794 -0
- package/design/spec/color.md +41 -0
- package/design/spec/spacing.md +28 -0
- package/design/spec/typography.md +29 -0
- package/design/tokens/base.css +144 -0
- package/design/tokens/index.css +8 -0
- package/dist/ag-grid-override.scss +1 -0
- package/dist/element.scss +1 -0
- package/dist/index.scss +1 -0
- package/dist/portal.scss +1 -0
- package/dist/style-override.scss +1 -0
- package/dist/tokens.css +144 -0
- package/es/chunk-GBB7LDKQ.js +261 -0
- package/es/chunk-MDI2SCUP.js +281 -0
- package/es/chunk-QDTNMM7W.js +286 -0
- package/es/chunk-YLNAFAWE.js +233 -0
- package/es/common-preset.d.ts +38 -0
- package/es/common-preset.js +157 -0
- package/es/index.d.ts +32 -0
- package/es/index.js +1 -0
- package/es/presets/security.d.ts +16 -0
- package/es/presets/security.js +99 -0
- package/es/renderers-BFRSp2BH.d.ts +51 -0
- package/es/renderers-DMZbi_Gs.d.ts +51 -0
- package/es/renderers-DWhUlI2y.d.ts +47 -0
- package/es/types-04qLKHMt.d.ts +62 -0
- package/es/types-BrCPjAH6.d.ts +62 -0
- package/es/types-QZ1gy9KX.d.ts +63 -0
- package/examples/migration-operations-to-renderOps.md +107 -0
- package/examples/wk-exempt.example.json +30 -0
- package/mcp/server.js +394 -0
- package/package.json +130 -0
- package/reference/SelectPopupCom.vue +634 -0
- package/reference/ag-cell-renders.ts +644 -0
- package/reference/define-columns.ts +185 -0
- package/reference/jhlc.d.ts +1 -0
- package/scanner/coverage.mjs +287 -0
- package/scanner/exempt.mjs +127 -0
- package/scanner/fix.mjs +216 -0
- package/scanner/index.mjs +403 -0
- package/scanner/integration.mjs +155 -0
- package/scanner/report.mjs +459 -0
- package/scanner/rules/_shared.mjs +134 -0
- package/scanner/rules/button.mjs +97 -0
- package/scanner/rules/color.mjs +118 -0
- package/scanner/rules/componentFamily.mjs +184 -0
- package/scanner/rules/dialog.mjs +42 -0
- package/scanner/rules/form.mjs +86 -0
- package/scanner/rules/index.mjs +58 -0
- package/scanner/rules/table.mjs +170 -0
- package/scanner/rules/tag.mjs +245 -0
- package/scanner/snapshot.mjs +198 -0
- package/skills/_flows/full-audit.md +65 -0
- package/skills/_flows/legacy-skin-align.md +71 -0
- package/skills/_flows/new-project-init.md +80 -0
- package/skills/_flows/progressive-migrate.md +49 -0
- package/skills/_meta/_compat/README.md +47 -0
- package/skills/_meta/_compat/editors.json +76 -0
- package/skills/_meta/_compat/headers/agents.txt +7 -0
- package/skills/_meta/_compat/headers/claude-code.txt +7 -0
- package/skills/_meta/_compat/headers/cline.txt +7 -0
- package/skills/_meta/_compat/headers/cursor-mdc.txt +5 -0
- package/skills/_meta/_compat/headers/github-copilot.txt +5 -0
- package/skills/_meta/_compat/headers/kiro.txt +4 -0
- package/skills/_meta/_compat/headers/qoder.txt +4 -0
- package/skills/_meta/_compat/headers/trae.txt +3 -0
- package/skills/_meta/_compat/headers/windsurf.txt +5 -0
- package/skills/_meta/_detection.md +81 -0
- package/skills/_meta/_registry.md +96 -0
- package/skills/element/component-family/SKILL.md +71 -0
- package/skills/element/el-dialog/SKILL.md +124 -0
- package/skills/element/el-form/SKILL.md +84 -0
- package/skills/element/el-table/SKILL.md +86 -0
- package/skills/element/el-tag/SKILL.md +127 -0
- package/skills/layouts/detail-page/SKILL.md +99 -0
- package/skills/layouts/form-dialog/SKILL.md +128 -0
- package/skills/layouts/list-page/SKILL.md +111 -0
- package/skills/layouts/tree-list/SKILL.md +108 -0
- package/skills/ops/audit/SKILL.md +109 -0
- package/skills/ops/fix/SKILL.md +52 -0
- package/skills/ops/fix/USAGE.md +24 -0
- package/skills/ops/migrate/SKILL.md +157 -0
- package/skills/ops/scan/SKILL.md +71 -0
- package/skills/ops/scan/USAGE.md +16 -0
- package/skills/runtime/design-tokens/SKILL.md +88 -0
- package/skills/runtime/design-tokens/USAGE.md +19 -0
- package/skills/runtime/migration/SKILL.md +106 -0
- package/skills/runtime/migration/USAGE.md +34 -0
- package/skills/runtime/style-align/SKILL.md +124 -0
- package/skills/runtime/style-align/USAGE.md +52 -0
- package/skills/vendors/ag-grid/SKILL.md +94 -0
- package/skills/vendors/base-table/SKILL.md +57 -0
- package/skills/vendors/c-components/SKILL.md +36 -0
- package/skills/vendors/custom-wrappers/SKILL.md +45 -0
- package/skills/vendors/jh-components/SKILL.md +42 -0
- package/skills/vendors/unknown-wrapper/SKILL.md +44 -0
- package/standards/engineering/01-import-order.md +46 -0
- package/standards/engineering/02-naming.md +54 -0
- package/standards/engineering/03-scss-structure.md +59 -0
- package/standards/ui/01-table.md +111 -0
- package/standards/ui/02-button.md +83 -0
- package/standards/ui/03-form.md +118 -0
- package/standards/ui/04-tag-status.md +110 -0
- package/standards/ui/05-dialog-pagination.md +118 -0
- package/styles/element/_card.scss +26 -0
- package/styles/element/_descriptions.scss +22 -0
- package/styles/element/_dialog.scss +43 -0
- package/styles/element/_drawer.scss +22 -0
- package/styles/element/_feedback.scss +52 -0
- package/styles/element/_form.scss +22 -0
- package/styles/element/_navigation.scss +36 -0
- package/styles/element/_overlay.scss +32 -0
- package/styles/element/_pagination.scss +16 -0
- package/styles/element/_steps.scss +32 -0
- package/styles/element/_table.scss +13 -0
- package/styles/element/_tabs.scss +40 -0
- package/styles/element/_tree.scss +27 -0
- package/styles/element/_upload.scss +34 -0
- package/styles/element/index.scss +17 -0
- package/styles/index.scss +21 -0
- package/styles/layouts/_detail-page.scss +27 -0
- package/styles/layouts/_form-dialog.scss +19 -0
- package/styles/layouts/_list-page.scss +47 -0
- package/styles/layouts/_tree-list.scss +33 -0
- package/styles/layouts/index.scss +6 -0
- package/styles/presets/element-only.scss +6 -0
- package/styles/presets/full.scss +12 -0
- package/styles/presets/security.scss +37 -0
- package/styles/presets/skin.scss +14 -0
- package/styles/presets/tokens-only.scss +7 -0
- package/styles/tokens/index.scss +79 -0
- package/styles/vendors/_ag-grid.scss +273 -0
- package/styles/vendors/_base-components.scss +480 -0
- package/styles/vendors/_base-query-toolbar.scss +253 -0
- package/styles/vendors/_base-table.scss +41 -0
- package/styles/vendors/_c-components.scss +34 -0
- package/styles/vendors/_custom-wrappers.scss +30 -0
- package/styles/vendors/_jh-drag-col.scss +63 -0
- package/styles/vendors/_jh-pagination.scss +81 -0
- package/styles/vendors/_jh-tree.scss +196 -0
- package/styles/vendors/_portal.scss +114 -0
- package/styles/vendors/index.scss +17 -0
- package/templates/ag-grid-page/TPL-AG-GRID.md +76 -0
- package/templates/form-dialog/TPL-FORM-DIALOG.md +165 -0
- package/templates/list-page/TPL-LIST.md +139 -0
- package/templates/tree-list/TPL-TREE-LIST.md +176 -0
- package/templates/ui-optimization-report/TPL-UI-OPTIM-REPORT.md +343 -0
package/SKILL.md
ADDED
|
@@ -0,0 +1,632 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: |
|
|
3
|
+
UI 风格对齐 Skill —— 扫描 Vue SFC 文件,识别与 wl-skills-ui 五层规范不一致的控件写法,
|
|
4
|
+
生成整改清单,经用户确认后执行全量自动修复,最终验证归零。
|
|
5
|
+
支持老项目 Skin 化妆模式(不改布局)和新项目 Native 原生模式(完整接入)。
|
|
6
|
+
applyTo: "**/*.vue"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# UI 风格对齐 Skill
|
|
10
|
+
|
|
11
|
+
## 快速触发与生命周期命令
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# 安装/更新 AI Skill、触发提示、MCP 配置和 manifest
|
|
15
|
+
npx wl-ui init --project . --mode native
|
|
16
|
+
npx wl-ui update --project .
|
|
17
|
+
|
|
18
|
+
# 查看差异、体检、清理
|
|
19
|
+
npx wl-ui diff --project .
|
|
20
|
+
npx wl-ui doctor --project .
|
|
21
|
+
npx wl-ui clean --project . --dry-run
|
|
22
|
+
|
|
23
|
+
# 输出 AI 触发提示
|
|
24
|
+
npx wl-ui prompts
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
可选编辑器:`github-copilot`、`cursor`、`windsurf`、`kiro`、`trae`、`claude-code`、`cline`、`agents-generic`、`qoder`。修复前优先使用 `--dry-run` 或 MCP 工具 `wks_ui_fix_dry_run`。
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
## 一、适用场景
|
|
31
|
+
- 新业务系统首次接入统一风格标准(推荐先走「新系统快速接入方案」,见第八节)
|
|
32
|
+
- 已有系统定期合规检查
|
|
33
|
+
- Code Review 前的自动化预检
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 二、工作流程(必须严格按顺序执行,不得跳过)
|
|
38
|
+
|
|
39
|
+
### Phase 1 — 扫描(只读,不修改任何文件)
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# 推荐:一站式(接入完整性 + 风格扫描 + 报告)
|
|
43
|
+
npx wl-ui all --project [项目根目录] --outFile /tmp/scan-result.md
|
|
44
|
+
|
|
45
|
+
# 单独风格扫描
|
|
46
|
+
npx wl-ui scan --target [项目src目录] --outFile /tmp/scan-result.md
|
|
47
|
+
|
|
48
|
+
# 单独接入完整性检查
|
|
49
|
+
npx wl-ui check --project [项目根目录]
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
> 包未安装时也可:`node [SKILL_ROOT]/scanner/index.mjs all --project ...`
|
|
53
|
+
|
|
54
|
+
读取扫描输出,提取:
|
|
55
|
+
- 接入完整性 I001~I004 通过情况
|
|
56
|
+
- 总 issue 数量
|
|
57
|
+
- 按规则分类统计(R001~R018)
|
|
58
|
+
- 每个 issue 的文件路径 + 行号 + 规则 + 建议
|
|
59
|
+
|
|
60
|
+
### Phase 2 — 汇报
|
|
61
|
+
|
|
62
|
+
向用户展示以下格式的摘要:
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
## 扫描结果摘要
|
|
66
|
+
- 扫描文件数:XX
|
|
67
|
+
- 发现问题数:XX(高危 X / 中危 X / 低危 X)
|
|
68
|
+
|
|
69
|
+
### 高危(直接影响视觉一致性)
|
|
70
|
+
| 规则 | 说明 | 数量 | 文件 |
|
|
71
|
+
...
|
|
72
|
+
|
|
73
|
+
### 中危(风格偏差)
|
|
74
|
+
...
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Phase 3 — 确认
|
|
78
|
+
|
|
79
|
+
询问用户:
|
|
80
|
+
1. 是否全量修复,还是指定规则/文件?
|
|
81
|
+
2. 对于无法自动修复的问题(R009/R012),是否手动处理?
|
|
82
|
+
|
|
83
|
+
**未经确认,禁止修改任何文件。**
|
|
84
|
+
|
|
85
|
+
### Phase 4 — 修复
|
|
86
|
+
|
|
87
|
+
按确认范围:
|
|
88
|
+
- A 类(attr 缺失 / hex 颜色)→ `npx wl-ui fix --target [src] [--dry-run]`
|
|
89
|
+
- B 类(结构改造,如 R004/R013/R015)→ AI 逐文件编辑
|
|
90
|
+
|
|
91
|
+
每修复一个文件,输出该文件的修改摘要(改了什么、改了几处)。
|
|
92
|
+
|
|
93
|
+
### Phase 5 — 验证
|
|
94
|
+
|
|
95
|
+
重新运行 Phase 1 的扫描命令,验证 issue 数量归零或达到预期水平。
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## 三、规则定义(R001—R022)
|
|
100
|
+
|
|
101
|
+
### Category A:表格(el-table / AG Grid)
|
|
102
|
+
|
|
103
|
+
#### R001 — el-table-column 缺少居中对齐【高危】
|
|
104
|
+
**检测**:`<el-table-column` 没有 `align="center"`,或有 `align="left"`
|
|
105
|
+
**标准**:所有列必须 `align="center"`,selection 列 width=55,index 列 width=60
|
|
106
|
+
```diff
|
|
107
|
+
- <el-table-column label="名称" prop="name">
|
|
108
|
+
+ <el-table-column align="center" label="名称" prop="name">
|
|
109
|
+
- <el-table-column type="selection" align="left" width="70">
|
|
110
|
+
+ <el-table-column type="selection" align="center" header-align="center" width="55">
|
|
111
|
+
```
|
|
112
|
+
> ⚠️ `selection` 列必须同时加 `align="center"` **和** `header-align="center"`,否则表头复选框与数据行复选框会出现垂直错位。
|
|
113
|
+
|
|
114
|
+
#### R002 — el-table 缺少空状态文本【中危】
|
|
115
|
+
**检测**:`<el-table` 没有 `empty-text` 属性
|
|
116
|
+
**标准**:统一 `empty-text="暂无数据"`
|
|
117
|
+
```diff
|
|
118
|
+
- <el-table :data="list">
|
|
119
|
+
+ <el-table :data="list" empty-text="暂无数据">
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
#### R003 — BaseTable 缺少空状态文本【中危】
|
|
123
|
+
**检测**:`<BaseTable` 没有 `empty-text` 属性
|
|
124
|
+
**标准**:统一 `empty-text="暂无数据"`
|
|
125
|
+
```diff
|
|
126
|
+
- <BaseTable :hook="page">
|
|
127
|
+
+ <BaseTable :hook="page" empty-text="暂无数据">
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
#### R021 — BaseTable 缺少 AGGrid 渲染模式【高危】
|
|
131
|
+
**检测**:`<BaseTable` 没有 `render-type="agGrid"`
|
|
132
|
+
**标准**:与 `wl-skills-kit` 页面模板保持一致,所有业务表格必须显式使用 AGGrid 渲染模式
|
|
133
|
+
```diff
|
|
134
|
+
- <BaseTable :data="list" :columns="columns" />
|
|
135
|
+
+ <BaseTable render-type="agGrid" :cid="TABLE_CID" :data="list" :columns="columns" />
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
#### R022 — BaseTable 缺少唯一 cid【高危】
|
|
139
|
+
**检测**:`<BaseTable` 没有 `cid` 或 `:cid`
|
|
140
|
+
**标准**:每个 BaseTable 必须具备页面内/全局稳定唯一的 cid,推荐 `{pageAbbr}-{base36Timestamp}`,多表追加 `-sub1/-sub2`
|
|
141
|
+
```diff
|
|
142
|
+
- <BaseTable render-type="agGrid" :data="list" :columns="columns" />
|
|
143
|
+
+ <BaseTable render-type="agGrid" :cid="TABLE_CID" :data="list" :columns="columns" />
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
### Category B:按钮(el-button)
|
|
149
|
+
|
|
150
|
+
#### R004 — 操作列使用文字按钮【高危】
|
|
151
|
+
**检测**:列定义模板中有 `jh-op-btn` 缺失的操作按钮
|
|
152
|
+
**标准**:操作列必须用 `defaultSlot: ({ row }) => renderOps([...])` 图标按钮系统
|
|
153
|
+
|
|
154
|
+
#### R013 — columnsDef 旧格式 operations:[] 文字按钮【高危】
|
|
155
|
+
**检测**:script 块中 columnsDef 内有 `operations: [` 旧格式数组(由 scanner/index.mjs 单独检测)
|
|
156
|
+
**标准**:同 R004,改为 `defaultSlot: ({ row }) => renderOps([...])`
|
|
157
|
+
|
|
158
|
+
**简单迁移(无条件显示)**:
|
|
159
|
+
```diff
|
|
160
|
+
- { label: '操作', width: 120, operations: [
|
|
161
|
+
- { name: 'view', label: '查看', onClick: (row) => modal.view(row.id) },
|
|
162
|
+
- { name: 'edit', label: '编辑', onClick: (row) => modal.edit(row.id) },
|
|
163
|
+
- ]}
|
|
164
|
+
+ { label: '操作', width: 100,
|
|
165
|
+
+ defaultSlot: ({ row }) => renderOps([
|
|
166
|
+
+ { type: 'view', onClick: () => modal.view(row.id) },
|
|
167
|
+
+ { type: 'edit', onClick: () => modal.edit(row.id) },
|
|
168
|
+
+ ])
|
|
169
|
+
+ }
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
**含条件显示的迁移(`show:` 参数直接保留)**:
|
|
173
|
+
```diff
|
|
174
|
+
- operations: [
|
|
175
|
+
- { name: 'delete', label: '删除', show: () => optr.value !== 'view', onClick: ... },
|
|
176
|
+
- { name: 'view', label: '详情', show: () => optr.value === 'view', onClick: ... },
|
|
177
|
+
- ]
|
|
178
|
+
+ defaultSlot: ({ row }) => renderOps([
|
|
179
|
+
+ { type: 'del', show: () => optr.value !== 'view', onClick: ... },
|
|
180
|
+
+ { type: 'view', show: () => optr.value === 'view', onClick: ... },
|
|
181
|
+
+ ])
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
**含 Upload / 自定义组件的操作(特殊案例,不能直接用 renderOps)**:
|
|
185
|
+
将 Upload 操作从 operations[] 中抽出,改为 toolbarDef() 中的 `renderNode:` 按钮,操作列仍用 renderOps 承载其他操作。
|
|
186
|
+
|
|
187
|
+
**标签→type 映射**:查看→`view`,编辑/修改→`edit`,删除/移除→`del`,审核/审批→`ok`,提交→`send`,流程记录→`log`
|
|
188
|
+
**参考**:`reference/ag-cell-renders.ts` - `renderOps` 函数
|
|
189
|
+
|
|
190
|
+
#### R005 — 工具栏按钮缺少 icon【中危】
|
|
191
|
+
**检测**:toolbarDef / 顶部 el-button 没有 `icon` 属性
|
|
192
|
+
**标准**:工具栏按钮必须带 icon + 文字
|
|
193
|
+
```diff
|
|
194
|
+
- <el-button type="primary" @click="handleAdd">新增</el-button>
|
|
195
|
+
+ <el-button type="primary" icon="Plus" @click="handleAdd">新增</el-button>
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
### Category C:表单控件(el-input / el-select / el-date-picker)
|
|
201
|
+
|
|
202
|
+
#### R006 — el-input / el-select 未统一 size【中危】
|
|
203
|
+
**检测**:`<el-input` 或 `<el-select` 没有 `size="small"` 属性
|
|
204
|
+
**标准**:全局统一 `size="small"`
|
|
205
|
+
```diff
|
|
206
|
+
- <el-input v-model="form.name" placeholder="请输入">
|
|
207
|
+
+ <el-input size="small" v-model="form.name" placeholder="请输入">
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
#### R007 — el-date-picker 宽度未撑满【中危】
|
|
211
|
+
**检测**:`<el-date-picker` 没有 `style` 包含 `width:100%`
|
|
212
|
+
**标准**:在 el-form-item 内必须 `style="width:100%"`
|
|
213
|
+
```diff
|
|
214
|
+
- <el-date-picker v-model="form.date" type="date">
|
|
215
|
+
+ <el-date-picker style="width:100%" v-model="form.date" type="date">
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
#### R008 — el-form labelWidth 不统一【低危】
|
|
219
|
+
**检测**:`labelWidth` 小于 150px
|
|
220
|
+
**标准**:统一 `labelWidth="150px"`(最长标签"隐患排查内容及标准"9字=~126px+padding=142px,150px安全兜底)
|
|
221
|
+
**注意**:此规则需人工确认,不自动修改(可能有特殊布局需求)
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
### Category D:状态标签(ElTag)
|
|
226
|
+
|
|
227
|
+
#### R009 — 状态字段纯文本渲染【高危】
|
|
228
|
+
**检测**:column 的 `name` 含 `Status/Level/State` 关键字,但 `defaultNode/defaultSlot` 没有 `renderTagNode` 或 `ElTag`
|
|
229
|
+
**标准**:
|
|
230
|
+
- 动态状态(启停/审批/流程)→ `renderTagNode()` / 使用 `COLUMN_AUTO_MAP` 自动映射
|
|
231
|
+
- 常用字段直接用 `defineColumns()` 包裹列定义,自动应用:`enableStatus/approvalStatus/riskLevel/permitStatus/trainStatus/credentialStatus/unifyQuestionStatus` 等
|
|
232
|
+
**参考**:`reference/define-columns.ts` COLUMN_AUTO_MAP 完整列表
|
|
233
|
+
**注意**:此规则需人工确认,不自动修复
|
|
234
|
+
|
|
235
|
+
#### R010 — 分类字段使用填充色 ElTag【中危】
|
|
236
|
+
**检测**:`effect` 不是 `"plain"`,但字段语义是分类/归档属性
|
|
237
|
+
**标准**:分类字段统一 `effect="plain"`(outline 风格)
|
|
238
|
+
```diff
|
|
239
|
+
- h(ElTag, { type: 'warning' }, () => label)
|
|
240
|
+
+ h(ElTag, { type: 'warning', effect: 'plain' }, () => label)
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
### Category E:弹窗/分页
|
|
246
|
+
|
|
247
|
+
#### R011 — 分页组件位置错误【高危】
|
|
248
|
+
**检测**:`<pagination` 或 `<Pagination` 出现在 `<template #footer>` 内
|
|
249
|
+
**标准**:分页必须在内容区(el-col 内),footer 只放操作按钮
|
|
250
|
+
**参考**:`reference/SelectPopupCom.vue`
|
|
251
|
+
|
|
252
|
+
#### R012 — 弹窗内 el-table 缺少空状态【中危】
|
|
253
|
+
同 R002,特指弹窗(el-dialog)内的 el-table
|
|
254
|
+
|
|
255
|
+
#### R014 — selection 列缺少 header-align="center"【中危】
|
|
256
|
+
**检测**:`type="selection"` 的列没有 `header-align="center"`
|
|
257
|
+
**标准**:必须同时设置 `align="center"` 和 `header-align="center"`,两者缺一都会导致复选框错位
|
|
258
|
+
```diff
|
|
259
|
+
- <el-table-column type="selection" width="55" fixed="left" align="center">
|
|
260
|
+
+ <el-table-column type="selection" width="55" fixed="left" align="center" header-align="center">
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
#### R015 — 弹窗嵌套表格操作列使用文字 el-button【高危】
|
|
264
|
+
**检测**:`modal.vue` 文件中,`el-table-column label="操作"` 内使用 `<el-button link>`
|
|
265
|
+
**标准**:弹窗内嵌套的 el-table 操作列与主列表操作列风格一致,使用 `jh-op-btn` 图标按钮
|
|
266
|
+
```diff
|
|
267
|
+
- <el-button size="small" link type="danger" @click="handleDeleteItem(row, $index)">删除</el-button>
|
|
268
|
+
+ <button class="jh-op-btn jh-op-del" type="button" title="删除"
|
|
269
|
+
+ :disabled="optr === 'view'" @click.stop="handleDeleteItem(row, $index)">
|
|
270
|
+
+ <el-icon><Delete /></el-icon>
|
|
271
|
+
+ </button>
|
|
272
|
+
```
|
|
273
|
+
> 支持图标类型:`jh-op-del`(删除)、`jh-op-view`(查看/详情)、`jh-op-edit`(编辑)
|
|
274
|
+
|
|
275
|
+
#### R016 — `<style>` 块存在硬编码 hex 颜色【中危】
|
|
276
|
+
**检测**:`<style>` 块中直接写入已有 CSS Token 对应的 hex 颜色值
|
|
277
|
+
**标准**:使用 CSS 变量代替硬编码,确保品牌色切换生效
|
|
278
|
+
```diff
|
|
279
|
+
- color: #4368ff;
|
|
280
|
+
+ color: var(--el-color-primary);
|
|
281
|
+
- background: #fb2323;
|
|
282
|
+
+ background: var(--el-color-danger);
|
|
283
|
+
```
|
|
284
|
+
**已覆盖颜色**:`#409eff/#3a7afe/#4368ff`→primary,`#fb2323/#f56c6c`→danger,`#0cc859/#67c23a`→success,`#ffaf27/#e6a23c`→warning,`#ecf5ff`→primary-light-9
|
|
285
|
+
|
|
286
|
+
#### R017 — 编号/工号/证件号列缺少 renderBadge【高危】
|
|
287
|
+
**检测**:`columnsDef()` / `columns` 数组中,label 含“编号”“工号”“证件号”但没有 `renderBadge` / `defaultSlot`(脚本式列定义)
|
|
288
|
+
**标准**:所有标识符类字段(射5类)必须使用 `renderBadge(row.xxx)`,包括:
|
|
289
|
+
- label 含“编号”:门岗编号、主机编号、通道编号…
|
|
290
|
+
- label 含“工号”:上报人工号、处置人工号…
|
|
291
|
+
- label 含“证件号”:证件号码、驾驶员证件号码、车主证件号码…
|
|
292
|
+
```diff
|
|
293
|
+
- { label: "工号", name: "userNo", minWidth: 100 }
|
|
294
|
+
+ { label: "工号", name: "userNo", minWidth: 100,
|
|
295
|
+
+ defaultSlot: ({ row }) => renderBadge(row.userNo) }
|
|
296
|
+
- { label: "证件号码", name: "identityNo", minWidth: 180 }
|
|
297
|
+
+ { label: "证件号码", name: "identityNo", minWidth: 180,
|
|
298
|
+
+ defaultSlot: ({ row }) => renderBadge(row.identityNo) }
|
|
299
|
+
```
|
|
300
|
+
> **答疑解惑:证件号码要用 badge 吗?** 是的。证件号码是唧18位的唯一标识字符串,badge 的等宽字体让长串数字更易辨识,视觉上传达“这是个标识码”的语义。
|
|
301
|
+
|
|
302
|
+
#### R018 — `logicType:dict` 列缺少 defaultSlot【高危】
|
|
303
|
+
**检测**:`columnsDef()` / `columns` 中某列有 `logicType: BusLogicDataType.dict`,但没有 `defaultSlot` / `renderTag` / `renderDictClassifyTag`(脚本式列定义)
|
|
304
|
+
**标准**:`logicType:dict` 仅提供字符串渲染,必须换为标签渲染:
|
|
305
|
+
```diff
|
|
306
|
+
- { name: "trainLevel", label: "培训级别",
|
|
307
|
+
- logicType: BusLogicDataType.dict, logicValue: "trainLevel" }
|
|
308
|
+
+ { name: "trainLevel", label: "培训级别", width: 100,
|
|
309
|
+
+ defaultSlot: ({ row }) => renderDictClassifyTag(row.trainLevel, 'trainLevel', TYPE_MAP) }
|
|
310
|
+
- { name: "authStatus", label: "权限状态",
|
|
311
|
+
- logicType: BusLogicDataType.dict, logicValue: "authStatus" }
|
|
312
|
+
+ { name: "authStatus", label: "权限状态", width: 100,
|
|
313
|
+
+ defaultSlot: ({ row }) => renderDictClassifyTag(row.authStatus, 'authStatus') }
|
|
314
|
+
```
|
|
315
|
+
**判断原则**:字段名含 `Type/Level/Kind` → `renderDictClassifyTag`(分类);含 `Status/State/Flag` → `renderTagNode`(状态)
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
## 四、labelWidth 选取建议
|
|
320
|
+
|
|
321
|
+
| 最长标签字数 | 建议 labelWidth |
|
|
322
|
+
|---|---|
|
|
323
|
+
| ≤5字(如"创建时间")| 100px |
|
|
324
|
+
| 6~7字(如"厂级单位名称")| 120px |
|
|
325
|
+
| 8~9字(如"隐患排查内容及标准")| **150px**(推荐统一值)|
|
|
326
|
+
| ≥10字 | 180px(特殊表单单独处理)|
|
|
327
|
+
|
|
328
|
+
**当前统一标准:150px**(能安全覆盖本系统内所有已知标签,避免换行错落)
|
|
329
|
+
|
|
330
|
+
---
|
|
331
|
+
|
|
332
|
+
## 五、参考实现路径
|
|
333
|
+
|
|
334
|
+
| 标准实现 | 参考文件 |
|
|
335
|
+
|---|---|
|
|
336
|
+
| AG Grid 列渲染(状态/badge/ops)| `runtime/core/renderers.ts` / `reference/ag-cell-renders.ts` |
|
|
337
|
+
| 业务列定义自动化 + COLUMN_AUTO_MAP | `runtime/core/registry.ts` 中 `defineColumns` |
|
|
338
|
+
| 通用业务枚举与 `installCommonPreset()` | `runtime/presets/common.ts` |
|
|
339
|
+
| 选择弹窗完整实现 | `reference/SelectPopupCom.vue` |
|
|
340
|
+
| CSS Token 变量(品牌色等)| `design/tokens/base.css`(业务侧 `<link>` 引入)|
|
|
341
|
+
| Element Plus 全局覆盖 | `styles/element/`(业务侧 `@use '@agile-team/wl-skills-ui/styles' as *`)|
|
|
342
|
+
| Vendor 封装组件样式(树/分页/搜索/AG Grid)| `styles/vendors/_*.scss` |
|
|
343
|
+
| Portal 视觉增强(可选)| `styles/vendors/_portal.scss` |
|
|
344
|
+
|
|
345
|
+
**COLUMN_AUTO_MAP 已覆盖字段(defineColumns自动生效)**:
|
|
346
|
+
|
|
347
|
+
| 字段名 | 渲染效果 |
|
|
348
|
+
|---|---|
|
|
349
|
+
| `enableStatus` | 启用=绿/停用=红 Tag |
|
|
350
|
+
| `approvalStatus` | 审批状态 Tag |
|
|
351
|
+
| `verifyStatus` | 核实状态 Tag |
|
|
352
|
+
| `riskLevel` | 风险分级 Tag |
|
|
353
|
+
| `taskStatus` | 排查任务状态 Tag |
|
|
354
|
+
| `planStatus` | 计划状态 Tag |
|
|
355
|
+
| `flagNormal` | 正常/异常 Tag |
|
|
356
|
+
| `riskStatus` | 隐患状态 Tag |
|
|
357
|
+
| `correctStatus` | 整改状态 Tag |
|
|
358
|
+
| `permitStatus` | 危险作业票状态 Tag(草稿/待审批/作业中/已完工/已撤销) |
|
|
359
|
+
| `trainStatus` | 培训状态 Tag(未完成/已完成) |
|
|
360
|
+
| `credentialStatus` | 证书状态 Tag(有效/即将过期/已过期) |
|
|
361
|
+
| `unifyQuestionStatus` | 题库状态 Tag(草稿/已发布/已停用) |
|
|
362
|
+
| `riskNo` | 蓝色圆角徽标 |
|
|
363
|
+
| `ratingLevel` | 彩色圆形徽标 |
|
|
364
|
+
|
|
365
|
+
**新增内容(最近改造积累)**:
|
|
366
|
+
|
|
367
|
+
| 字段名 | 渲染效果 |
|
|
368
|
+
|---|---|
|
|
369
|
+
| `drillType` | 演练方式 Tag(桌面=灰/实战=橙) |
|
|
370
|
+
| `coursewareType` | 课件类型 Tag |
|
|
371
|
+
| `trainLevel` | 培训级别 Tag |
|
|
372
|
+
| `planType` | 预案分类 Tag |
|
|
373
|
+
| `planNo` / `fileNo` / `userNo` | 蓝色编号徽标 |
|
|
374
|
+
| `baseCount` / 数值类 | 绿色数值徽标 |
|
|
375
|
+
| `evaluateStandard` / 警示文字类 | 红色字体 |
|
|
376
|
+
|
|
377
|
+
---
|
|
378
|
+
|
|
379
|
+
## 六、无法自动修复的规则(需 AI 辅助人工确认)
|
|
380
|
+
|
|
381
|
+
| 规则 | 原因 |
|
|
382
|
+
|---|---|
|
|
383
|
+
| R008 labelWidth | 可能有特殊布局需求,修改前需看表单 |
|
|
384
|
+
| R009 状态字段 | 需要识别业务语义,无法纯正则判断 |
|
|
385
|
+
| R010 分类 vs 状态 | 需结合字段业务含义判断 |
|
|
386
|
+
| R013(含 Upload/二维码等特殊操作) | Upload 组件嵌入 operations[] 时需抽离到 toolbarDef renderNode,不能直接自动迁移 |
|
|
387
|
+
|
|
388
|
+
对这类规则,AI 的职责是:**标注疑似问题 + 给出建议 + 等待用户逐条确认**,而不是直接修改。
|
|
389
|
+
|
|
390
|
+
---
|
|
391
|
+
|
|
392
|
+
## 七、执行约束
|
|
393
|
+
|
|
394
|
+
1. **Phase 3 用户确认是强制门槛**,未确认不得修改文件
|
|
395
|
+
2. **每次只修改一类规则**,修改后立即验证该类归零再继续下一类
|
|
396
|
+
3. **不修改以下路径**:`node_modules/`、`dist/`、`*.min.js`、已手动精细调整的文件(需用户标注)
|
|
397
|
+
4. **幂等性**:脚本可重复运行,已符合标准的不会被二次修改
|
|
398
|
+
|
|
399
|
+
---
|
|
400
|
+
|
|
401
|
+
## 八、新系统快速接入方案(推荐)
|
|
402
|
+
|
|
403
|
+
对于**全新业务系统**,使用本方案可让所有业务页面从第一行代码就符合风格标准,彻底无需事后补丁。
|
|
404
|
+
|
|
405
|
+
> 详细接入步骤见 [README — 快速开始](../README.md#快速开始),以下仅列核心要点。
|
|
406
|
+
|
|
407
|
+
### 核心三步
|
|
408
|
+
|
|
409
|
+
```bash
|
|
410
|
+
pnpm add @agile-team/wl-skills-ui
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
```html
|
|
414
|
+
<!-- index.html <head> 最先加载 -->
|
|
415
|
+
<link rel="stylesheet" href="/node_modules/@agile-team/wl-skills-ui/design/tokens/base.css" />
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
```scss
|
|
419
|
+
@use '@agile-team/wl-skills-ui/styles' as *;
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
```ts
|
|
423
|
+
// src/main.ts
|
|
424
|
+
import { installCommonPreset } from '@agile-team/wl-skills-ui/runtime/common-preset';
|
|
425
|
+
installCommonPreset();
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
### 列定义用 defineColumns() 包裹
|
|
429
|
+
|
|
430
|
+
```typescript
|
|
431
|
+
// 每个业务文件 columnsDef() 末尾:
|
|
432
|
+
import { defineColumns, renderOps } from '@agile-team/wl-skills-ui/runtime';
|
|
433
|
+
|
|
434
|
+
columnsDef(): TableColumnDesc<any>[] {
|
|
435
|
+
return defineColumns([
|
|
436
|
+
{ label: '名称', name: 'name' },
|
|
437
|
+
{ label: '状态', name: 'enableStatus' }, // 自动渲染彩色Tag
|
|
438
|
+
{ label: '风险分级', name: 'riskLevel' }, // 自动渲染Tag
|
|
439
|
+
{ label: '操作', width: 100,
|
|
440
|
+
defaultSlot: ({ row }) => renderOps([
|
|
441
|
+
{ type: 'view', onClick: () => modal.view(row.id) },
|
|
442
|
+
{ type: 'edit', onClick: () => modal.edit(row.id) },
|
|
443
|
+
{ type: 'del', onClick: () => handleDel(row.id) },
|
|
444
|
+
])
|
|
445
|
+
},
|
|
446
|
+
]);
|
|
447
|
+
}
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
### 8.2 能保证的效果
|
|
451
|
+
|
|
452
|
+
| 功能项 | 保证方式 |
|
|
453
|
+
|---|---|
|
|
454
|
+
| 状态列彩色 Tag | `defineColumns` COLUMN_AUTO_MAP 自动配置 |
|
|
455
|
+
| 操作列图标按钮 | `renderOps([...])` 统一渲染系统 |
|
|
456
|
+
| 操作列条件显示 | `show: condition` 替代 `disabled: (row) => !condition` |
|
|
457
|
+
| 自动分隔线 | 图标组与文字组之间 `renderOps` 自动插入 |
|
|
458
|
+
| 点击阻止冒泡 | `renderOps` 内部自动 `e.stopPropagation()` |
|
|
459
|
+
|
|
460
|
+
### 8.3 不在 defineColumns 范围内、需手动保证的
|
|
461
|
+
|
|
462
|
+
| 功能项 | 标准做法 |
|
|
463
|
+
|---|---|
|
|
464
|
+
| BaseTable `empty-text` | 每个 `<BaseTable>` 加 `empty-text="暂无数据"` |
|
|
465
|
+
| el-form `labelWidth` | 统一 `labelWidth="150px"` |
|
|
466
|
+
| 弹窗内控件 `size` | `el-input/el-select` 加 `size="small"` |
|
|
467
|
+
| el-date-picker 宽度 | 加 `style="width:100%"` |
|
|
468
|
+
| 输入框圆角 | 已在 `element.scss` 全局设置 `border-radius: 6px`,**无需各 modal 单独处理** |
|
|
469
|
+
| 弹窗嵌套表格操作列 | 使用 `jh-op-btn` 图标按钮(见 R015),不得用 `el-button link` |
|
|
470
|
+
| selection 列对齐 | `align="center"` + `header-align="center"` 必须同时设置(见 R014)|
|
|
471
|
+
|
|
472
|
+
上述 4 项运行扫描器(Phase 1)可自动检测,R002/R003/R006/R007/R008 规则覆盖。
|
|
473
|
+
|
|
474
|
+
### 8.4 新增业务专属状态字段
|
|
475
|
+
|
|
476
|
+
当新系统有自己的状态字段时,按此模式扩展 `ag-cell-renders.ts` + `define-columns.ts`:
|
|
477
|
+
|
|
478
|
+
```typescript
|
|
479
|
+
// ag-cell-renders.ts — 追加新状态映射
|
|
480
|
+
export const MY_STATUS_MAP: Record<string | number, TagMapItem> = {
|
|
481
|
+
"0": { label: "待处理", type: "info" },
|
|
482
|
+
"1": { label: "处理中", type: "warning" },
|
|
483
|
+
"2": { label: "已完成", type: "success" },
|
|
484
|
+
"3": { label: "已驳回", type: "danger" },
|
|
485
|
+
};
|
|
486
|
+
export const renderMyStatus = (v) => renderTagNode(v, MY_STATUS_MAP);
|
|
487
|
+
|
|
488
|
+
// define-columns.ts — 追加到 COLUMN_AUTO_MAP
|
|
489
|
+
myStatus: {
|
|
490
|
+
width: 90, fixed: "right",
|
|
491
|
+
defaultNode: ({ row }) => renderMyStatus(row.myStatus)
|
|
492
|
+
},
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
新增后,所有含 `name: 'myStatus'` 的列,用 `defineColumns()` 包裹后自动生效,全项目一次性覆盖。
|
|
496
|
+
|
|
497
|
+
---
|
|
498
|
+
|
|
499
|
+
## 九、枚举/状态/分类/编号统一展示规范
|
|
500
|
+
|
|
501
|
+
> 本规范源于企业系统全量改造积累,解决"每次发现、每次手动追加"的痛点。
|
|
502
|
+
> 凡是表格列,遇到 **枚举值**,必须按下表分类选择渲染函数,禁止纯文本展示。
|
|
503
|
+
|
|
504
|
+
### 9.1 三类字段 → 三种渲染方式
|
|
505
|
+
|
|
506
|
+
| 字段类别 | 典型字段 | 视觉效果 | 渲染函数 | Tag 风格 |
|
|
507
|
+
|---|---|---|---|---|
|
|
508
|
+
| **状态类**(二元/流转) | enableStatus、approvalStatus、verifyStatus、credentialStatus | 实心彩色 Tag | `renderXxxStatus(value)` / `renderTagNode(value, MAP)` | `effect="dark"` 或默认 |
|
|
509
|
+
| **分类/级别类**(组织/归档属性) | coursewareType、trainLevel、planType、checkLevel、riskLevel、drillType | 镂空 outline Tag | `renderClassifyTag(value, MAP)` / `renderDictClassifyTag(value, dictKey, colorMap?)` | `effect="plain"` |
|
|
510
|
+
| **编号/代码类** | planNo、fileNo、userNo、riskNo | 蓝色圆角徽标 | `renderBadge(value)` | `.jh-riskno-badge` |
|
|
511
|
+
| **数值型**(考核基数/评分/权重) | baseCount、score、weight | 绿色圆角徽标 | `renderCountBadge(value)` | `.jh-count-badge` |
|
|
512
|
+
| **警示文本型**(考评标准/扣分依据) | evaluateStandard、deductReason | 红色字体 #f56c6c | `renderDangerText(value)` | `color: #f56c6c` |
|
|
513
|
+
|
|
514
|
+
#### 状态类颜色语义(强制规范)
|
|
515
|
+
|
|
516
|
+
| 状态含义 | ElTag type | 例子 |
|
|
517
|
+
|---|---|---|
|
|
518
|
+
| 正常 / 有效 / 已完成 / 启用 | `success`(绿) | 已启用、证书有效、已完工 |
|
|
519
|
+
| 警告 / 临时 / 待处理 / 即将过期 | `warning`(橙) | 即将过期、待审批 |
|
|
520
|
+
| 停用 / 驳回 / 已过期 / 危险 | `danger`(红) | 已停用、审批驳回、证书过期 |
|
|
521
|
+
| 草稿 / 未开始 / 中性 | `info`(灰) | 草稿、未处理 |
|
|
522
|
+
| 主流程默认状态 | `""`(蓝) | 作业中、处理中 |
|
|
523
|
+
|
|
524
|
+
#### 分类/级别类颜色建议(非强制,可根据业务调整)
|
|
525
|
+
|
|
526
|
+
| 等级/类别含义 | 建议 type |
|
|
527
|
+
|---|---|
|
|
528
|
+
| 最高级 / 综合 / 默认 | `""`(蓝)|
|
|
529
|
+
| 次级 / 专项 | `warning`(橙)|
|
|
530
|
+
| 基层 / 现场 / 细分 | `info`(灰)|
|
|
531
|
+
|
|
532
|
+
### 9.2 分类字段:静态 map vs 动态字典
|
|
533
|
+
|
|
534
|
+
**情况一:字典项目固定,前端已知所有枚举值**
|
|
535
|
+
|
|
536
|
+
使用 `renderClassifyTag(value, MAP)` — 静态 map,label 直接写在代码里:
|
|
537
|
+
|
|
538
|
+
```typescript
|
|
539
|
+
// ag-cell-renders.ts 新增:
|
|
540
|
+
export const COURSEWARE_TYPE_MAP = {
|
|
541
|
+
"1": { label: "视频", type: "" },
|
|
542
|
+
"2": { label: "文档", type: "info" },
|
|
543
|
+
};
|
|
544
|
+
export const renderCoursewareType = (v) => renderClassifyTag(v, COURSEWARE_TYPE_MAP);
|
|
545
|
+
|
|
546
|
+
// columnsDef() 中使用:
|
|
547
|
+
{ name: "coursewareType", label: "课件类型", width: 90, align: "center",
|
|
548
|
+
defaultSlot: ({ row }) => renderCoursewareType(row.coursewareType) }
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
**情况二:字典项目由后端配置,前端通过 businessLogicDataStore 动态获取**
|
|
552
|
+
|
|
553
|
+
使用 `renderDictClassifyTag(value, dictKey, colorMap?)` — 动态取 label,只需提供颜色映射:
|
|
554
|
+
|
|
555
|
+
```typescript
|
|
556
|
+
// 颜色映射(只需 value → type,无需写 label)
|
|
557
|
+
export const TRAIN_LEVEL_TYPE_MAP: Record<string, string> = {
|
|
558
|
+
"1": "", // 公司级(蓝)
|
|
559
|
+
"2": "warning", // 部门/厂级(橙)
|
|
560
|
+
"3": "info", // 班组/车间级(灰)
|
|
561
|
+
"4": "info", // 岗位级(灰)
|
|
562
|
+
};
|
|
563
|
+
|
|
564
|
+
// columnsDef() 中使用:
|
|
565
|
+
import { renderDictClassifyTag, TRAIN_LEVEL_TYPE_MAP } from "@/util/ag-cell-renders";
|
|
566
|
+
|
|
567
|
+
{ name: "trainLevel", label: "培训级别", width: 100, align: "center",
|
|
568
|
+
defaultSlot: ({ row }) => renderDictClassifyTag(row.trainLevel, 'trainLevel', TRAIN_LEVEL_TYPE_MAP) }
|
|
569
|
+
```
|
|
570
|
+
|
|
571
|
+
`renderDictClassifyTag` 内部通过 Pinia `businessLogicDataStore.get(key)` 取 label,异步加载完成后 Vue 自动重渲染,无需额外处理。
|
|
572
|
+
|
|
573
|
+
### 9.3 已有颜色映射常量(直接复用)
|
|
574
|
+
|
|
575
|
+
以下常量已定义在 `src/util/ag-cell-renders.ts`,无需重新定义:
|
|
576
|
+
|
|
577
|
+
| 常量名 | 用途 | 适用场景 |
|
|
578
|
+
|---|---|---|
|
|
579
|
+
| `COURSEWARE_TYPE_MAP` | 课件类型(视频/文档),静态map | `renderClassifyTag(v, COURSEWARE_TYPE_MAP)` |
|
|
580
|
+
| `TRAIN_LEVEL_TYPE_MAP` | 培训级别颜色方案 | `renderDictClassifyTag(v, 'trainLevel', TRAIN_LEVEL_TYPE_MAP)` |
|
|
581
|
+
| `PLAN_TYPE_COLOR_MAP` | 预案分类颜色方案 | `renderDictClassifyTag(v, 'planType', PLAN_TYPE_COLOR_MAP)` |
|
|
582
|
+
| `DRILL_TYPE_COLOR_MAP` | 演练方式颜色方案(桌面=灰/实战=橙) | `renderDictClassifyTag(v, 'drillType', DRILL_TYPE_COLOR_MAP)` |
|
|
583
|
+
|
|
584
|
+
**独立渲染函数(无需 MAP 参数)**:
|
|
585
|
+
|
|
586
|
+
| 函数名 | 用途 | CSS 类 |
|
|
587
|
+
|---|---|---|
|
|
588
|
+
| `renderCountBadge(value)` | 数值型徽标(绿色系) | `.jh-count-badge` |
|
|
589
|
+
| `renderDangerText(value)` | 警示文本(红色字体 #f56c6c) | 内联 style |
|
|
590
|
+
|
|
591
|
+
> **参考文件同步规则**:`@agile-team/wl-skills-ui/reference/ag-cell-renders.ts` 与业务项目中的 `src/util/ag-cell-renders.ts` 保持语义同步。每次在业务项目新增渲染函数后,同步更新 reference 文件,保证 skills 工具链对新项目的指导准确性。
|
|
592
|
+
|
|
593
|
+
### 9.4 迁移规则(logicType 列改造)
|
|
594
|
+
|
|
595
|
+
**凡是使用 `logicType: BusLogicDataType.dict` 且语义是分类/级别的列,必须改为 `renderDictClassifyTag`**。
|
|
596
|
+
|
|
597
|
+
```typescript
|
|
598
|
+
// ❌ 旧写法 — 纯文本,无视觉区分
|
|
599
|
+
{ name: "trainLevel", label: "培训级别",
|
|
600
|
+
logicType: BusLogicDataType.dict, logicValue: "trainLevel" }
|
|
601
|
+
|
|
602
|
+
// ✅ 新写法 — 镂空彩色 Tag
|
|
603
|
+
{ name: "trainLevel", label: "培训级别", width: 100, align: "center",
|
|
604
|
+
defaultSlot: ({ row }) => renderDictClassifyTag(row.trainLevel, 'trainLevel', TRAIN_LEVEL_TYPE_MAP) }
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
判断原则:
|
|
608
|
+
- 字段名含 `Type/Level/Kind/Class/Category` → **分类类** → `renderDictClassifyTag`
|
|
609
|
+
- 字段名含 `Status/State/Flag` → **状态类** → `renderXxxStatus` 或 `renderTagNode`
|
|
610
|
+
- 字段名含 `No/Code/Id`(非主键) → **编号类** → `renderBadge`
|
|
611
|
+
|
|
612
|
+
> **补充说明:以下 label 含“中文关键字”的字段同样适用 `renderBadge`,字段名不含 No/Code 也不例外:**
|
|
613
|
+
>
|
|
614
|
+
> | label 关键字 | 典型字段名 | 正确处理 |
|
|
615
|
+
> |---|---|---|
|
|
616
|
+
> | 编号 | `gateCode`, `hostCode`, `passagewayCode` | `renderBadge` |
|
|
617
|
+
> | 工号 | `userNo`, `workNo`, `employeeNo` | `renderBadge` |
|
|
618
|
+
> | 证件号码 | `identityNo`, `idCardNo`, `certNo` | `renderBadge` |
|
|
619
|
+
> | 设备编号/车牌号 | `deviceCode`, `carNo` | `renderBadge` |
|
|
620
|
+
> | 驾驶员证件号码 | `driverIdNo` | `renderBadge` |
|
|
621
|
+
>
|
|
622
|
+
> **采用 `renderBadge` 而非普通文本的原因**:等宽字体让长串数字(如 18 位身份证)更易辨识,蓝色边框视觉传达“标识符”语义。
|
|
623
|
+
|
|
624
|
+
### 9.5 selection 列对齐(嵌套 el-table 同样适用)
|
|
625
|
+
|
|
626
|
+
```typescript
|
|
627
|
+
// ✅ 标准写法(外层 BaseTable 和弹窗内嵌套 el-table 均适用)
|
|
628
|
+
<el-table-column type="selection" width="55" fixed="left" align="center" header-align="center" />
|
|
629
|
+
```
|
|
630
|
+
|
|
631
|
+
- `width` 必须为 **55**(42 会导致表头复选框溢出错位)
|
|
632
|
+
- `align` 和 `header-align` 必须**同时**设置为 `center`
|