@agile-team/wl-skills-kit 2.1.2 → 2.1.3
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 +14 -0
- package/README.md +6 -5
- package/bin/wl-skills.js +35 -1
- package/files/.github/guides/README.md +13 -13
- package/files/.github/guides/architecture.md +555 -555
- package/files/.github/guides/usage.md +166 -166
- package/files/.github/reports/README.md +65 -65
- package/files/.github/reports/SYS_DICT_INFO.md +19 -19
- package/files/.github/reports/SYS_MENU_INFO.md +247 -247
- package/files/.github/reports/SYS_PERMISSION_INFO.md +20 -20
- package/files/.github/reports//347/273/204/344/273/266/346/217/220/345/217/226/345/273/272/350/256/256.md +33 -33
- package/files/.github/reports//350/247/204/350/214/203/345/256/241/346/237/245/346/212/245/345/221/212.md +44 -44
- package/files/.github/skills/_compat/README.md +108 -108
- package/files/.github/skills/_compat/headers/agents.txt +8 -8
- package/files/.github/skills/_compat/headers/claude-code.txt +7 -7
- package/files/.github/skills/_compat/headers/cline.txt +7 -7
- package/files/.github/skills/_compat/headers/cursor-mdc.txt +16 -16
- package/files/.github/skills/_compat/headers/cursor-rules.txt +7 -7
- package/files/.github/skills/_compat/headers/github-copilot.txt +1 -1
- package/files/.github/skills/_compat/headers/kiro.txt +10 -10
- package/files/.github/skills/_compat/headers/trae.txt +11 -11
- package/files/.github/skills/_compat/headers/windsurf.txt +7 -7
- package/files/.github/skills/_registry.md +81 -81
- package/files/.github/skills/core/api-contract/SKILL.md +344 -344
- package/files/.github/skills/core/api-contract/USAGE.md +110 -110
- package/files/.github/skills/core/convention-audit/SKILL.md +189 -189
- package/files/.github/skills/core/convention-audit/USAGE.md +99 -99
- package/files/.github/skills/core/page-codegen/SKILL.md +973 -973
- package/files/.github/skills/core/page-codegen/USAGE.md +102 -102
- package/files/.github/skills/core/page-codegen/templates/_index.md +46 -46
- package/files/.github/skills/core/page-codegen/templates/domains/_CONTRIBUTING.md +107 -107
- package/files/.github/skills/core/page-codegen/templates/domains/produce/TPL-OPERATION-STATION.md +442 -442
- package/files/.github/skills/core/page-codegen/templates/domains/sale/README.md +26 -26
- package/files/.github/skills/core/page-codegen/templates/universal/TPL-CHANGE-HISTORY.md +276 -276
- package/files/.github/skills/core/page-codegen/templates/universal/TPL-DETAIL-TABS.md +1145 -1145
- package/files/.github/skills/core/page-codegen/templates/universal/TPL-DRIVEN.md +124 -124
- package/files/.github/skills/core/page-codegen/templates/universal/TPL-FORM-ROUTE.md +436 -436
- package/files/.github/skills/core/page-codegen/templates/universal/TPL-LIST.md +191 -191
- package/files/.github/skills/core/page-codegen/templates/universal/TPL-MASTER-DETAIL.md +148 -148
- package/files/.github/skills/core/page-codegen/templates/universal/TPL-RECORD-FORM.md +371 -371
- package/files/.github/skills/core/page-codegen/templates/universal/TPL-TREE-LIST.md +186 -186
- package/files/.github/skills/core/prototype-scan/SKILL.md +498 -498
- package/files/.github/skills/core/prototype-scan/USAGE.md +95 -95
- package/files/.github/skills/core/template-extract/SKILL.md +139 -139
- package/files/.github/skills/core/template-extract/USAGE.md +93 -93
- package/files/.github/skills/domain/README.md +51 -51
- package/files/.github/skills/ops/code-fix/SKILL.draft.md +108 -108
- package/files/.github/skills/sync/dict-sync/SKILL.draft.md +100 -100
- package/files/.github/skills/sync/menu-sync/SKILL.md +258 -258
- package/files/.github/skills/sync/menu-sync/USAGE.md +104 -104
- package/files/.github/skills/sync/menu-sync/env/env.local.json +6 -6
- package/files/.github/skills/sync/menu-sync/env/guide.md +83 -83
- package/files/.github/skills/sync/permission-sync/SKILL.draft.md +91 -91
- package/files/.github/standards/01-toolchain.md +57 -57
- package/files/.github/standards/02-code-structure.md +111 -111
- package/files/.github/standards/03-comments.md +53 -53
- package/files/.github/standards/04-coding-basics.md +33 -33
- package/files/.github/standards/05-logging.md +38 -38
- package/files/.github/standards/06-security.md +44 -44
- package/files/.github/standards/07-config.md +52 -52
- package/files/.github/standards/08-git.md +60 -60
- package/files/.github/standards/09-typescript.md +71 -71
- package/files/.github/standards/10-pinia.md +57 -57
- package/files/.github/standards/11-form-validation.md +81 -81
- package/files/.github/standards/12-base-table.md +116 -116
- package/files/.github/standards/13-platform-components.md +123 -123
- package/files/.github/standards/index.md +89 -89
- package/files/demo/produce/aiflow/mmwr-customer-apply-change-history/data.ts +196 -196
- package/files/demo/produce/aiflow/mmwr-customer-apply-change-history/index.scss +150 -150
- package/files/demo/produce/aiflow/mmwr-customer-apply-change-history/index.vue +79 -79
- package/files/docs/jh-date-range.md +257 -257
- package/files/docs/jh-date.md +222 -222
- package/files/docs/jh-dept-picker.md +190 -190
- package/files/docs/jh-drag-row.md +590 -590
- package/files/docs/jh-file-upload.md +216 -216
- package/files/docs/jh-picker.md +218 -218
- package/files/docs/jh-select.md +148 -148
- package/files/docs/jh-text.md +248 -248
- package/files/docs/jh-user-picker.md +197 -197
- package/package.json +2 -4
|
@@ -1,81 +1,81 @@
|
|
|
1
|
-
# 11 — 表单与校验规范
|
|
2
|
-
|
|
3
|
-
> **强制度**:🔴 必遵。
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## c_formModal / c_formSections 场景
|
|
8
|
-
|
|
9
|
-
平台已封装组件,**内置完整生命周期**:
|
|
10
|
-
|
|
11
|
-
```
|
|
12
|
-
open → 数据回填 → validate → submit → close / resetFields
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
✅ AI 直接按组件文档使用即可,**不需要重复写 validate / resetFields 逻辑**。
|
|
16
|
-
|
|
17
|
-
参考:`src/components/local/c_formModal/README.md`
|
|
18
|
-
|
|
19
|
-
---
|
|
20
|
-
|
|
21
|
-
## FORM_ROUTE 独立路由表单页(c_formModal 不适用时)
|
|
22
|
-
|
|
23
|
-
无 c_formModal 托管的复杂表单(多 Tab、多子表、向导式),**必须遵守**:
|
|
24
|
-
|
|
25
|
-
### 1. 提交前调用 validate
|
|
26
|
-
|
|
27
|
-
```typescript
|
|
28
|
-
async function handleSubmit() {
|
|
29
|
-
const valid = await formRef.value?.validate();
|
|
30
|
-
if (!valid) return;
|
|
31
|
-
await postAction(API_CONFIG.save, formData.value);
|
|
32
|
-
}
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
### 2. 取消/离开调用 resetFields
|
|
36
|
-
|
|
37
|
-
```typescript
|
|
38
|
-
function handleCancel() {
|
|
39
|
-
formRef.value?.resetFields();
|
|
40
|
-
router.back();
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
onBeforeRouteLeave(() => {
|
|
44
|
-
formRef.value?.resetFields();
|
|
45
|
-
});
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
### 3. rules 在 data.ts 中独立导出
|
|
49
|
-
|
|
50
|
-
```typescript
|
|
51
|
-
// data.ts
|
|
52
|
-
export const formRules = {
|
|
53
|
-
fieldName: [
|
|
54
|
-
{ required: true, message: "请输入字段名", trigger: "blur" },
|
|
55
|
-
{ max: 50, message: "不超过 50 字符", trigger: "blur" },
|
|
56
|
-
],
|
|
57
|
-
status: [{ required: true, message: "请选择状态", trigger: "change" }],
|
|
58
|
-
};
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
❌ **禁止**:把 rules 写在 `<template>` 字面量里。
|
|
62
|
-
|
|
63
|
-
---
|
|
64
|
-
|
|
65
|
-
## 校验时机
|
|
66
|
-
|
|
67
|
-
| 时机 | 触发 |
|
|
68
|
-
| ----------------- | -------------------------------- |
|
|
69
|
-
| `blur` 失焦 | 字符串类、必填字段 |
|
|
70
|
-
| `change` 变更 | 选择类(select / date / picker) |
|
|
71
|
-
| 手动 `validate()` | 提交时全量校验 |
|
|
72
|
-
| 字段间联动 | `watch` + 手动 `validateField()` |
|
|
73
|
-
|
|
74
|
-
## AI 检查清单
|
|
75
|
-
|
|
76
|
-
生成 FORM_ROUTE 模板代码时确认:
|
|
77
|
-
|
|
78
|
-
- [ ] 提交按钮 click 处理函数中调用了 `formRef.value?.validate()`
|
|
79
|
-
- [ ] 取消按钮 / 路由离开钩子中调用了 `resetFields()`
|
|
80
|
-
- [ ] rules 定义在 `data.ts` 而非 `<template>`
|
|
81
|
-
- [ ] 必填字段都加了 `required: true` 校验规则
|
|
1
|
+
# 11 — 表单与校验规范
|
|
2
|
+
|
|
3
|
+
> **强制度**:🔴 必遵。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## c_formModal / c_formSections 场景
|
|
8
|
+
|
|
9
|
+
平台已封装组件,**内置完整生命周期**:
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
open → 数据回填 → validate → submit → close / resetFields
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
✅ AI 直接按组件文档使用即可,**不需要重复写 validate / resetFields 逻辑**。
|
|
16
|
+
|
|
17
|
+
参考:`src/components/local/c_formModal/README.md`
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## FORM_ROUTE 独立路由表单页(c_formModal 不适用时)
|
|
22
|
+
|
|
23
|
+
无 c_formModal 托管的复杂表单(多 Tab、多子表、向导式),**必须遵守**:
|
|
24
|
+
|
|
25
|
+
### 1. 提交前调用 validate
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
async function handleSubmit() {
|
|
29
|
+
const valid = await formRef.value?.validate();
|
|
30
|
+
if (!valid) return;
|
|
31
|
+
await postAction(API_CONFIG.save, formData.value);
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### 2. 取消/离开调用 resetFields
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
function handleCancel() {
|
|
39
|
+
formRef.value?.resetFields();
|
|
40
|
+
router.back();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
onBeforeRouteLeave(() => {
|
|
44
|
+
formRef.value?.resetFields();
|
|
45
|
+
});
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### 3. rules 在 data.ts 中独立导出
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
// data.ts
|
|
52
|
+
export const formRules = {
|
|
53
|
+
fieldName: [
|
|
54
|
+
{ required: true, message: "请输入字段名", trigger: "blur" },
|
|
55
|
+
{ max: 50, message: "不超过 50 字符", trigger: "blur" },
|
|
56
|
+
],
|
|
57
|
+
status: [{ required: true, message: "请选择状态", trigger: "change" }],
|
|
58
|
+
};
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
❌ **禁止**:把 rules 写在 `<template>` 字面量里。
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## 校验时机
|
|
66
|
+
|
|
67
|
+
| 时机 | 触发 |
|
|
68
|
+
| ----------------- | -------------------------------- |
|
|
69
|
+
| `blur` 失焦 | 字符串类、必填字段 |
|
|
70
|
+
| `change` 变更 | 选择类(select / date / picker) |
|
|
71
|
+
| 手动 `validate()` | 提交时全量校验 |
|
|
72
|
+
| 字段间联动 | `watch` + 手动 `validateField()` |
|
|
73
|
+
|
|
74
|
+
## AI 检查清单
|
|
75
|
+
|
|
76
|
+
生成 FORM_ROUTE 模板代码时确认:
|
|
77
|
+
|
|
78
|
+
- [ ] 提交按钮 click 处理函数中调用了 `formRef.value?.validate()`
|
|
79
|
+
- [ ] 取消按钮 / 路由离开钩子中调用了 `resetFields()`
|
|
80
|
+
- [ ] rules 定义在 `data.ts` 而非 `<template>`
|
|
81
|
+
- [ ] 必填字段都加了 `required: true` 校验规则
|
|
@@ -1,116 +1,116 @@
|
|
|
1
|
-
# 12 — BaseTable 渲染与 AGGrid cid 唯一性规范
|
|
2
|
-
|
|
3
|
-
> **强制度**:🔴 必遵。
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## 渲染模式(强制)
|
|
8
|
-
|
|
9
|
-
所有 `BaseTable` 必须默认使用 **AGGrid** 渲染:
|
|
10
|
-
|
|
11
|
-
```vue
|
|
12
|
-
<BaseTable
|
|
13
|
-
ref="tableRef"
|
|
14
|
-
render-type="agGrid"
|
|
15
|
-
cid="mca-745831"
|
|
16
|
-
:data="list"
|
|
17
|
-
:columns="columns"
|
|
18
|
-
showToolbar
|
|
19
|
-
/>
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
> 全局配置:`envConfig().componentConfig.table = { renderType: 'agGrid' }`
|
|
23
|
-
> 设置后所有未显式指定 `render-type` 的 BaseTable 默认 AGGrid。
|
|
24
|
-
|
|
25
|
-
---
|
|
26
|
-
|
|
27
|
-
## cid 命名规则(核心)
|
|
28
|
-
|
|
29
|
-
AGGrid 通过 `cid` 持久化列配置(列宽、顺序、显示),**cid 必须全局唯一**。
|
|
30
|
-
|
|
31
|
-
### 表格级 cid
|
|
32
|
-
|
|
33
|
-
```
|
|
34
|
-
格式:{页面目录首字母缩写}-{Unix秒后6位}
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
**生成规则(AI 执行)**:
|
|
38
|
-
|
|
39
|
-
1. 取页面 kebab-case 目录名,每个单词取首字母拼接为缩写
|
|
40
|
-
2. 取 `Math.floor(Date.now() / 1000).toString().slice(-6)` 作为 6 位时间戳后缀
|
|
41
|
-
3. 用 `-` 连接
|
|
42
|
-
|
|
43
|
-
**示例**:
|
|
44
|
-
|
|
45
|
-
| 页面目录 | 缩写 | cid |
|
|
46
|
-
| ------------------------ | ---- | ----------------- |
|
|
47
|
-
| `mmwr-customer-archive` | mca | `mca-745831` |
|
|
48
|
-
| `domestic-trade-order` | dto | `dto-745832` |
|
|
49
|
-
| 同页面第二个表格(子表) | mca | `mca-745831-sub1` |
|
|
50
|
-
| 同页面第三个表格 | mca | `mca-745831-sub2` |
|
|
51
|
-
|
|
52
|
-
### 列级 cid
|
|
53
|
-
|
|
54
|
-
```
|
|
55
|
-
格式:{表格cid的缩写部分}-{fieldName}
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
```typescript
|
|
59
|
-
// 表格缩写为 mca
|
|
60
|
-
columnsDef(): TableColumnDesc<any>[] {
|
|
61
|
-
return [
|
|
62
|
-
{ type: 'selection' },
|
|
63
|
-
{ type: 'index' },
|
|
64
|
-
{ label: '取样', name: 'sampling', cid: 'mca-sampling', width: 70 },
|
|
65
|
-
{ label: '线上公告', name: 'onlineAnnouncement', cid: 'mca-onlineAnnouncement', width: 70 },
|
|
66
|
-
]
|
|
67
|
-
}
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
---
|
|
71
|
-
|
|
72
|
-
## 禁止事项
|
|
73
|
-
|
|
74
|
-
- ❌ 随机短字符串 `cid="ipiCfsb"`(AI 重新生成时极易碰撞)
|
|
75
|
-
- ❌ 纯字段名 `cid: "sampling"`(不同页面同名字段冲突)
|
|
76
|
-
- ❌ 省略 cid(列配置持久化完全失效)
|
|
77
|
-
- ❌ 跨页面复用同一 cid
|
|
78
|
-
|
|
79
|
-
---
|
|
80
|
-
|
|
81
|
-
## Pre-flight 声明示例
|
|
82
|
-
|
|
83
|
-
```
|
|
84
|
-
✅ cid 已生成:mca-745831(mmwr-customer-archive)
|
|
85
|
-
✅ 列级 cid 前缀:mca-
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
---
|
|
89
|
-
|
|
90
|
-
## 完整代码示例
|
|
91
|
-
|
|
92
|
-
```vue
|
|
93
|
-
<!-- index.vue -->
|
|
94
|
-
<template>
|
|
95
|
-
<BaseTable
|
|
96
|
-
ref="tableRef"
|
|
97
|
-
render-type="agGrid"
|
|
98
|
-
cid="mca-745831"
|
|
99
|
-
:data="list"
|
|
100
|
-
:columns="columns"
|
|
101
|
-
showToolbar
|
|
102
|
-
/>
|
|
103
|
-
</template>
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
```typescript
|
|
107
|
-
// data.ts
|
|
108
|
-
columnsDef(): TableColumnDesc<any>[] {
|
|
109
|
-
return [
|
|
110
|
-
{ type: 'selection' },
|
|
111
|
-
{ type: 'index' },
|
|
112
|
-
{ label: '客户名称', name: 'customerName', cid: 'mca-customerName', minWidth: 120 },
|
|
113
|
-
{ label: '状态', name: 'status', cid: 'mca-status', minWidth: 80 },
|
|
114
|
-
]
|
|
115
|
-
}
|
|
116
|
-
```
|
|
1
|
+
# 12 — BaseTable 渲染与 AGGrid cid 唯一性规范
|
|
2
|
+
|
|
3
|
+
> **强制度**:🔴 必遵。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 渲染模式(强制)
|
|
8
|
+
|
|
9
|
+
所有 `BaseTable` 必须默认使用 **AGGrid** 渲染:
|
|
10
|
+
|
|
11
|
+
```vue
|
|
12
|
+
<BaseTable
|
|
13
|
+
ref="tableRef"
|
|
14
|
+
render-type="agGrid"
|
|
15
|
+
cid="mca-745831"
|
|
16
|
+
:data="list"
|
|
17
|
+
:columns="columns"
|
|
18
|
+
showToolbar
|
|
19
|
+
/>
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
> 全局配置:`envConfig().componentConfig.table = { renderType: 'agGrid' }`
|
|
23
|
+
> 设置后所有未显式指定 `render-type` 的 BaseTable 默认 AGGrid。
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## cid 命名规则(核心)
|
|
28
|
+
|
|
29
|
+
AGGrid 通过 `cid` 持久化列配置(列宽、顺序、显示),**cid 必须全局唯一**。
|
|
30
|
+
|
|
31
|
+
### 表格级 cid
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
格式:{页面目录首字母缩写}-{Unix秒后6位}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**生成规则(AI 执行)**:
|
|
38
|
+
|
|
39
|
+
1. 取页面 kebab-case 目录名,每个单词取首字母拼接为缩写
|
|
40
|
+
2. 取 `Math.floor(Date.now() / 1000).toString().slice(-6)` 作为 6 位时间戳后缀
|
|
41
|
+
3. 用 `-` 连接
|
|
42
|
+
|
|
43
|
+
**示例**:
|
|
44
|
+
|
|
45
|
+
| 页面目录 | 缩写 | cid |
|
|
46
|
+
| ------------------------ | ---- | ----------------- |
|
|
47
|
+
| `mmwr-customer-archive` | mca | `mca-745831` |
|
|
48
|
+
| `domestic-trade-order` | dto | `dto-745832` |
|
|
49
|
+
| 同页面第二个表格(子表) | mca | `mca-745831-sub1` |
|
|
50
|
+
| 同页面第三个表格 | mca | `mca-745831-sub2` |
|
|
51
|
+
|
|
52
|
+
### 列级 cid
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
格式:{表格cid的缩写部分}-{fieldName}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
// 表格缩写为 mca
|
|
60
|
+
columnsDef(): TableColumnDesc<any>[] {
|
|
61
|
+
return [
|
|
62
|
+
{ type: 'selection' },
|
|
63
|
+
{ type: 'index' },
|
|
64
|
+
{ label: '取样', name: 'sampling', cid: 'mca-sampling', width: 70 },
|
|
65
|
+
{ label: '线上公告', name: 'onlineAnnouncement', cid: 'mca-onlineAnnouncement', width: 70 },
|
|
66
|
+
]
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## 禁止事项
|
|
73
|
+
|
|
74
|
+
- ❌ 随机短字符串 `cid="ipiCfsb"`(AI 重新生成时极易碰撞)
|
|
75
|
+
- ❌ 纯字段名 `cid: "sampling"`(不同页面同名字段冲突)
|
|
76
|
+
- ❌ 省略 cid(列配置持久化完全失效)
|
|
77
|
+
- ❌ 跨页面复用同一 cid
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Pre-flight 声明示例
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
✅ cid 已生成:mca-745831(mmwr-customer-archive)
|
|
85
|
+
✅ 列级 cid 前缀:mca-
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## 完整代码示例
|
|
91
|
+
|
|
92
|
+
```vue
|
|
93
|
+
<!-- index.vue -->
|
|
94
|
+
<template>
|
|
95
|
+
<BaseTable
|
|
96
|
+
ref="tableRef"
|
|
97
|
+
render-type="agGrid"
|
|
98
|
+
cid="mca-745831"
|
|
99
|
+
:data="list"
|
|
100
|
+
:columns="columns"
|
|
101
|
+
showToolbar
|
|
102
|
+
/>
|
|
103
|
+
</template>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
// data.ts
|
|
108
|
+
columnsDef(): TableColumnDesc<any>[] {
|
|
109
|
+
return [
|
|
110
|
+
{ type: 'selection' },
|
|
111
|
+
{ type: 'index' },
|
|
112
|
+
{ label: '客户名称', name: 'customerName', cid: 'mca-customerName', minWidth: 120 },
|
|
113
|
+
{ label: '状态', name: 'status', cid: 'mca-status', minWidth: 80 },
|
|
114
|
+
]
|
|
115
|
+
}
|
|
116
|
+
```
|
|
@@ -1,123 +1,123 @@
|
|
|
1
|
-
# 13 — 平台组件合规规范(核心 AI 质量门控)
|
|
2
|
-
|
|
3
|
-
> **强制度**:🔴 必遵 + 阻断式。
|
|
4
|
-
> 这是防止 AI 绕过平台封装、自由发挥使用 `el-*` 原生组件的核心规则。
|
|
5
|
-
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## 总原则
|
|
9
|
-
|
|
10
|
-
> **优先使用平台封装组件;无对应封装时才允许使用 `el-*` 原生组件;
|
|
11
|
-
> 跨 3+ 页面相同 `el-*` 模式 → convention-audit 输出"组件提取建议"到 `reports/`,由人工评审决定是否封装。**
|
|
12
|
-
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
## 组件强制对照表
|
|
16
|
-
|
|
17
|
-
| 场景 | 优先使用(有则必用) | 替代方案 |
|
|
18
|
-
| ------------------- | --------------------------------------------- | ---------------------------- |
|
|
19
|
-
| 查询栏 | `BaseQuery` | ❌ el-form 手写查询区 |
|
|
20
|
-
| 工具栏 / 操作按钮行 | `BaseToolbar` | ❌ 自定义按钮排列 |
|
|
21
|
-
| 列表 / 表格 | `BaseTable` (`render-type="agGrid"`) | ❌ el-table |
|
|
22
|
-
| 表单弹窗 | `c_formModal` | ❌ el-dialog + el-form 手写 |
|
|
23
|
-
| 列表选择弹窗 | `c_listModal` | ❌ el-dialog + el-table 手写 |
|
|
24
|
-
| 表单内容分区 | `c_formSections` | ❌ 裸分组 |
|
|
25
|
-
| 分割标题 | `c_spliterTitle` | ❌ el-divider |
|
|
26
|
-
| 复杂路由表单页 | FORM-ROUTE 模板 | ❌ 完全手写 |
|
|
27
|
-
| 日期 / 日期范围 | `jh-date` / `jh-date-range` | ❌ el-date-picker |
|
|
28
|
-
| 文件上传 | `jh-file-upload` | ❌ el-upload |
|
|
29
|
-
| 用户选择 | `jh-user-picker` | ❌ 自定义弹窗选人 |
|
|
30
|
-
| 部门选择 | `jh-dept-picker` | ❌ 同上 |
|
|
31
|
-
| 下拉 / 选择器 | `jh-select` / `jh-picker` | ❌ el-select 手写 options |
|
|
32
|
-
| 只读文本展示 | `jh-text` | ❌ span/div 直接渲染 |
|
|
33
|
-
| 分页 | `jh-pagination` | ❌ el-pagination |
|
|
34
|
-
| 上下分栏 | `jh-drag-row` | ❌ 手动 flex/grid |
|
|
35
|
-
| 左右分割 | `C_Splitter` | ❌ 手动 flex/grid |
|
|
36
|
-
| 树形面板 | `C_Tree` | ❌ el-tree 手写 |
|
|
37
|
-
| 状态标签 | `C_TagStatus` | ❌ el-tag + 颜色映射 |
|
|
38
|
-
| HTTP 请求 | `getAction/postAction/putAction/deleteAction` | ❌ axios / fetch 直接调用 |
|
|
39
|
-
|
|
40
|
-
---
|
|
41
|
-
|
|
42
|
-
## 组件在 template 中的书写顺序
|
|
43
|
-
|
|
44
|
-
当页面同时存在多个区块时,**有则按下列顺序排列**(**全部可选,不强制必须存在**):
|
|
45
|
-
|
|
46
|
-
```
|
|
47
|
-
BaseQuery → BaseToolbar → BaseTable → jh-pagination
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
✅ 仅有 BaseTable 的页面:直接写 BaseTable,没问题
|
|
51
|
-
✅ 仅 BaseQuery + BaseToolbar 的录入型页面:按此顺序,后接表单区即可
|
|
52
|
-
❌ 顺序颠倒:BaseToolbar 写在 BaseQuery 之前
|
|
53
|
-
|
|
54
|
-
---
|
|
55
|
-
|
|
56
|
-
## docs/ 文档前置读取清单
|
|
57
|
-
|
|
58
|
-
生成涉及以下场景的代码时,AI 必须先读取对应文档(按需,不全读):
|
|
59
|
-
|
|
60
|
-
| 涉及组件 / 模式 | 必读文档 |
|
|
61
|
-
| --------------------------- | --------------------------------------------- |
|
|
62
|
-
| `jh-date` / `jh-date-range` | `docs/jh-date.md` / `docs/jh-date-range.md` |
|
|
63
|
-
| `jh-file-upload` | `docs/jh-file-upload.md` |
|
|
64
|
-
| `jh-user-picker` | `docs/jh-user-picker.md` |
|
|
65
|
-
| `jh-dept-picker` | `docs/jh-dept-picker.md` |
|
|
66
|
-
| `jh-select` | `docs/jh-select.md` |
|
|
67
|
-
| `jh-picker` | `docs/jh-picker.md` |
|
|
68
|
-
| `jh-text` | `docs/jh-text.md` |
|
|
69
|
-
| `jh-pagination` | `docs/jh-pagination.md` |
|
|
70
|
-
| `jh-drag-row` | `docs/jh-drag-row.md` |
|
|
71
|
-
| HTTP 请求方式 | `docs/request.md` |
|
|
72
|
-
| 页面 Hook 模式 | `docs/page-query-hook-best-practices.md` |
|
|
73
|
-
| BaseQuery / BaseTable 等 | `src/components/remote/{Component}/README.md` |
|
|
74
|
-
| c_formModal / c_listModal | `src/components/local/{component}/README.md` |
|
|
75
|
-
|
|
76
|
-
> AI 在 Pre-flight 声明中明确列出已读文档。
|
|
77
|
-
|
|
78
|
-
---
|
|
79
|
-
|
|
80
|
-
## AbstractPageQueryHook(强制)
|
|
81
|
-
|
|
82
|
-
所有页面 `data.ts` **必须** `extends AbstractPageQueryHook`:
|
|
83
|
-
|
|
84
|
-
```typescript
|
|
85
|
-
import { AbstractPageQueryHook } from '@jhlc/common-core/src/page-hooks/page-query-hook.ts'
|
|
86
|
-
|
|
87
|
-
export function createPage() {
|
|
88
|
-
let Page = new (class extends AbstractPageQueryHook {
|
|
89
|
-
constructor() { super({ url: { list: '...' } }) }
|
|
90
|
-
queryDef() { return [...] }
|
|
91
|
-
toolbarDef() { return [...] }
|
|
92
|
-
columnsDef() { return [...] }
|
|
93
|
-
})()
|
|
94
|
-
return Page.create() as any
|
|
95
|
-
}
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
---
|
|
99
|
-
|
|
100
|
-
## 提取建议触发规则
|
|
101
|
-
|
|
102
|
-
`convention-audit` 扫描发现 **3+ 个页面**出现相同的未封装 `el-*` 模式时,输出到 `reports/组件提取建议.md`:
|
|
103
|
-
|
|
104
|
-
```markdown
|
|
105
|
-
| 建议组件名 | 出现次数 | 页面路径 | 菜单位置(来自文件头) | 模式描述 |
|
|
106
|
-
| ------------- | -------- | ------------------------------- | ----------------------- | ---------------- |
|
|
107
|
-
| c_statusBadge | 5 处 | src/views/sale/.../index.vue 等 | 销售管理 > 国内贸易订单 | 状态枚举彩色标签 |
|
|
108
|
-
| c_priceFormat | 4 处 | ... | ... | 千分位金额显示 |
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
> ⚠️ AI **不自动提取**。人工确认后,触发 template-extract 或手动封装。
|
|
112
|
-
|
|
113
|
-
---
|
|
114
|
-
|
|
115
|
-
## AI 检查清单(每次代码生成前自查)
|
|
116
|
-
|
|
117
|
-
- [ ] 查询区使用了 BaseQuery,没有自己写 el-form?
|
|
118
|
-
- [ ] 表格使用了 BaseTable + agGrid + cid,没有用 el-table?
|
|
119
|
-
- [ ] 弹窗使用了 c_formModal / c_listModal,没有手写 el-dialog?
|
|
120
|
-
- [ ] 日期组件用了 jh-date 系列,没有用 el-date-picker?
|
|
121
|
-
- [ ] HTTP 请求都走 `this.getAction / postAction`,没有 import axios?
|
|
122
|
-
- [ ] data.ts 继承了 AbstractPageQueryHook?
|
|
123
|
-
- [ ] 涉及 jh-_ 组件时已读取对应 docs/jh-_.md?
|
|
1
|
+
# 13 — 平台组件合规规范(核心 AI 质量门控)
|
|
2
|
+
|
|
3
|
+
> **强制度**:🔴 必遵 + 阻断式。
|
|
4
|
+
> 这是防止 AI 绕过平台封装、自由发挥使用 `el-*` 原生组件的核心规则。
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 总原则
|
|
9
|
+
|
|
10
|
+
> **优先使用平台封装组件;无对应封装时才允许使用 `el-*` 原生组件;
|
|
11
|
+
> 跨 3+ 页面相同 `el-*` 模式 → convention-audit 输出"组件提取建议"到 `reports/`,由人工评审决定是否封装。**
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 组件强制对照表
|
|
16
|
+
|
|
17
|
+
| 场景 | 优先使用(有则必用) | 替代方案 |
|
|
18
|
+
| ------------------- | --------------------------------------------- | ---------------------------- |
|
|
19
|
+
| 查询栏 | `BaseQuery` | ❌ el-form 手写查询区 |
|
|
20
|
+
| 工具栏 / 操作按钮行 | `BaseToolbar` | ❌ 自定义按钮排列 |
|
|
21
|
+
| 列表 / 表格 | `BaseTable` (`render-type="agGrid"`) | ❌ el-table |
|
|
22
|
+
| 表单弹窗 | `c_formModal` | ❌ el-dialog + el-form 手写 |
|
|
23
|
+
| 列表选择弹窗 | `c_listModal` | ❌ el-dialog + el-table 手写 |
|
|
24
|
+
| 表单内容分区 | `c_formSections` | ❌ 裸分组 |
|
|
25
|
+
| 分割标题 | `c_spliterTitle` | ❌ el-divider |
|
|
26
|
+
| 复杂路由表单页 | FORM-ROUTE 模板 | ❌ 完全手写 |
|
|
27
|
+
| 日期 / 日期范围 | `jh-date` / `jh-date-range` | ❌ el-date-picker |
|
|
28
|
+
| 文件上传 | `jh-file-upload` | ❌ el-upload |
|
|
29
|
+
| 用户选择 | `jh-user-picker` | ❌ 自定义弹窗选人 |
|
|
30
|
+
| 部门选择 | `jh-dept-picker` | ❌ 同上 |
|
|
31
|
+
| 下拉 / 选择器 | `jh-select` / `jh-picker` | ❌ el-select 手写 options |
|
|
32
|
+
| 只读文本展示 | `jh-text` | ❌ span/div 直接渲染 |
|
|
33
|
+
| 分页 | `jh-pagination` | ❌ el-pagination |
|
|
34
|
+
| 上下分栏 | `jh-drag-row` | ❌ 手动 flex/grid |
|
|
35
|
+
| 左右分割 | `C_Splitter` | ❌ 手动 flex/grid |
|
|
36
|
+
| 树形面板 | `C_Tree` | ❌ el-tree 手写 |
|
|
37
|
+
| 状态标签 | `C_TagStatus` | ❌ el-tag + 颜色映射 |
|
|
38
|
+
| HTTP 请求 | `getAction/postAction/putAction/deleteAction` | ❌ axios / fetch 直接调用 |
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## 组件在 template 中的书写顺序
|
|
43
|
+
|
|
44
|
+
当页面同时存在多个区块时,**有则按下列顺序排列**(**全部可选,不强制必须存在**):
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
BaseQuery → BaseToolbar → BaseTable → jh-pagination
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
✅ 仅有 BaseTable 的页面:直接写 BaseTable,没问题
|
|
51
|
+
✅ 仅 BaseQuery + BaseToolbar 的录入型页面:按此顺序,后接表单区即可
|
|
52
|
+
❌ 顺序颠倒:BaseToolbar 写在 BaseQuery 之前
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## docs/ 文档前置读取清单
|
|
57
|
+
|
|
58
|
+
生成涉及以下场景的代码时,AI 必须先读取对应文档(按需,不全读):
|
|
59
|
+
|
|
60
|
+
| 涉及组件 / 模式 | 必读文档 |
|
|
61
|
+
| --------------------------- | --------------------------------------------- |
|
|
62
|
+
| `jh-date` / `jh-date-range` | `docs/jh-date.md` / `docs/jh-date-range.md` |
|
|
63
|
+
| `jh-file-upload` | `docs/jh-file-upload.md` |
|
|
64
|
+
| `jh-user-picker` | `docs/jh-user-picker.md` |
|
|
65
|
+
| `jh-dept-picker` | `docs/jh-dept-picker.md` |
|
|
66
|
+
| `jh-select` | `docs/jh-select.md` |
|
|
67
|
+
| `jh-picker` | `docs/jh-picker.md` |
|
|
68
|
+
| `jh-text` | `docs/jh-text.md` |
|
|
69
|
+
| `jh-pagination` | `docs/jh-pagination.md` |
|
|
70
|
+
| `jh-drag-row` | `docs/jh-drag-row.md` |
|
|
71
|
+
| HTTP 请求方式 | `docs/request.md` |
|
|
72
|
+
| 页面 Hook 模式 | `docs/page-query-hook-best-practices.md` |
|
|
73
|
+
| BaseQuery / BaseTable 等 | `src/components/remote/{Component}/README.md` |
|
|
74
|
+
| c_formModal / c_listModal | `src/components/local/{component}/README.md` |
|
|
75
|
+
|
|
76
|
+
> AI 在 Pre-flight 声明中明确列出已读文档。
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## AbstractPageQueryHook(强制)
|
|
81
|
+
|
|
82
|
+
所有页面 `data.ts` **必须** `extends AbstractPageQueryHook`:
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
import { AbstractPageQueryHook } from '@jhlc/common-core/src/page-hooks/page-query-hook.ts'
|
|
86
|
+
|
|
87
|
+
export function createPage() {
|
|
88
|
+
let Page = new (class extends AbstractPageQueryHook {
|
|
89
|
+
constructor() { super({ url: { list: '...' } }) }
|
|
90
|
+
queryDef() { return [...] }
|
|
91
|
+
toolbarDef() { return [...] }
|
|
92
|
+
columnsDef() { return [...] }
|
|
93
|
+
})()
|
|
94
|
+
return Page.create() as any
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## 提取建议触发规则
|
|
101
|
+
|
|
102
|
+
`convention-audit` 扫描发现 **3+ 个页面**出现相同的未封装 `el-*` 模式时,输出到 `reports/组件提取建议.md`:
|
|
103
|
+
|
|
104
|
+
```markdown
|
|
105
|
+
| 建议组件名 | 出现次数 | 页面路径 | 菜单位置(来自文件头) | 模式描述 |
|
|
106
|
+
| ------------- | -------- | ------------------------------- | ----------------------- | ---------------- |
|
|
107
|
+
| c_statusBadge | 5 处 | src/views/sale/.../index.vue 等 | 销售管理 > 国内贸易订单 | 状态枚举彩色标签 |
|
|
108
|
+
| c_priceFormat | 4 处 | ... | ... | 千分位金额显示 |
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
> ⚠️ AI **不自动提取**。人工确认后,触发 template-extract 或手动封装。
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## AI 检查清单(每次代码生成前自查)
|
|
116
|
+
|
|
117
|
+
- [ ] 查询区使用了 BaseQuery,没有自己写 el-form?
|
|
118
|
+
- [ ] 表格使用了 BaseTable + agGrid + cid,没有用 el-table?
|
|
119
|
+
- [ ] 弹窗使用了 c_formModal / c_listModal,没有手写 el-dialog?
|
|
120
|
+
- [ ] 日期组件用了 jh-date 系列,没有用 el-date-picker?
|
|
121
|
+
- [ ] HTTP 请求都走 `this.getAction / postAction`,没有 import axios?
|
|
122
|
+
- [ ] data.ts 继承了 AbstractPageQueryHook?
|
|
123
|
+
- [ ] 涉及 jh-_ 组件时已读取对应 docs/jh-_.md?
|