@skyfox2000/webui 1.4.6 → 1.4.8

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 (48) hide show
  1. package/lib/TemplateFile.d.ts +1 -0
  2. package/lib/assets/modules/{baseLayout-CUZpKmC0.js → baseLayout-DIny49tw.js} +6 -6
  3. package/lib/assets/modules/{file-upload-BrTPBL29.js → file-upload-DHUBZlX4.js} +1 -1
  4. package/lib/assets/modules/{index-NDOzpgzV.js → index-BIAdOoSj.js} +10 -10
  5. package/lib/assets/modules/{index-BqoqvtEv.js → index-CEffEFtI.js} +1 -1
  6. package/lib/assets/modules/index-DyRjXb_O.js +114 -0
  7. package/lib/assets/modules/{menuTabs-BaZAmaXz.js → menuTabs-CCrFWIOl.js} +7 -7
  8. package/lib/assets/modules/{toolIcon-DHKszGtC.js → toolIcon-BGZR_aUI.js} +1 -1
  9. package/lib/assets/modules/{uploadList-DSN9t4r8.js → uploadList-CMXuGRWT.js} +163 -153
  10. package/lib/assets/modules/{uploadList-C5R2XD5x.js → uploadList-l4q5o65m.js} +150 -138
  11. package/lib/components/common/icon/helper.vue.d.ts +2 -0
  12. package/lib/components/content/dialog/index.vue.d.ts +1 -0
  13. package/lib/components/content/drawer/index.vue.d.ts +2 -0
  14. package/lib/components/content/tree/index.vue.d.ts +3 -14
  15. package/lib/components/form/upload/uploadList.vue.d.ts +3 -0
  16. package/lib/es/AceEditor/index.js +3 -3
  17. package/lib/es/BasicLayout/index.js +6 -6
  18. package/lib/es/Error403/index.js +1 -1
  19. package/lib/es/Error404/index.js +1 -1
  20. package/lib/es/ExcelForm/index.js +5 -5
  21. package/lib/es/MenuLayout/index.js +6 -6
  22. package/lib/es/TemplateFile/index.js +208 -0
  23. package/lib/es/UploadForm/index.js +6 -6
  24. package/lib/utils/tree.d.ts +9 -0
  25. package/lib/webui.css +1 -1
  26. package/lib/webui.es.js +514 -489
  27. package/package.json +8 -2
  28. package/src/components/common/icon/helper.vue +3 -1
  29. package/src/components/content/dialog/index.vue +15 -13
  30. package/src/components/content/dialog/templateFile.vue +259 -0
  31. package/src/components/content/dialog/uploadForm.vue +6 -14
  32. package/src/components/content/drawer/index.vue +29 -51
  33. package/src/components/content/tree/index.vue +26 -25
  34. package/src/components/form/select/index.vue +1 -1
  35. package/src/components/form/upload/uploadList.vue +66 -89
  36. package/src/utils/tree.ts +20 -0
  37. package/.eslintrc.js +0 -23
  38. package/.prettierrc +0 -11
  39. package/.vscode/settings.json +0 -25
  40. package/env.d.ts +0 -11
  41. package/index.html +0 -19
  42. package/lib/assets/modules/index-DP1u2P1k.js +0 -112
  43. package/plugins/vite-plugin-auto-generate-vue.ts +0 -105
  44. package/postcss.config.ts +0 -6
  45. package/tailwind.config.ts +0 -11
  46. package/tsconfig.json +0 -46
  47. package/vite.config.ts +0 -120
  48. package//344/273/243/347/240/201/350/247/204/350/214/203/345/217/212/351/243/216/346/240/274/346/214/207/345/215/227.md +0 -116
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skyfox2000/webui",
3
- "version": "1.4.6",
3
+ "version": "1.4.8",
4
4
  "description": "后台前端通用组件定义",
5
5
  "type": "module",
6
6
  "keywords": [],
@@ -24,6 +24,12 @@
24
24
  "types": "./lib/*.d.ts"
25
25
  }
26
26
  },
27
+ "files": [
28
+ "lib",
29
+ "src",
30
+ "package.json",
31
+ "README.md"
32
+ ],
27
33
  "scripts": {
28
34
  "build": "pnpm i && vue-tsc -b && vite build",
29
35
  "build:dts": "vue-tsc -b && vite-dts-declaration",
@@ -65,4 +71,4 @@
65
71
  "vite-plugin-dts": "^4.5.4",
66
72
  "vue-tsc": "^2.2.0"
67
73
  }
