@agile-team/wl-skills-kit 1.0.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.
Files changed (112) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +328 -0
  3. package/bin/wl-skills.js +104 -0
  4. package/files/.github/copilot-instructions.md +211 -0
  5. package/files/.github/docs/SYS_MENU_INFO.md +247 -0
  6. package/files/.github/docs/menu-sync-design.md +265 -0
  7. package/files/.github/docs/use-skill.md +379 -0
  8. package/files/.github/docs/wl-skills-kit.md +266 -0
  9. package/files/.github/skills/api-contract/SKILL.md +247 -0
  10. package/files/.github/skills/convention-extract/SKILL.md +355 -0
  11. package/files/.github/skills/menu-sync/SKILL.md +255 -0
  12. package/files/.github/skills/menu-sync/env/guide.md +73 -0
  13. package/files/.github/skills/page-codegen/SKILL.md +825 -0
  14. package/files/.github/skills/page-codegen/TPL-CHANGE-HISTORY.md +281 -0
  15. package/files/.github/skills/page-codegen/TPL-DETAIL-TABS.md +1112 -0
  16. package/files/.github/skills/page-codegen/TPL-DRIVEN.md +124 -0
  17. package/files/.github/skills/page-codegen/TPL-FORM-ROUTE.md +441 -0
  18. package/files/.github/skills/page-codegen/TPL-LIST.md +196 -0
  19. package/files/.github/skills/page-codegen/TPL-MASTER-DETAIL.md +153 -0
  20. package/files/.github/skills/page-codegen/TPL-OPERATION-STATION.md +442 -0
  21. package/files/.github/skills/page-codegen/TPL-RECORD-FORM.md +376 -0
  22. package/files/.github/skills/page-codegen/TPL-TREE-LIST.md +191 -0
  23. package/files/.github/skills/prototype-scan/SKILL.md +414 -0
  24. package/files/demo/README.md +44 -0
  25. package/files/demo/produce/aiflow/mmwr-customer-apply-add/api.md +54 -0
  26. package/files/demo/produce/aiflow/mmwr-customer-apply-add/data.ts +346 -0
  27. package/files/demo/produce/aiflow/mmwr-customer-apply-add/index.scss +1 -0
  28. package/files/demo/produce/aiflow/mmwr-customer-apply-add/index.vue +28 -0
  29. package/files/demo/produce/aiflow/mmwr-customer-apply-add-form/data.ts +115 -0
  30. package/files/demo/produce/aiflow/mmwr-customer-apply-add-form/index.scss +44 -0
  31. package/files/demo/produce/aiflow/mmwr-customer-apply-add-form/index.vue +43 -0
  32. package/files/demo/produce/aiflow/mmwr-customer-apply-change/data.ts +338 -0
  33. package/files/demo/produce/aiflow/mmwr-customer-apply-change/index.scss +1 -0
  34. package/files/demo/produce/aiflow/mmwr-customer-apply-change/index.vue +28 -0
  35. package/files/demo/produce/aiflow/mmwr-customer-apply-change-form/data.ts +115 -0
  36. package/files/demo/produce/aiflow/mmwr-customer-apply-change-form/index.scss +44 -0
  37. package/files/demo/produce/aiflow/mmwr-customer-apply-change-form/index.vue +43 -0
  38. package/files/demo/produce/aiflow/mmwr-customer-apply-change-history/data.ts +196 -0
  39. package/files/demo/produce/aiflow/mmwr-customer-apply-change-history/index.scss +150 -0
  40. package/files/demo/produce/aiflow/mmwr-customer-apply-change-history/index.vue +79 -0
  41. package/files/demo/produce/aiflow/mmwr-customer-archive/api.md +88 -0
  42. package/files/demo/produce/aiflow/mmwr-customer-archive/data.ts +601 -0
  43. package/files/demo/produce/aiflow/mmwr-customer-archive/index.scss +1 -0
  44. package/files/demo/produce/aiflow/mmwr-customer-archive/index.vue +64 -0
  45. package/files/demo/produce/aiflow/mmwr-customer-detail/api.md +67 -0
  46. package/files/demo/produce/aiflow/mmwr-customer-detail/data.ts +286 -0
  47. package/files/demo/produce/aiflow/mmwr-customer-detail/index.scss +139 -0
  48. package/files/demo/produce/aiflow/mmwr-customer-detail/index.vue +318 -0
  49. package/files/demo/produce/aiflow/mmwr-temp-customer-archive/api.md +98 -0
  50. package/files/demo/produce/aiflow/mmwr-temp-customer-archive/data.ts +543 -0
  51. package/files/demo/produce/aiflow/mmwr-temp-customer-archive/index.scss +1 -0
  52. package/files/demo/produce/aiflow/mmwr-temp-customer-archive/index.vue +52 -0
  53. package/files/demo/sale/demo/add-demo/data.ts +518 -0
  54. package/files/demo/sale/demo/add-demo/index.scss +207 -0
  55. package/files/demo/sale/demo/add-demo/index.vue +167 -0
  56. package/files/demo/sale/demo/billet-flame-cut-plan/data.ts +524 -0
  57. package/files/demo/sale/demo/billet-flame-cut-plan/index.scss +155 -0
  58. package/files/demo/sale/demo/billet-flame-cut-plan/index.vue +117 -0
  59. package/files/demo/sale/demo/domestic-trade-order/data.ts +308 -0
  60. package/files/demo/sale/demo/domestic-trade-order/index.scss +99 -0
  61. package/files/demo/sale/demo/domestic-trade-order/index.vue +77 -0
  62. package/files/demo/sale/demo/heat-batch-return/data.ts +367 -0
  63. package/files/demo/sale/demo/heat-batch-return/index.scss +100 -0
  64. package/files/demo/sale/demo/heat-batch-return/index.vue +170 -0
  65. package/files/demo/sale/demo/heat-batch-return/meltDialog.vue +320 -0
  66. package/files/demo/sale/demo/metallurgical-spec/data.ts +825 -0
  67. package/files/demo/sale/demo/metallurgical-spec/index.scss +264 -0
  68. package/files/demo/sale/demo/metallurgical-spec/index.vue +309 -0
  69. package/files/docs/jh-date-range.md +257 -0
  70. package/files/docs/jh-date.md +222 -0
  71. package/files/docs/jh-dept-picker.md +190 -0
  72. package/files/docs/jh-drag-row.md +590 -0
  73. package/files/docs/jh-file-upload.md +216 -0
  74. package/files/docs/jh-pagination.md +505 -0
  75. package/files/docs/jh-picker.md +218 -0
  76. package/files/docs/jh-select.md +148 -0
  77. package/files/docs/jh-text.md +248 -0
  78. package/files/docs/jh-user-picker.md +197 -0
  79. package/files/docs/page-query-hook-best-practices.md +362 -0
  80. package/files/docs/request.md +925 -0
  81. package/files/src/components/global/C_ParentView/index.vue +3 -0
  82. package/files/src/components/global/C_RightToolbar/index.vue +459 -0
  83. package/files/src/components/global/C_Splitter/index.vue +195 -0
  84. package/files/src/components/global/C_SvgIcon/index.vue +61 -0
  85. package/files/src/components/global/C_SvgIcon/svgicon.js +10 -0
  86. package/files/src/components/global/C_TagStatus/README.md +264 -0
  87. package/files/src/components/global/C_TagStatus/config.ts +192 -0
  88. package/files/src/components/global/C_TagStatus/index.vue +127 -0
  89. package/files/src/components/global/C_TagStatus/types.ts +64 -0
  90. package/files/src/components/global/C_Tree/README.md +153 -0
  91. package/files/src/components/global/C_Tree/index.scss +42 -0
  92. package/files/src/components/global/C_Tree/index.vue +119 -0
  93. package/files/src/components/global/C_Tree/types.ts +59 -0
  94. package/files/src/components/local/c_formModal/README.md +235 -0
  95. package/files/src/components/local/c_formModal/data.ts +95 -0
  96. package/files/src/components/local/c_formModal/index.scss +8 -0
  97. package/files/src/components/local/c_formModal/index.vue +107 -0
  98. package/files/src/components/local/c_formSections/README.md +496 -0
  99. package/files/src/components/local/c_formSections/data.ts +175 -0
  100. package/files/src/components/local/c_formSections/index.scss +280 -0
  101. package/files/src/components/local/c_formSections/index.vue +429 -0
  102. package/files/src/components/local/c_listModal/data.ts +41 -0
  103. package/files/src/components/local/c_listModal/index.vue +136 -0
  104. package/files/src/components/local/c_spliterTitle/index.scss +25 -0
  105. package/files/src/components/local/c_spliterTitle/index.vue +21 -0
  106. package/files/src/components/remote/AGGrid/README.md +530 -0
  107. package/files/src/components/remote/BaseForm/README.md +508 -0
  108. package/files/src/components/remote/BaseQuery/README.md +865 -0
  109. package/files/src/components/remote/BaseTable/README.md +941 -0
  110. package/files/src/components/remote/BaseToolbar/README.md +496 -0
  111. package/files/src/types/page.ts +24 -0
  112. package/package.json +31 -0
