sohelp-eleplus 1.1.21 → 1.1.24

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 (110) hide show
  1. package/cache/DictCache.js +38 -7
  2. package/cache/ModuleCache.js +18 -1
  3. package/cache/README.md +53 -0
  4. package/components.js +1 -0
  5. package/http/CrudHttp.js +63 -43
  6. package/http/DictHttp.js +5 -1
  7. package/http/ModuleHttp.js +26 -11
  8. package/http/README.md +50 -0
  9. package/http/SohelpHttp.js +48 -49
  10. package/package.json +1 -1
  11. package/sohelp-ace-editor/README.md +53 -0
  12. package/sohelp-application-select/README.md +15 -0
  13. package/sohelp-autocode/README.md +38 -0
  14. package/sohelp-autocode/index.vue +7 -7
  15. package/sohelp-calendar-view/README.md +15 -0
  16. package/sohelp-card/README.md +27 -0
  17. package/sohelp-card-view/README.md +15 -0
  18. package/sohelp-condition/README.md +61 -0
  19. package/sohelp-cry-input/README.md +30 -0
  20. package/sohelp-date/README.md +27 -0
  21. package/sohelp-datetime/README.md +29 -0
  22. package/sohelp-datetime-picker/README.md +36 -0
  23. package/sohelp-datetime-range/README.md +35 -0
  24. package/sohelp-dict/README.md +43 -0
  25. package/sohelp-dict/index.vue +118 -72
  26. package/sohelp-drawer/README.md +42 -0
  27. package/sohelp-drawer/index.vue +4 -1
  28. package/sohelp-drop-card/README.md +41 -0
  29. package/sohelp-dyn-select/README.md +36 -0
  30. package/sohelp-dyn-select/index.vue +2 -2
  31. package/sohelp-dyn-tree/README.md +31 -0
  32. package/sohelp-dyn-tree-select/README.md +28 -0
  33. package/sohelp-entity-form/README.md +45 -0
  34. package/sohelp-entity-form/index.vue +14 -5
  35. package/sohelp-entity-grid/README.md +18 -0
  36. package/sohelp-file-upload/README.md +35 -0
  37. package/sohelp-file-upload/index.vue +21 -3
  38. package/sohelp-filter-scheme/README.md +41 -0
  39. package/sohelp-grid/README.md +47 -0
  40. package/sohelp-grid/index.vue +124 -73
  41. package/sohelp-grid/js/DefaultGridOptions.js +2 -1
  42. package/sohelp-grid/js/DefaultProps.js +5 -1
  43. package/sohelp-grid/js/useSohelpGridConfig.js +33 -4
  44. package/sohelp-grid-select/README.md +38 -0
  45. package/sohelp-grid-view/README.md +34 -0
  46. package/sohelp-grid-view/filter/README.md +45 -0
  47. package/sohelp-grid-view/filter/config/README.md +37 -0
  48. package/sohelp-grid-view/filter/filter-form.vue +15 -12
  49. package/sohelp-grid-view/index.vue +62 -2
  50. package/sohelp-grid-view-select/README.md +36 -0
  51. package/sohelp-group-view/README.md +7 -0
  52. package/sohelp-icon-select/README.md +21 -0
  53. package/sohelp-image-upload/README.md +35 -0
  54. package/sohelp-image-upload/index.vue +8 -2
  55. package/sohelp-import/README.md +35 -0
  56. package/sohelp-input/README.md +21 -0
  57. package/sohelp-modal/README.md +30 -0
  58. package/sohelp-modal/index.vue +2 -1
  59. package/sohelp-module/README.md +24 -0
  60. package/sohelp-number-input/README.md +18 -0
  61. package/sohelp-number-range/README.md +24 -0
  62. package/sohelp-org-select/README.md +20 -0
  63. package/sohelp-org-tree/README.md +18 -0
  64. package/sohelp-org-tree-select/README.md +22 -0
  65. package/sohelp-org-user-tree/README.md +18 -0
  66. package/sohelp-org-user-tree-select/README.md +7 -0
  67. package/sohelp-page/README.md +21 -0
  68. package/sohelp-pagination/README.md +13 -0
  69. package/sohelp-power/README.md +27 -0
  70. package/sohelp-pro-form/README.md +35 -0
  71. package/sohelp-pro-form/components/pro-form-item.vue +10 -7
  72. package/sohelp-pro-form/index.vue +6 -0
  73. package/sohelp-pro-form/util.js +6 -13
  74. package/sohelp-pro-layout/README.md +7 -0
  75. package/sohelp-pro-table/README.md +13 -0
  76. package/sohelp-process/README.md +24 -0
  77. package/sohelp-rate/README.md +23 -0
  78. package/sohelp-rate/index.vue +12 -8
  79. package/sohelp-relation/README.md +7 -0
  80. package/sohelp-rich-text/README.md +23 -0
  81. package/sohelp-richtext/README.md +3 -0
  82. package/sohelp-role-select/README.md +20 -0
  83. package/sohelp-search/README.md +7 -0
  84. package/sohelp-search-pro-form/README.md +3 -0
  85. package/sohelp-select/README.md +51 -0
  86. package/sohelp-select/index.vue +18 -21
  87. package/sohelp-split-panel/README.md +31 -0
  88. package/sohelp-switch/README.md +33 -0
  89. package/sohelp-table/README.md +36 -0
  90. package/sohelp-table-select/index.vue +358 -0
  91. package/sohelp-tenant-select/README.md +31 -0
  92. package/sohelp-text/README.md +17 -0
  93. package/sohelp-textarea-input/README.md +24 -0
  94. package/sohelp-textarea-input/index.vue +16 -11
  95. package/sohelp-time/README.md +22 -0
  96. package/sohelp-tree/README.md +32 -0
  97. package/sohelp-tree-select/README.md +18 -0
  98. package/sohelp-user-select/README.md +22 -0
  99. package/sohelp-user-tag/README.md +15 -0
  100. package/sohelp-user-tree/README.md +15 -0
  101. package/sohelp-vform-drawer/README.md +25 -0
  102. package/sohelp-vform-eleplus/README.md +39 -0
  103. package/sohelp-vform-modal/README.md +25 -0
  104. package/sohelp-vform-select/README.md +15 -0
  105. package/sohelp-vxe-grid/README.md +50 -0
  106. package/sohelp-vxe-grid-select/README.md +36 -0
  107. package/sohelp-vxe-table/README.md +27 -0
  108. package/sohelp-workflow/README.md +28 -0
  109. package/sohelp-workflow-drawer/README.md +38 -0
  110. package/sohelp-grid/SohelpGridConfig.js~ +0 -408
