@agile-team/wl-skills-kit 2.6.0 → 2.7.1

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.
@@ -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
- | top-height | 上部区域的初始高度(单位:px) | `number` | - |
182
- | topPercent | 上部区域的初始百分比(与 top-height 二选一) | `number` | - |
183
- | bottomHeight | 下部区域的初始高度(单位:px) | `number` | - |
184
- | bottomPercent | 下部区域的初始百分比 | `number` | - |
185
- | height | 容器总高度 | `string` | `"400px"` |
186
- | sliderWidth | 拖拽分割线的宽度(单位:px) | `number` | `10` |
187
-
188
- > **提示**: 推荐使用 `top-height` 设置上部区域高度,下部区域会自动填充剩余空间。
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
- .drager {
517
- background: #e0e0e0; // 手柄背景色
518
- height: 6px; // 手柄高度
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
- .top-area {
535
- padding: 10px;
557
+ .drager_top {
558
+ padding-bottom: 10px;
536
559
  }
537
560
 
538
- .bottom-area {
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:合同附件
@@ -50,7 +50,9 @@ const form = ref({
50
50
  | collapseTag | 多选时是否折叠 Tag | `boolean` | `false` |
51
51
  | teleported | 是否将下拉面板插入 body | `boolean` | `true` |
52
52
 
53
- > **重点**: 当 `dict` 属性存在时,组件会自动加载对应字典数据,无需手动设置 `items`。
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
- // data.ts 查询项配置
86
- export const queryItemsConfig: BaseQueryItemDesc<any>[] = [
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. **始终使用 dict 属性**
130
- - 不要手动写 options
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`
@@ -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
- > - `dict` 传入时,会自动设置 `type="dict"`
72
- > - 同时使用 `logicType` `logicValue` 可以实现自动翻译
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:BaseDetail 配置式用法
136
+ ### 场景 5:BaseFormDetail 配置式用法(自动渲染)
137
+
138
+ 在 `BaseFormDetail` 中,当配置项没有自定义 `component` 时,框架会自动使用 `jh-text` 渲染,并传入 `content`、`logicType`、`logicValue`:
136
139
 
137
140
  ```ts
138
- // data.ts 详情项配置
139
- export const detailItemsConfig: BaseFormDetailDesc[] = [
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
- // 会自动渲染为 jh-text 并翻译字典
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
- logicValue: "userId"
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
  ## 与手动处理对比
@@ -0,0 +1,159 @@
1
+ # jh-textarea - 多行文本输入组件
2
+
3
+ > 平台统一的多行文本输入组件,适用于备注、描述等需要输入较长文本的场景
4
+
5
+ ## 📦 组件位置
6
+
7
+ ```ts
8
+ import "@jhlc/common-core";
9
+ ```
10
+
11
+ 组件已全局注册,可直接在模板中使用 `<jh-textarea />`。
12
+
13
+ ---
14
+
15
+ ## 基本用法
16
+
17
+ ### 1️⃣ 表单录入(最常用)
18
+
19
+ ```vue
20
+ <template>
21
+ <jh-textarea v-model="form.remark" placeholder="请输入备注" />
22
+ </template>
23
+
24
+ <script setup lang="ts">
25
+ import { ref } from "vue";
26
+
27
+ const form = ref({
28
+ remark: ""
29
+ });
30
+ </script>
31
+ ```
32
+
33
+ ---
34
+
35
+ ### 2️⃣ 限制行数
36
+
37
+ ```vue
38
+ <jh-textarea v-model="form.description" :rows="4" placeholder="请输入描述信息" />
39
+ ```
40
+
41
+ ---
42
+
43
+ ## Props 属性
44
+
45
+ | 参数 | 说明 | 类型 | 默认值 |
46
+ | -------------------- | ----------------------- | ------------------ | -------------- |
47
+ | modelValue / v-model | 绑定值 | `string` | - |
48
+ | placeholder | 占位提示 | `string` | `"请输入"` |
49
+ | rows | 显示行数 | `number` | `3` |
50
+ | maxlength | 最大输入长度 | `number` | - |
51
+ | showWordLimit | 是否显示字数统计 | `boolean` | `false` |
52
+ | disabled | 是否禁用 | `boolean` | `false` |
53
+ | clearable | 是否可清空 | `boolean` | `true` |
54
+ | autosize | 自适应内容高度 | `boolean \| object`| `false` |
55
+
56
+ ---
57
+
58
+ ## Events 事件
59
+
60
+ | 事件名 | 说明 | 回调参数 |
61
+ | ----------------- | ------------ | ----------------- |
62
+ | change | 值变化时触发 | `(value) => void` |
63
+ | update:modelValue | v-model 更新 | `(value) => void` |
64
+ | blur | 失去焦点 | `() => void` |
65
+
66
+ ---
67
+
68
+ ## 常见场景
69
+
70
+ ### 场景 1:表单备注
71
+
72
+ ```vue
73
+ <jh-textarea v-model="form.remark" placeholder="请输入备注" />
74
+ ```
75
+
76
+ ### 场景 2:带字数限制
77
+
78
+ ```vue
79
+ <jh-textarea
80
+ v-model="form.description"
81
+ :maxlength="500"
82
+ show-word-limit
83
+ placeholder="请输入描述(最多500字)"
84
+ />
85
+ ```
86
+
87
+ ### 场景 3:BaseQuery / BaseForm 配置式用法
88
+
89
+ ```ts
90
+ import { BusLogicDataType } from "@jhlc/types/src/logical-data";
91
+
92
+ export const formItems: BaseFormItemDesc<any>[] = [
93
+ {
94
+ name: "remark",
95
+ label: "备注",
96
+ logicType: BusLogicDataType.textarea,
97
+ // 自动渲染为 jh-textarea
98
+ },
99
+ ];
100
+ ```
101
+
102
+ > **源码映射**(`getFormItemByLogicType`):`BusLogicDataType.textarea` → `jh-textarea`
103
+
104
+ ---
105
+
106
+ ## 与 el-input 对比
107
+
108
+ ### 使用 jh-textarea(推荐)
109
+
110
+ ```vue
111
+ <jh-textarea v-model="form.remark" />
112
+ ```
113
+
114
+ ✅ 统一样式风格
115
+ ✅ 简化配置
116
+
117
+ ### 使用 el-input(不推荐)
118
+
119
+ ```vue
120
+ <el-input v-model="form.remark" type="textarea" :rows="3" />
121
+ ```
122
+
123
+ ❌ 需要每次指定 `type="textarea"`
124
+ ❌ 样式与交互可能不统一
125
+
126
+ ---
127
+
128
+ ## 最佳实践
129
+
130
+ 1. **表单中长文本字段统一使用 jh-textarea**
131
+ - 与 `jh-select`、`jh-date` 等保持一致的组件体系
132
+
133
+ 2. **配合 logicType 使用**
134
+ - 配置式表单中使用 `logicType: BusLogicDataType.textarea`
135
+ - 框架自动渲染为 `jh-textarea`
136
+
137
+ 3. **详情页展示使用 jh-text**
138
+ - 编辑:`jh-textarea`
139
+ - 展示:`jh-text`
140
+
141
+ ---
142
+
143
+ ## 注意事项
144
+
145
+ 1. **仅用于编辑场景**
146
+ - 详情/只读展示使用 `jh-text`
147
+
148
+ 2. **长度限制建议配合后端校验**
149
+ - 前端 `maxlength` 仅做交互限制
150
+
151
+ ---
152
+
153
+ ## 🚀 快速开始
154
+
155
+ 1. 直接使用 v-model 绑定字段
156
+ 2. 配置式表单使用 `logicType: BusLogicDataType.textarea`
157
+ 3. 详情展示统一使用 `jh-text`
158
+
159
+ **推荐作为平台统一的多行文本输入组件使用!**
@@ -97,6 +97,23 @@ const form = ref({
97
97
 
98
98
  > ⚠️ `jh-user-picker` 仅用于选择,展示请使用 `jh-text`
99
99
 
100
+ ### 场景 4:BaseQuery 配置式用法(推荐)
101
+
102
+ ```ts
103
+ import { BusLogicDataType } from "@jhlc/types/src/logical-data";
104
+
105
+ export const queryItems: BaseQueryItemDesc<any>[] = [
106
+ {
107
+ name: "createUserId",
108
+ label: "创建人",
109
+ logicType: BusLogicDataType.user,
110
+ // 自动渲染为 UserPickerComponent
111
+ },
112
+ ];
113
+ ```
114
+
115
+ > **源码映射**: `BusLogicDataType.user` → `UserPickerComponent`
116
+
100
117
  ---
101
118
 
102
119
  ## 与手动实现对比