68
- }
74
+ }
@@ -2,11 +2,13 @@
2
2
  import { Popover } from 'ant-design-vue';
3
3
  import ToolIcon from './toolIcon.vue';
4
4
  import { useAttrs } from 'vue';
5
+ import { TooltipPlacement } from 'ant-design-vue/es/tooltip';
5
6
 
6
7
  defineProps<{
7
8
  text?: string;
8
9
  maxWidth?: string;
9
10
  size?: number;
11
+ placement?: TooltipPlacement;
10
12
  }>();
11
13
  // 关闭自动继承属性到根元素
12
14
  defineOptions({
@@ -16,7 +18,7 @@ const attrs = useAttrs(); // 手动获取 $attrs
16
18
  </script>
17
19
 
18
20
  <template>
19
- <Popover placement="topRight">
21
+ <Popover :placement="placement ?? 'topRight'">
20
22
  <template #content>
21
23
  <slot>
22
24
  <div class="text-[14px]" :class="[maxWidth]">
@@ -100,19 +100,21 @@ const doDialogClose = () => {
100
100
  <slot></slot>
101
101
  </div>
102
102
  <template #footer>
103
- <Space>
104
- <Button @click="doDialogClose" v-if="cancelText !== ''">
105
- {{ cancelText ?? '取消' }}
106
- </Button>
107
- <Button @click="doDialogSaveAs" v-if="saveAsText !== '' && editorCtrl?.saveAsBtnVisible !== false"
108
- type="primary" :loading="editorCtrl?.isFormSaving.value">
109
- {{ saveAsText ?? '另存为' }}
110
- </Button>
111
- <Button @click="doDialogSave" v-if="saveText !== '' && editorCtrl?.saveBtnVisible !== false" type="primary"
112
- :loading="editorCtrl?.isFormSaving.value">
113
- {{ saveText ?? '保存' }}
114
- </Button>
115
- </Space>
103
+ <slot name="footer">
104
+ <Space>
105
+ <Button @click="doDialogClose" v-if="cancelText !== ''">
106
+ {{ cancelText ?? '取消' }}
107
+ </Button>
108
+ <Button @click="doDialogSaveAs" v-if="saveAsText !== '' && editorCtrl?.saveAsBtnVisible !== false"
109
+ type="primary" :loading="editorCtrl?.isFormSaving.value">
110
+ {{ saveAsText ?? '另存为' }}
111
+ </Button>
112
+ <Button @click="doDialogSave" v-if="saveText !== '' && editorCtrl?.saveBtnVisible !== false"
113
+ type="primary" :loading="editorCtrl?.isFormSaving.value">
114
+ {{ saveText ?? '保存' }}
115
+ </Button>
116
+ </Space>
117
+ </slot>
116
118
  </template>
117
119
  </Modal>
118
120
  </template>
@@ -0,0 +1,259 @@
1
+ <script setup lang="ts">
2
+ import { watch, ref, onMounted, PropType } from 'vue';
3
+ import { Button } from '../../common';
4
+ import { Modal, Space } from 'ant-design-vue';
5
+ import { doQuery, EditorControl, MinioFile, UploadFile, UploadStatus } from '@/index';
6
+ import { AnyData, ApiResponse, IUrlInfo, ResStatus } from '@skyfox2000/fapi';
7
+ import UploadList from '../../form/upload/uploadList.vue';
8
+ import { AsyncUploader } from '@/utils/file-upload';
9
+
10
+ const props = defineProps({
11
+ /**
12
+ * 模板API域名配置
13
+ * 默认使用父级API
14
+ */
15
+ api: {
16
+ type: String as PropType<string>,
17
+ required: false,
18
+ },
19
+ /**
20
+ * 模板类别
21
+ */
22
+ templateType: {
23
+ type: String as PropType<string>,
24
+ required: true,
25
+ },
26
+ /**
27
+ * 文件后缀限制
28
+ */
29
+ fileExt: {
30
+ type: Array as PropType<string[]>,
31
+ required: false,
32
+ },
33
+ /**
34
+ * 弹窗控制器
35
+ */
36
+ uploadForm: {
37
+ type: Object as PropType<EditorControl<AnyData>>,
38
+ required: true,
39
+ },
40
+ /**
41
+ * 文件列表地址
42
+ */
43
+ fileListUrl: {
44
+ type: Object as PropType<IUrlInfo>,
45
+ required: false,
46
+ },
47
+ /**
48
+ * 上传地址和参数
49
+ */
50
+ uploadUrl: {
51
+ type: Object as PropType<IUrlInfo>,
52
+ required: false,
53
+ },
54
+ /**
55
+ * 下载地址和参数
56
+ */
57
+ downloadUrl: {
58
+ type: Object as PropType<IUrlInfo>,
59
+ required: false,
60
+ },
61
+ /**
62
+ * 删除地址和参数
63
+ */
64
+ deleteUrl: {
65
+ type: Object as PropType<IUrlInfo>,
66
+ required: false,
67
+ },
68
+ /**
69
+ * 是否显示删除按钮
70
+ */
71
+ showDelete: {
72
+ type: Boolean as PropType<boolean>,
73
+ required: false,
74
+ default: true,
75
+ },
76
+ /**
77
+ * 最多上传文件数
78
+ */
79
+ maxCount: {
80
+ type: Number as PropType<number>,
81
+ required: false,
82
+ },
83
+ });
84
+ /**
85
+ * minio桶名称template
86
+ *
87
+ * 子目录templateType
88
+ */
89
+ const fileListUrl = ref(props.fileListUrl || {
90
+ api: props.api,
91
+ authorize: true,
92
+ url: '/api/TemplateFileSrv/list',
93
+ });
94
+ const uploadUrl = ref(props.uploadUrl || {
95
+ api: props.api,
96
+ authorize: true,
97
+ url: '/api/TemplateFileSrv/upload',
98
+ });
99
+ const downloadUrl = ref(props.downloadUrl || {
100
+ api: props.api,
101
+ authorize: true,
102
+ url: '/api/TemplateFileSrv/download',
103
+ });
104
+ const deleteUrl = ref(props.deleteUrl || {
105
+ api: props.api,
106
+ authorize: true,
107
+ url: '/api/TemplateFileSrv/delete',
108
+ });
109
+
110
+ const uploadFormCtrl = props.uploadForm;
111
+ const open = ref<boolean>(false);
112
+
113
+ const fileList = ref<UploadFile[]>([]);
114
+ const emit = defineEmits<{
115
+ /**
116
+ * 显示预处理
117
+ */
118
+ 'before:file-list': [EditorControl<AnyData>, UploadFile[]];
119
+ /**
120
+ * 上传前预处理
121
+ */
122
+ 'before:upload': [UploadFile[]];
123
+ /**
124
+ * 上传结束,处理上传后的文件
125
+ */
126
+ 'after:upload': [boolean, UploadFile[]];
127
+ /**
128
+ * 上传进度
129
+ */
130
+ 'on:progress': [UploadFile];
131
+ }>();
132
+
133
+ watch(
134
+ () => uploadFormCtrl.visible.value,
135
+ () => {
136
+ open.value = uploadFormCtrl.visible.value;
137
+ },
138
+ );
139
+
140
+
141
+ /**
142
+ * 加载现有模板文件列表
143
+ */
144
+ const loadFileList = async () => {
145
+ const res: ApiResponse<MinioFile[]> | null = await doQuery<MinioFile[]>(props.uploadForm, {
146
+ urlKey: 'list',
147
+ url: fileListUrl.value,
148
+ params: {
149
+ Query: {
150
+ PrefixPath: props.templateType,
151
+ }
152
+ },
153
+ });
154
+ if (res?.status === ResStatus.SUCCESS && res.data) {
155
+ const files = res.data as MinioFile[];
156
+ const list = files.map((file) => {
157
+ const uploadFile: UploadFile = {
158
+ uid: file.Key,
159
+ size: file.Size,
160
+ name: file.FileName!,
161
+ status: UploadStatus.Online,
162
+ lastModified: file.UpdateTime ? new Date(file.UpdateTime).getTime() : 0,
163
+ lastModifiedDate: file.UpdateTime ? new Date(file.UpdateTime) : new Date(),
164
+ params: {},
165
+ minioFile: file,
166
+ }
167
+ return uploadFile;
168
+ })
169
+ emit('before:file-list', uploadFormCtrl, list);
170
+ fileList.value.push(...list);
171
+ }
172
+ };
173
+
174
+ const dialogSave = async () => {
175
+ emit('before:upload', fileList.value);
176
+ const uploader = new AsyncUploader(uploadUrl.value, 3);
177
+ await uploader.doUpload(
178
+ fileList.value,
179
+ uploadFormCtrl.isFormLoading,
180
+ true,
181
+ async (result, files) => {
182
+ emit('after:upload', result, files);
183
+ if (result) {
184
+ uploadFormCtrl.visible.value = false;
185
+ }
186
+ },
187
+ (file) => {
188
+ emit('on:progress', file);
189
+ },
190
+ );
191
+ };
192
+
193
+ onMounted(() => {
194
+ if (!fileListUrl.value.api) {
195
+ fileListUrl.value.api = uploadFormCtrl.page.api;
196
+ }
197
+ if (!uploadUrl.value.api) {
198
+ uploadUrl.value.api = uploadFormCtrl.page.api;
199
+ }
200
+ if (!downloadUrl.value.api) {
201
+ downloadUrl.value.api = uploadFormCtrl.page.api;
202
+ }
203
+ if (!deleteUrl.value.api) {
204
+ deleteUrl.value.api = uploadFormCtrl.page.api;
205
+ }
206
+ loadFileList();
207
+
208
+ open.value = uploadFormCtrl.visible.value;
209
+ });
210
+
211
+ const dialogClose = () => {
212
+ uploadFormCtrl.visible.value = false;
213
+ };
214
+ </script>
215
+ <template>
216
+ <Modal title="模板文件管理" v-model:open="open"
217
+ :wrapClassName="'modal mx-auto ' + ($attrs.width ? 'w-[' + $attrs.width + ']' : 'w-[500px]')"
218
+ @close="dialogClose">
219
+ <UploadList v-model:file-list="fileList" :parent-path="props.templateType" :upload-url="uploadUrl"
220
+ :download-url="downloadUrl" :delete-url="deleteUrl" :max-count="maxCount" :file-ext="fileExt"
221
+ :show-delete="showDelete" />
222
+ <template #footer>
223
+ <Space>
224
+ <Button @click="dialogClose">关闭</Button>
225
+ <Button @click="dialogSave" type="primary" :loading="uploadFormCtrl.isFormSaving.value"
226
+ :disabled="fileList.length === 0">
227
+ 上传保存
228
+ </Button>
229
+ </Space>
230
+ </template>
231
+ </Modal>
232
+ </template>
233
+ <style>
234
+ .modal {
235
+ .ant-modal-content {
236
+ padding: 16px;
237
+ }
238
+ }
239
+
240
+ .full-modal {
241
+ .ant-modal {
242
+ width: 100% !important;
243
+ max-width: 100%;
244
+ top: 0;
245
+ padding-bottom: 0;
246
+ margin: 0;
247
+ }
248
+
249
+ .ant-modal-content {
250
+ display: flex;
251
+ flex-direction: column;
252
+ height: calc(100vh);
253
+ }
254
+
255
+ .ant-modal-body {
256
+ flex: 1;
257
+ }
258
+ }
259
+ </style>
@@ -136,24 +136,16 @@ const dialogClose = () => {
136
136
  };
137
137
  </script>
138
138
  <template>
139
- <Modal
140
- title="文件上传"
141
- v-model:open="open"
142
- :wrapClassName="'modal mx-auto ' + ($attrs.width ? 'w-[' + $attrs.width + ']' : 'w-[430px]')"
143
- @close="dialogClose"
144
- >
145
- <UploadList
146
- v-model:file-list="fileList"
147
- :upload-url="uploadUrl!"
148
- :download-url="downloadUrl"
149
- :max-count="maxCount"
150
- :file-ext="fileExt"
151
- />
139
+ <Modal title="文件上传" v-model:open="open"
140
+ :wrapClassName="'modal mx-auto ' + ($attrs.width ? 'w-[' + $attrs.width + ']' : 'w-[500px]')"
141
+ @close="dialogClose">
142
+ <UploadList v-model:file-list="fileList" :upload-url="uploadUrl!" :download-url="downloadUrl"
143
+ :max-count="maxCount" :file-ext="fileExt" />
152
144
  <template #footer>
153
145
  <Space>
154
146
  <Button @click="dialogClose">取消</Button>
155
147
  <Button @click="dialogSave" type="primary" :loading="uploadFormCtrl.isFormSaving.value">
156
- 上传文件并保存
148
+ 上传保存
157
149
  </Button>
158
150
  </Space>
159
151
  </template>
@@ -74,65 +74,43 @@ const doDrawerClose = () => {
74
74
  };
75
75
  </script>
76
76
  <template>
77
- <Drawer
78
- v-model:open="open"
79
- :get-container="false"
80
- :closable="false"
81
- :header-style="{
82
- height: '40px',
83
- padding: '10px 6px 10px 16px',
84
- backgroundColor: token.colorBgLayout,
85
- }"
86
- :body-style="{
87
- padding: '10px 16px',
88
- }"
89
- :footer-style="{
90
- textAlign: 'right',
91
- }"
92
- :style="{
77
+ <Drawer v-model:open="open" :get-container="false" :closable="false" :header-style="{
78
+ height: '40px',
79
+ padding: '10px 6px 10px 16px',
80
+ backgroundColor: token.colorBgLayout,
81
+ }" :body-style="{
82
+ padding: '10px 16px',
83
+ }" :footer-style="{
84
+ textAlign: 'right',
85
+ }" :style="{
93
86
  position: 'absolute',
94
87
  boxShadow: 'rgba(0, 0, 0, 0.3) -2px 0px 8px',
95
- }"
96
- width="420px"
97
- @close="doDrawerClose"
98
- >
88
+ }" width="420px" @close="doDrawerClose">
99
89
  <template #extra>