@@ -1,30 +1,25 @@
1
1
  <!-- 字典组件 -->
2
2
  <template>
3
3
  <template v-if="type === 'text'">
4
- <el-text
5
- v-bind="$attrs"
6
- :style="getStyle(item)"
7
- style="
8
- border-radius: 3px;
9
- margin-right: 3px;
10
- padding-left: 6px;
11
- padding-right: 6px;
12
- padding-top: 3px;
13
- padding-bottom: 3px;
14
- display: flex;
15
- align-items: center;
16
- "
17
- v-for="(item, index) in valueData"
18
- :key="item.value"
19
- >
20
- <el-icon :size="18" style="margin: 2px 5px 0 0">
21
- <component :is="ElementPlusIcons[icon]" v-if="ElementPlusIcons[icon]" />
22
- <component :is="EleAdminPlusIcons[icon]" v-else-if="EleAdminPlusIcons[icon]" />
23
- <span :class="icon" v-else></span>
24
- </el-icon>
4
+ <div style="display: flex; align-items: center; flex-wrap: wrap; gap: 5px">
5
+ <el-text
6
+ v-bind="$attrs"
7
+ :style="getStyle(item)"
8
+ style="padding: 0 6px; border-radius: 3px"
9
+ v-for="item in valueData"
10
+ :key="item.value"
11
+ >
12
+ <div class="sohelp-dict-item">
13
+ <el-icon v-if="item.icon">
14
+ <component :is="ElementPlusIcons[icon]" v-if="ElementPlusIcons[icon]" />
15
+ <component :is="EleAdminPlusIcons[icon]" v-else-if="EleAdminPlusIcons[icon]" />
16
+ <span :class="icon" v-else></span>
17
+ </el-icon>
25
18
 
26
- {{ item.label }}
27
- </el-text>
19
+ {{ item.label }}</div
20
+ >
21
+ </el-text></div
22
+ >
28
23
  </template>
