@agile-team/wl-skills-kit 2.7.0 → 2.7.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 +48 -0
- package/README.md +16 -1
- package/bin/wl-skills.js +1 -1
- package/files/.github/copilot-instructions.md +12 -0
- package/files/.github/guides/architecture.md +1 -1
- package/files/.github/skills/_best-practices.md +220 -0
- package/files/.github/skills/_registry.md +23 -19
- package/files/.github/skills/sync/_mcp-guardrail.md +109 -0
- package/files/.github/skills/sync/dict-sync/SKILL.md +86 -329
- package/files/.github/skills/sync/menu-sync/SKILL.md +34 -27
- package/files/.github/skills/sync/menu-sync/USAGE.md +17 -11
- package/files/.github/skills/sync/permission-sync/SKILL.md +19 -2
- package/files/docs/jh-date-range.md +40 -8
- package/files/docs/jh-date.md +45 -18
- package/files/docs/jh-dept-picker.md +17 -0
- package/files/docs/jh-drag-row.md +44 -21
- package/files/docs/jh-file-upload.md +43 -0
- package/files/docs/jh-select.md +51 -14
- package/files/docs/jh-text.md +29 -11
- package/files/docs/jh-textarea.md +159 -0
- package/files/docs/jh-user-picker.md +17 -0
- package/files/docs/page-query-hook-best-practices.md +431 -362
- package/mcp/api/client.js +8 -1
- package/mcp/server.js +21 -0
- package/package.json +5 -4
|
@@ -49,6 +49,14 @@ description: "Use when: managing roles, authorizing menus to roles, attaching ac
|
|
|
49
49
|
|
|
50
50
|
---
|
|
51
51
|
|
|
52
|
+
## ⚠️ 必读公共护栏
|
|
53
|
+
|
|
54
|
+
本 Skill 遵守 `../_mcp-guardrail.md`(MCP 调用纪律与自愈闭环)。AI 首次执行 sync 类任务时先 `read_file` 加载它。
|
|
55
|
+
|
|
56
|
+
本 Skill 使用的 MCP 工具:`wls_role_query` / `wls_role_upsert` / `wls_assignable_menus_query` / `wls_role_assign_menus` / `wls_action_query` / `wls_action_upsert`。调用失败时按 guardrail §2 剧本引导用户完善 `env.local.json` 后重试,**不得用 curl/手拼 HTTP 绕开 MCP**。
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
52
60
|
## MCP 工具调用规范
|
|
53
61
|
|
|
54
62
|
permission-sync 通过 6 个 MCP 工具完成所有操作(无需手动 fetch):
|
|
@@ -62,7 +70,7 @@ permission-sync 通过 6 个 MCP 工具完成所有操作(无需手动 fetch
|
|
|
62
70
|
| `wls_action_query` | 查询页面菜单下的动作(type=A) |
|
|
63
71
|
| `wls_action_upsert` | 批量新增动作(按 permission 去重) |
|
|
64
72
|
|
|
65
|
-
>
|
|
73
|
+
> 上表 6 个工具覆盖所有场景,**不得以任何理由跳过**。§6 仅为记录 MCP 内部调用的底层接口,供后端/运维联调参考,AI 禁止据此自行发起 HTTP 调用。
|
|
66
74
|
|
|
67
75
|
---
|
|
68
76
|
|
|
@@ -207,7 +215,10 @@ permission-sync 通过 6 个 MCP 工具完成所有操作(无需手动 fetch
|
|
|
207
215
|
|
|
208
216
|
---
|
|
209
217
|
|
|
210
|
-
## 6.
|
|
218
|
+
## 6. 后端接口参考(MCP 内部实现,AI 不得调用)
|
|
219
|
+
|
|
220
|
+
> 本节仅记录 MCP 内部调用的后端路径,用于后端联调 / 运维排查 / kit 维护者参考。
|
|
221
|
+
> **AI 绝不以任何方式直接发起这些请求**。MCP 不可用时的处理方式见末尾「MCP 不可用时怎么办」。
|
|
211
222
|
|
|
212
223
|
所有接口共用 Headers:
|
|
213
224
|
|
|
@@ -256,3 +267,9 @@ Authorization: Bearer <token>
|
|
|
256
267
|
- 角色分配可通过重新调用 saveRoleMenus 传旧 menuIds 恢复
|
|
257
268
|
- 新增的角色/动作建议通过后端管理界面手动删除(防止误删生产数据)
|
|
258
269
|
```
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## 9. MCP 不可用或调用失败时怎么办
|
|
274
|
+
|
|
275
|
+
见 `../_mcp-guardrail.md` §2 自愈闭环剧本。**原则**:先帮用户完善 `env.local.json` 里的 token / gatewayPath,重试 MCP 工具。**绝不允许** AI 用 curl/PowerShell/fetch 绕开 MCP 手拼 HTTP。
|
|
@@ -98,11 +98,11 @@ const query = ref({
|
|
|
98
98
|
|
|
99
99
|
```ts
|
|
100
100
|
// data.ts 查询项配置
|
|
101
|
-
export const
|
|
101
|
+
export const queryItems: BaseQueryItemDesc<any>[] = [
|
|
102
102
|
{
|
|
103
103
|
name: "createDateTime",
|
|
104
|
-
startName: "createDateTimeStart", //
|
|
105
|
-
endName: "createDateTimeEnd",
|
|
104
|
+
startName: "createDateTimeStart", // 开始字段(自动拆分)
|
|
105
|
+
endName: "createDateTimeEnd", // 结束字段(自动拆分)
|
|
106
106
|
label: "创建日期",
|
|
107
107
|
component: () => {
|
|
108
108
|
return {
|
|
@@ -110,18 +110,50 @@ export const queryItemsConfig: BaseQueryItemDesc<any>[] = [
|
|
|
110
110
|
type: "daterange",
|
|
111
111
|
rangeSeparator: "至",
|
|
112
112
|
showFormat: "YYYY-MM-DD",
|
|
113
|
-
|
|
113
|
+
format: "YYYY-MM-DD"
|
|
114
114
|
};
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
117
|
];
|
|
118
118
|
|
|
119
|
-
//
|
|
119
|
+
// 运行时框架会自动拆分为 startName 和 endName 两个字段:
|
|
120
120
|
// query.createDateTimeStart = "2026-01-01"
|
|
121
121
|
// query.createDateTimeEnd = "2026-01-31"
|
|
122
122
|
```
|
|
123
123
|
|
|
124
|
-
### 场景 4
|
|
124
|
+
### 场景 4:使用 defaultValue 预设值(源码内置)
|
|
125
|
+
|
|
126
|
+
框架在 `BaseQueryItemDesc` 中内置了丰富的日期范围预设值,配合 `startName` / `endName` 使用:
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
export const queryItems: BaseQueryItemDesc<any>[] = [
|
|
130
|
+
{
|
|
131
|
+
name: "dateRange",
|
|
132
|
+
startName: "startDate",
|
|
133
|
+
endName: "endDate",
|
|
134
|
+
label: "业务日期",
|
|
135
|
+
defaultValue: "recentDay7", // 默认选中近 7 天
|
|
136
|
+
component: () => ({ tag: "jh-date", type: "daterange" })
|
|
137
|
+
},
|
|
138
|
+
];
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
**全部可用预设值**(源码 `setFormDefaultValue`):
|
|
142
|
+
|
|
143
|
+
| 预设值 | 说明 |
|
|
144
|
+
| ------------------------------------- | ---------------------------------------- |
|
|
145
|
+
| `"recentDay3"` | 近 3 天(startDate ~ 明天) |
|
|
146
|
+
| `"recentDay7"` | 近 7 天(startDate ~ 明天) |
|
|
147
|
+
| `"recentDay30"` | 近 30 天(startDate ~ 明天) |
|
|
148
|
+
| `"recentDay3Datetime"` | 近 3 天(含时分秒 00:00:00 ~ 23:59:59) |
|
|
149
|
+
| `"rangeDatetimeToday"` | 今天(00:00:00 ~ 23:59:59) |
|
|
150
|
+
| `"rangeDayCurrentMonth1ToToday"` | 本月 1 号 ~ 今天 |
|
|
151
|
+
| `"rangeDayCurrentMonth1ToLastDay"` | 本月 1 号 ~ 本月最后一天 |
|
|
152
|
+
| `"rangeDatetimeCurrentMonth1ToLastDay"` | 本月 1 号 ~ 本月最后一天(含时分秒) |
|
|
153
|
+
|
|
154
|
+
> **单字段预设值**(非范围):`"currentDay"` | `"currentMonth"` | `"currentYear"` | `"currentDept"`
|
|
155
|
+
|
|
156
|
+
### 场景 5:与后端接口参数映射
|
|
125
157
|
|
|
126
158
|
```ts
|
|
127
159
|
// v-model 方式
|
|
@@ -183,7 +215,7 @@ params: {
|
|
|
183
215
|
### 1️⃣ 统一返回字符串格式(强烈推荐)
|
|
184
216
|
|
|
185
217
|
```vue
|
|
186
|
-
<jh-date-range v-model="query.dateRange"
|
|
218
|
+
<jh-date-range v-model="query.dateRange" format="YYYY-MM-DD" />
|
|
187
219
|
```
|
|
188
220
|
|
|
189
221
|
避免 Date / string 混用,接口参数更稳定
|
|
@@ -223,7 +255,7 @@ request({
|
|
|
223
255
|
- 必须使用数组字段接收
|
|
224
256
|
- 推荐默认 `[]`
|
|
225
257
|
|
|
226
|
-
2. **
|
|
258
|
+
2. **format 决定返回类型**
|
|
227
259
|
- 默认 `"YYYY-MM-DD"` 字符串数组
|
|
228
260
|
- 不建议返回 Date(容易引入时区/格式问题)
|
|
229
261
|
|
package/files/docs/jh-date.md
CHANGED
|
@@ -53,7 +53,9 @@ const form = ref({
|
|
|
53
53
|
| clearable | 是否可清空 | `boolean` | `true` |
|
|
54
54
|
| teleported | 是否将下拉面板插入 body | `boolean` | `true` |
|
|
55
55
|
|
|
56
|
-
>
|
|
56
|
+
> **重要说明**:
|
|
57
|
+
> - `format` 控制 v-model 返回值格式,`showFormat` 控制界面显示格式
|
|
58
|
+
> - 与 Element Plus 的 `value-format` / `format` 命名不同,请使用 jh-date 自己的 `format` 和 `showFormat`
|
|
57
59
|
|
|
58
60
|
---
|
|
59
61
|
|
|
@@ -96,36 +98,61 @@ const form = ref({
|
|
|
96
98
|
|
|
97
99
|
### 场景 3:BaseQuery 配置式用法
|
|
98
100
|
|
|
101
|
+
#### 方式一:使用 logicType 自动映射(推荐)
|
|
102
|
+
|
|
99
103
|
```ts
|
|
100
|
-
|
|
101
|
-
|
|
104
|
+
import { BusLogicDataType } from "@jhlc/types/src/logical-data";
|
|
105
|
+
|
|
106
|
+
export const queryItems: BaseQueryItemDesc<any>[] = [
|
|
102
107
|
{
|
|
103
108
|
name: "deliveryDate",
|
|
104
109
|
label: "交期日期",
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
tag: "jh-date",
|
|
108
|
-
type: "date",
|
|
109
|
-
showFormat: "YYYY-MM-DD",
|
|
110
|
-
valueFormat: "YYYY-MM-DD" // 或使用 format
|
|
111
|
-
};
|
|
112
|
-
}
|
|
110
|
+
logicType: BusLogicDataType.date,
|
|
111
|
+
// 自动渲染为 jh-date,默认 type="date",format="YYYY-MM-DD"
|
|
113
112
|
},
|
|
113
|
+
{
|
|
114
|
+
name: "year",
|
|
115
|
+
label: "年份",
|
|
116
|
+
logicType: BusLogicDataType.date_yyyy,
|
|
117
|
+
// 自动渲染为 jh-date,type="year",format="YYYY"
|
|
118
|
+
},
|
|
119
|
+
];
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
> **源码映射规则**(`getFormItemByLogicType`):
|
|
123
|
+
> - `BusLogicDataType.date` → `DateComponent`(type="date")
|
|
124
|
+
> - `BusLogicDataType.date_yyyy` → `DateComponent`(type="year", format="YYYY")
|
|
125
|
+
> - `BusLogicDataType.datetime` → `DateTimeComponent`(format="YYYY-MM-DD HH:mm:ss")
|
|
126
|
+
> - 自定义 `"month"` → `jh-date`(type="month")
|
|
127
|
+
|
|
128
|
+
#### 方式二:使用 component 自定义
|
|
129
|
+
|
|
130
|
+
```ts
|
|
131
|
+
export const queryItems: BaseQueryItemDesc<any>[] = [
|
|
114
132
|
{
|
|
115
133
|
name: "month",
|
|
116
134
|
label: "月份",
|
|
135
|
+
logicType: "month" as any,
|
|
136
|
+
dateFormat: "YYYY-MM",
|
|
137
|
+
// 源码会渲染为 jh-date,type="month",format="YYYY-MM"
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
name: "deliveryDate",
|
|
141
|
+
label: "交期日期",
|
|
117
142
|
component: () => {
|
|
118
143
|
return {
|
|
119
144
|
tag: "jh-date",
|
|
120
|
-
type: "
|
|
121
|
-
showFormat: "YYYY-MM",
|
|
122
|
-
|
|
145
|
+
type: "date",
|
|
146
|
+
showFormat: "YYYY-MM-DD",
|
|
147
|
+
format: "YYYY-MM-DD"
|
|
123
148
|
};
|
|
124
149
|
}
|
|
125
|
-
}
|
|
150
|
+
},
|
|
126
151
|
];
|
|
127
152
|
```
|
|
128
153
|
|
|
154
|
+
> **dateFormat 可选值**(在 BaseQueryItemDesc 中):`"YYYY-MM-DD"` | `"YYYY-MM"` | `"YYYYMM"` | `"YYYYMMDD"`
|
|
155
|
+
|
|
129
156
|
---
|
|
130
157
|
|
|
131
158
|
## 与 el-date-picker 对比
|
|
@@ -160,10 +187,10 @@ export const queryItemsConfig: BaseQueryItemDesc<any>[] = [
|
|
|
160
187
|
|
|
161
188
|
### 1️⃣ 统一返回字符串格式
|
|
162
189
|
|
|
163
|
-
推荐保持 `
|
|
190
|
+
推荐保持 `format="YYYY-MM-DD"`,避免 Date / string 混用:
|
|
164
191
|
|
|
165
192
|
```vue
|
|
166
|
-
<jh-date v-model="form.date"
|
|
193
|
+
<jh-date v-model="form.date" format="YYYY-MM-DD" />
|
|
167
194
|
```
|
|
168
195
|
|
|
169
196
|
---
|
|
@@ -185,7 +212,7 @@ export const queryItemsConfig: BaseQueryItemDesc<any>[] = [
|
|
|
185
212
|
|
|
186
213
|
## 注意事项
|
|
187
214
|
|
|
188
|
-
1. **v-model 返回值取决于
|
|
215
|
+
1. **v-model 返回值取决于 format**
|
|
189
216
|
- 默认返回 `"YYYY-MM-DD"` 字符串
|
|
190
217
|
- 若不配置可能返回 Date(取决于组件封装)
|
|
191
218
|
|
|
@@ -100,6 +100,23 @@ const form = ref({
|
|
|
100
100
|
|
|
101
101
|
> ⚠️ `jh-dept-picker` 仅用于选择,展示请使用 `jh-text`
|
|
102
102
|
|
|
103
|
+
### 场景 4:BaseQuery 配置式用法(推荐)
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
import { BusLogicDataType } from "@jhlc/types/src/logical-data";
|
|
107
|
+
|
|
108
|
+
export const queryItems: BaseQueryItemDesc<any>[] = [
|
|
109
|
+
{
|
|
110
|
+
name: "deptId",
|
|
111
|
+
label: "部门",
|
|
112
|
+
logicType: BusLogicDataType.dept,
|
|
113
|
+
// 自动渲染为 DeptPickerComponent
|
|
114
|
+
},
|
|
115
|
+
];
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
> **源码映射**: `BusLogicDataType.dept` → `DeptPickerComponent`
|
|
119
|
+
|
|
103
120
|
---
|
|
104
121
|
|
|
105
122
|
## 与手动实现对比
|
|
@@ -176,16 +176,24 @@ onMounted(() => {
|
|
|
176
176
|
|
|
177
177
|
## Props 属性
|
|
178
178
|
|
|
179
|
-
| 参数
|
|
180
|
-
|
|
|
181
|
-
|
|
|
182
|
-
| topPercent
|
|
183
|
-
| bottomHeight
|
|
184
|
-
|
|
|
185
|
-
|
|
|
186
|
-
|
|
|
187
|
-
|
|
188
|
-
|
|
179
|
+
| 参数 | 说明 | 类型 | 默认值 |
|
|
180
|
+
| ----------------- | -------------------------------------------- | --------- | ----------- |
|
|
181
|
+
| topHeight | 上部区域的初始高度(单位:px) | `number` | - |
|
|
182
|
+
| topPercent | 上部区域的初始百分比(与 topHeight 二选一) | `number` | - |
|
|
183
|
+
| bottomHeight | 下部区域的初始高度(单位:px) | `number` | - |
|
|
184
|
+
| isNest | 是否嵌套使用(嵌套在另一个 drag 组件内部) | `boolean` | `false` |
|
|
185
|
+
| width | 容器总宽度 | `string` | `"400px"` |
|
|
186
|
+
| height | 容器总高度 | `string` | `"400px"` |
|
|
187
|
+
| sliderWidth | 拖拽分割线的高度(单位:px) | `number` | `10` |
|
|
188
|
+
| sliderColor | 拖拽手柄指示线颜色 | `string` | `"#6f808d"` |
|
|
189
|
+
| sliderBgColor | 拖拽手柄背景色 | `string` | `"#a7caec"` |
|
|
190
|
+
| sliderHoverColor | 拖拽手柄悬停时指示线颜色 | `string` | `"#6f808d"` |
|
|
191
|
+
| sliderBgHoverColor| 拖拽手柄悬停时背景色 | `string` | `"#c8dcea"` |
|
|
192
|
+
|
|
193
|
+
> **提示**:
|
|
194
|
+
> - 推荐使用 `topHeight` 设置上部区域高度,下部区域会自动填充剩余空间
|
|
195
|
+
> - `topPercent` 与 `topHeight` 二选一;当两者都传时,`topHeight` 在 mounted 后会被转换为百分比
|
|
196
|
+
> - 实际项目中通常配合 CSS `height: 100%` 使容器占满可用空间,因此 `width`/`height` prop 仅作为兜底默认值
|
|
189
197
|
|
|
190
198
|
## Slots 插槽
|
|
191
199
|
|
|
@@ -506,37 +514,52 @@ const handlePlanChange = (row: any) => {
|
|
|
506
514
|
|
|
507
515
|
## 样式定制
|
|
508
516
|
|
|
509
|
-
###
|
|
517
|
+
### 通过 Props 自定义手柄颜色(推荐)
|
|
518
|
+
|
|
519
|
+
```vue
|
|
520
|
+
<jh-drag-row
|
|
521
|
+
:top-height="380"
|
|
522
|
+
slider-color="#409eff"
|
|
523
|
+
slider-bg-color="#e6f0fa"
|
|
524
|
+
slider-hover-color="#1890ff"
|
|
525
|
+
slider-bg-hover-color="#bae0ff"
|
|
526
|
+
>
|
|
527
|
+
...
|
|
528
|
+
</jh-drag-row>
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
### 通过 CSS 覆盖手柄样式
|
|
510
532
|
|
|
511
533
|
```scss
|
|
512
534
|
:deep(.drager_row) {
|
|
513
535
|
height: 100%;
|
|
514
536
|
|
|
515
|
-
//
|
|
516
|
-
.
|
|
517
|
-
background: #e0e0e0;
|
|
518
|
-
|
|
519
|
-
cursor: row-resize; // 鼠标样式
|
|
537
|
+
// 拖拽手柄(CSS 类名为 .slider_row)
|
|
538
|
+
> .slider_row {
|
|
539
|
+
background: #e0e0e0;
|
|
540
|
+
cursor: row-resize;
|
|
520
541
|
|
|
521
542
|
&:hover {
|
|
522
|
-
background: #1890ff;
|
|
543
|
+
background: #1890ff;
|
|
523
544
|
}
|
|
524
545
|
}
|
|
525
546
|
}
|
|
526
547
|
```
|
|
527
548
|
|
|
549
|
+
> **源码 CSS 类名参考**: `.drager_row`(主容器)、`.drager_top`(上部区域)、`.drager_bottom`(下部区域)、`.slider_row`(拖拽手柄)
|
|
550
|
+
|
|
528
551
|
### 调整上下区域内边距
|
|
529
552
|
|
|
530
553
|
```scss
|
|
531
554
|
:deep(.drager_row) {
|
|
532
555
|
height: 100%;
|
|
533
556
|
|
|
534
|
-
.
|
|
535
|
-
padding: 10px;
|
|
557
|
+
.drager_top {
|
|
558
|
+
padding-bottom: 10px;
|
|
536
559
|
}
|
|
537
560
|
|
|
538
|
-
.
|
|
539
|
-
padding: 10px;
|
|
561
|
+
.drager_bottom {
|
|
562
|
+
padding-top: 10px;
|
|
540
563
|
}
|
|
541
564
|
}
|
|
542
565
|
```
|
|
@@ -191,6 +191,49 @@ interface FileItem {
|
|
|
191
191
|
|
|
192
192
|
---
|
|
193
193
|
|
|
194
|
+
## 编程式调用(FormDialog 工具类)
|
|
195
|
+
|
|
196
|
+
源码中 `FormDialog` 提供了便捷的附件上传/预览方法,无需手动放置 `<jh-file-upload />`:
|
|
197
|
+
|
|
198
|
+
### uploadAttach — 上传附件弹窗
|
|
199
|
+
|
|
200
|
+
```ts
|
|
201
|
+
import { FormDialog } from "@jhlc/common-core/src/util/form-dialog";
|
|
202
|
+
|
|
203
|
+
const handleUpload = async () => {
|
|
204
|
+
const { type, fileList } = await FormDialog.uploadAttach("上传附件", {
|
|
205
|
+
relativeType: "order",
|
|
206
|
+
relativeId: orderId,
|
|
207
|
+
autoUpload: false, // 点确认后才上传
|
|
208
|
+
limit: 5,
|
|
209
|
+
deletable: true,
|
|
210
|
+
disabled: false,
|
|
211
|
+
});
|
|
212
|
+
if (type === "success") {
|
|
213
|
+
// 上传成功
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### previewAttach — 预览附件弹窗(只读)
|
|
219
|
+
|
|
220
|
+
```ts
|
|
221
|
+
FormDialog.previewAttach("查看附件", "order", orderId);
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### previewAttachBatch — 批量预览
|
|
225
|
+
|
|
226
|
+
```ts
|
|
227
|
+
FormDialog.previewAttachBatch("查看全部附件", [
|
|
228
|
+
{ relativeType: "order", relativeId: id1, title: "订单附件" },
|
|
229
|
+
{ relativeType: "contract", relativeId: id2, title: "合同附件" },
|
|
230
|
+
]);
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
> **源码位置**: `@jhlc/common-core/src/util/form-dialog.ts`
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
194
237
|
## 🎯 真实项目示例
|
|
195
238
|
|
|
196
239
|
### 示例 1:合同附件
|
package/files/docs/jh-select.md
CHANGED
|
@@ -50,7 +50,9 @@ const form = ref({
|
|
|
50
50
|
| collapseTag | 多选时是否折叠 Tag | `boolean` | `false` |
|
|
51
51
|
| teleported | 是否将下拉面板插入 body | `boolean` | `true` |
|
|
52
52
|
|
|
53
|
-
> **重点**:
|
|
53
|
+
> **重点**:
|
|
54
|
+
> - 当 `dict` 属性存在时,组件会自动加载对应字典数据,无需手动设置 `items`
|
|
55
|
+
> - 源码中 `BusLogicDataType.dict` 和 `BusLogicDataType.company` 都映射为 `SelectComponent`,即公司选择也使用同一组件
|
|
54
56
|
|
|
55
57
|
## Events 事件
|
|
56
58
|
|
|
@@ -81,9 +83,38 @@ const form = ref({
|
|
|
81
83
|
|
|
82
84
|
### 场景 4:BaseQuery 配置式用法(推荐)
|
|
83
85
|
|
|
86
|
+
#### 方式一:使用 logicType 自动映射(推荐)
|
|
87
|
+
|
|
84
88
|
```ts
|
|
85
|
-
|
|
86
|
-
|
|
89
|
+
import { BusLogicDataType } from "@jhlc/types/src/logical-data";
|
|
90
|
+
|
|
91
|
+
export const queryItems: BaseQueryItemDesc<any>[] = [
|
|
92
|
+
{
|
|
93
|
+
name: "status",
|
|
94
|
+
label: "状态",
|
|
95
|
+
logicType: BusLogicDataType.dict,
|
|
96
|
+
logicValue: "order_status",
|
|
97
|
+
// 自动渲染为 jh-select,自动加载字典 order_status 的选项
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
name: "companyId",
|
|
101
|
+
label: "公司",
|
|
102
|
+
logicType: BusLogicDataType.company,
|
|
103
|
+
logicValue: "companyId",
|
|
104
|
+
// BusLogicDataType.company 同样映射为 SelectComponent
|
|
105
|
+
},
|
|
106
|
+
];
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
> **源码映射规则**(`getFormItemByLogicType`):
|
|
110
|
+
> - `BusLogicDataType.dict` → `SelectComponent`
|
|
111
|
+
> - `BusLogicDataType.company` → `SelectComponent`
|
|
112
|
+
> - `BusLogicDataType.enums` → `SelectComponent`
|
|
113
|
+
|
|
114
|
+
#### 方式二:使用 component 自定义
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
export const queryItems: BaseQueryItemDesc<any>[] = [
|
|
87
118
|
{
|
|
88
119
|
name: "orderStatus",
|
|
89
120
|
label: "操作类型",
|
|
@@ -91,7 +122,6 @@ export const queryItemsConfig: BaseQueryItemDesc<any>[] = [
|
|
|
91
122
|
component: () => {
|
|
92
123
|
return {
|
|
93
124
|
tag: "jh-select",
|
|
94
|
-
// 方式一:静态数据
|
|
95
125
|
items: [
|
|
96
126
|
{ label: "是", value: 1 },
|
|
97
127
|
{ label: "否", value: 0 }
|
|
@@ -99,16 +129,22 @@ export const queryItemsConfig: BaseQueryItemDesc<any>[] = [
|
|
|
99
129
|
};
|
|
100
130
|
}
|
|
101
131
|
},
|
|
102
|
-
{
|
|
103
|
-
name: "status",
|
|
104
|
-
label: "状态",
|
|
105
|
-
logicType: BusLogicDataType.dict,
|
|
106
|
-
logicValue: "order_status" // 字典 code
|
|
107
|
-
// 方式二:使用字典数据(会自动加载)
|
|
108
|
-
}
|
|
109
132
|
];
|
|
110
133
|
```
|
|
111
134
|
|
|
135
|
+
#### historyTop 个人偏好(仅对 jh-select 生效)
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
{
|
|
139
|
+
name: "customerId",
|
|
140
|
+
label: "客户",
|
|
141
|
+
logicType: BusLogicDataType.dict,
|
|
142
|
+
logicValue: "customer_type",
|
|
143
|
+
historyTop: true,
|
|
144
|
+
// 启用后,用户近期选择过的选项会置顶显示
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
112
148
|
### 场景 5:静态 items 方式
|
|
113
149
|
|
|
114
150
|
```vue
|
|
@@ -126,9 +162,10 @@ export const queryItemsConfig: BaseQueryItemDesc<any>[] = [
|
|
|
126
162
|
|
|
127
163
|
## 最佳实践
|
|
128
164
|
|
|
129
|
-
1.
|
|
130
|
-
-
|
|
131
|
-
-
|
|
165
|
+
1. **优先使用 logicType + logicValue**
|
|
166
|
+
- 配置式优于模板式,保证字典来源统一
|
|
167
|
+
- `logicType: BusLogicDataType.dict` 自动渲染 jh-select
|
|
168
|
+
- 只有静态选项时才使用 `component` + `items`
|
|
132
169
|
|
|
133
170
|
2. **配合 jh-text 使用**
|
|
134
171
|
- 列表展示用 `jh-text`
|
package/files/docs/jh-text.md
CHANGED
|
@@ -67,9 +67,10 @@ import "@jhlc/common-core";
|
|
|
67
67
|
| fontSize | 字体大小 | `"extra-small" \| "small" \| "base" \| "medium" \| "large" \| "extra-large"` | - |
|
|
68
68
|
| fontWeight | 字体粗细 | `"light" \| "regular" \| "medium" \| "semi"` | - |
|
|
69
69
|
|
|
70
|
-
>
|
|
71
|
-
> - `
|
|
72
|
-
> -
|
|
70
|
+
> **源码说明**:
|
|
71
|
+
> - `content` 是框架内部渲染时优先使用的属性(如 `base-form-detail` 自动传入 `content: form[name]`)
|
|
72
|
+
> - `dict` 传入时,会自动设置 `type="dict"`
|
|
73
|
+
> - `logicType` + `logicValue` 是配置式用法的核心,框架会根据类型自动翻译(字典/用户/部门)
|
|
73
74
|
|
|
74
75
|
---
|
|
75
76
|
|
|
@@ -132,28 +133,45 @@ import "@jhlc/common-core";
|
|
|
132
133
|
/>
|
|
133
134
|
```
|
|
134
135
|
|
|
135
|
-
### 场景 5:
|
|
136
|
+
### 场景 5:BaseFormDetail 配置式用法(自动渲染)
|
|
137
|
+
|
|
138
|
+
在 `BaseFormDetail` 中,当配置项没有自定义 `component` 时,框架会自动使用 `jh-text` 渲染,并传入 `content`、`logicType`、`logicValue`:
|
|
136
139
|
|
|
137
140
|
```ts
|
|
138
|
-
|
|
139
|
-
|
|
141
|
+
import { BusLogicDataType } from "@jhlc/types/src/logical-data";
|
|
142
|
+
|
|
143
|
+
export const detailItems: BaseFormDetailDesc[] = [
|
|
140
144
|
{
|
|
141
145
|
name: "status",
|
|
142
146
|
label: "状态",
|
|
143
147
|
logicType: BusLogicDataType.dict,
|
|
144
|
-
logicValue: "order_status"
|
|
145
|
-
//
|
|
148
|
+
logicValue: "order_status",
|
|
149
|
+
// 框架自动渲染为: <jh-text :content="form.status" logicType="dict" logicValue="order_status" />
|
|
146
150
|
},
|
|
147
151
|
{
|
|
148
152
|
name: "createUserId",
|
|
149
153
|
label: "创建人",
|
|
150
154
|
logicType: BusLogicDataType.user,
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
155
|
+
// 自动翻译用户 ID 为用户名称
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
name: "deptId",
|
|
159
|
+
label: "部门",
|
|
160
|
+
logicType: BusLogicDataType.dept,
|
|
161
|
+
// 自动翻译部门 ID 为部门名称
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
name: "remark",
|
|
165
|
+
label: "备注",
|
|
166
|
+
// 无 logicType 时直接展示文本
|
|
167
|
+
},
|
|
154
168
|
];
|
|
155
169
|
```
|
|
156
170
|
|
|
171
|
+
> **源码逻辑**(`form-detail-item.ts` 的 `renderItem`):
|
|
172
|
+
> 1. 若配置了 `component` → 渲染自定义组件
|
|
173
|
+
> 2. 若未配置 `component` → 自动渲染 `<jh-text :content="form[name]" :logicType :logicValue />`
|
|
174
|
+
|
|
157
175
|
---
|
|
158
176
|
|
|
159
177
|
## 与手动处理对比
|