@@ -0,0 +1,247 @@
1
+ ---
2
+ name: api-contract
3
+ description: "Use when: designing API contracts between frontend and backend based on prototype page inventory, defining request/response field structures, establishing naming conventions, and generating an api.md file per page for team alignment before coding. Triggers on: api contract, interface design, 接口约定, 前后端对齐, 字段定义, 接口设计, api.md."
4
+ ---
5
+
6
+ # Skill: 接口约定(api-contract)
7
+
8
+ 基于《页面清单》为每个页面生成 `api.md` 文件,放在**页面目录下**(和 index.vue 同级)。
9
+
10
+ **双重作用:**
11
+
12
+ 1. **前端** — data.ts 中 `API_CONFIG` 的 URL 和字段名直接基于 api.md
13
+ 2. **后端** — 拿到 api.md 直接出接口(Controller + Service + Entity),字段名一致,联调零成本
14
+
15
+ ---
16
+
17
+ ## 全局规范
18
+
19
+ ### URL 命名
20
+
21
+ ```
22
+ /[服务缩写]/[资源名CamelCase]/[操作]
23
+ ```
24
+
25
+ | 服务缩写 | 含义 | 示例 |
26
+ | -------- | -------- | ------------------------------------ |
27
+ | pm | 生产管理 | `/pm/omptMillPlanOrder/list` |
28
+ | mmwr | 精整作业 | `/mmwr/mmwrTechFinish/queryTechList` |
29
+ | mmsm | 炼钢管理 | `/mmsm/mmsmRsltLadleUse/list` |
30
+ | sale | 销售管理 | `/sale/saleOrder/list` |
31
+ | hrms | 人力资源 | `/hrms/hrmsEmployee/list` |
32
+ | base | 基础数据 | `/base/cmUserGroup/list` |
33
+
34
+ ### 标准操作集
35
+
36
+ | 操作 | 方法 | URL 后缀 | 说明 |
37
+ | -------- | ---- | ----------------- | ----------------------------------------------------- |
38
+ | 分页列表 | POST | `/list` | 基类 `super({ url: { list } })` 自动调用 |
39
+ | 单条查询 | GET | `/getById?id=xxx` | `getAction(API_CONFIG.getById, { id })` |
40
+ | 新增 | POST | `/save` | `postAction(API_CONFIG.save, formData)` |
41
+ | 编辑 | POST | `/update` | `postAction(API_CONFIG.update, formData)` |
42
+ | 删除 | POST | `/remove` | 基类 `super({ url: { remove } })` + `this.remove(id)` |
43
+ | 导出 | GET | `/export` | `getAction(API_CONFIG.export, params)` |
44
+
45
+ ### 业务操作命名规范
46
+
47
+ 非标准 CRUD 操作按以下约定命名,URL 后缀使用**动词原形**(camelCase):
48
+
49
+ | 操作 | 方法 | URL 后缀 | 请求说明 |
50
+ | ---------- | ---- | ----------------- | --------------------------------------- |
51
+ | 提交审批 | POST | `/submit` | `{ id }` 或 `{ ids: [] }` |
52
+ | 审批通过 | POST | `/approve` | `{ id, opinion? }` |
53
+ | 审批驳回 | POST | `/reject` | `{ id, opinion }` |
54
+ | 撤回 | POST | `/withdraw` | `{ id }` 撤回已提交的单据 |
55
+ | 启用/禁用 | POST | `/changeStatus` | `{ id, status }` |
56
+ | 转化 | POST | `/convert` | `{ id }` 临时→正式(如临时客户→正式) |
57
+ | 下发 | POST | `/release` | `{ id }` 计划/工单下发执行 |
58
+ | 关闭 | POST | `/close` | `{ id }` 关闭订单/计划 |
59
+ | 作废 | POST | `/cancel` | `{ id }` 作废单据 |
60
+ | 批量操作 | POST | `/batchXxx` | 如 `/batchSubmit`、`/batchRemove` |
61
+ | 子表查询 | POST | `/queryXxxList` | 如 `/queryDetailList`,主从表场景 |
62
+
63
+ > **命名原则**:`/[服务缩写]/[资源名]/[动作]`,动作用英文动词原形,不用中文拼音,不加 `do` / `handle` 前缀。
64
+
65
+ ### 统一响应结构
66
+
67
+ ```json
68
+ // 分页查询
69
+ { "code": 200, "message": "操作成功", "result": { "records": [], "total": 100, "current": 1, "size": 20 } }
70
+
71
+ // 单条查询
72
+ { "code": 200, "result": { /* Entity */ } }
73
+
74
+ // 增删改
75
+ { "code": 200, "message": "操作成功", "result": true }
76
+ ```
77
+
78
+ ### 字段命名
79
+
80
+ | 端 | 规范 | 说明 |
81
+ | ---- | ------------ | ------------------------------ |
82
+ | 前端 | `camelCase` | 所有请求/响应字段名 |
83
+ | 后端 | `snake_case` | 数据库字段,Jackson 自动转驼峰 |
84
+
85
+ ---
86
+
87
+ ## 执行步骤
88
+
89
+ ### Step 1:接收输入
90
+
91
+ 从 Phase 1 《页面清单》获取:
92
+
93
+ - 业务服务缩写(如 `pm`)
94
+ - 资源名(camelCase,如 `omptMillPlanOrder`)
95
+ - 各页面的查询字段、表格列、表单字段
96
+
97
+ ### Step 2:为每个页面生成 api.md
98
+
99
+ 文件放在**页面目录下**(和 index.vue 同级),字段名与 data.ts 完全一致。
100
+
101
+ ### Step 3:同步生成 API_CONFIG
102
+
103
+ api.md 中的接口 URL 直接对应 data.ts 中的 `API_CONFIG`:
104
+
105
+ ```typescript
106
+ export const API_CONFIG = {
107
+ list: "/pm/omptMillPlanOrder/list",
108
+ remove: "/pm/omptMillPlanOrder/remove",
109
+ getById: "/pm/omptMillPlanOrder/getById",
110
+ save: "/pm/omptMillPlanOrder/save",
111
+ update: "/pm/omptMillPlanOrder/update",
112
+ export: "/pm/omptMillPlanOrder/export",
113
+ // 按需增加业务操作
114
+ release: "/pm/omptMillPlanOrder/release"
115
+ } as const;
116
+ ```
117
+
118
+ ---
119
+
120
+ ## api.md 模板
121
+
122
+ 每个页面目录下生成:
123
+
124
+ ````markdown
125
+ # 接口约定 - [页面中文名]
126
+
127
+ > 页面路径:`src/views/[域]/[模块]/[子模块]/[目录]/`
128
+ > 服务缩写:[pm / mmwr / sale / ...]
129
+ > 资源名:[camelCase 实体名]
130
+ > 状态:🟡 待后端确认
131
+
132
+ ---
133
+
134
+ ## API_CONFIG
135
+
136
+ ```typescript
137
+ export const API_CONFIG = {
138
+ list: "/[服务缩写]/[资源名]/list",
139
+ remove: "/[服务缩写]/[资源名]/remove",
140
+ getById: "/[服务缩写]/[资源名]/getById",
141
+ save: "/[服务缩写]/[资源名]/save",
142
+ update: "/[服务缩写]/[资源名]/update",
143
+ export: "/[服务缩写]/[资源名]/export"
144
+ } as const;
145
+ ```
146
+
147
+ ---
148
+
149
+ ## 实体定义
150
+
151
+ > 字段名与 data.ts 中 queryDef/columnsDef 使用的字段名**完全一致**
152
+
153
+ | 字段名 | 类型 | 说明 | 必填 | 字典(logicValue) | 备注 |
154
+ | ------------- | ------ | -------- | ---- | ---------------- | -------------------- |
155
+ | id | string | 主键 | 自动 | - | 后端生成 |
156
+ | [field1] | string | [说明] | ✅ | - | |
157
+ | [statusField] | string | [状态] | ✅ | [dictCode] | 前端 logicValue 对应 |
158
+ | [dateField] | string | [日期] | ❌ | - | YYYY-MM-DD |
159
+ | createTime | string | 创建时间 | 自动 | - | YYYY-MM-DD HH:mm:ss |
160
+ | updateTime | string | 更新时间 | 自动 | - | |
161
+ | createBy | string | 创建人 | 自动 | - | |
162
+
163
+ ---
164
+
165
+ ## 接口清单
166
+
167
+ ### 1. 分页查询
168
+
169
+ ```
170
+ POST /[服务缩写]/[资源名]/list
171
+ ```
172
+
173
+ | 字段 | 类型 | 必填 | 说明 |
174
+ | ------------- | ------ | ---- | ----------------------------------- |
175
+ | current | number | ✅ | 页码(基类自动传) |
176
+ | size | number | ✅ | 每页条数(基类自动传) |
177
+ | [queryField1] | string | ❌ | [说明] |
178
+ | [queryField2] | string | ❌ | [说明],对应 logicValue: [dictCode] |
179
+ | [startDate] | string | ❌ | 开始日期 YYYY-MM-DD |
180
+ | [endDate] | string | ❌ | 结束日期 YYYY-MM-DD |
181
+
182
+ **响应 records:** 同实体定义
183
+
184
+ ### 2. 详情查询
185
+
186
+ ```
187
+ GET /[服务缩写]/[资源名]/getById?id=xxx
188
+ ```
189
+
190
+ **响应 result:** 单个 Entity
191
+
192
+ ### 3. 新增
193
+
194
+ ```
195
+ POST /[服务缩写]/[资源名]/save
196
+ ```
197
+
198
+ **请求:** 实体定义中必填字段(不含 id、createTime 等自动字段)
199
+
200
+ ### 4. 编辑
201
+
202
+ ```
203
+ POST /[服务缩写]/[资源名]/update
204
+ ```
205
+
206
+ **请求:** 同新增 + `id`(必填)
207
+
208
+ ### 5. 删除
209
+
210
+ ```
211
+ POST /[服务缩写]/[资源名]/remove
212
+ ```
213
+
214
+ **请求:** `{ "ids": ["xxx"] }` 或 `{ "id": "xxx" }`
215
+
216
+ ### 6. 导出(如需要)
217
+
218
+ ```
219
+ GET /[服务缩写]/[资源名]/export?[查询参数]
220
+ ```
221
+
222
+ ---
223
+
224
+ ## 数据字典
225
+
226
+ | dictCode(logicValue) | 用途 | 出现位置 |
227
+ | -------------------- | ------ | ---------------------------- |
228
+ | [dictCode] | [说明] | queryDef / columnsDef / form |
229
+
230
+ ---
231
+
232
+ ## 联调注意
233
+
234
+ 1. 前端字段全部 camelCase,后端 JSON 序列化输出 camelCase
235
+ 2. 时间字段统一 `YYYY-MM-DD HH:mm:ss`
236
+ 3. 大数字 ID 后端转字符串
237
+ 4. 分页参数是 `current` / `size`(基类自动处理)
238
+ 5. 枚举字段前端传 value,后端可返回 `[field]Label` 辅助展示
239
+ ````
240
+
241
+ ---
242
+
243
+ ## 状态标记
244
+
245
+ - 🟡 待后端确认 — 刚生成
246
+ - 🟢 已确认 — 双方对齐,可编码
247
+ - 🔴 有变更 — 需双方同步
@@ -0,0 +1,355 @@
1
+ ---
2
+ name: convention-extract
3
+ description: "Use when: scanning a Vue project to extract and document coding conventions, file structure rules, naming patterns, component usage patterns, and API writing standards into a reusable conventions document. Triggers on: extract conventions, project standards, coding rules, 提炼规范, 编码规范, 项目扫描规范."
4
+ ---
5
+
6
+ # Skill: 规范提炼(convention-extract)
7
+
8
+ 扫描 Vue 项目源码,将隐含的编码规范显式化、固化,供 AI 在代码生成时精确还原项目风格。
9
+
10
+ **cx-ui-produce 项目的规范已提炼完成并固化在 `.github/copilot-instructions.md` 中。**
11
+ 以下是完整规范详情,新项目接入时参考「扫描步骤」重新执行。
12
+
13
+ ---
14
+
15
+ ## 已固化规范:cx-ui-produce
16
+
17
+ ### 1. 技术栈
18
+
19
+ ```
20
+ Vue 3.2 + Vite + TypeScript(strict: false)
21
+ Element Plus 2.x + @jhlc/jh-ui 3.x(自研组件库)
22
+ @jhlc/common-core 3.x(查询/表格/工具栏/HTTP/页面Hook基类)
23
+ Windi CSS + SCSS
24
+ Pinia + pinia-plugin-persistedstate
25
+ Module Federation(@originjs/vite-plugin-federation,子应用架构)
26
+ ```
27
+
28
+ ### 2. 微前端架构
29
+
30
+ - 本项目是 Module Federation **子应用**(produce 域)
31
+ - 路由、权限、布局、Store 均从主应用 `main` 远程加载
32
+ - 子应用只负责 `src/views/` 下的业务页面
33
+ - 页面在 `vite/plugins/shared/pages.ts` 注册,构建后通过 `exposes` 暴露给主应用
34
+ - 共享依赖:vue, pinia, vue-router, element-plus, @jhlc/common-core
35
+
36
+ ### 3. 目录结构
37
+
38
+ ```
39
+ src/views/[域]/[模块]/[子模块分组]/[kebab-case-页面目录]/
40
+ ├── index.vue ← 纯模板 + createPage 解构,不写业务逻辑
41
+ ├── data.ts ← AbstractPageQueryHook 类 + API_CONFIG
42
+ ├── index.scss ← 页面样式(可为空)
43
+ └── api.md ← 接口约定(前端预留 + 后端出接口依据)
44
+ ```
45
+
46
+ 弹窗组件提取策略:
47
+
48
+ - **通用弹窗**(2+ 页面复用)→ `src/components/local/c_xxxModal/`(如 `c_modal/`)
49
+ - **极个性弹窗**(仅单页面,c_modal 无法满足)→ 页面 `components/xxxModal.vue`
50
+
51
+ ### 4. data.ts 编码模式(核心)
52
+
53
+ 所有页面使用 `class extends AbstractPageQueryHook` 配置化开发:
54
+
55
+ ```typescript
56
+ import {
57
+ AbstractPageQueryHook,
58
+ BaseQueryItemDesc,
59
+ ActionButtonDesc,
60
+ TableColumnDesc
61
+ } from "@/types/page";
62
+ import { getAction, postAction } from "@jhlc/common-core/src/api/action";
63
+ import { ElMessage, ElMessageBox } from "element-plus";
64
+
65
+ // ✅ API 配置:URL 格式为 /[服务缩写]/[资源名CamelCase]/[操作]
66
+ export const API_CONFIG = {
67
+ list: "/pm/omptMillPlanOrder/list",
68
+ export: "/pm/omptMillPlanOrder/export",
69
+ remove: "/pm/omptMillPlanOrder/remove",
70
+ getById: "/pm/omptMillPlanOrder/getById",
71
+ save: "/pm/omptMillPlanOrder/save",
72
+ update: "/pm/omptMillPlanOrder/update"
73
+ } as const;
74
+
75
+ // ✅ createPage 工厂:接收弹窗 ref,返回 Page.create()
76
+ export function createPage(addModalRef?: any) {
77
+ let Page = new (class extends AbstractPageQueryHook {
78
+ constructor() {
79
+ // super 传入 list 和 remove 的 URL,基类自动处理分页查询和删除
80
+ super({ url: { list: API_CONFIG.list, remove: API_CONFIG.remove } });
81
+ }
82
+
83
+ // ✅ 查询条件(BaseQuery 组件数据源)
84
+ queryDef(): BaseQueryItemDesc<any>[] {
85
+ return [
86
+ // 普通输入框(默认)
87
+ { name: "orderNo", label: "订单号", placeholder: "请输入订单号" },
88
+ // 字典下拉(自动加载字典数据)
89
+ {
90
+ name: "planStatus",
91
+ label: "计划状态",
92
+ placeholder: "请选择",
93
+ logicType: BusLogicDataType.dict,
94
+ logicValue: "planStatus"
95
+ },
96
+ // 月份选择器
97
+ {
98
+ name: "orderMonth",
99
+ label: "订单月",
100
+ placeholder: "请选择",
101
+ component: () => ({
102
+ tag: "jh-date",
103
+ type: "month",
104
+ showFormat: "YYYY-MM",
105
+ format: "YYYYMM"
106
+ })
107
+ },
108
+ // 日期范围选择器
109
+ {
110
+ name: "planDate",
111
+ startName: "planStartDate",
112
+ endName: "planEndDate",
113
+ label: "计划时间",
114
+ placeholder: "请选择",
115
+ component: () => ({
116
+ tag: "jh-date",
117
+ type: "daterange",
118
+ rangeSeparator: "至",
119
+ showFormat: "YYYY-MM-DD",
120
+ valueFormat: "YYYY-MM-DD"
121
+ })
122
+ }
123
+ ];
124
+ }
125
+
126
+ // ✅ 工具栏按钮(BaseToolbar 组件数据源)
127
+ toolbarDef(): ActionButtonDesc[] {
128
+ return [
129
+ {
130
+ name: "primary",
131
+ label: "新增",
132
+ plain: true,
133
+ onClick: () => addModalRef?.value?.open()
134
+ },
135
+ {
136
+ name: "danger",
137
+ label: "删除",
138
+ plain: true,
139
+ onClick: () => {
140
+ this.actionBatch(
141
+ this.postAction,
142
+ API_CONFIG.remove,
143
+ "确定删除选中数据吗?",
144
+ this.getSelection().map((item) => item.id)
145
+ );
146
+ }
147
+ }
148
+ ];
149
+ }
150
+
151
+ // ✅ 表格列(BaseTable 组件数据源)
152
+ columnsDef(): TableColumnDesc<any>[] {
153
+ return [
154
+ { type: "selection" },
155
+ { type: "index" },
156
+ {
157
+ label: "订单号",
158
+ name: "orderNo",
159
+ minWidth: 120,
160
+ sortable: true,
161
+ filterable: true
162
+ },
163
+ // 字典列(自动翻译 value → label)
164
+ {
165
+ label: "计划状态",
166
+ name: "planStatus",
167
+ minWidth: 120,
168
+ logicType: BusLogicDataType.dict,
169
+ logicValue: "planStatus",
170
+ sortable: true,
171
+ filterable: true
172
+ },
173
+ {
174
+ label: "计划重量",
175
+ name: "planWeight",
176
+ minWidth: 120,
177
+ sortable: true,
178
+ filterable: true
179
+ },
180
+ // 操作列
181
+ {
182
+ label: "操作",
183
+ operations: [
184
+ {
185
+ name: "edit",
186
+ label: "编辑",
187
+ onClick: (row) => addModalRef?.value?.open(row.id)
188
+ },
189
+ {
190
+ name: "remove",
191
+ label: "删除",
192
+ onClick: (row) => this.remove(row.id)
193
+ }
194
+ ]
195
+ }
196
+ ];
197
+ }
198
+ })();
199
+
200
+ return Page.create() as any;
201
+ }
202
+ ```
203
+
204
+ ### 5. index.vue 模式
205
+
206
+ ```vue
207
+ <template>
208
+ <div class="app-container app-page-container">
209
+ <BaseQuery
210
+ :form="queryParam"
211
+ :items="queryItems"
212
+ @select="select"
213
+ @reset="select"
214
+ />
215
+ <BaseToolbar :items="toolbars" />
216
+ <BaseTable ref="tableRef" :data="list" :columns="columns" showToolbar />
217
+ <jh-pagination
218
+ v-show="page.total && page.total > 0"
219
+ :total="page.total || 0"
220
+ v-model:currentPage="page.current"
221
+ v-model:pageSize="page.size"
222
+ @current-change="select"
223
+ @size-change="select"
224
+ />
225
+ </div>
226
+ </template>
227
+
228
+ <script setup lang="ts">
229
+ import { createPage } from "./data";
230
+
231
+ const Page = createPage();
232
+ const {
233
+ tableRef,
234
+ page,
235
+ queryParam,
236
+ list,
237
+ queryItems,
238
+ columns,
239
+ toolbars,
240
+ select
241
+ } = Page;
242
+
243
+ onMounted(() => select());
244
+ </script>
245
+
246
+ <style scoped lang="scss">
247
+ @import "./index.scss";
248
+ </style>
249
+ ```
250
+
251
+ **强制规则:**
252
+
253
+ - `<script setup lang="ts">` 必须
254
+ - index.vue 里**不写业务逻辑**
255
+ - 最外层 class 必须是 `app-container app-page-container`
256
+ - 弹窗组件放在根 `</div>` 之后
257
+ - 样式用 `@import "./index.scss"`
258
+
259
+ ### 6. API 写法
260
+
261
+ ```typescript
262
+ // ✅ 使用 @jhlc/common-core 封装方法
263
+ import { getAction, postAction } from "@jhlc/common-core/src/api/action";
264
+
265
+ // URL 格式:/[服务缩写]/[资源名CamelCase]/[操作]
266
+ // 服务缩写如:pm(生产管理)、mmwr(精整)、mmsm(炼钢)、sale(销售)、hrms(人力)
267
+
268
+ // 分页查询(基类 super({ url }) 自动处理)
269
+ // 单条查询
270
+ getAction(API_CONFIG.getById, { id });
271
+ // 新增 / 编辑
272
+ postAction(API_CONFIG.save, formData);
273
+ postAction(API_CONFIG.update, formData);
274
+ // 删除(单条)
275
+ this.remove(row.id); // 基类内置方法
276
+ // 批量操作
277
+ this.actionBatch(this.postAction, url, "确认提示", ids);
278
+ ```
279
+
280
+ 详细文档:`docs/request.md`、`docs/page-query-hook-best-practices.md`
281
+
282
+ ### 7. 命名规范
283
+
284
+ | 位置 | 规范 | 示例 |
285
+ | ------------ | ----------------------- | ------------------------------------ |
286
+ | 路由/目录 | kebab-case | `ompt-mill-plan/` |
287
+ | pages.ts | `["kebab名", "中文名"]` | `["ompt-mill-plan", "轧钢计划编制"]` |
288
+ | 字段名 | camelCase | `orderNo`, `planStatus` |
289
+ | logicValue | camelCase | `planStatus`, `plineCode` |
290
+ | 全局组件 | `C_PascalCase/` | `C_Tree/` |
291
+ | 局部组件 | `c_camelCase/` | `c_modal/`、`c_detailPanel/` |
292
+ | 页面私有组件 | camelCase | `addModal.vue`(仅极个性弹窗) |
293
+ | API CONFIG | UPPER_SNAKE(变量名) | `API_CONFIG` |
294
+ | 服务缩写 | 小写简写 | `pm`, `mmwr`, `mmsm`, `sale` |
295
+
296
+ ### 8. 共享业务组件分类与命名
297
+
298
+ | 分类 | 路径 | 命名 | 职责 | 示例 |
299
+ |---|---|---|---|---|
300
+ | **通用弹窗** | `src/components/local/c_xxxModal/` | `c_formModal`、`c_modal` | 配置驱动的表单弹窗,多页面复用 | `c_formModal`(CRUD 弹窗) |
301
+ | **业务表单容器** | `src/components/local/c_xxxForm/` | `c_customerApplyForm` | 封装多 Tab 表单 + 数据契约(loadData/collectFormData/validate),多页面共享 | `c_customerTabs`(建议重命名为 `c_customerApplyForm`) |
302
+ | **配置驱动模板** | `src/components/template/XxxTemplate/` | PascalCase | 布局完全相同的 3+ 页面共用的模板组件,页面仅传 config | `FinishingAchievementTemplate`(7 个精整实绩页共用) |
303
+ | **页面私有组件** | `页面目录/components/` | camelCase | 仅单页面使用、c_modal 无法满足的极个性弹窗 | `addModal.vue` |
304
+
305
+ **命名避坑**:
306
+ - ❌ 不要用 `c_xxxTabs` 命名业务表单容器 → 容易与 `el-tabs` / `jh-tabs` 混淆
307
+ - ✅ 用 `c_xxxForm` / `c_xxxPanel` 表达其"表单容器"本质
308
+
309
+ ### 9. 路由导航规范(微前端子应用)
310
+
311
+ | 场景 | 方式 | 原因 |
312
+ |---|---|---|
313
+ | **菜单页 → 隐藏页**(列表→表单) | `envConfig()?.router.resolve() + location.href` | 父壳需刷新菜单高亮 |
314
+ | **隐藏页 → 隐藏页**(表单→变更历史) | `envConfig()?.router.resolve() + location.href` | `router.push()` 跳过 shell 的 `generateCurrentRoute`,导致 "Invalid route component" 报错 |
315
+ | **返回上一页** | `useRouter().back()` | 任何页面均可用,无需加载组件 |
316
+
317
+ > ⚠️ **所有前进导航(无论是否隐藏页)必须用 `location.href`**,`useRouter().push()` 仅用于 `.back()`。
318
+
319
+ ### 10. 样式规范
320
+
321
+ - Windi CSS 工具类优先
322
+ - `:deep()` 替代 `::v-deep` / `/deep/`
323
+ - jh-drag-row 必须:`.app-page-container .drager_row { height: 100%; }`
324
+ - 所有页面/组件样式统一写在 `index.scss` 中,不可在 template 中大量使用内联 style
325
+
326
+ ### 11. pages.ts 注册
327
+
328
+ ```typescript
329
+ // vite/plugins/shared/pages.ts
330
+ const moduleName = gProd("base-path", {
331
+ subModuleKey: [["kebab-目录名", "中文名"]]
332
+ });
333
+ // 导出到 list 数组
334
+ export const list: SharedPageItem[] = [...moduleName, ...otherModule];
335
+ ```
336
+
337
+ ---
338
+
339
+ ## 扫描步骤(新项目时使用)
340
+
341
+ 当接入新项目时,扫描以下文件提炼规范:
342
+
343
+ 1. `package.json` → 技术栈 + 依赖版本
344
+ 2. `vite.config.ts` / `vite/plugins/` → 构建配置 + 微前端配置
345
+ 3. 页面注册文件(如 `pages.ts`、`router/index.ts`)→ 路由注册规范
346
+ 4. `src/views/` 选取 2-3 个典型页面 → 页面结构 + data.ts 模式
347
+ 5. `src/components/` → 全局/局部组件规范
348
+ 6. `src/api/` → API 写法规范
349
+ 7. `src/types/` → 类型规范
350
+ 8. 组件文档(如 `docs/`)→ 自研组件用法
351
+ 9. `.env*` / 环境配置文件 → 环境变量
352
+
353
+ > **如果新项目是空白/刚初始化的**,跳过本步骤,直接复制 cx-ui-produce 的 `.github/copilot-instructions.md` 作为基础模板,按实际修改即可。
354
+
355
+ 输出更新本文件的「已固化规范」部分。