29
24
  <template v-else-if="type === 'tag'">
30
25
  <div class="tags" style="display: flex; gap: 5px; flex-wrap: wrap">
@@ -36,45 +31,53 @@
36
31
  :key="item.value"
37
32
  :disable-transitions="true"
38
33
  >
39
- <el-icon :size="18" style="margin: 2px 5px 0 0">
40
- <component :is="ElementPlusIcons[icon]" v-if="ElementPlusIcons[icon]" />
41
- <component :is="EleAdminPlusIcons[icon]" v-else-if="EleAdminPlusIcons[icon]" />
42
- <span :class="icon" v-else></span>
43
- </el-icon>
44
- {{ item.label }}
34
+ <div class="sohelp-dict-item">
35
+ <el-icon v-if="item.icon">
36
+ <component :is="ElementPlusIcons[icon]" v-if="ElementPlusIcons[icon]" />
37
+ <component :is="EleAdminPlusIcons[icon]" v-else-if="EleAdminPlusIcons[icon]" />
38
+ <span :class="icon" v-else></span>
39
+ </el-icon>
40
+ {{ item.label }}</div
41
+ >
45
42
  </el-tag>
46
43
  </div>
47
44
  </template>
45
+
48
46
  <el-radio-group
49
47
  v-bind="$attrs"
50
48
  v-else-if="type === 'radio'"
51
49
  :disabled="disabled"
52
- :model-value="modelValue"
50
+ v-model="modelValue"
53
51
  @change="change"
54
52
  >
55
53
  <el-radio v-for="item in data.value" :key="item.value" :label="item.value">
56
- <el-icon :size="18" style="margin: 2px 5px 0 0">
57
- <component :is="ElementPlusIcons[icon]" v-if="ElementPlusIcons[icon]" />
58
- <component :is="EleAdminPlusIcons[icon]" v-else-if="EleAdminPlusIcons[icon]" />
59
- <span :class="icon" v-else></span>
60
- </el-icon>
61
- {{ item.label }}
54
+ <div class="sohelp-dict-item">
55
+ <el-icon v-if="item.icon">
56
+ <component :is="ElementPlusIcons[icon]" v-if="ElementPlusIcons[icon]" />
57
+ <component :is="EleAdminPlusIcons[icon]" v-else-if="EleAdminPlusIcons[icon]" />
58
+ <span :class="icon" v-else></span>
59
+ </el-icon>
60
+ {{ item.label }}</div
61
+ >
62
62
  </el-radio>
63
63
  </el-radio-group>
64
+
64
65
  <el-checkbox-group
65
66
  v-bind="$attrs"
66
67
  v-else-if="type === 'checkbox'"
67
68
  :disabled="disabled"
68
- :model-value="modelValue"
69
+ v-model="modelValue"
69
70
  @change="change"
70
71
  >
71
72
  <el-checkbox v-for="item in data.value" :key="item.value" :label="item.value">
72
- <el-icon :size="18" style="margin: 2px 5px 0 0">
73
- <component :is="ElementPlusIcons[icon]" v-if="ElementPlusIcons[icon]" />
74
- <component :is="EleAdminPlusIcons[icon]" v-else-if="EleAdminPlusIcons[icon]" />
75
- <span :class="icon" v-else></span>
76
- </el-icon>
77
- {{ item.label }}
73
+ <div class="sohelp-dict-item">
74
+ <el-icon v-if="item.icon">
75
+ <component :is="ElementPlusIcons[icon]" v-if="ElementPlusIcons[icon]" />
76
+ <component :is="EleAdminPlusIcons[icon]" v-else-if="EleAdminPlusIcons[icon]" />
77
+ <span :class="icon" v-else></span>
78
+ </el-icon>
79
+ {{ item.label }}</div
80
+ >
78
81
  </el-checkbox>
79
82
  </el-checkbox-group>
80
83
 
@@ -84,7 +87,6 @@
84
87
  clearable
85
88
  v-else
86
89
  v-model="modelValue"
87
- :model-value="modelValue"
88
90
  :disabled="disabled"
89
91
  :placeholder="placeholder"
90
92
  :multiple="type === 'multipleSelect'"
@@ -92,27 +94,40 @@
92
94
  style="min-width: 120px"
93
95
  @change="change"
94
96
  ref="dictSelectRef"