100
- <div class="hover:bg-gray-200 w-[24px] h-[24px] rounded-md">
101
- <ToolIcon
102
- class="top-[-2px] left-[2px] w-6 h-6"
103
- icon="icon-new"
104
- :angle="45"
105
- fontsize="24px"
106
- clickable
107
- color="#666"
108
- :position="[0, 0]"
109
- @click="doDrawerClose"
110
- />
111
- </div>
90
+ <slot name="extra">
91
+ <div class="hover:bg-gray-200 w-[24px] h-[24px] rounded-md">
92
+ <ToolIcon class="top-[-2px] left-[2px] w-6 h-6" icon="icon-new" :angle="45" fontsize="24px" clickable
93
+ color="#666" :position="[0, 0]" @click="doDrawerClose" />
94
+ </div>
95
+ </slot>
112
96
  </template>
113
97
  <template #default>
114
98
  <slot></slot>
115
99
  </template>
116
100
  <template #footer>
117
- <Space>
118
- <Button @click="doDrawerClose" v-if="cancelText !== ''">{{ cancelText ?? '取消' }}</Button>
119
- <Button
120
- @click="doDrawerSaveAs"
121
- v-if="saveAsText !== '' && editorCtrl.saveAsBtnVisible !== false"
122
- type="primary"
123
- :loading="editorCtrl.isFormSaving.value"
124
- >
125
- {{ saveAsText ?? '另存为' }}
126
- </Button>
127
- <Button
128
- @click="doDrawerSave"
129
- v-if="saveText !== '' && editorCtrl.saveBtnVisible !== false"
130
- type="primary"
131
- :loading="editorCtrl.isFormSaving.value"
132
- >
133
- {{ saveText ?? '保存' }}
134
- </Button>
135
- </Space>
101
+ <slot name="footer">
102
+ <Space>
103
+ <Button @click="doDrawerClose" v-if="cancelText !== ''">{{ cancelText ?? '取消' }}</Button>
104
+ <Button @click="doDrawerSaveAs" v-if="saveAsText !== '' && editorCtrl.saveAsBtnVisible !== false"
105
+ type="primary" :loading="editorCtrl.isFormSaving.value">
106
+ {{ saveAsText ?? '另存为' }}
107
+ </Button>
108
+ <Button @click="doDrawerSave" v-if="saveText !== '' && editorCtrl.saveBtnVisible !== false"
109
+ type="primary" :loading="editorCtrl.isFormSaving.value">
110
+ {{ saveText ?? '保存' }}
111
+ </Button>
112
+ </Space>
113
+ </slot>
136
114
  </template>
