@agile-team/wl-skills-kit 1.2.1 → 2.1.0
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 +120 -0
- package/README.md +169 -366
- package/bin/wl-skills.js +149 -43
- package/files/.github/copilot-instructions.md +104 -43
- package/files/.github/guides/README.md +13 -0
- package/files/.github/guides/architecture.md +555 -0
- package/files/.github/guides/usage.md +166 -0
- package/files/.github/reports/README.md +65 -0
- package/files/.github/reports/SYS_DICT_INFO.md +19 -0
- package/files/.github/reports/SYS_PERMISSION_INFO.md +20 -0
- package/files/.github/reports//347/273/204/344/273/266/346/217/220/345/217/226/345/273/272/350/256/256.md +33 -0
- package/files/.github/reports//350/247/204/350/214/203/345/256/241/346/237/245/346/212/245/345/221/212.md +44 -0
- package/files/.github/skills/_compat/README.md +108 -0
- package/files/.github/skills/_compat/editors.json +61 -0
- package/files/.github/skills/_compat/headers/agents.txt +8 -0
- package/files/.github/skills/_compat/headers/claude-code.txt +7 -0
- package/files/.github/skills/_compat/headers/cline.txt +7 -0
- package/files/.github/skills/_compat/headers/cursor-mdc.txt +16 -0
- package/files/.github/skills/_compat/headers/cursor-rules.txt +7 -0
- package/files/.github/skills/_compat/headers/github-copilot.txt +1 -0
- package/files/.github/skills/_compat/headers/kiro.txt +10 -0
- package/files/.github/skills/_compat/headers/trae.txt +11 -0
- package/files/.github/skills/_compat/headers/windsurf.txt +7 -0
- package/files/.github/skills/_registry.md +81 -0
- package/files/.github/skills/{api-contract → core/api-contract}/SKILL.md +126 -29
- package/files/.github/skills/core/api-contract/USAGE.md +110 -0
- package/files/.github/skills/core/convention-audit/SKILL.md +189 -0
- package/files/.github/skills/core/convention-audit/USAGE.md +99 -0
- package/files/.github/skills/{page-codegen → core/page-codegen}/SKILL.md +64 -21
- package/files/.github/skills/core/page-codegen/USAGE.md +102 -0
- package/files/.github/skills/core/page-codegen/templates/_index.md +46 -0
- package/files/.github/skills/core/page-codegen/templates/domains/_CONTRIBUTING.md +107 -0
- package/files/.github/skills/{page-codegen → 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 -0
- package/files/.github/skills/{page-codegen → core/page-codegen/templates/universal}/TPL-DETAIL-TABS.md +94 -39
- package/files/.github/skills/{page-codegen → core/page-codegen/templates/universal}/TPL-DRIVEN.md +124 -124
- package/files/.github/skills/core/prototype-scan/USAGE.md +95 -0
- package/files/.github/skills/core/template-extract/SKILL.md +139 -0
- package/files/.github/skills/core/template-extract/USAGE.md +93 -0
- package/files/.github/skills/domain/README.md +51 -0
- package/files/.github/skills/ops/code-fix/SKILL.draft.md +108 -0
- package/files/.github/skills/sync/dict-sync/SKILL.draft.md +100 -0
- package/files/.github/skills/{menu-sync → sync/menu-sync}/SKILL.md +258 -258
- package/files/.github/skills/sync/menu-sync/USAGE.md +104 -0
- package/files/.github/skills/{menu-sync → sync/menu-sync}/env/guide.md +83 -83
- package/files/.github/skills/sync/permission-sync/SKILL.draft.md +91 -0
- package/files/.github/standards/01-toolchain.md +57 -0
- package/files/.github/standards/02-code-structure.md +111 -0
- package/files/.github/standards/03-comments.md +53 -0
- package/files/.github/standards/04-coding-basics.md +33 -0
- package/files/.github/standards/05-logging.md +38 -0
- package/files/.github/standards/06-security.md +44 -0
- package/files/.github/standards/07-config.md +52 -0
- package/files/.github/standards/08-git.md +60 -0
- package/files/.github/standards/09-typescript.md +71 -0
- package/files/.github/standards/10-pinia.md +57 -0
- package/files/.github/standards/11-form-validation.md +81 -0
- package/files/.github/standards/12-base-table.md +116 -0
- package/files/.github/standards/13-platform-components.md +123 -0
- package/files/.github/standards/index.md +89 -0
- 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 +4 -1
- package/files/.github/docs/menu-sync-design.md +0 -264
- package/files/.github/docs/use-skill.md +0 -382
- package/files/.github/docs/wl-skills-kit.md +0 -266
- package/files/.github/skills/convention-extract/SKILL.md +0 -236
- /package/files/.github/{docs → reports}/SYS_MENU_INFO.md +0 -0
- /package/files/.github/skills/{page-codegen → core/page-codegen/templates/universal}/TPL-CHANGE-HISTORY.md +0 -0
- /package/files/.github/skills/{page-codegen → core/page-codegen/templates/universal}/TPL-FORM-ROUTE.md +0 -0
- /package/files/.github/skills/{page-codegen → core/page-codegen/templates/universal}/TPL-LIST.md +0 -0
- /package/files/.github/skills/{page-codegen → core/page-codegen/templates/universal}/TPL-MASTER-DETAIL.md +0 -0
- /package/files/.github/skills/{page-codegen → core/page-codegen/templates/universal}/TPL-RECORD-FORM.md +0 -0
- /package/files/.github/skills/{page-codegen → core/page-codegen/templates/universal}/TPL-TREE-LIST.md +0 -0
- /package/files/.github/skills/{prototype-scan → core/prototype-scan}/SKILL.md +0 -0
- /package/files/.github/skills/{menu-sync → sync/menu-sync}/env/env.local.json +0 -0
|
@@ -1,83 +1,83 @@
|
|
|
1
|
-
# env.local.json 配置说明
|
|
2
|
-
|
|
3
|
-
> 该目录下的 `env.local.json` 已加入 `.gitignore`,**不会提交到远端仓库**。
|
|
4
|
-
> 每位成员在本地维护自己的副本,首次使用时按本文档填写即可。
|
|
5
|
-
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## 文件结构
|
|
9
|
-
|
|
10
|
-
```json
|
|
11
|
-
{
|
|
12
|
-
"gatewayPath": "http://192.168.10.50:9000",
|
|
13
|
-
"parentMenuId": "1803456789012345678",
|
|
14
|
-
"sysAppNo": "QjQuXy1kbKxZyjhS5N2",
|
|
15
|
-
"token": "eyJhbGci..."
|
|
16
|
-
}
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
---
|
|
20
|
-
|
|
21
|
-
## 字段说明
|
|
22
|
-
|
|
23
|
-
| 字段 | 说明 | 示例 |
|
|
24
|
-
|---|---|---|
|
|
25
|
-
| `gatewayPath` | 后端网关地址,含协议和端口,**末尾不加斜杠** | `http://192.168.10.50:9000` |
|
|
26
|
-
| `parentMenuId` | 目标父级目录的菜单数据库 ID(每套环境不同) | `1803456789012345678` |
|
|
27
|
-
| `sysAppNo` | 应用编码(非明文,从已有菜单接口响应中获取) | `QjQuXy1kbKxZyjhS5N2` |
|
|
28
|
-
| `token` | 当前登录用户的 Bearer Token,**不含 `bearer ` 前缀** | `eyJhbGci...` |
|
|
29
|
-
|
|
30
|
-
---
|
|
31
|
-
|
|
32
|
-
## 如何获取各字段
|
|
33
|
-
|
|
34
|
-
### gatewayPath
|
|
35
|
-
|
|
36
|
-
询问后端同事,或查看浏览器 Network 面板中任意接口请求的 URL,取协议 + 域名/IP + 端口部分。
|
|
37
|
-
|
|
38
|
-
### parentMenuId
|
|
39
|
-
|
|
40
|
-
**方法 A(推荐)**:系统管理后台 → 菜单管理 → 找到目标父级目录 → 点编辑/查看 → 复制菜单 ID
|
|
41
|
-
|
|
42
|
-
**方法 B(API 查询)**:
|
|
43
|
-
|
|
44
|
-
```
|
|
45
|
-
GET {gatewayPath}/system/menu/children?menuId=0
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
从顶级节点向下逐层查找,直到找到目标父级目录。也可以告诉 AI「帮我查一下父级菜单 ID」,AI 会自动调接口查询。
|
|
49
|
-
|
|
50
|
-
### sysAppNo
|
|
51
|
-
|
|
52
|
-
系统用编码后的字符串标识应用(如 `QjQuXy1kbKxZyjhS5N2`),而非明文 `produce` / `sale`。
|
|
53
|
-
|
|
54
|
-
**获取方式**:浏览器 F12 → Network → 找任意菜单相关接口的响应体 → 查看已有菜单条目的 `sysAppNo` 字段值,复制即可。
|
|
55
|
-
|
|
56
|
-
> ℹ️ 同一领域下所有菜单的 `sysAppNo` 相同,复制任意一个即可。
|
|
57
|
-
|
|
58
|
-
### token
|
|
59
|
-
|
|
60
|
-
1. 在浏览器中登录系统
|
|
61
|
-
2. 按 F12 打开 DevTools → Network 面板
|
|
62
|
-
3. 随便点一个接口请求
|
|
63
|
-
4. 查看 Request Headers → `authorization` 字段
|
|
64
|
-
5. 去掉 `bearer ` 前缀,复制剩余字符串粘贴到 `token` 字段
|
|
65
|
-
|
|
66
|
-
> Token 有有效期,若创建菜单时提示鉴权失败,重新登录后刷新 token 即可。
|
|
67
|
-
|
|
68
|
-
---
|
|
69
|
-
|
|
70
|
-
## 使用方式
|
|
71
|
-
|
|
72
|
-
配置完成后,直接对 AI 说:
|
|
73
|
-
|
|
74
|
-
> 「帮我创建菜单」/ 「同步菜单」/ 「补菜单」
|
|
75
|
-
|
|
76
|
-
AI 会自动执行:
|
|
77
|
-
1. 读取 `SYS_MENU_INFO.md`(菜单定义)
|
|
78
|
-
2. 读取 `env.local.json`(环境配置)
|
|
79
|
-
3. 调 `/system/menu/children` 查询父级已有子节点(去重)
|
|
80
|
-
4. 逐条调 `/system/menu/save` 创建缺失菜单
|
|
81
|
-
5. 输出 `created / skipped` 结果表
|
|
82
|
-
|
|
83
|
-
**全程无需手动执行任何命令。**
|
|
1
|
+
# env.local.json 配置说明
|
|
2
|
+
|
|
3
|
+
> 该目录下的 `env.local.json` 已加入 `.gitignore`,**不会提交到远端仓库**。
|
|
4
|
+
> 每位成员在本地维护自己的副本,首次使用时按本文档填写即可。
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 文件结构
|
|
9
|
+
|
|
10
|
+
```json
|
|
11
|
+
{
|
|
12
|
+
"gatewayPath": "http://192.168.10.50:9000",
|
|
13
|
+
"parentMenuId": "1803456789012345678",
|
|
14
|
+
"sysAppNo": "QjQuXy1kbKxZyjhS5N2",
|
|
15
|
+
"token": "eyJhbGci..."
|
|
16
|
+
}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 字段说明
|
|
22
|
+
|
|
23
|
+
| 字段 | 说明 | 示例 |
|
|
24
|
+
|---|---|---|
|
|
25
|
+
| `gatewayPath` | 后端网关地址,含协议和端口,**末尾不加斜杠** | `http://192.168.10.50:9000` |
|
|
26
|
+
| `parentMenuId` | 目标父级目录的菜单数据库 ID(每套环境不同) | `1803456789012345678` |
|
|
27
|
+
| `sysAppNo` | 应用编码(非明文,从已有菜单接口响应中获取) | `QjQuXy1kbKxZyjhS5N2` |
|
|
28
|
+
| `token` | 当前登录用户的 Bearer Token,**不含 `bearer ` 前缀** | `eyJhbGci...` |
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## 如何获取各字段
|
|
33
|
+
|
|
34
|
+
### gatewayPath
|
|
35
|
+
|
|
36
|
+
询问后端同事,或查看浏览器 Network 面板中任意接口请求的 URL,取协议 + 域名/IP + 端口部分。
|
|
37
|
+
|
|
38
|
+
### parentMenuId
|
|
39
|
+
|
|
40
|
+
**方法 A(推荐)**:系统管理后台 → 菜单管理 → 找到目标父级目录 → 点编辑/查看 → 复制菜单 ID
|
|
41
|
+
|
|
42
|
+
**方法 B(API 查询)**:
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
GET {gatewayPath}/system/menu/children?menuId=0
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
从顶级节点向下逐层查找,直到找到目标父级目录。也可以告诉 AI「帮我查一下父级菜单 ID」,AI 会自动调接口查询。
|
|
49
|
+
|
|
50
|
+
### sysAppNo
|
|
51
|
+
|
|
52
|
+
系统用编码后的字符串标识应用(如 `QjQuXy1kbKxZyjhS5N2`),而非明文 `produce` / `sale`。
|
|
53
|
+
|
|
54
|
+
**获取方式**:浏览器 F12 → Network → 找任意菜单相关接口的响应体 → 查看已有菜单条目的 `sysAppNo` 字段值,复制即可。
|
|
55
|
+
|
|
56
|
+
> ℹ️ 同一领域下所有菜单的 `sysAppNo` 相同,复制任意一个即可。
|
|
57
|
+
|
|
58
|
+
### token
|
|
59
|
+
|
|
60
|
+
1. 在浏览器中登录系统
|
|
61
|
+
2. 按 F12 打开 DevTools → Network 面板
|
|
62
|
+
3. 随便点一个接口请求
|
|
63
|
+
4. 查看 Request Headers → `authorization` 字段
|
|
64
|
+
5. 去掉 `bearer ` 前缀,复制剩余字符串粘贴到 `token` 字段
|
|
65
|
+
|
|
66
|
+
> Token 有有效期,若创建菜单时提示鉴权失败,重新登录后刷新 token 即可。
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## 使用方式
|
|
71
|
+
|
|
72
|
+
配置完成后,直接对 AI 说:
|
|
73
|
+
|
|
74
|
+
> 「帮我创建菜单」/ 「同步菜单」/ 「补菜单」
|
|
75
|
+
|
|
76
|
+
AI 会自动执行:
|
|
77
|
+
1. 读取 `SYS_MENU_INFO.md`(菜单定义)
|
|
78
|
+
2. 读取 `env.local.json`(环境配置)
|
|
79
|
+
3. 调 `/system/menu/children` 查询父级已有子节点(去重)
|
|
80
|
+
4. 逐条调 `/system/menu/save` 创建缺失菜单
|
|
81
|
+
5. 输出 `created / skipped` 结果表
|
|
82
|
+
|
|
83
|
+
**全程无需手动执行任何命令。**
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: permission-sync
|
|
3
|
+
description: "[PLANNED — DRAFT, not yet active] 权限同步 Skill 设计草稿。基于 reports/SYS_PERMISSION_INFO.md 基线,将页面级/按钮级权限码注册到系统权限表,并按角色分配。"
|
|
4
|
+
status: planned
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Skill: 权限同步(permission-sync)— 草稿
|
|
8
|
+
|
|
9
|
+
> ⚠️ **本文件为设计草稿(SKILL.draft.md),未启用,不参与 AI 调度。**
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 1. 设计目标
|
|
14
|
+
|
|
15
|
+
新增页面后,除菜单外还需注册:
|
|
16
|
+
|
|
17
|
+
- **页面访问权限**(`mmwr:customer:list`)
|
|
18
|
+
- **按钮级权限**(`mmwr:customer:add` / `:edit` / `:remove` / `:approve` / `:export` ...)
|
|
19
|
+
- **数据权限**(可选:客户经理只看自己的客户等)
|
|
20
|
+
- **角色绑定**(哪些角色获得这些权限)
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 2. 数据流
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
本地基线 后端接口 Skill 触发
|
|
28
|
+
──────────────────────────────────────── ────────────────────────────────── ────────────────
|
|
29
|
+
reports/SYS_PERMISSION_INFO.md ─fetch─→ GET /sys/permission/listAll
|
|
30
|
+
←compare── POST /sys/permission/batchSave
|
|
31
|
+
─upload─→ POST /sys/role/assignPermissions ─→ "同步权限"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 3. 权限码命名规范
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
{服务缩写}:{资源camelCase}:{操作}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
| 操作 | 含义 | 示例 |
|
|
43
|
+
| -------- | -------------- | ------------------------------- |
|
|
44
|
+
| list | 查看列表 | `mmwr:customer:list` |
|
|
45
|
+
| detail | 查看详情 | `mmwr:customer:detail` |
|
|
46
|
+
| add | 新增 | `mmwr:customer:add` |
|
|
47
|
+
| edit | 编辑 | `mmwr:customer:edit` |
|
|
48
|
+
| remove | 删除 | `mmwr:customer:remove` |
|
|
49
|
+
| export | 导出 | `mmwr:customer:export` |
|
|
50
|
+
| import | 导入 | `mmwr:customer:import` |
|
|
51
|
+
| submit | 提交审批 | `mmwr:customer:submit` |
|
|
52
|
+
| approve | 审批通过 | `mmwr:customer:approve` |
|
|
53
|
+
| reject | 审批驳回 | `mmwr:customer:reject` |
|
|
54
|
+
| {custom} | 自定义业务操作 | `mmwr:customer:convertToFormal` |
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## 4. 三种工作模式
|
|
59
|
+
|
|
60
|
+
| 模式 | 触发 | 动作 |
|
|
61
|
+
| ---------- | ----------------------- | ------------------------------------------------------ |
|
|
62
|
+
| `scan` | "扫描权限码" | 从 src/views/ 扫 v-permission / hasPerm 调用,输出清单 |
|
|
63
|
+
| `register` | "注册权限码 / 同步权限" | 对比基线 → 创建缺失 + 更新描述 |
|
|
64
|
+
| `assign` | "给 XX 角色分配权限" | 选定角色 + 选定权限码 → 调 /sys/role/assignPermissions |
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## 5. 安全约束
|
|
69
|
+
|
|
70
|
+
- **生产环境拒绝直接 push**:检测 gatewayPath 含 prod/.com 时强制走"导出 SQL"模式
|
|
71
|
+
- **角色分配二次确认**:每次 assign 必须在 Pre-flight 中列出"角色 → 新增/移除的权限",得到用户 yes 才执行
|
|
72
|
+
- **不删除权限**:永远只新增/更新,删除走人工 SQL(防误删导致大面积失权)
|
|
73
|
+
- **审计**:每次 register/assign 输出 `reports/PERMISSION_SYNC_<YYYYMMDD>.md`,含完整调用日志和回滚 SQL
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## 6. 与其他 Skill 联动
|
|
78
|
+
|
|
79
|
+
- **page-codegen**:生成 toolbar 时根据 api.md 操作集自动加 `v-permission` 指令
|
|
80
|
+
- **menu-sync**:菜单注册后提示"是否同步注册访问权限"
|
|
81
|
+
- **convention-audit**:审计按钮是否都有 v-permission
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## 7. 转正前的开发任务
|
|
86
|
+
|
|
87
|
+
- [ ] 确认后端权限模型(RBAC / ABAC?是否分页面权限和按钮权限?)
|
|
88
|
+
- [ ] 数据权限是否纳入本 Skill(建议:暂不,单独 data-permission-sync)
|
|
89
|
+
- [ ] 设计 v-permission 指令的项目内实现(如 @jhlc/common-core 提供则复用)
|
|
90
|
+
- [ ] 多租户场景下的权限继承策略
|
|
91
|
+
- [ ] 与 SSO(嘉为蓝鲸)权限同步策略
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# 01 — 工具链前置检测
|
|
2
|
+
|
|
3
|
+
> **强制度**:🔴 阻断式。检测未通过 → AI 必须暂停代码生成。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 检测目标
|
|
8
|
+
|
|
9
|
+
确认项目已正确安装 `@robot-admin/git-standards`,工具链有效。
|
|
10
|
+
|
|
11
|
+
## 检测项
|
|
12
|
+
|
|
13
|
+
AI 在执行任何代码生成任务**之前**,必须检查以下三个特征文件是否存在于项目根目录:
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
✓ .prettierrc.js
|
|
17
|
+
✓ eslint.config.ts
|
|
18
|
+
✓ .husky/ (目录)
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## 判定规则
|
|
22
|
+
|
|
23
|
+
| 状态 | 处理 |
|
|
24
|
+
| ------------ | --------------------------- |
|
|
25
|
+
| 三者全部存在 | ✅ 工具链就绪,继续执行任务 |
|
|
26
|
+
| 缺任意一个 | ❌ 暂停任务,输出下方提示 |
|
|
27
|
+
|
|
28
|
+
## 暂停提示标准格式
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
❌ 工具链检测失败:未找到 .prettierrc.js / eslint.config.ts / .husky/
|
|
32
|
+
→ 请执行:npx @robot-admin/git-standards init
|
|
33
|
+
→ 或联系 CHENY(工号 409322)解决
|
|
34
|
+
→ ⛔ 代码生成已暂停,修复后重新触发
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Pre-flight 声明示例
|
|
38
|
+
|
|
39
|
+
工具链就绪:
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
✅ 工具链检测:.prettierrc.js ✓ eslint.config.ts ✓ .husky/ ✓ [全部就绪]
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
工具链缺失:
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
❌ 工具链检测:未检测到 .husky/ → 已暂停,提醒已发出
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## 为什么必须前置
|
|
54
|
+
|
|
55
|
+
- `eslint.config.ts` 缺失 → 代码风格无法约束,AI 生成代码可能不通过 lint
|
|
56
|
+
- `.prettierrc.js` 缺失 → 格式不统一,团队协作冲突
|
|
57
|
+
- `.husky/` 缺失 → 提交前钩子失效,console.log / 死代码会进入仓库
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# 02 — 代码结构与顺序规范
|
|
2
|
+
|
|
3
|
+
> **强制度**:🔴 必遵。AI 生成代码必须严格按下列顺序输出。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 4 文件原则(页面目录强制结构)
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
src/views/[域]/[模块]/[子模块]/[kebab-case目录]/
|
|
11
|
+
├── index.vue ← 纯模板 + 解构,不写业务逻辑
|
|
12
|
+
├── data.ts ← AbstractPageQueryHook 类 + API_CONFIG
|
|
13
|
+
├── index.scss ← 页面样式(可为空)
|
|
14
|
+
└── api.md ← 接口约定文档
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
**禁止**:把业务逻辑写在 index.vue;缺少 data.ts;缺少 api.md。
|
|
18
|
+
|
|
19
|
+
## 弹窗组件归属
|
|
20
|
+
|
|
21
|
+
| 场景 | 位置 |
|
|
22
|
+
| ----------------------- | ------------------------------------ |
|
|
23
|
+
| 通用弹窗(2+ 页面复用) | `src/components/local/c_xxxModal/` |
|
|
24
|
+
| 极个性弹窗(仅单页面) | 页面目录下 `components/xxxModal.vue` |
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## index.vue 三段式(顺序固定,不可调换)
|
|
29
|
+
|
|
30
|
+
```vue
|
|
31
|
+
<template>
|
|
32
|
+
<!-- 纯模板 + 组件组合 -->
|
|
33
|
+
</template>
|
|
34
|
+
|
|
35
|
+
<script setup lang="ts">
|
|
36
|
+
/* 业务逻辑全部从 data.ts 导入,按下方 9 段式 */
|
|
37
|
+
</script>
|
|
38
|
+
|
|
39
|
+
<style scoped lang="scss">
|
|
40
|
+
@import "./index.scss";
|
|
41
|
+
/* 仅允许这一行 import,全部样式写在 index.scss */
|
|
42
|
+
</style>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## `<script setup>` 9 段式(按需使用,用到的必须遵守此顺序)
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
// ===== 1. import 语句(外部库 → 内部模块 → 类型)=====
|
|
51
|
+
import { ref, computed, onMounted } from "vue";
|
|
52
|
+
import { createPage } from "./data";
|
|
53
|
+
|
|
54
|
+
// ===== 2. 组件宏(defineOptions / defineProps / defineEmits)=====
|
|
55
|
+
defineOptions({ name: "PageName" });
|
|
56
|
+
|
|
57
|
+
// ===== 3. 路由 & Store =====
|
|
58
|
+
const route = useRoute();
|
|
59
|
+
|
|
60
|
+
// ===== 4. createPage() 调用 + 解构(核心模式)=====
|
|
61
|
+
const Page = createPage();
|
|
62
|
+
const {
|
|
63
|
+
tableRef,
|
|
64
|
+
page,
|
|
65
|
+
queryParam,
|
|
66
|
+
list,
|
|
67
|
+
queryItems,
|
|
68
|
+
columns,
|
|
69
|
+
toolbars,
|
|
70
|
+
select,
|
|
71
|
+
} = Page;
|
|
72
|
+
|
|
73
|
+
// ===== 5. 页面补充状态(ref / reactive / computed)=====
|
|
74
|
+
const loading = ref(false);
|
|
75
|
+
|
|
76
|
+
// ===== 6. watch / watchEffect =====
|
|
77
|
+
|
|
78
|
+
// ===== 7. 业务方法(API 调用 / 事件处理)=====
|
|
79
|
+
async function handleSubmit() {}
|
|
80
|
+
|
|
81
|
+
// ===== 8. 生命周期 =====
|
|
82
|
+
onMounted(() => select());
|
|
83
|
+
|
|
84
|
+
// ===== 9. defineExpose =====
|
|
85
|
+
defineExpose({ select });
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## data.ts 内部顺序(强制)
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
// 1. import(类型 → 基类 → API 工具 → 工具函数)
|
|
94
|
+
// 2. API_CONFIG(接口路径集中声明,as const)
|
|
95
|
+
// 3. createPage()(constructor → queryDef → toolbarDef → columnsDef → 业务方法)
|
|
96
|
+
// 4. 页面共用辅助函数(可选,纯函数)
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## index.scss 顺序(建议)
|
|
102
|
+
|
|
103
|
+
```scss
|
|
104
|
+
// 1. 变量覆盖
|
|
105
|
+
// 2. 容器级样式 (.app-page-container)
|
|
106
|
+
// 3. 区域级样式 (.search-area / .table-area)
|
|
107
|
+
// 4. 组件深层覆盖 (:deep(.el-table))
|
|
108
|
+
// 5. 响应式 (@media)
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
> 禁止 `::v-deep` / `/deep/`,统一使用 `:deep()`。
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# 03 — 注释规范
|
|
2
|
+
|
|
3
|
+
> **强制度**:🟡 建议。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 文件头注释
|
|
8
|
+
|
|
9
|
+
由 VS Code 插件 **koroFileHeader** 自动生成,不手写。
|
|
10
|
+
项目根有 `.fileheader` 配置文件。
|
|
11
|
+
|
|
12
|
+
**插件缺失提示**:
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
⚠️ 未检测到 koroFileHeader 配置生效
|
|
16
|
+
→ 请安装插件:VS Code 扩展商店搜索 "koroFileHeader"
|
|
17
|
+
→ 或联系 CHENY(工号 409322)获取一键安装指引
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 函数注释
|
|
23
|
+
|
|
24
|
+
仅复杂业务逻辑需要:
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
/**
|
|
28
|
+
* @description 批量提交客户档案
|
|
29
|
+
* @param ids 选中的客户 ID 列表
|
|
30
|
+
* @returns 后端响应结果
|
|
31
|
+
*/
|
|
32
|
+
async function batchSubmit(ids: string[]) { ... }
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 行内注释
|
|
38
|
+
|
|
39
|
+
- 解释「**为什么**」而非「是什么」
|
|
40
|
+
- 统一使用 `//`,不使用 `/* */`
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
// 后端要求 status 必须先转字符串再传(接口字段类型不一致历史遗留)
|
|
44
|
+
params.status = String(params.status);
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## 禁止事项
|
|
50
|
+
|
|
51
|
+
- ❌ 提交注释掉的死代码(直接删除,git 可追溯历史)
|
|
52
|
+
- ❌ 显而易见的注释,如 `// 声明变量`、`// 调用接口`
|
|
53
|
+
- ❌ TODO 不带责任人或日期,如 `// TODO: 待优化`,应写为 `// TODO(cheny, 2026-04): 接口字段后端确认中`
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# 04 — 基础编码规范
|
|
2
|
+
|
|
3
|
+
> **强制度**:🔴 必遵。
|
|
4
|
+
> 参考 jhat.tech 开发规范 + Robot_Admin 实践。
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 13 条核心约定
|
|
9
|
+
|
|
10
|
+
1. **变量声明**:优先 `const`,必须重新赋值时用 `let`,禁止 `var`
|
|
11
|
+
2. **解构赋值**:优先使用 `const { a, b } = obj`,而非 `obj.a` / `obj.b`
|
|
12
|
+
3. **异步处理**:统一 `async/await`,禁止 `.then()` 链式调用
|
|
13
|
+
4. **字符串引号**:统一单引号(以 `.prettierrc.js` 为准)
|
|
14
|
+
5. **模板字符串**:替代字符串拼接,`` `Hello ${name}` `` 而非 `'Hello ' + name`
|
|
15
|
+
6. **大括号**:所有代码块必须使用大括号包裹,即使只有一行
|
|
16
|
+
7. **条件层级**:最多三层,超过三层必须抽成函数
|
|
17
|
+
8. **模板表达式**:`<template>` 中只写简单表达式,复杂逻辑提取为 `computed` 或方法
|
|
18
|
+
9. **对象遍历**:禁止 `for...in`,使用 `Object.keys(obj).forEach()`
|
|
19
|
+
10. **undefined 判断**:使用 `typeof variable !== 'undefined'`
|
|
20
|
+
11. **v-for**:必须设置 `:key`,优先用业务主键 id 而非 index
|
|
21
|
+
12. **指令缩写**:统一 `:`(v-bind)、`@`(v-on)、`#`(v-slot)
|
|
22
|
+
13. **this 别名**:`<script setup>` 中无 `this`;旧 Options API 中的 `this` 别名用 `self`
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## 全局禁止事项
|
|
27
|
+
|
|
28
|
+
- ❌ index.vue 中写业务逻辑(逻辑全在 data.ts)
|
|
29
|
+
- ❌ 使用 Vuex(本项目用 Pinia)
|
|
30
|
+
- ❌ `::v-deep` / `/deep/`(用 `:deep()`)
|
|
31
|
+
- ❌ 直接用 axios(用 getAction/postAction,详见 13-platform-components.md)
|
|
32
|
+
- ❌ 手写查询表单/工具栏/分页(用 BaseQuery/BaseToolbar/jh-pagination)
|
|
33
|
+
- ❌ 每个页面重复写弹窗(优先用 `c_modal` / `c_formModal` 等局部公共组件)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# 05 — 日志输出规范
|
|
2
|
+
|
|
3
|
+
> **强制度**:🔴 必遵。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 开发期
|
|
8
|
+
|
|
9
|
+
- 允许 `console.log` 调试,ESLint 仅给 `warn` 提示
|
|
10
|
+
- AI 生成的代码**不要**包含调试用 `console.log`
|
|
11
|
+
|
|
12
|
+
## 提交期
|
|
13
|
+
|
|
14
|
+
- husky pre-commit 钩子自动触发 lint 检查
|
|
15
|
+
- **必须清理** `console.log` / `console.warn` / `console.debug` 才能提交
|
|
16
|
+
|
|
17
|
+
## 生产代码
|
|
18
|
+
|
|
19
|
+
- ❌ 禁止出现 `console.log`、`console.warn`、`console.error`
|
|
20
|
+
- ❌ 大量 console 输出会带来性能问题(参考 jhat.tech 规范)
|
|
21
|
+
|
|
22
|
+
## 替代方案
|
|
23
|
+
|
|
24
|
+
| 场景 | 替代方式 |
|
|
25
|
+
| -------- | ---------------------------------------------- |
|
|
26
|
+
| 错误监控 | 走全局错误处理器(接入 Sentry 或自研上报通道) |
|
|
27
|
+
| 调试信息 | 仅在开发环境通过 `import.meta.env.DEV` 守卫 |
|
|
28
|
+
| 用户提示 | 使用 `ElMessage` / `jh-message` |
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
// ✅ 允许:开发期守卫
|
|
32
|
+
if (import.meta.env.DEV) {
|
|
33
|
+
console.log("[debug] payload:", payload);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// ❌ 禁止:生产代码无守卫的 console
|
|
37
|
+
console.log("user info:", user);
|
|
38
|
+
```
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# 06 — 安全规范
|
|
2
|
+
|
|
3
|
+
> **强制度**:🔴 必遵。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## v-html 使用约束
|
|
8
|
+
|
|
9
|
+
- ❌ 默认禁止 `v-html`
|
|
10
|
+
- ✅ 仅当内容来源受控(如后端返回已消毒的富文本),且必须在使用处加注释说明来源:
|
|
11
|
+
|
|
12
|
+
```vue
|
|
13
|
+
<!-- v-html 安全声明:内容来自 /api/notice/detail,后端已做 XSS 过滤 -->
|
|
14
|
+
<div v-html="notice.content" />
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Token 存储
|
|
18
|
+
|
|
19
|
+
- ✅ 仅存 `sessionStorage` / `localStorage`
|
|
20
|
+
- ❌ 禁止放在 URL 参数(被日志记录)
|
|
21
|
+
- ❌ 禁止放在 `<meta>` 标签(HTML 静态可见)
|
|
22
|
+
|
|
23
|
+
## 接口请求
|
|
24
|
+
|
|
25
|
+
- ✅ 统一通过 `getAction / postAction / putAction / deleteAction` 走拦截器
|
|
26
|
+
- ✅ 拦截器自动注入 token、统一处理 401 跳转
|
|
27
|
+
- ❌ 禁止 `import axios from 'axios'` 直接使用
|
|
28
|
+
|
|
29
|
+
## 用户输入
|
|
30
|
+
|
|
31
|
+
- ✅ 通过接口参数对象传递
|
|
32
|
+
- ❌ 禁止拼接到 URL 字符串
|
|
33
|
+
- ❌ 禁止直接传给 SQL 语句生成函数(防 SQL 注入)
|
|
34
|
+
|
|
35
|
+
## 对象遍历
|
|
36
|
+
|
|
37
|
+
- ❌ 禁止 `for...in`(可能枚举原型链属性,存在安全隐患)
|
|
38
|
+
- ✅ 使用 `Object.keys(obj).forEach()` / `Object.entries(obj)`
|
|
39
|
+
|
|
40
|
+
## 危险 API
|
|
41
|
+
|
|
42
|
+
- ❌ **禁止 `eval()`** —— 任何场景均不允许
|
|
43
|
+
- ❌ 禁止 `new Function(string)` 动态执行字符串代码
|
|
44
|
+
- ❌ 禁止 `setTimeout(string)` 字符串形式调用
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# 07 — 配置管理规范
|
|
2
|
+
|
|
3
|
+
> **强制度**:🔴 必遵。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 环境变量
|
|
8
|
+
|
|
9
|
+
- 统一存放 `envs/.env.{mode}` 文件
|
|
10
|
+
- 命名以 `VITE_` 开头(Vite 暴露给客户端的前缀)
|
|
11
|
+
- 通过 `import.meta.env.VITE_XXX` 读取
|
|
12
|
+
- ❌ 不硬编码环境相关值
|
|
13
|
+
|
|
14
|
+
```typescript
|
|
15
|
+
// ✅ 正确
|
|
16
|
+
const apiBase = import.meta.env.VITE_API_URL;
|
|
17
|
+
|
|
18
|
+
// ❌ 错误
|
|
19
|
+
const apiBase = "http://10.0.0.5:8080/api";
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## API 地址
|
|
23
|
+
|
|
24
|
+
- ✅ 通过 `import.meta.env.VITE_API_URL` 等环境变量获取
|
|
25
|
+
- ❌ 不在代码中硬编码 `http://` / `https://` 地址
|
|
26
|
+
|
|
27
|
+
## 接口路径
|
|
28
|
+
|
|
29
|
+
- ✅ 集中在 `data.ts` 的 `API_CONFIG` 对象中声明(`as const`)
|
|
30
|
+
- ❌ 不散落在模板字符串、方法内部
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
export const API_CONFIG = {
|
|
34
|
+
list: "/mmwr/customer/list",
|
|
35
|
+
save: "/mmwr/customer/save",
|
|
36
|
+
remove: "/mmwr/customer/remove",
|
|
37
|
+
} as const;
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## 敏感信息
|
|
41
|
+
|
|
42
|
+
- ❌ 不提交到仓库(已纳入 `.gitignore`)
|
|
43
|
+
- ✅ 团队共享走内部文档或专用密钥服务
|
|
44
|
+
|
|
45
|
+
## AI 检查清单
|
|
46
|
+
|
|
47
|
+
生成代码前,AI 必须确认:
|
|
48
|
+
|
|
49
|
+
- [ ] 没有硬编码的 IP / 域名 / 端口
|
|
50
|
+
- [ ] 所有 API 路径在 `API_CONFIG` 中声明
|
|
51
|
+
- [ ] 环境变量都加了 `VITE_` 前缀
|
|
52
|
+
- [ ] 没有把 token / secret / 密码以明文形式写入代码
|