97
+ :style="getStyle(data?.value?.find((item) => item.value === modelValue))"
95
98
  >
99
+ <template #tag>
100
+ <div style="display: flex; gap: 5px; flex-wrap: wrap">
101
+ <el-tag v-for="item in valueData" :key="item" :style="getStyle(item)">
102
+ <div class="sohelp-dict-item">
103
+ <el-icon v-if="item.icon">
104
+ <component :is="ElementPlusIcons[icon]" v-if="ElementPlusIcons[icon]" />
105
+ <component :is="EleAdminPlusIcons[icon]" v-else-if="EleAdminPlusIcons[icon]" />
106
+ <span :class="icon" v-else></span>
107
+ </el-icon>
108
+
109
+ {{ item.label }}</div
110
+ >
111
+ </el-tag>
112
+ </div>
113
+ </template>
114
+
96
115
  <template #prefix v-if="icon">
97
- <el-icon :size="18" style="margin-right: 5px">
116
+ <el-icon :size="16" style="margin-right: 5px">
98
117
  <component :is="ElementPlusIcons[icon]" v-if="ElementPlusIcons[icon]" />
99
118
  <component :is="EleAdminPlusIcons[icon]" v-else-if="EleAdminPlusIcons[icon]" />
100
119
  <span :class="icon" v-else></span>
101
120
  </el-icon>
102
121
  </template>
103
- <el-option
104
- v-for="item in data.value"
105
- :key="item.id"
106
- :value="item.value"
107
- :label="item.label"
108
- :style="`color:${item.fontColor}`"
109
- >
110
- <el-icon :size="18" v-if="item.icon" style="margin-right: 5px">
111
- <component :is="ElementPlusIcons[item.icon]" v-if="ElementPlusIcons[item.icon]" />
112
- <component :is="EleAdminPlusIcons[item.icon]" v-else-if="EleAdminPlusIcons[item.icon]" />
113
- <span :class="item.icon" v-else></span>
114
- </el-icon>
115
- {{ item.label }}
122
+ <el-option v-for="item in data.value" :key="item.id" :value="item.value" :label="item.label">
123
+ <el-tag class="sohelp-dict-item" size="small" :style="getStyle(item)" :color="item.backgroundColor">
124
+ <el-icon v-if="item.icon">
125
+ <component :is="ElementPlusIcons[item.icon]" v-if="ElementPlusIcons[item.icon]" />
126
+ <component :is="EleAdminPlusIcons[item.icon]" v-else-if="EleAdminPlusIcons[item.icon]" />
127
+ <span :class="item.icon" v-else></span>
128
+ </el-icon>
129
+ <span>{{ item.label }}</span>
130
+ </el-tag>
116
131
  </el-option>
117
132
  </el-select>
118
133
  </template>
@@ -123,7 +138,10 @@
123
138
  import * as ElementPlusIcons from '@element-plus/icons-vue';
124
139
  import * as EleAdminPlusIcons from '../sohelp-icon-select/icons';
125
140
 
126
- const modelValue = defineModel('modelValue', { type: [String, Number, Array], default: '' });
141
+ const modelValue = defineModel('modelValue', {
142
+ type: [String, Number, Array],
143
+ default: ''
144
+ });
127
145
  const emit = defineEmits('change');
