el-plus-crud 0.0.74 → 0.0.76

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 (31) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/el-plus-crud.mjs +10 -10
  3. package/example/App.vue +69 -68
  4. package/lib/components/el-plus-form/ElPlusForm.vue +2 -1
  5. package/lib/components/el-plus-form/ElPlusFormDialog.vue +90 -89
  6. package/lib/components/el-plus-form/ElPlusFormGroup.vue +2 -1
  7. package/lib/components/el-plus-form/components/ElPlusFormBtn.vue +2 -1
  8. package/lib/components/el-plus-form/components/ElPlusFormBtns.vue +2 -1
  9. package/lib/components/el-plus-form/components/ElPlusFormFile.vue +49 -48
  10. package/lib/components/el-plus-form/components/ElPlusFormInput.vue +64 -63
  11. package/lib/components/el-plus-form/components/ElPlusFormLink.vue +284 -283
  12. package/lib/components/el-plus-form/components/ElPlusFormLkuser.vue +492 -491
  13. package/lib/components/el-plus-form/components/ElPlusFormNumber.vue +149 -148
  14. package/lib/components/el-plus-form/components/ElPlusFormPassword.vue +46 -45
  15. package/lib/components/el-plus-form/components/ElPlusFormQuickInput.vue +98 -97
  16. package/lib/components/el-plus-form/components/ElPlusFormSelect.vue +164 -163
  17. package/lib/components/el-plus-form/components/ElPlusFormTextarea.vue +52 -51
  18. package/lib/components/el-plus-form/components/ElPlusFormUpbtn.vue +146 -145
  19. package/lib/components/el-plus-form/components/ElPlusFormUpload.vue +371 -370
  20. package/lib/components/el-plus-form/components/components/file-icons/FileIcons.vue +137 -136
  21. package/lib/components/el-plus-table/ElPlusTable.vue +2 -1
  22. package/lib/components/el-plus-table/components/columnItem.vue +214 -213
  23. package/lib/components/el-plus-table/components/header.vue +2 -1
  24. package/lib/components/el-plus-table/components/settingColumn.vue +180 -179
  25. package/lib/components/el-plus-table/util/index.ts +148 -148
  26. package/lib/config/index.ts +32 -32
  27. package/lib/index.ts +52 -52
  28. package/package-lock.json +2 -2
  29. package/package.json +1 -1
  30. package/types/global.d.ts +13 -13
  31. package/types/{formList.d.ts → index.d.ts} +1 -0