137
115
  </Drawer>
138
116
  </template>
@@ -3,9 +3,8 @@ import { onMounted, ref, useAttrs, watch } from 'vue';
3
3
  import { Tree } from 'ant-design-vue';
4
4
  import { ToolIcon } from '../../common';
5
5
  import { TreeControl, TreeNode, queryTree } from '@/index';
6
- import { TreeDataNode } from 'ant-design-vue/es/vc-tree-select/interface';
7
- import { EventDataNode } from 'ant-design-vue/es/vc-tree/interface';
8
6
  import { fieldMapping } from '@skyfox2000/fapi';
7
+ import { findNodeByKey, TreeNodeInfo } from '@/utils/tree';
9
8
 
10
9
  /**
11
10
  * 组件属性定义
@@ -31,6 +30,7 @@ const attrs = useAttrs();
31
30
  const treeCtrl = props.treeCtrl;
32
31
  // 树节点数据
33
32
  const treeData = ref<TreeNode[]>([]);
33
+ // const treeRef = ref();
34
34
 
35
35
  // 监听树数据变化
36
36
  watch(
@@ -38,7 +38,26 @@ watch(
38
38
  (newVal) => {
39
39
  if (newVal) {
40
40
  treeData.value = treeCtrl.fieldMap ? fieldMapping(treeCtrl.fieldMap, newVal) : newVal;
41
- handleSelect(props.selectedKeys ?? []);
41
+ // 获取当前选中的节点
42
+ const selectedNode = findNodeByKey(treeData.value, selectedKeys.value[0]);
43
+
44
+ if (selectedNode) {
45
+ // 构建info对象
46
+ const info: TreeNodeInfo = {
47
+ event: 'select',
48
+ node: {
49
+ // 根据你的TreeNode结构构建node对象
50
+ key: selectedNode.key,
51
+ title: selectedNode.title,
52
+ checked: true,
53
+ dataRef: selectedNode
54
+ },
55
+ selected: true,
56
+ selectedNodes: [selectedNode]
57
+ };
58
+
59
+ handleSelect(selectedKeys.value, info);
60
+ }
42
61
  }
43
62
  },
44
63
  );
@@ -47,12 +66,7 @@ const emit = defineEmits<{
47
66
  (
48
67
  e: 'select',
49
68
  selectedKeys: (string | number)[],
50
- info?: {
51
- event: 'select';
52
- node: EventDataNode;
53
- selected: boolean;
54
- selectedNodes: TreeDataNode[];
55
- },
69
+ info?: TreeNodeInfo,
56
70
  ): void;
57
71
  (e: 'update:selectedKeys', value: (string | number)[]): void;
58
72
  }>();
@@ -81,12 +95,7 @@ watch(
81
95
  // 值变化事件
82
96
  const handleSelect = (
83
97
  keys: (string | number)[],
84
- info?: {
85
- event: 'select';
86
- node: EventDataNode;
87
- selected: boolean;
88
- selectedNodes: TreeDataNode[];
89
- },
98
+ info?: TreeNodeInfo,
90
99
  ) => {
91
100
  if (keys.length === 0) {
92
101
  keys.push(...selectedKeys.value);
@@ -118,16 +127,8 @@ onMounted(() => {
118
127
  </script>
119
128
 
120
129
  <template>
121
- <Tree
122
- class="w-full"
123
- :show-line="true"
124
- :tree-data="treeData"
125
- v-model:expanded-keys="expandedKeys"
126
- :selected-keys="selectedKeys"
127
- :loading="treeCtrl.isTreeLoading"
128
- @select="handleSelect"
129
- v-bind="attrs"
130
- >
130
+ <Tree class="w-full" :show-line="true" :tree-data="treeData" v-model:expanded-keys="expandedKeys"
131
+ :selected-keys="selectedKeys" :loading="treeCtrl.isTreeLoading" @select="handleSelect" v-bind="attrs">
131
132
  <template #title="{ key, label, icon }">
132
133
  <slot name="title" :label="label" :key="key" :icon="icon">
133
134
  <div class="flex items-center gap-1">
@@ -89,7 +89,7 @@ const onChanged = (value: any) => {
89
89
  innerValue.value = value;
90
90
  emit('update:labels', labels);
91
91
  emit('update:label', labels.join(";"));
92
- emit('change', value);
92
+ emit('change', value, selectedOptions);
93
93
 
94
94
  if (errInfo?.value.errClass && editorCtrl) {
95
95
  /// 重新开始验证