128
146
  const props = defineProps({
129
147
  /** 字典类型 */
@@ -134,7 +152,10 @@
134
152
  /** 组件类型 */
135
153
  type: String,
136
154
  /** 是否禁用 */
137
- disabled: Boolean,
155
+ disabled: {
156
+ type: Boolean,
157
+ default: false
158
+ },
138
159
  /** 提示文本 */
139
160
  placeholder: String,
140
161
  /** select的下拉是否插入到body下 */
@@ -164,6 +185,7 @@
164
185
  nextTick(() => {
165
186
  if (!modelValue.value && (props.type === 'select' || props.type === undefined) && data.value[0]) {
166
187
  modelValue.value = data.value[0].value;
188
+ } else {
167
189
  }
168
190
  if (props.autoFocus) {
169
191
  dictSelectRef.value?.focus();
@@ -207,19 +229,14 @@
207
229
  : val
208
230
  .split(',')
209
231
  .map((v) => v.trim())
210
- .filter(Boolean);
211
-
212
- return (data.value || [])
213
- .map((d) => (values.includes(d.value) ? d : null))
214
- .filter(Boolean)
215
- .concat(
216
- values.filter((v) => !(data.value || []).some((d) => d.value === v)).map((v) => ({ value: v, label: v }))
217
- );
232
+ .filter((v) => v !== '');
233
+
234
+ const dictData = data.value || [];
235
+ const dictValueSet = new Set(dictData.map((d) => d.value));
236
+ const matchedItems = dictData.filter((d) => values.includes(d.value));
237
+ const customItems = values.filter((v) => !dictValueSet.has(v)).map((v) => ({ value: v, label: v }));
238
+ return [...matchedItems, ...customItems].filter((item) => item.id);
218
239
  });
219
- /** 更新选中数据 */
220
- // const updateValue = (value) => {
221
- // emit('update:modelValue', value);
222
- // };
223
240
  </script>
224
241
 
225
242
  <script>
@@ -228,3 +245,32 @@
228
245
  inheritAttrs: false
229
246
  };
230
247
  </script>
248
+ <style scoped lang="scss">
249
+ .el-select {
250
+ border-radius: 8px;
251
+ :deep(.el-select__selection) {
252
+ .el-select__placeholder {
253
+ color: inherit;
254
+ }
255
+ }
256
+ :deep(.el-select__prefix) {
257
+ color: inherit;
258
+ }
259
+ }
260
+ .sohelp-dict-item {
261
+ display: flex;
262
+ flex: 0 0 auto !important;
263
+ align-items: center;
264
+ :deep(.el-tag__content) {
265
+ display: flex;
266
+ align-items: center;
267
+ }
268
+ :deep(.el-icon) {
269
+ font-size: 14px;
270
+ margin-right: 2px;
271
+ }
272
+ }
273
+ .el-select__popper .el-select-dropdown__list .el-select-dropdown__item {
274
+ // font-size: inherit;
275
+ }
276
+ </style>
@@ -0,0 +1,42 @@
1
+ # 抽屉组件 (Drawer)
2
+
3
+ 对 `ele-drawer` 的简单封装,提供便捷的显示/隐藏控制。
4
+
5
+ ## 属性 (Props)
6
+
7
+ | 属性名 | 类型 | 默认值 | 说明 |
8
+ | :--- | :--- | :--- | :--- |
9
+ | modelValue | Boolean | false | 控制抽屉显示隐藏 (v-model)。 |
10
+ | ... | - | - | 支持 `ele-drawer` 的其他属性。 |
11
+
12
+ ## 方法 (Exposed Methods)
13
+
14
+ | 方法名 | 说明 |
15
+ | :--- | :--- |
16
+ | show | 显示抽屉。 |
17
+ | close | 关闭抽屉。 |
18
+
19
+ ## 插槽 (Slots)
20
+
21
+ | 插槽名 | 说明 |
22
+ | :--- | :--- |
23
+ | default | 抽屉主体内容。 |
24
+ | footer | 抽屉底部区域。 |
25
+
26
+ ## 使用示例
27
+
28
+ ```vue
29
+ <template>
30
+ <sohelp-drawer v-model="visible" title="详情">
31
+ <div>内容区域</div>
32
+ <template #footer>
33
+ <el-button @click="visible = false">关闭</el-button>
34
+ </template>
35
+ </sohelp-drawer>
36
+ </template>
37
+
38
+ <script setup>
39
+ import { ref } from 'vue';
40
+ const visible = ref(false);
41
+ </script>
42
+ ```
@@ -29,7 +29,10 @@
29
29
 
30
30
  defineExpose({
31
31
  show,
32
- close
32
+ close,
33
+ getValue: () => {
34
+ return modelValue.value;
35
+ }
33
36
  });
34
37
  </script>
35
38
  <script>
@@ -0,0 +1,41 @@
1
+ # 下拉卡片 (Drop Card)
2
+
3
+ 点击按钮后展示下拉卡片的组件,基于 Tooltip 实现,适合用于复杂内容的下拉展示。
4
+
5
+ ## 属性 (Props)
6
+
7
+ | 属性名 | 类型 | 默认值 | 说明 |
8
+ | :--- | :--- | :--- | :--- |
9
+ | title | String | - | 按钮显示的标题。 |
10
+ | icon | Object/String | - | 按钮图标。 |
11
+ | placement | String | 'bottom-end' | 弹出位置。 |
12
+ | trigger | String | 'click' | 触发方式。 |
13
+ | effect | String | 'light' | Tooltip 主题。 |
14
+
15
+ ## 方法 (Exposed Methods)
16
+
17
+ | 方法名 | 说明 |
18
+ | :--- | :--- |
19
+ | close | 关闭下拉卡片。 |
20
+
21
+ ## 插槽 (Slots)
22
+
23
+ | 插槽名 | 说明 |
24
+ | :--- | :--- |
25
+ | default | 卡片主体内容。 |
26
+ | footer | 卡片底部操作区。 |
27
+
28
+ ## 使用示例
29
+
30
+ ```vue
31
+ <template>
32
+ <sohelp-drop-card title="更多筛选" icon="Filter">
33
+ <el-form>
34
+ <el-form-item label="名称"><el-input /></el-form-item>
35
+ </el-form>
36
+ <template #footer>
37
+ <el-button type="primary" size="small">查询</el-button>
38
+ </template>
39
+ </sohelp-drop-card>
40
+ </template>
41
+ ```
@@ -0,0 +1,36 @@
1
+ # 动态下拉选择 (Dynamic Select)
2
+
3
+ 支持从 URL、Promise 或函数动态加载数据源的下拉选择组件。
4
+
5
+ ## 属性 (Props)
6
+
7
+ | 属性名 | 类型 | 默认值 | 说明 |
8
+ | :--- | :--- | :--- | :--- |
9
+ | modelValue | String/Number/Array | - | 绑定的值 (v-model)。 |
10
+ | datasource | Array/Function/Promise | - | 数据源 (Required)。 |
11
+ | url | String | - | 数据加载 URL (若 datasource 为空时使用)。 |
12
+ | labelField | String | - | 显示字段名。 |
13
+ | valueField | String | - | 值字段名。 |
14
+ | readonly | Boolean | false | 是否只读 (只读模式下显示文本)。 |
15
+
16
+ ## 使用示例
17
+
18
+ ```vue
19
+ <template>
20
+ <!-- 从 URL 加载 -->
21
+ <sohelp-dyn-select
22
+ v-model="userId"
23
+ url="/api/users"
24
+ labelField="username"
25
+ valueField="id"
26
+ />
27
+
28
+ <!-- 从静态数组加载 -->
29
+ <sohelp-dyn-select
30
+ v-model="type"
31
+ :datasource="[{ label: 'A', value: 1 }, { label: 'B', value: 2 }]"
32
+ labelField="label"
33
+ valueField="value"
34
+ />
35
+ </template>
36
+ ```
@@ -13,7 +13,6 @@
13
13
  :labelField="labelField"
14
14
  :valueField="valueField"
15
15
  />
16
-
17
16
  </div>
18
17
  </template>
19
18
  <script>
@@ -82,7 +81,8 @@
82
81
  () => props.modelValue,
83
82
  (val) => {
84
83
  value.value = val;
85
- },{
84
+ },
85
+ {
86
86
  immediate: true,
87
87
  deep: true
88
88
  }
@@ -0,0 +1,31 @@
1
+ # 动态树 (Dynamic Tree)
2
+
3
+ 从后端 URL 加载扁平数据并自动转换为树形结构展示的组件。
4
+
5
+ ## 属性 (Props)
6
+
7
+ | 属性名 | 类型 | 默认值 | 说明 |
8
+ | :--- | :--- | :--- | :--- |
9
+ | url | String | - | 数据接口 URL (Required)。 |
10
+ | valueField | String | 'id' | ID 字段名。 |
11
+ | labelField | String | 'org_name' | 显示字段名。 |
12
+ | parentField | String | 'parent_id' | 父级 ID 字段名。 |
13
+ | ... | - | - | 支持 `sohelp-tree` (el-tree) 的其他属性。 |
14
+
15
+ ## 事件 (Events)
16
+
17
+ | 事件名 | 说明 | 回调参数 |
18
+ | :--- | :--- | :--- |
19
+ | node-click | 节点点击事件。 | `data, node, el` |
20
+
21
+ ## 使用示例
22
+
23
+ ```vue
24
+ <template>
25
+ <sohelp-dyn-tree
26
+ url="/engine/web/org/list"
27
+ labelField="org_name"
28
+ @node-click="handleNodeClick"
29
+ />
30
+ </template>
31
+ ```
@@ -0,0 +1,28 @@
1
+ # 动态树选择 (Dynamic Tree Select)
2
+
3
+ 基于 `ele-tree-select`,支持从后端 URL 加载数据并自动转树形结构的选择组件。
4
+
5
+ ## 属性 (Props)
6
+
7
+ | 属性名 | 类型 | 默认值 | 说明 |
8
+ | :--- | :--- | :--- | :--- |
9
+ | modelValue | String/Number/Array | - | 绑定的值 (v-model)。 |
10
+ | url | String | '/engine/web/org/list' | 数据接口 URL。 |
11
+ | valueField | String | 'id' | ID 字段名。 |
12
+ | labelField | String | 'org_name' | 显示字段名。 |
13
+ | parentField | String | 'parent_id' | 父级 ID 字段名。 |
14
+ | height | String | '255' | 下拉框高度。 |
15
+ | checkStrictly | Boolean | false | 是否严格的遵循父子不互相关联。 |
16
+ | ... | - | - | 支持 `ele-tree-select` 的其他属性。 |
17
+
18
+ ## 使用示例
19
+
20
+ ```vue
21
+ <template>
22
+ <sohelp-dyn-tree-select
23
+ v-model="orgId"
24
+ url="/api/orgs"
25
+ placeholder="选择部门"
26
+ />
27
+ </template>
28
+ ```
@@ -0,0 +1,45 @@
1
+ # 实体表单 (Entity Form)
2
+
3
+ 基于元数据配置 (`refid`) 自动渲染的表单组件,支持复杂的表单逻辑、公式计算和布局控制。
4
+
5
+ ## 功能特性
6
+
7
+ - **元数据驱动**:通过 `refid` 自动加载表单配置。
8
+ - **公式计算**:支持字段间的自动计算公式。
9
+ - **响应式布局**:支持 `grid` 布局配置。
10
+ - **自定义插槽**:支持插槽覆盖特定字段的渲染。
11
+
12
+ ## 属性 (Props)
13
+
14
+ | 属性名 | 类型 | 默认值 | 说明 |
15
+ | :--- | :--- | :--- | :--- |
16
+ | modelValue | Object | - | 表单数据对象 (v-model)。 |
17
+ | refid | String | - | 实体引用 ID (Required)。 |
18
+ | formConfig | Object | - | 表单配置对象 (Required)。 |
19
+ | readonly | Boolean | false | 是否只读。 |
20
+ | autoLoad | Boolean | true | 是否自动加载数据。 |
21
+ | labelWidth | String | 'auto' | 标签宽度。 |
22
+ | gridNum | Number | 1 | 列数。 |
23
+
24
+ ## 方法 (Exposed Methods)
25
+
26
+ 可通过 `ref` 获取实例调用:
27
+ - `getRef(name)`: 获取内部字段组件实例。
28
+
29
+ ## 使用示例
30
+
31
+ ```vue
32
+ <template>
33
+ <sohelp-entity-form
34
+ v-model="formData"
35
+ refid="user_entity"
36
+ :formConfig="config"
37
+ />
38
+ </template>
39
+
40
+ <script setup>
41
+ import { ref } from 'vue';
42
+ const formData = ref({});
43
+ const config = { ... }; // 通常由后端获取
44
+ </script>
45
+ ```
@@ -15,6 +15,7 @@
15
15
  :rowProps="{
16
16
  gutter: 20
17
17
  }"
18
+ :saveParams="saveParams"
18
19
  @updateValue="setFieldValue"
19
20
  >
20
21
  <!-- 自定义插槽 -->
@@ -36,13 +37,10 @@
36
37
  import { useMobile } from '@/utils/use-mobile';
37
38
  import { useI18n } from 'vue-i18n';
38
39
  import { EleMessage } from '@/components/ele-admin-plus/components';
39
- import { SohelpInput, SohelpNumberInput } from '../components';
40
40
 
41
- const { query } = useRoute();
42
41
  const formValue = ref({});
43
42
  const formData = ref({});
44
43
  const defaultFormValue = ref({});
45
- const form = ref({});
46
44
  const loading = ref(false);
47
45
  const { mobile } = useMobile();
48
46
  const emit = defineEmits(['update:modelValue', 'update:data']);
@@ -74,9 +72,12 @@
74
72
  gridNum: {
75
73
  type: Number,
76
74
  default: 1
75
+ },
76
+ saveParams: {
77
+ type: Object,
78
+ default: () => ({})
77
79
  }
78
80
  });