@@ -1,491 +1,492 @@
1
- <template>
2
- <div class="el-plus-form-link-user">
3
- <el-select ref="selectRef" style="width: 100%" :class="desc.class" :style="desc.style" v-bind="topAttrs" :teleported="false" :disabled="disabled" :loading="loading" :modelValue="values" @visible-change="handelVisibleChange" @clear="handelClear">
4
- <el-option v-for="option in options" :key="option.value" v-bind="option" />
5
- </el-select>
6
- <!-- 弹框 -->
7
- <el-dialog :width="desc.dialogWidth || '900px'" :title="desc.placeholder || '选择' + desc.label" draggable :closeOnClickModal="false" showCancel v-model="isShowDialog" append-to-body destroy-on-close>
8
- <div style="width: 100%" class="form-link-user-dialog">
9
- <div class="panel-left">
10
- <!-- 搜索 -->
11
- <el-select style="width: 300px" placeholder="输入用户名进行搜索" v-bind="selectAttrs" @change="handelSelectChange">
12
- <el-option v-for="option in selectOptions" :key="option.value" v-bind="option" />
13
- </el-select>
14
- <el-divider></el-divider>
15
- <div class="dept-breadcrumb">
16
- <el-breadcrumb separator="/">
17
- <el-breadcrumb-item @click="goIndex(-1)">组织架构</el-breadcrumb-item>
18
- <el-breadcrumb-item v-for="(item, i) in deptTreeItems" :key="i" @click="goIndex(i)">
19
- {{ item.label }}
20
- </el-breadcrumb-item>
21
- </el-breadcrumb>
22
- </div>
23
- <!-- 组织机构列表 -->
24
- <el-table ref="multipleTableRef" :data="tableData" style="width: 100%; height: 500px" max-height="500px" @select="handelTableSelect" @select-all="handelTableSelectAll">
25
- <el-table-column type="selection" width="55" :selectable="handelTableSelectable" />
26
- <el-table-column label="组织/部门/人员" prop="label">
27
- <template #default="{ row }">
28
- <div style="display: flex; align-items: center">
29
- <el-icon style="margin-right: 5px">
30
- <Share v-if="row.type === 2" />
31
- <UserFilled v-else />
32
- </el-icon>
33
- {{ row.label }}
34
- </div>
35
- </template>
36
- </el-table-column>
37
- <el-table-column label="操作" width="80">
38
- <template #default="{ row, $index }">
39
- <el-button v-if="row.type === 2" :disabled="selectUser.some((item) => item.value === row.value)" type="primary" text plain @click="goInto(row, $index)">进入</el-button>
40
- </template>
41
- </el-table-column>
42
- </el-table>
43
- </div>
44
- <div class="panel-right">
45
- <div class="right-title">已选中项:</div>
46
- <el-scrollbar height="480px" class="tag-list">
47
- <el-tag style="margin-right: 10px; margin-bottom: 10px" v-for="tag in selectUser" :key="tag.value" closable @close="() => handelTagRemove(tag)">
48
- <el-icon style="margin-right: 5px">
49
- <Share v-if="tag.type === 2" />
50
- <UserFilled v-else />
51
- </el-icon>
52
- {{ tag.label }}
53
- </el-tag>
54
- </el-scrollbar>
55
- <div class="btn-panel">
56
- <el-button @click="cancel">取消</el-button>
57
- <el-button type="primary" @click="submit">确定</el-button>
58
- </div>
59
- </div>
60
- </div>
61
- </el-dialog>
62
- </div>
63
- </template>
64
- <script lang="ts">
65
- export default {
66
- name: 'ElPlusFormLkuser',
67
- inheritAttrs: false,
68
- typeName: 'lkuser',
69
- customOptions: {}
70
- }
71
- </script>
72
- <script lang="ts" setup>
73
- import { ref, reactive, nextTick, watch, onMounted, computed, inject, onBeforeMount, useAttrs } from 'vue'
74
- import { Share, UserFilled } from '@element-plus/icons-vue'
75
- import { cloneDeep } from 'lodash'
76
- import { getAttrs } from '../mixins'
77
- import { ICRUDConfig } from 'types/formList'
78
-
79
- const globalData = inject('globalData') as any
80
- const defaultConf = inject('defaultConf') as ICRUDConfig
81
-
82
- interface ILinkItem {
83
- // 选中类型: 1,用户、 2:部门
84
- type: 1 | 2
85
- label: string
86
- value: string
87
- }
88
-
89
- const props = defineProps<{
90
- modelValue?: []
91
- field: string
92
- loading?: boolean
93
- desc: { [key: string]: any }
94
- formData: { [key: string]: any }
95
- disabled?: boolean
96
- }>()
97
-
98
- const onEvents = ref(getEvents(props))
99
-
100
- const emits = defineEmits(['update:modelValue', 'change', 'input', 'validateThis'])
101
-
102
- const currentValue = ref((props.modelValue || []) as any[])
103
- emits('update:modelValue', currentValue)
104
-
105
- // 顶部的select
106
- const selectRef = ref()
107
- const values = reactive([] as Array<string>)
108
- const options = reactive([] as Array<ILinkItem>)
109
- const topAttrs = reactive({
110
- multiple: true,
111
- size: props.desc.size,
112
- collapseTags: false,
113
- collapseTagsTooltip: false,
114
- clearable: true
115
- })
116
-
117
- const isShowDialog = ref(false)
118
-
119
- // 存储的值
120
- const selectUser = reactive([] as Array<ILinkItem>)
121
-
122
- // 搜索框
123
- const selectOptions = reactive([] as any[])
124
- const selectAttrs = ref({})
125
-
126
- /**
127
- * 处理自定义请求
128
- * @param param
129
- */
130
- async function remoteMethod(query: string) {
131
- selectOptions.splice(0, selectOptions.length, ...(await selectRemote(query)))
132
- }
133
-
134
- // 组织架构数据
135
- const deptTreeIndex = ref([] as number[])
136
- const deptTreeItems = ref([] as any[])
137
- // 用户数据列表
138
- const tableUserData = ref([] as any[])
139
-
140
- // 机构列表数据
141
- const multipleTableRef = ref()
142
- const tableData = computed(() => {
143
- const tempList = [] as ILinkItem[]
144
- // 遍历组织架构数据
145
- let tempData = cloneDeep(globalData[defaultConf.form?.linkUser?.deptListKey || ''])
146
- if (deptTreeIndex.value && deptTreeIndex.value.length > 0) {
147
- deptTreeIndex.value.map((item) => {
148
- tempData = tempData[item].children || []
149
- })
150
- }
151
- tempData.map((item: any) => tempList.push({ type: 2, label: item.name, value: item.id }))
152
- // 遍历用户数据
153
- tableUserData.value.map((item) => tempList.push({ type: 1, label: item.nickname, value: item.userId }))
154
-
155
- // 这里默认选中
156
- nextTick(() => {
157
- setTimeout(() => {
158
- tempList.map((item) => {
159
- multipleTableRef.value?.toggleRowSelection(
160
- item,
161
- selectUser.some((i) => i.value === item.value)
162
- )
163
- })
164
- }, 10)
165
- })
166
- return tempList
167
- })
168
-
169
- /**
170
- * 获取事件
171
- * @returns
172
- */
173
- function getEvents(props: any) {
174
- const tempOn = {} as any
175
- if (props.desc?.on) {
176
- Object.keys(props.desc.on).map((key: string) => {
177
- tempOn[key] = (val: any) => {
178
- props.desc.on[key](props.formData, props.rowIndex, val)
179
- }
180
- })
181
- }
182
- return tempOn
183
- }
184
-
185
- /**
186
- * 处理点击事件
187
- * @param val
188
- */
189
- function handelVisibleChange(val: any) {
190
- if (val) {
191
- selectRef.value.blur()
192
- isShowDialog.value = true
193
- }
194
- }
195
-
196
- /**
197
- * 处理清空选项
198
- */
199
- function handelClear() {
200
- selectUser.splice(0, selectUser.length)
201
- // 清空列表选中项
202
- tableData.value.map((item) => {
203
- multipleTableRef.value?.toggleRowSelection(
204
- item,
205
- selectUser.some((i) => i.value === item.value)
206
- )
207
- })
208
- submit()
209
- }
210
-
211
- /**
212
- * 处理自定义请求
213
- * @param param
214
- */
215
-
216
- /**
217
- * 处理下拉框选中
218
- * @param val
219
- */
220
- function handelSelectChange(val: any) {
221
- addAndRemove({ ...selectOptions.find((item) => item.value === val), type: 1 })
222
- }
223
-
224
- /**
225
- * 远程查询用户列表
226
- * @param nickname
227
- */
228
- async function selectRemote(nickname: string) {
229
- if (nickname.length > 0) {
230
- return ((await defaultConf.form?.linkUser?.getUserList({ nickname, current: 1, size: 10, enabled: 1 })) as any).records?.map((item: any) => {
231
- return { value: item.userId, label: item.nickname }
232
- })
233
- }
234
- return []
235
- }
236
-
237
- /**
238
- * 进入下级组织架构
239
- * @param item
240
- */
241
- async function goInto(item: ILinkItem, index: number) {
242
- // 查询机构用户
243
- tableUserData.value = (await defaultConf.form?.linkUser?.getUserList({ deptId: item.value, size: 999 })).records as any[]
244
- deptTreeIndex.value.push(index)
245
- deptTreeItems.value.push(item)
246
- }
247
-
248
- /**
249
- * 返回上级组织架构
250
- * @param index
251
- */
252
- async function goIndex(index: number) {
253
- // 查询机构用户
254
- tableUserData.value = index >= 0 ? ((await defaultConf.form?.linkUser?.getUserList({ deptId: deptTreeItems.value[index].value, size: 999 })).records as any[]) : []
255
- deptTreeIndex.value.splice(index + 1)
256
- deptTreeItems.value.splice(index + 1)
257
- }
258
-
259
- /**
260
- * 处理当前行是否能够被选中
261
- * @param row
262
- */
263
- function handelTableSelectable(row: any) {
264
- if (props.desc.onlyUser) {
265
- return row.type === 1
266
- }
267
- return true
268
- }
269
-
270
- /**
271
- * 处理单个选中的情况
272
- * @param selection
273
- * @param row
274
- */
275
- function handelTableSelect(selection: ILinkItem[], item: ILinkItem) {
276
- addAndRemove(item, !selection.some((i) => i.value === item.value))
277
- }
278
-
279
- /**
280
- * 处理全选
281
- * @param selection
282
- * @param row
283
- */
284
- function handelTableSelectAll(selection: ILinkItem[]) {
285
- const isRemove = !(selection && selection.length > 0)
286
- tableData.value.map((item) => {
287
- if (!props.desc.onlyUser || (props.desc.onlyUser && item.type === 1)) {
288
- addAndRemove(item, isRemove)
289
- }
290
- })
291
- }
292
-
293
- /**
294
- * 处理删除标签
295
- * @param item
296
- */
297
- function handelTagRemove(item: ILinkItem) {
298
- if (tableData.value.some((i) => i.value === item.value)) {
299
- multipleTableRef.value?.toggleRowSelection(item, false)
300
- }
301
- addAndRemove(item, true)
302
- }
303
-
304
- /**
305
- * 添加或者移除
306
- * @param item
307
- */
308
- function addAndRemove(item: ILinkItem, isRemove: boolean = false) {
309
- // 校验是否已经有了
310
- const index = selectUser.findIndex((i) => i.value === item.value)
311
- if (isRemove) {
312
- if (index >= 0) {
313
- selectUser.splice(index, 1)
314
- }
315
- } else {
316
- if (index < 0) {
317
- selectUser.push(item)
318
- }
319
- }
320
- }
321
-
322
- /**
323
- * 取消按钮
324
- */
325
- function cancel() {
326
- isShowDialog.value = false
327
- }
328
-
329
- /**
330
- * 确认按钮
331
- */
332
- function submit() {
333
- options.splice(0, options.length, ...selectUser)
334
- const userIds = [] as string[]
335
- const deptIds = [] as string[]
336
- const userNames = [] as string[]
337
- const deptNames = [] as string[]
338
- values.splice(0, values.length)
339
-
340
- // 遍历数据
341
- selectUser.map((item) => {
342
- values.push(item.value)
343
- if (item.type === 1) {
344
- userIds.push(item.value)
345
- userNames.push(item.label)
346
- } else {
347
- deptIds.push(item.value)
348
- deptNames.push(item.label)
349
- }
350
- })
351
-
352
- isShowDialog.value = false
353
- currentValue.value = selectUser.length > 0 ? [userIds, deptIds, userNames, deptNames] : []
354
- // 触发外部change事件
355
- if (onEvents.value.change) {
356
- onEvents.value.change(props.formData, null, currentValue.value)
357
- }
358
- emits('validateThis')
359
- }
360
-
361
- /**
362
- * 初始化选中数据
363
- */
364
- function initSelectData() {
365
- const tempList = [] as Array<ILinkItem>
366
- if (props.modelValue) {
367
- let [userIds, deptIds, userNames, deptNames] = props.modelValue as any
368
- if (deptIds && deptNames && deptIds.length === deptNames.length) {
369
- deptIds.map((id: string, i: number) => {
370
- tempList.push({ type: 2, value: id, label: deptNames[i] })
371
- })
372
- }
373
- if (userIds && userNames && userIds.length === userNames.length) {
374
- userIds.map((id: string, i: number) => {
375
- tempList.push({ type: 1, value: id, label: userNames[i] })
376
- })
377
- }
378
- }
379
- return tempList
380
- }
381
-
382
- /**
383
- * 初始化选中Id
384
- */
385
- function initSelectIds() {
386
- const tempList = [] as Array<string>
387
- if (props.modelValue) {
388
- let [userIds, deptIds] = props.modelValue as any
389
- tempList.push(...(deptIds || []))
390
- tempList.push(...(userIds || []))
391
- }
392
- return tempList
393
- }
394
-
395
- /**
396
- * 初始化数据
397
- */
398
- function init() {
399
- selectUser.splice(0, selectUser.length, ...initSelectData())
400
- options.splice(0, options.length, ...initSelectData())
401
- values.splice(0, values.length, ...initSelectIds())
402
- }
403
-
404
- onBeforeMount(async () => {
405
- // // 如果没有配置,则抛出一个警告
406
- selectAttrs.value = await getAttrs(props, {
407
- remote: true,
408
- filterable: true,
409
- remoteShowSuffix: true,
410
- loadingText: '远程查询中...',
411
- remoteMethod: remoteMethod,
412
- ...useAttrs()
413
- })
414
- })
415
-
416
- watch(
417
- () => props.modelValue,
418
- () => init(),
419
- { deep: true }
420
- )
421
-
422
- onMounted(async () => {
423
- init()
424
- })
425
- </script>
426
- <style lang="scss" scoped>
427
- .el-plus-form-link-user {
428
- width: 100%;
429
-
430
- .items-panel {
431
- :deep(.el-input__inner) {
432
- cursor: pointer;
433
- }
434
- }
435
-
436
- :deep(.el-tag__close) {
437
- display: none !important;
438
- }
439
- }
440
- </style>
441
- <style lang="scss">
442
- .form-link-user-dialog {
443
- width: 100%;
444
- display: flex;
445
- box-sizing: border-box;
446
-
447
- .panel-left {
448
- width: 60%;
449
- display: flex;
450
- flex-direction: column;
451
-
452
- .dept-breadcrumb {
453
- width: 100%;
454
- padding: 0 10px;
455
- margin-bottom: 20px;
456
- cursor: pointer;
457
- }
458
- }
459
-
460
- .panel-right {
461
- width: 40%;
462
- margin-left: 20px;
463
- border-left: 1px var(--el-border-color) var(--el-border-style);
464
- padding: 20px;
465
- display: flex;
466
- overflow: hidden;
467
- flex-direction: column;
468
-
469
- .right-title {
470
- width: 100%;
471
- font-size: 14px;
472
- color: #999999;
473
- margin-bottom: 20px;
474
- }
475
-
476
- .tag-list {
477
- width: 100%;
478
- flex: 1;
479
- overflow-y: hidden;
480
- }
481
-
482
- .btn-panel {
483
- width: 100%;
484
- min-height: 50px;
485
- padding-top: 10px;
486
- display: flex;
487
- justify-content: center;
488
- }
489
- }
490
- }
491
- </style>
1
+ <template>
2
+ <div class="el-plus-form-link-user">
3
+ <el-select ref="selectRef" style="width: 100%" :class="desc.class" :style="desc.style" v-bind="topAttrs" :teleported="false" :disabled="disabled" :loading="loading" :modelValue="values" @visible-change="handelVisibleChange" @clear="handelClear">
4
+ <el-option v-for="option in options" :key="option.value" v-bind="option" />
5
+ </el-select>
6
+ <!-- 弹框 -->
7
+ <el-dialog :width="desc.dialogWidth || '900px'" :title="desc.placeholder || '选择' + desc.label" draggable :closeOnClickModal="false" showCancel v-model="isShowDialog" append-to-body destroy-on-close>
8
+ <div style="width: 100%" class="form-link-user-dialog">
9
+ <div class="panel-left">
10
+ <!-- 搜索 -->
11
+ <el-select style="width: 300px" placeholder="输入用户名进行搜索" v-bind="selectAttrs" @change="handelSelectChange">
12
+ <el-option v-for="option in selectOptions" :key="option.value" v-bind="option" />
13
+ </el-select>
14
+ <el-divider></el-divider>
15
+ <div class="dept-breadcrumb">
16
+ <el-breadcrumb separator="/">
17
+ <el-breadcrumb-item @click="goIndex(-1)">组织架构</el-breadcrumb-item>
18
+ <el-breadcrumb-item v-for="(item, i) in deptTreeItems" :key="i" @click="goIndex(i)">
19
+ {{ item.label }}
20
+ </el-breadcrumb-item>
21
+ </el-breadcrumb>
22
+ </div>
23
+ <!-- 组织机构列表 -->
24
+ <el-table ref="multipleTableRef" :data="tableData" style="width: 100%; height: 500px" max-height="500px" @select="handelTableSelect" @select-all="handelTableSelectAll">
25
+ <el-table-column type="selection" width="55" :selectable="handelTableSelectable" />
26
+ <el-table-column label="组织/部门/人员" prop="label">
27
+ <template #default="{ row }">
28
+ <div style="display: flex; align-items: center">
29
+ <el-icon style="margin-right: 5px">
30
+ <Share v-if="row.type === 2" />
31
+ <UserFilled v-else />
32
+ </el-icon>
33
+ {{ row.label }}
34
+ </div>
35
+ </template>
36
+ </el-table-column>
37
+ <el-table-column label="操作" width="80">
38
+ <template #default="{ row, $index }">
39
+ <el-button v-if="row.type === 2" :disabled="selectUser.some((item) => item.value === row.value)" type="primary" text plain @click="goInto(row, $index)">进入</el-button>
40
+ </template>
41
+ </el-table-column>
42
+ </el-table>
43
+ </div>
44
+ <div class="panel-right">
45
+ <div class="right-title">已选中项:</div>
46
+ <el-scrollbar height="480px" class="tag-list">
47
+ <el-tag style="margin-right: 10px; margin-bottom: 10px" v-for="tag in selectUser" :key="tag.value" closable @close="() => handelTagRemove(tag)">
48
+ <el-icon style="margin-right: 5px">
49
+ <Share v-if="tag.type === 2" />
50
+ <UserFilled v-else />
51
+ </el-icon>
52
+ {{ tag.label }}
53
+ </el-tag>
54
+ </el-scrollbar>
55
+ <div class="btn-panel">
56
+ <el-button @click="cancel">取消</el-button>
57
+ <el-button type="primary" @click="submit">确定</el-button>
58
+ </div>
59
+ </div>
60
+ </div>
61
+ </el-dialog>
62
+ </div>
63
+ </template>
64
+ <script lang="ts">
65
+ export default {
66
+ name: 'ElPlusFormLkuser',
67
+ inheritAttrs: false,
68
+ typeName: 'lkuser',
69
+ customOptions: {}
70
+ }
71
+ </script>
72
+ <script lang="ts" setup>
73
+ import { ref, reactive, nextTick, watch, onMounted, computed, inject, onBeforeMount, useAttrs } from 'vue'
74
+ import { Share, UserFilled } from '@element-plus/icons-vue'
75
+ import { cloneDeep } from 'lodash'
76
+ import { getAttrs } from '../mixins'
77
+ import { ICRUDConfig } from 'types'
78
+
79
+ const globalData = inject('globalData') as any
80
+ const defaultConf = inject('defaultConf') as ICRUDConfig
81
+
82
+ interface ILinkItem {
83
+ // 选中类型: 1,用户、 2:部门
84
+ type: 1 | 2
85
+ label: string
86
+ value: string
87
+ }
88
+
89
+ const props = defineProps<{
90
+ modelValue?: []
91
+ field: string
92
+ loading?: boolean
93
+ desc: { [key: string]: any }
94
+ formData: { [key: string]: any }
95
+ disabled?: boolean
96
+ }>()
97
+
98
+ const onEvents = ref(getEvents(props))
99
+
100
+ const emits = defineEmits(['update:modelValue', 'change', 'input', 'validateThis'])
101
+
102
+ const currentValue = ref((props.modelValue || []) as any[])
103
+ emits('update:modelValue', currentValue)
104
+
105
+ // 顶部的select
106
+ const selectRef = ref()
107
+ const values = reactive([] as Array<string>)
108
+ const options = reactive([] as Array<ILinkItem>)
109
+ const topAttrs = reactive({
110
+ multiple: true,
111
+ size: props.desc.size,
112
+ collapseTags: false,
113
+ collapseTagsTooltip: false,
114
+ clearable: true
115
+ })
116
+
117
+ const isShowDialog = ref(false)
118
+
119
+ // 存储的值
120
+ const selectUser = reactive([] as Array<ILinkItem>)
121
+
122
+ // 搜索框
123
+ const selectOptions = reactive([] as any[])
124
+ const selectAttrs = ref({})
125
+
126
+ /**
127
+ * 处理自定义请求
128
+ * @param param
129
+ */
130
+ async function remoteMethod(query: string) {
131
+ selectOptions.splice(0, selectOptions.length, ...(await selectRemote(query)))
132
+ }
133
+
134
+ // 组织架构数据
135
+ const deptTreeIndex = ref([] as number[])
136
+ const deptTreeItems = ref([] as any[])
137
+ // 用户数据列表
138
+ const tableUserData = ref([] as any[])
139
+
140
+ // 机构列表数据
141
+ const multipleTableRef = ref()
142
+ const tableData = computed(() => {
143
+ const tempList = [] as ILinkItem[]
144
+ // 遍历组织架构数据
145
+ let tempData = cloneDeep(globalData[defaultConf.form?.linkUser?.deptListKey || ''])
146
+ if (deptTreeIndex.value && deptTreeIndex.value.length > 0) {
147
+ deptTreeIndex.value.map((item) => {
148
+ tempData = tempData[item].children || []
149
+ })
150
+ }
151
+ tempData.map((item: any) => tempList.push({ type: 2, label: item.name, value: item.id }))
152
+ // 遍历用户数据
153
+ tableUserData.value.map((item) => tempList.push({ type: 1, label: item.nickname, value: item.userId }))
154
+
155
+ // 这里默认选中
156
+ nextTick(() => {
157
+ setTimeout(() => {
158
+ tempList.map((item) => {
159
+ multipleTableRef.value?.toggleRowSelection(
160
+ item,
161
+ selectUser.some((i) => i.value === item.value)
162
+ )
163
+ })
164
+ }, 10)
165
+ })
166
+ return tempList
167
+ })
168
+
169
+ /**
170
+ * 获取事件
171
+ * @returns
172
+ */
173
+ function getEvents(props: any) {
174
+ const tempOn = {} as any
175
+ if (props.desc?.on) {
176
+ Object.keys(props.desc.on).map((key: string) => {
177
+ tempOn[key] = (val: any) => {
178
+ props.desc.on[key](props.formData, props.rowIndex, val)
179
+ }
180
+ })
181
+ }
182
+ return tempOn
183
+ }
184
+
185
+ /**
186
+ * 处理点击事件
187
+ * @param val
188
+ */
189
+ function handelVisibleChange(val: any) {
190
+ if (val) {
191
+ selectRef.value.blur()
192
+ isShowDialog.value = true
193
+ }
194
+ }
195
+
196
+ /**
197
+ * 处理清空选项
198
+ */
199
+ function handelClear() {
200
+ selectUser.splice(0, selectUser.length)
201
+ // 清空列表选中项
202
+ tableData.value.map((item) => {
203
+ multipleTableRef.value?.toggleRowSelection(
204
+ item,
205
+ selectUser.some((i) => i.value === item.value)
206
+ )
207
+ })
208
+ submit()
209
+ }
210
+
211
+ /**
212
+ * 处理自定义请求
213
+ * @param param
214
+ */
215
+
216
+ /**
217
+ * 处理下拉框选中
218
+ * @param val
219
+ */
220
+ function handelSelectChange(val: any) {
221
+ addAndRemove({ ...selectOptions.find((item) => item.value === val), type: 1 })
222
+ }
223
+
224
+ /**
225
+ * 远程查询用户列表
226
+ * @param nickname
227
+ */
228
+ async function selectRemote(nickname: string) {
229
+ if (nickname.length > 0) {
230
+ return ((await defaultConf.form?.linkUser?.getUserList({ nickname, current: 1, size: 10, enabled: 1 })) as any).records?.map((item: any) => {
231
+ return { value: item.userId, label: item.nickname }
232
+ })
233
+ }
234
+ return []
235
+ }
236
+
237
+ /**
238
+ * 进入下级组织架构
239
+ * @param item
240
+ */
241
+ async function goInto(item: ILinkItem, index: number) {
242
+ // 查询机构用户
243
+ tableUserData.value = (await defaultConf.form?.linkUser?.getUserList({ deptId: item.value, size: 999 })).records as any[]
244
+ deptTreeIndex.value.push(index)
245
+ deptTreeItems.value.push(item)
246
+ }
247
+
248
+ /**
249
+ * 返回上级组织架构
250
+ * @param index
251
+ */
252
+ async function goIndex(index: number) {
253
+ // 查询机构用户
254
+ tableUserData.value = index >= 0 ? ((await defaultConf.form?.linkUser?.getUserList({ deptId: deptTreeItems.value[index].value, size: 999 })).records as any[]) : []
255
+ deptTreeIndex.value.splice(index + 1)
256
+ deptTreeItems.value.splice(index + 1)
257
+ }
258
+
259
+ /**
260
+ * 处理当前行是否能够被选中
261
+ * @param row
262
+ */
263
+ function handelTableSelectable(row: any) {
264
+ if (props.desc.onlyUser) {
265
+ return row.type === 1
266
+ }
267
+ return true
268
+ }
269
+
270
+ /**
271
+ * 处理单个选中的情况
272
+ * @param selection
273
+ * @param row
274
+ */
275
+ function handelTableSelect(selection: ILinkItem[], item: ILinkItem) {
276
+ addAndRemove(item, !selection.some((i) => i.value === item.value))
277
+ }
278
+
279
+ /**
280
+ * 处理全选
281
+ * @param selection
282
+ * @param row
283
+ */
284
+ function handelTableSelectAll(selection: ILinkItem[]) {
285
+ const isRemove = !(selection && selection.length > 0)
286
+ tableData.value.map((item) => {
287
+ if (!props.desc.onlyUser || (props.desc.onlyUser && item.type === 1)) {
288
+ addAndRemove(item, isRemove)
289
+ }
290
+ })
291
+ }
292
+
293
+ /**
294
+ * 处理删除标签
295
+ * @param item
296
+ */
297
+ function handelTagRemove(item: ILinkItem) {
298
+ if (tableData.value.some((i) => i.value === item.value)) {
299
+ multipleTableRef.value?.toggleRowSelection(item, false)
300
+ }
301
+ addAndRemove(item, true)
302
+ }
303
+
304
+ /**
305
+ * 添加或者移除
306
+ * @param item
307
+ */
308
+ function addAndRemove(item: ILinkItem, isRemove: boolean = false) {
309
+ // 校验是否已经有了
310
+ const index = selectUser.findIndex((i) => i.value === item.value)
311
+ if (isRemove) {
312
+ if (index >= 0) {
313
+ selectUser.splice(index, 1)
314
+ }
315
+ } else {
316
+ if (index < 0) {
317
+ selectUser.push(item)
318
+ }
319
+ }
320
+ }
321
+
322
+ /**
323
+ * 取消按钮
324
+ */
325
+ function cancel() {
326
+ isShowDialog.value = false
327
+ }
328
+
329
+ /**
330
+ * 确认按钮
331
+ */
332
+ function submit() {
333
+ options.splice(0, options.length, ...selectUser)
334
+ const userIds = [] as string[]
335
+ const deptIds = [] as string[]
336
+ const userNames = [] as string[]
337
+ const deptNames = [] as string[]
338
+ values.splice(0, values.length)
339
+
340
+ // 遍历数据
341
+ selectUser.map((item) => {
342
+ values.push(item.value)
343
+ if (item.type === 1) {
344
+ userIds.push(item.value)
345
+ userNames.push(item.label)
346
+ } else {
347
+ deptIds.push(item.value)
348
+ deptNames.push(item.label)
349
+ }
350
+ })
351
+
352
+ isShowDialog.value = false
353
+ currentValue.value = selectUser.length > 0 ? [userIds, deptIds, userNames, deptNames] : []
354
+ // 触发外部change事件
355
+ if (onEvents.value.change) {
356
+ onEvents.value.change(props.formData, null, currentValue.value)
357
+ }
358
+ emits('validateThis')
359
+ }
360
+
361
+ /**
362
+ * 初始化选中数据
363
+ */
364
+ function initSelectData() {
365
+ const tempList = [] as Array<ILinkItem>
366
+ if (props.modelValue) {
367
+ let [userIds, deptIds, userNames, deptNames] = props.modelValue as any
368
+ if (deptIds && deptNames && deptIds.length === deptNames.length) {
369
+ deptIds.map((id: string, i: number) => {
370
+ tempList.push({ type: 2, value: id, label: deptNames[i] })
371
+ })
372
+ }
373
+ if (userIds && userNames && userIds.length === userNames.length) {
374
+ userIds.map((id: string, i: number) => {
375
+ tempList.push({ type: 1, value: id, label: userNames[i] })
376
+ })
377
+ }
378
+ }
379
+ return tempList
380
+ }
381
+
382
+ /**
383
+ * 初始化选中Id
384
+ */
385
+ function initSelectIds() {
386
+ const tempList = [] as Array<string>
387
+ if (props.modelValue) {
388
+ let [userIds, deptIds] = props.modelValue as any
389
+ tempList.push(...(deptIds || []))
390
+ tempList.push(...(userIds || []))
391
+ }
392
+ return tempList
393
+ }
394
+
395
+ /**
396
+ * 初始化数据
397
+ */
398
+ function init() {
399
+ selectUser.splice(0, selectUser.length, ...initSelectData())
400
+ options.splice(0, options.length, ...initSelectData())
401
+ values.splice(0, values.length, ...initSelectIds())
402
+ }
403
+
404
+ onBeforeMount(async () => {
405
+ // // 如果没有配置,则抛出一个警告
406
+ selectAttrs.value = await getAttrs(props, {
407
+ remote: true,
408
+ filterable: true,
409
+ remoteShowSuffix: true,
410
+ loadingText: '远程查询中...',
411
+ remoteMethod: remoteMethod,
412
+ ...useAttrs()
413
+ })
414
+ })
415
+
416
+ watch(
417
+ () => props.modelValue,
418
+ () => init(),
419
+ { deep: true }
420
+ )
421
+
422
+ onMounted(async () => {
423
+ init()
424
+ })
425
+ </script>
426
+ <style lang="scss" scoped>
427
+ .el-plus-form-link-user {
428
+ width: 100%;
429
+
430
+ .items-panel {
431
+ :deep(.el-input__inner) {
432
+ cursor: pointer;
433
+ }
434
+ }
435
+
436
+ :deep(.el-tag__close) {
437
+ display: none !important;
438
+ }
439
+ }
440
+ </style>
441
+ <style lang="scss">
442
+ .form-link-user-dialog {
443
+ width: 100%;
444
+ display: flex;
445
+ box-sizing: border-box;
446
+
447
+ .panel-left {
448
+ width: 60%;
449
+ display: flex;
450
+ flex-direction: column;
451
+
452
+ .dept-breadcrumb {
453
+ width: 100%;
454
+ padding: 0 10px;
455
+ margin-bottom: 20px;
456
+ cursor: pointer;
457
+ }
458
+ }
459
+
460
+ .panel-right {
461
+ width: 40%;
462
+ margin-left: 20px;
463
+ border-left: 1px var(--el-border-color) var(--el-border-style);
464
+ padding: 20px;
465
+ display: flex;
466
+ overflow: hidden;
467
+ flex-direction: column;
468
+
469
+ .right-title {
470
+ width: 100%;
471
+ font-size: 14px;
472
+ color: #999999;
473
+ margin-bottom: 20px;
474
+ }
475
+
476
+ .tag-list {
477
+ width: 100%;
478
+ flex: 1;
479
+ overflow-y: hidden;
480
+ }
481
+
482
+ .btn-panel {
483
+ width: 100%;
484
+ min-height: 50px;
485
+ padding-top: 10px;
486
+ display: flex;
487
+ justify-content: center;
488
+ }
489
+ }
490
+ }
491
+ </style>
492
+ types