@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
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Skill: element/component-family
|
|
2
|
+
|
|
3
|
+
## 定位
|
|
4
|
+
|
|
5
|
+
用于治理 Element Plus 首批 B 端高频组件族的统一视觉,包括 card、tabs、descriptions、tree、drawer、upload、steps、overlay、navigation、feedback。
|
|
6
|
+
|
|
7
|
+
核心原则:wk-skills-ui 优先保证样式绝对管控。无论项目使用纯 `el-*`、老旧封装、Base*/jh*/C_*,还是 wl-skills-kit 最佳写法,都先通过 L1/L2 样式层统一视觉,再按需引导规范化重构。
|
|
8
|
+
|
|
9
|
+
## 覆盖组件
|
|
10
|
+
|
|
11
|
+
| 组件族 | 标签 | 典型场景 |
|
|
12
|
+
|---|---|---|
|
|
13
|
+
| card | `el-card` | 列表容器、详情卡片、统计卡片 |
|
|
14
|
+
| tabs | `el-tabs` `el-tab-pane` | 详情页 Tab、配置页 Tab、主从信息切换 |
|
|
15
|
+
| descriptions | `el-descriptions` | 只读详情、字段展示 |
|
|
16
|
+
| tree | `el-tree` | 左树右表、组织树、区域树 |
|
|
17
|
+
| drawer | `el-drawer` | 抽屉详情、抽屉编辑 |
|
|
18
|
+
| upload | `el-upload` | 附件上传、图片上传、文件列表 |
|
|
19
|
+
| steps | `el-steps` `el-step` | 审批流、流程状态 |
|
|
20
|
+
| overlay | `el-popover` `el-tooltip` `el-dropdown` | 辅助说明、溢出提示、更多操作 |
|
|
21
|
+
| navigation | `el-menu` `el-breadcrumb` | 导航、面包屑 |
|
|
22
|
+
| feedback | `el-empty` `el-result` `el-alert` `el-badge` `el-timeline` | 空状态、异常状态、提示反馈 |
|
|
23
|
+
|
|
24
|
+
## 扫描规则
|
|
25
|
+
|
|
26
|
+
| Rule | 含义 |
|
|
27
|
+
|---|---|
|
|
28
|
+
| R031 | `el-card` 建议标识 detail-card/stat-card/wk-card 等场景 class |
|
|
29
|
+
| R032 | `el-tabs` 建议标识 detail-tabs/config-tabs/wk-tabs 等场景 class |
|
|
30
|
+
| R033 | `el-descriptions` 建议使用 border 或统一详情容器 |
|
|
31
|
+
| R034 | `el-drawer` 建议明确 size |
|
|
32
|
+
| R035 | `el-upload` 建议配置 accept/limit/tip |
|
|
33
|
+
| R036 | `el-steps` 建议明确 active/process-status/finish-status |
|
|
34
|
+
| R037 | `el-empty` / `el-result` / `el-alert` 建议提供统一操作入口 |
|
|
35
|
+
|
|
36
|
+
## B 端业务场景识别
|
|
37
|
+
|
|
38
|
+
扫描报告的 `componentCoverage.businessScenarios` 会识别:
|
|
39
|
+
|
|
40
|
+
- `query-table`:查询区 + 表格
|
|
41
|
+
- `toolbar-actions`:工具栏 / 批量操作栏
|
|
42
|
+
- `tree-table`:左树右表
|
|
43
|
+
- `dialog-form`:弹窗表单
|
|
44
|
+
- `drawer-detail`:抽屉详情 / 抽屉编辑
|
|
45
|
+
- `detail-card`:详情卡片
|
|
46
|
+
- `tab-workbench`:Tab 工作台 / Tab 详情
|
|
47
|
+
- `attachment-upload`:附件上传
|
|
48
|
+
- `process-flow`:流程 / 审批
|
|
49
|
+
- `feedback-state`:空状态 / 异常状态
|
|
50
|
+
|
|
51
|
+
## AI 使用流程
|
|
52
|
+
|
|
53
|
+
1. 识别当前页面是否命中上述组件族。
|
|
54
|
+
2. 优先确认项目是否加载 `@agile-team/wk-skills-ui/styles` 或 `styles/presets/skin`。
|
|
55
|
+
3. 运行 `wks_ui_scan --output json` 获取 `componentCoverage`。
|
|
56
|
+
4. 如果只是视觉不统一,优先使用 wk-skills-ui 样式层解决。
|
|
57
|
+
5. 如果扫描结果提示页面结构、BaseTable、renderOps 等规范问题,再桥接 wl-skills-kit。
|
|
58
|
+
|
|
59
|
+
## 推荐 MCP
|
|
60
|
+
|
|
61
|
+
- `wks_ui_route_intent`:根据用户自然语言判断组件族和治理流程。
|
|
62
|
+
- `wks_ui_scan`:只读扫描并输出组件覆盖。
|
|
63
|
+
- `wks_ui_recommend_flow`:根据扫描 JSON 推荐下一步。
|
|
64
|
+
- `wks_ui_fix_dry_run`:修复前预览,不直接写入。
|
|
65
|
+
|
|
66
|
+
## 执行约束
|
|
67
|
+
|
|
68
|
+
- 不为了样式统一强制改业务结构。
|
|
69
|
+
- 不把老项目强制迁移到 wl-skills-kit。
|
|
70
|
+
- 不直接删除项目已有封装。
|
|
71
|
+
- 修复前必须先 dry-run 并给用户确认。
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: |
|
|
3
|
+
弹窗组件规范 Skill — el-dialog 内分页位置、嵌套表格操作列按钮风格标准。
|
|
4
|
+
覆盖规则:R011 R015。
|
|
5
|
+
applyTo: "**/*.vue"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# 弹窗组件规范
|
|
9
|
+
|
|
10
|
+
## R011 — 分页器必须放在 `<template #footer>` 中 【高危】
|
|
11
|
+
|
|
12
|
+
弹窗内的 `el-pagination` 必须在 `#footer` slot 内,不得放在内容区(会导致布局溢出)。
|
|
13
|
+
|
|
14
|
+
```diff
|
|
15
|
+
<el-dialog v-model="visible" title="选择记录">
|
|
16
|
+
<el-table :data="list" empty-text="暂无数据">
|
|
17
|
+
<!-- 表格内容 -->
|
|
18
|
+
</el-table>
|
|
19
|
+
- <el-pagination ... />
|
|
20
|
+
|
|
21
|
+
+ <template #footer>
|
|
22
|
+
+ <div class="dialog-footer-pagination">
|
|
23
|
+
+ <el-pagination
|
|
24
|
+
+ v-model:current-page="page.current"
|
|
25
|
+
+ v-model:page-size="page.size"
|
|
26
|
+
+ :total="page.total"
|
|
27
|
+
+ layout="total, sizes, prev, pager, next"
|
|
28
|
+
+ />
|
|
29
|
+
+ </div>
|
|
30
|
+
+ </template>
|
|
31
|
+
</el-dialog>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## R015 — 弹窗嵌套表格操作列必须用 `jh-op-btn` 图标按钮 【高危】
|
|
37
|
+
|
|
38
|
+
弹窗内 `el-table` 的操作列**不得使用 `el-button link`**,必须与主列表操作列风格一致。
|
|
39
|
+
|
|
40
|
+
```diff
|
|
41
|
+
<!-- ❌ 旧写法 -->
|
|
42
|
+
<el-table-column label="操作" width="120">
|
|
43
|
+
<template #default="{ row, $index }">
|
|
44
|
+
<el-button size="small" link type="danger"
|
|
45
|
+
@click="handleDeleteItem(row, $index)">删除</el-button>
|
|
46
|
+
<el-button size="small" link type="primary"
|
|
47
|
+
@click="handleViewItem(row)">查看</el-button>
|
|
48
|
+
</template>
|
|
49
|
+
</el-table-column>
|
|
50
|
+
|
|
51
|
+
<!-- ✅ 新写法 -->
|
|
52
|
+
<el-table-column label="操作" width="100" align="center">
|
|
53
|
+
<template #default="{ row, $index }">
|
|
54
|
+
<button class="jh-op-btn jh-op-view" type="button" title="查看"
|
|
55
|
+
@click.stop="handleViewItem(row)">
|
|
56
|
+
<el-icon><View /></el-icon>
|
|
57
|
+
</button>
|
|
58
|
+
<button class="jh-op-btn jh-op-del" type="button" title="删除"
|
|
59
|
+
:disabled="optr === 'view'"
|
|
60
|
+
@click.stop="handleDeleteItem(row, $index)">
|
|
61
|
+
<el-icon><Delete /></el-icon>
|
|
62
|
+
</button>
|
|
63
|
+
</template>
|
|
64
|
+
</el-table-column>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
或使用 `renderOps` 更简洁:
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
{ label: '操作', width: 100, align: 'center',
|
|
71
|
+
defaultSlot: ({ row, $index }) => renderOps([
|
|
72
|
+
{ type: 'view', onClick: () => handleViewItem(row) },
|
|
73
|
+
{ type: 'del', show: optr.value !== 'view', onClick: () => handleDeleteItem(row, $index) },
|
|
74
|
+
])
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## 支持的图标类型
|
|
81
|
+
|
|
82
|
+
| CSS 类 | 图标 | 适用场景 |
|
|
83
|
+
| ------------ | ------ | --------- |
|
|
84
|
+
| `jh-op-del` | Delete | 删除/移除 |
|
|
85
|
+
| `jh-op-view` | View | 查看/详情 |
|
|
86
|
+
| `jh-op-edit` | Edit | 编辑/修改 |
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## 弹窗标准结构
|
|
91
|
+
|
|
92
|
+
```html
|
|
93
|
+
<el-dialog
|
|
94
|
+
v-model="visible"
|
|
95
|
+
title="选择记录"
|
|
96
|
+
width="900px"
|
|
97
|
+
:close-on-click-modal="false"
|
|
98
|
+
>
|
|
99
|
+
<!-- 搜索区(可选) -->
|
|
100
|
+
<div class="search-bar">...</div>
|
|
101
|
+
|
|
102
|
+
<!-- 表格 -->
|
|
103
|
+
<el-table :data="list" empty-text="暂无数据" height="400">
|
|
104
|
+
<el-table-column
|
|
105
|
+
type="selection"
|
|
106
|
+
width="55"
|
|
107
|
+
align="center"
|
|
108
|
+
header-align="center"
|
|
109
|
+
/>
|
|
110
|
+
...列定义...
|
|
111
|
+
</el-table>
|
|
112
|
+
|
|
113
|
+
<!-- Footer:分页 + 操作按钮 -->
|
|
114
|
+
<template #footer>
|
|
115
|
+
<div class="dialog-footer">
|
|
116
|
+
<el-pagination ... />
|
|
117
|
+
<div class="footer-btns">
|
|
118
|
+
<el-button @click="visible = false">取消</el-button>
|
|
119
|
+
<el-button type="primary" @click="handleConfirm">确定</el-button>
|
|
120
|
+
</div>
|
|
121
|
+
</div>
|
|
122
|
+
</template>
|
|
123
|
+
</el-dialog>
|
|
124
|
+
```
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: |
|
|
3
|
+
表单控件规范 Skill — el-input / el-select / el-date-picker / el-form 的尺寸、宽度、labelWidth 标准。
|
|
4
|
+
覆盖规则:R006 R007 R008。
|
|
5
|
+
applyTo: "**/*.vue"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# 表单控件规范
|
|
9
|
+
|
|
10
|
+
## R006 — el-input / el-select 必须 `size="small"` 【中危】
|
|
11
|
+
|
|
12
|
+
全局统一 `size="small"`,确保 32px 高度的密度体验。
|
|
13
|
+
|
|
14
|
+
```diff
|
|
15
|
+
- <el-input v-model="form.name" placeholder="请输入">
|
|
16
|
+
+ <el-input size="small" v-model="form.name" placeholder="请输入">
|
|
17
|
+
|
|
18
|
+
- <el-select v-model="form.type">
|
|
19
|
+
+ <el-select size="small" v-model="form.type">
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
> 可以通过全局配置 `ElConfigProvider` 统一设置,但建议显式声明,避免嵌套组件污染。
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## R007 — el-date-picker 必须 `style="width:100%"` 【中危】
|
|
27
|
+
|
|
28
|
+
el-date-picker 默认宽度不会自动撑满 el-form-item,必须显式设置。
|
|
29
|
+
|
|
30
|
+
```diff
|
|
31
|
+
- <el-date-picker v-model="form.date" type="date" placeholder="请选择">
|
|
32
|
+
+ <el-date-picker style="width:100%" v-model="form.date" type="date" placeholder="请选择">
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## R008 — el-form `labelWidth` 建议 ≥ 150px 【低危】
|
|
38
|
+
|
|
39
|
+
```diff
|
|
40
|
+
- <el-form :model="form" labelWidth="100px">
|
|
41
|
+
+ <el-form :model="form" labelWidth="150px">
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
> 本系统内最长标签"隐患排查内容及标准"9字 ≈ 126px + padding ≈ 142px,`150px` 为安全兜底值。
|
|
45
|
+
> 此规则**需人工确认**,不自动修改(部分特殊布局可能需要不同值)。
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## 完整标准表单示例
|
|
50
|
+
|
|
51
|
+
```html
|
|
52
|
+
<el-form :model="form" label-width="150px" label-position="right">
|
|
53
|
+
<el-row :gutter="20">
|
|
54
|
+
<el-col :span="12">
|
|
55
|
+
<el-form-item label="姓名" prop="name">
|
|
56
|
+
<el-input size="small" v-model="form.name" placeholder="请输入姓名" />
|
|
57
|
+
</el-form-item>
|
|
58
|
+
</el-col>
|
|
59
|
+
<el-col :span="12">
|
|
60
|
+
<el-form-item label="所属部门" prop="dept">
|
|
61
|
+
<el-select size="small" v-model="form.dept" placeholder="请选择">
|
|
62
|
+
<el-option
|
|
63
|
+
v-for="o in deptOptions"
|
|
64
|
+
:key="o.value"
|
|
65
|
+
:label="o.label"
|
|
66
|
+
:value="o.value"
|
|
67
|
+
/>
|
|
68
|
+
</el-select>
|
|
69
|
+
</el-form-item>
|
|
70
|
+
</el-col>
|
|
71
|
+
<el-col :span="12">
|
|
72
|
+
<el-form-item label="开始日期" prop="startDate">
|
|
73
|
+
<el-date-picker
|
|
74
|
+
style="width:100%"
|
|
75
|
+
size="small"
|
|
76
|
+
v-model="form.startDate"
|
|
77
|
+
type="date"
|
|
78
|
+
placeholder="请选择日期"
|
|
79
|
+
/>
|
|
80
|
+
</el-form-item>
|
|
81
|
+
</el-col>
|
|
82
|
+
</el-row>
|
|
83
|
+
</el-form>
|
|
84
|
+
```
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: |
|
|
3
|
+
表格组件规范 Skill — el-table / BaseTable / el-table-column 的对齐、空状态、selection 列标准。
|
|
4
|
+
覆盖规则:R001 R002 R003 R014。
|
|
5
|
+
applyTo: "**/*.vue"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# 表格组件规范
|
|
9
|
+
|
|
10
|
+
## R001 — el-table-column 必须 `align="center"` 【高危】
|
|
11
|
+
|
|
12
|
+
**所有列**(含 selection / index)均必须居中对齐。
|
|
13
|
+
|
|
14
|
+
```diff
|
|
15
|
+
- <el-table-column label="名称" prop="name">
|
|
16
|
+
+ <el-table-column align="center" label="名称" prop="name">
|
|
17
|
+
|
|
18
|
+
- <el-table-column type="selection" width="70" align="left">
|
|
19
|
+
+ <el-table-column type="selection" width="55" align="center" header-align="center" fixed="left">
|
|
20
|
+
|
|
21
|
+
- <el-table-column type="index" width="80">
|
|
22
|
+
+ <el-table-column type="index" align="center" width="60">
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
> ⚠️ selection 列:`width=55`,`align="center"` **且** `header-align="center"` 两者必须同时设置,缺一会导致复选框垂直错位。
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## R002 — el-table 必须 `empty-text="暂无数据"` 【中危】
|
|
30
|
+
|
|
31
|
+
```diff
|
|
32
|
+
- <el-table :data="list">
|
|
33
|
+
+ <el-table :data="list" empty-text="暂无数据">
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## R003 — BaseTable 必须 `empty-text="暂无数据"` 【中危】
|
|
39
|
+
|
|
40
|
+
```diff
|
|
41
|
+
- <BaseTable :hook="page">
|
|
42
|
+
+ <BaseTable :hook="page" empty-text="暂无数据">
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## R014 — selection 列必须 `header-align="center"` 【中危】
|
|
48
|
+
|
|
49
|
+
```diff
|
|
50
|
+
- <el-table-column type="selection" width="55" fixed="left" align="center">
|
|
51
|
+
+ <el-table-column type="selection" width="55" fixed="left" align="center" header-align="center">
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## 完整标准写法示例
|
|
57
|
+
|
|
58
|
+
```html
|
|
59
|
+
<el-table :data="list" empty-text="暂无数据">
|
|
60
|
+
<el-table-column
|
|
61
|
+
type="selection"
|
|
62
|
+
width="55"
|
|
63
|
+
fixed="left"
|
|
64
|
+
align="center"
|
|
65
|
+
header-align="center"
|
|
66
|
+
/>
|
|
67
|
+
<el-table-column type="index" align="center" width="60" label="序号" />
|
|
68
|
+
<el-table-column align="center" prop="name" label="名称" min-width="120" />
|
|
69
|
+
<el-table-column align="center" prop="status" label="状态" width="90">
|
|
70
|
+
<template #default="{ row }">
|
|
71
|
+
<!-- 使用 renderTagSlot 渲染彩色 Tag,见 tag-status/SKILL.md -->
|
|
72
|
+
</template>
|
|
73
|
+
</el-table-column>
|
|
74
|
+
</el-table>
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## labelWidth 选取建议
|
|
80
|
+
|
|
81
|
+
| 最长标签字数 | 建议 labelWidth |
|
|
82
|
+
| ------------ | --------------------------- |
|
|
83
|
+
| ≤ 5 字 | `100px` |
|
|
84
|
+
| 6~7 字 | `120px` |
|
|
85
|
+
| 8~9 字 | `150px`(**推荐统一值**) |
|
|
86
|
+
| ≥ 10 字 | `180px`(特殊表单单独处理) |
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: |
|
|
3
|
+
枚举/状态/分类展示规范 Skill — 表格列中遇到枚举值时,按字段语义选择正确的渲染函数。
|
|
4
|
+
包含状态类/分类类/编号类/数值类/警示文本类五种渲染模式,及静态 map 与动态字典两种接入方式。
|
|
5
|
+
applyTo: "**/*.{ts,vue}"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# 枚举/状态/分类展示规范
|
|
9
|
+
|
|
10
|
+
> 凡是表格列,遇到**枚举值**,必须按下表分类选择渲染函数,禁止纯文本展示。
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## 五类字段 → 五种渲染方式
|
|
15
|
+
|
|
16
|
+
| 字段类别 | 典型字段 | 视觉效果 | 渲染函数 |
|
|
17
|
+
| --------------------------- | -------------------------------------- | ---------------- | --------------------------- |
|
|
18
|
+
| **状态类**(二元/流转) | enableStatus、permitStatus、riskStatus | 实心彩色 Tag | `renderTagNode(v, MAP)` |
|
|
19
|
+
| **分类/级别类**(归档属性) | coursewareType、trainLevel、planType | 镂空 outline Tag | `renderClassifyTag(v, MAP)` |
|
|
20
|
+
| **编号/代码类** | riskNo、planNo、fileNo | 蓝色圆角徽标 | `renderBadge(v)` |
|
|
21
|
+
| **数值型** | baseCount、score | 绿色圆角徽标 | `renderCountBadge(v)` |
|
|
22
|
+
| **警示文本型** | evaluateStandard | 红色字体 | `renderDangerText(v)` |
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## 状态类颜色语义(强制规范)
|
|
27
|
+
|
|
28
|
+
| 状态含义 | ElTag type | 例子 |
|
|
29
|
+
| ------------------------------- | ------------------ | -------------------------- |
|
|
30
|
+
| 正常 / 有效 / 已完成 / 启用 | `success`(绿) | 已启用、证书有效、已完工 |
|
|
31
|
+
| 警告 / 临时 / 待处理 / 即将过期 | `warning`(橙) | 即将过期、待审批 |
|
|
32
|
+
| 停用 / 驳回 / 已过期 / 危险 | `danger`(红) | 已停用、审批驳回、证书过期 |
|
|
33
|
+
| 草稿 / 未开始 / 中性 | `info`(灰) | 草稿、未处理 |
|
|
34
|
+
| 主流程默认状态 | `"primary"` / `""` | 作业中、处理中 |
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## 判断原则
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
字段名含 Status / State / Flag → 状态类 → renderTagNode
|
|
42
|
+
字段名含 Type / Level / Kind / Category → 分类类 → renderClassifyTag
|
|
43
|
+
字段名含 No / Code / Id(非主键) → 编号类 → renderBadge
|
|
44
|
+
字段名含 Count / Score / Weight → 数值类 → renderCountBadge
|
|
45
|
+
字段名含 Reason / Standard / 文本 → 警示文本 → renderDangerText
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## 静态 Map(字典固定时)
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
import { renderTagNode, renderClassifyTag } from '@agile-team/wk-skills-ui/runtime';
|
|
54
|
+
|
|
55
|
+
export const MY_STATUS_MAP = {
|
|
56
|
+
"0": { label: "待处理", type: "info" },
|
|
57
|
+
"1": { label: "处理中", type: "primary" },
|
|
58
|
+
"2": { label: "已完成", type: "success" },
|
|
59
|
+
"3": { label: "已驳回", type: "danger" },
|
|
60
|
+
} as const;
|
|
61
|
+
|
|
62
|
+
// 在 columnsDef 中:
|
|
63
|
+
{ name: 'myStatus', label: '状态', width: 90,
|
|
64
|
+
defaultNode: ({ row }) => renderTagNode(row.myStatus, MY_STATUS_MAP) }
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## 动态字典(后端配置时)
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
import { renderDictClassifyTag } from '@agile-team/wk-skills-ui/runtime/common-preset';
|
|
73
|
+
|
|
74
|
+
// 只需定义颜色映射,label 由字典动态获取
|
|
75
|
+
export const TRAIN_LEVEL_COLOR_MAP: Record<string, string> = {
|
|
76
|
+
"1": "", // 公司级(蓝)
|
|
77
|
+
"2": "warning", // 部门级(橙)
|
|
78
|
+
"3": "info", // 班组级(灰)
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
// 在 columnsDef 中:
|
|
82
|
+
{ name: 'trainLevel', label: '培训级别', width: 100,
|
|
83
|
+
defaultSlot: ({ row }) => renderDictClassifyTag(row.trainLevel, 'trainLevel', TRAIN_LEVEL_COLOR_MAP) }
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
> 注意:使用 `renderDictClassifyTag` 前需调用 `setDictResolver(fn)` 注入字典查询函数。
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## 通用业务预设(已内置,无需重新定义)
|
|
91
|
+
|
|
92
|
+
`installCommonPreset()` 后通过 `defineColumns()` 自动生效:
|
|
93
|
+
|
|
94
|
+
| 字段名 | 渲染 | 常量 |
|
|
95
|
+
| ------------------ | ------------ | ----------------------- |
|
|
96
|
+
| `riskLevel` | 风险分级 Tag | `RISK_LEVEL_MAP` |
|
|
97
|
+
| `taskStatus` | 排查任务状态 | `TASK_STATUS_MAP` |
|
|
98
|
+
| `riskStatus` | 隐患状态 | `RISK_STATUS_MAP` |
|
|
99
|
+
| `permitStatus` | 作业票状态 | `PERMIT_STATUS_MAP` |
|
|
100
|
+
| `trainStatus` | 培训状态 | `TRAIN_STATUS_MAP` |
|
|
101
|
+
| `credentialStatus` | 证书状态 | `CREDENTIAL_STATUS_MAP` |
|
|
102
|
+
| `coursewareType` | 课件类型 | `COURSEWARE_TYPE_MAP` |
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## R009 — 状态字段禁止纯文本渲染 【高危,需人工确认】
|
|
107
|
+
|
|
108
|
+
```diff
|
|
109
|
+
// ❌ 纯文本
|
|
110
|
+
{ name: 'status', label: '状态' }
|
|
111
|
+
|
|
112
|
+
// ✅ 使用 defineColumns 自动映射(enableStatus / riskLevel 等已注册字段)
|
|
113
|
+
// 或显式指定渲染器:
|
|
114
|
+
{ name: 'status', label: '状态', width: 90,
|
|
115
|
+
defaultNode: ({ row }) => renderTagNode(row.status, MY_STATUS_MAP) }
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## R010 — 分类字段必须 `effect="plain"` 【中危,需人工确认】
|
|
119
|
+
|
|
120
|
+
```diff
|
|
121
|
+
// ❌ 分类字段用实心 Tag
|
|
122
|
+
h(ElTag, { type: 'warning' }, () => label)
|
|
123
|
+
|
|
124
|
+
// ✅ 分类字段用镂空 Tag
|
|
125
|
+
h(ElTag, { type: 'warning', effect: 'plain', size: 'small' }, () => label)
|
|
126
|
+
// 或直接用 renderClassifyTag(value, MAP)
|
|
127
|
+
```
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: |
|
|
3
|
+
详情页骨架 Skill — 检测/对齐 .detail-page 只读展示页面结构,
|
|
4
|
+
适用于流程详情、档案详情、记录详情等以 el-descriptions 或自定义 label-value 为主的页面。
|
|
5
|
+
applyTo: "**/*.vue"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# layouts/detail-page SKILL
|
|
9
|
+
|
|
10
|
+
## 适用场景
|
|
11
|
+
|
|
12
|
+
**只读展示页**:以 `el-descriptions` 或自定义 label-value 卡片为主,可附带子表格(只读)。
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Detect — 识别详情页
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
检测条件(满足任意 2 项即判定):
|
|
20
|
+
✓ 文件名含 Detail / Info / Profile / View(如 DetailPage.vue / InfoView.vue)
|
|
21
|
+
✓ 页面以 el-descriptions 为主体
|
|
22
|
+
✓ 路由 path 含 /detail/:id 或 /view/:id
|
|
23
|
+
✓ 页面顶部有面包屑 + 返回按钮
|
|
24
|
+
✓ 无 el-form 表单提交逻辑
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Diagnose — 诊断问题
|
|
30
|
+
|
|
31
|
+
| 问题 | 规则 | 说明 |
|
|
32
|
+
|---|---|---|
|
|
33
|
+
| 根节点缺少 `.detail-page` | L-301 | 应为 `<div class="detail-page">` |
|
|
34
|
+
| 子表格有操作列文字按钮 | R015 | 详情页内嵌 el-table 也须用 jh-op-btn(仅下载/查看类图标)|
|
|
35
|
+
| 状态字段纯文本展示 | R009 | 详情页状态字段也应用 renderTagNode |
|
|
36
|
+
| label-value 未用统一 class | L-302 | 自定义 label-value 应用 `.detail-item` 统一间距 |
|
|
37
|
+
| 硬编码颜色 | R016-R018 | 详情页强调色应用 CSS Token |
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Repair — 修复指引
|
|
42
|
+
|
|
43
|
+
### 标准结构(el-descriptions 版)
|
|
44
|
+
|
|
45
|
+
```vue
|
|
46
|
+
<template>
|
|
47
|
+
<div class="detail-page">
|
|
48
|
+
<!-- 顶部操作栏 -->
|
|
49
|
+
<div class="detail-page__header">
|
|
50
|
+
<el-page-header @back="$router.back()" :content="pageTitle" />
|
|
51
|
+
<div class="detail-page__actions">
|
|
52
|
+
<el-button icon="Edit" @click="handleEdit">编辑</el-button>
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
|
|
56
|
+
<!-- 基本信息卡片 -->
|
|
57
|
+
<el-card class="detail-page__card" header="基本信息">
|
|
58
|
+
<el-descriptions :column="2" border>
|
|
59
|
+
<el-descriptions-item label="名称">{{ info.name }}</el-descriptions-item>
|
|
60
|
+
<el-descriptions-item label="状态">
|
|
61
|
+
<component :is="renderTagNode(info.enableStatus, ENABLE_STATUS_MAP)" />
|
|
62
|
+
</el-descriptions-item>
|
|
63
|
+
<el-descriptions-item label="创建时间">{{ info.createTime }}</el-descriptions-item>
|
|
64
|
+
<el-descriptions-item label="备注" :span="2">{{ info.remark }}</el-descriptions-item>
|
|
65
|
+
</el-descriptions>
|
|
66
|
+
</el-card>
|
|
67
|
+
|
|
68
|
+
<!-- 子表格(只读,可选) -->
|
|
69
|
+
<el-card class="detail-page__card" header="关联记录">
|
|
70
|
+
<el-table :data="subList" empty-text="暂无数据">
|
|
71
|
+
<el-table-column type="index" label="序号" width="60" align="center" />
|
|
72
|
+
<el-table-column prop="name" label="名称" align="center" />
|
|
73
|
+
<el-table-column label="操作" width="80" align="center">
|
|
74
|
+
<template #default="{ row }">
|
|
75
|
+
<button class="jh-op-btn jh-op-view" title="查看" @click="viewAttach(row)">
|
|
76
|
+
<el-icon><View /></el-icon>
|
|
77
|
+
</button>
|
|
78
|
+
</template>
|
|
79
|
+
</el-table-column>
|
|
80
|
+
</el-table>
|
|
81
|
+
</el-card>
|
|
82
|
+
</div>
|
|
83
|
+
</template>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### SCSS 对应
|
|
87
|
+
|
|
88
|
+
```scss
|
|
89
|
+
// styles/layouts/_detail-page.scss 已提供基础骨架
|
|
90
|
+
// .detail-page__card 提供卡片间距
|
|
91
|
+
// .detail-page__header 提供顶部操作栏布局
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## 关联资源
|
|
97
|
+
|
|
98
|
+
- 样式实现:[styles/layouts/_detail-page.scss](../../../styles/layouts/_detail-page.scss)
|
|
99
|
+
- 相关 skills:[element/el-table](../../element/el-table/SKILL.md) | [layouts/form-dialog](../form-dialog/SKILL.md)
|