79
-
80
81
  /**
81
82
  * 存储表单初始值用于对比变更
82
83
  *
@@ -220,6 +221,10 @@
220
221
  editParams.readonly = item?.readonly || false;
221
222
  editParams.placeholder = item?.placeholder || placeholderMap[item?.editor] || '';
222
223
 
224
+ if (props.readonly) {
225
+ editParams.placeholder = '';
226
+ }
227
+
223
228
  return {
224
229
  key: item?.name || 'tempKey' + index,
225
230
  type: item?.editor ? item.editor : matchingType(item?.type || ''),
@@ -253,7 +258,10 @@
253
258
  }
254
259
  isConfigInitialized.value = true;
255
260
  defaultFormValue.value = init;
256
- return Promise.resolve(init);
261
+
262
+ return new Promise((resolve) => {
263
+ resolve(init);
264
+ });
257
265
  };
258
266
  /**
259
267
  * 获取表单数据
@@ -436,6 +444,7 @@
436
444
  */
437
445
  const save = async (params = {}, callback) => {
438
446
  await isConfigDone();
447
+
439
448
  loading.value = true;
440
449
  const refid = props.refid;
441
450
  const key = refid && refid.indexOf('!') !== -1 ? refid.split('!')[1] : 'default';
@@ -0,0 +1,18 @@
1
+ # 实体表格 (Entity Grid)
2
+
3
+ 基于元数据配置 (`refid`) 自动渲染的表格组件,封装了 `sohelp-grid-view`。
4
+
5
+ ## 属性 (Props)
6
+
7
+ | 属性名 | 类型 | 默认值 | 说明 |
8
+ | :--- | :--- | :--- | :--- |
9
+ | refid | String | - | 实体引用 ID (Required)。 |
10
+ | modelValue | Object | - | 绑定的值。 |
11
+
12
+ ## 使用示例
13
+
14
+ ```vue
15
+ <template>
16
+ <sohelp-entity-grid refid="user_list_view" />
17
+ </template>
18
+ ```
@@ -0,0 +1,35 @@
1
+ # SohelpFileUpload 文件上传组件
2
+
3
+ 基于 `vxe-upload` 封装的文件上传组件,支持拖拽、粘贴上传、多文件上传、文件大小限制、文件类型限制以及下载功能。
4
+
5
+ ## 基础用法
6
+
7
+ ```html
8
+ <sohelp-file-upload v-model="fileIds" :limit="5" :fileSize="10" />
9
+ ```
10
+
11
+ ## 属性 (Props)
12
+
13
+ | 属性名 | 类型 | 默认值 | 说明 |
14
+ |Data | Array | [] | 文件对象数组,包含 name, url, id 等信息 |
15
+ | modelValue | Array/String | [] | 绑定的文件 ID 集合 |
16
+ | limit | Number | - | 最大允许上传个数 |
17
+ | fileSize | Number | - | 单个文件大小限制 (MB) |
18
+ | fileType | Array | - | 允许上传的文件类型后缀,如 ['jpg', 'png'] |
19
+ | drag | Boolean | false | 是否启用拖拽上传 |
20
+ | isShowTip | Boolean | true | 是否显示提示信息 |
21
+ | readonly | Boolean | false | 是否只读模式 |
22
+
23
+ ## 事件 (Events)
24
+
25
+ | 事件名 | 说明 | 回调参数 |
26
+ | update:modelValue | 更新绑定的 ID 集合 | (ids: Array) |
27
+ | update:data | 更新文件对象数组 | (files: Array) |
28
+
29
+ ## 功能特性
30
+
31
+ - **上传**: 调用后端接口 `/engine/web/file/upload` 上传文件。
32
+ - **下载**: 点击文件名可下载文件,调用 `/engine/web/file/download/{id}`。
33
+ - **删除**: 支持删除已上传文件。
34
+ - **进度**: 显示上传进度。
35
+ - **校验**: 校验文件数量、大小和类型。