@ebiz/designer-components 0.1.14 → 0.1.16
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/dist/designer-components.css +1 -1
- package/dist/index.mjs +13812 -13623
- package/package.json +1 -1
- package/src/components/EbizApproval.vue +107 -163
- package/src/components/EbizEmployeeSelector.vue +336 -310
- package/src/components/EbizFileList.vue +417 -0
- package/src/index.js +3 -0
- package/src/router/index.js +6 -0
- package/src/views/EbizFileListDemo.vue +310 -0
- package/src/views/Home.vue +2 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="ebiz-employee-selector">
|
|
3
3
|
<!-- 选择框展示区 -->
|
|
4
|
-
<div v-if="showDefault" style="display: flex; flex-direction: column; align-items: flex-start; gap: 10px">
|
|
4
|
+
<div v-if="showDefault" style="display: flex; flex-direction: column; align-items: flex-start; gap: 10px;">
|
|
5
5
|
<div class="selected-items" v-if="selectedItems && selectedItems.length">
|
|
6
6
|
<div v-for="(item, index) in selectedItems" :key="index" class="selected-item">
|
|
7
7
|
<t-avatar v-if="item.avatar" :image="item.avatar" size="small" />
|
|
@@ -17,16 +17,9 @@
|
|
|
17
17
|
</div>
|
|
18
18
|
|
|
19
19
|
<!-- 选择弹窗 -->
|
|
20
|
-
<t-dialog
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
:width="800"
|
|
24
|
-
footer
|
|
25
|
-
:close-btn="true"
|
|
26
|
-
:close-on-esc-keydown="true"
|
|
27
|
-
:close-on-overlay-click="true"
|
|
28
|
-
destroyOnClose
|
|
29
|
-
>
|
|
20
|
+
<t-dialog v-model:visible="dialogVisible" :header="props.content" :width="800" footer :close-btn="true"
|
|
21
|
+
:close-on-esc-keydown="true" :close-on-overlay-click="true" destroyOnClose>
|
|
22
|
+
|
|
30
23
|
<!-- 选项卡 -->
|
|
31
24
|
<t-tabs v-model="activeTab" class="selector-tabs">
|
|
32
25
|
<t-tab-panel value="organization" label="组织架构" :destroyOnHide="false"></t-tab-panel>
|
|
@@ -36,7 +29,9 @@
|
|
|
36
29
|
<!-- <t-tab-panel value="subordinate" label="我的下属" :destroyOnHide="false"></t-tab-panel> -->
|
|
37
30
|
</t-tabs>
|
|
38
31
|
|
|
32
|
+
|
|
39
33
|
<div>
|
|
34
|
+
|
|
40
35
|
<div class="selector-dialog-content">
|
|
41
36
|
<!-- 左侧选择区域 -->
|
|
42
37
|
<div class="left-panel">
|
|
@@ -47,43 +42,21 @@
|
|
|
47
42
|
</div>
|
|
48
43
|
<!-- 组织架构 -->
|
|
49
44
|
<div v-show="activeTab === 'organization'" class="tab-content">
|
|
50
|
-
<t-tree
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
expandAll
|
|
54
|
-
:keys="{ label: 'name', value: 'id', children: 'children' }"
|
|
55
|
-
hover
|
|
56
|
-
activable
|
|
57
|
-
:active="currentActive"
|
|
58
|
-
@click="handleActive"
|
|
59
|
-
/>
|
|
45
|
+
<t-tree ref="organizationTree" :data="organizationData"
|
|
46
|
+
:keys="{ label: 'name', value: 'id', children: 'children' }" hover activable :active="currentActive"
|
|
47
|
+
@active="handleActive" />
|
|
60
48
|
</div>
|
|
61
49
|
|
|
62
50
|
<!-- 角色 -->
|
|
63
51
|
<div v-show="activeTab === 'role'" class="tab-content">
|
|
64
|
-
<t-tree
|
|
65
|
-
|
|
66
|
-
:data="roleData"
|
|
67
|
-
expandAll
|
|
68
|
-
:keys="{ label: 'name', value: 'code' }"
|
|
69
|
-
hover
|
|
70
|
-
activable
|
|
71
|
-
:active="currentActive"
|
|
72
|
-
@click="handleActive"
|
|
73
|
-
/>
|
|
52
|
+
<t-tree ref="roleTree" :data="roleData" :keys="{ label: 'name', value: 'code' }" hover activable
|
|
53
|
+
:active="currentActive" @active="handleActive" />
|
|
74
54
|
</div>
|
|
75
55
|
|
|
76
56
|
<!-- 岗位 -->
|
|
77
57
|
<div v-show="activeTab === 'position'" class="tab-content">
|
|
78
|
-
<t-tree
|
|
79
|
-
|
|
80
|
-
:data="positionData"
|
|
81
|
-
:keys="{ label: 'name', value: 'id' }"
|
|
82
|
-
hover
|
|
83
|
-
activable
|
|
84
|
-
:active="currentActive"
|
|
85
|
-
@click="handleActive"
|
|
86
|
-
/>
|
|
58
|
+
<t-tree ref="positionTree" :data="positionData" :keys="{ label: 'name', value: 'id' }" hover activable
|
|
59
|
+
:active="currentActive" @active="handleActive" />
|
|
87
60
|
</div>
|
|
88
61
|
|
|
89
62
|
<!-- 同部门 -->
|
|
@@ -127,35 +100,24 @@
|
|
|
127
100
|
|
|
128
101
|
<!-- 搜索框 -->
|
|
129
102
|
<div class="search-box">
|
|
130
|
-
<t-input
|
|
131
|
-
v-model="searchText"
|
|
132
|
-
placeholder="请输入姓名/拼音/工号搜索"
|
|
133
|
-
clearable
|
|
134
|
-
@keyup.enter="handleSearch"
|
|
135
|
-
>
|
|
103
|
+
<t-input v-model="searchText" placeholder="请输入姓名/拼音/工号搜索" clearable @keyup.enter="handleSearchEnter">
|
|
136
104
|
<template #suffix-icon>
|
|
137
|
-
<t-icon name="search" @click="
|
|
105
|
+
<t-icon name="search" @click="handleSearchClick"></t-icon>
|
|
138
106
|
</template>
|
|
139
107
|
</t-input>
|
|
140
|
-
<t-button v-if="searchText" size="small" theme="default" class="clear-search-btn"
|
|
141
|
-
>清除搜索</t-button
|
|
142
|
-
>
|
|
108
|
+
<t-button v-if="searchText" size="small" theme="default" class="clear-search-btn"
|
|
109
|
+
@click="clearSearch">清除搜索</t-button>
|
|
143
110
|
</div>
|
|
144
111
|
|
|
145
112
|
<div class="employee-list">
|
|
146
|
-
<div
|
|
147
|
-
v-
|
|
148
|
-
:key="index"
|
|
149
|
-
class="employee-item"
|
|
150
|
-
@click="handleCheckChange(item)"
|
|
151
|
-
>
|
|
152
|
-
<t-checkbox v-model="item.checked" style="pointer-events: none"></t-checkbox>
|
|
113
|
+
<div v-for="(item, index) in filteredEmployeeList" :key="index" class="employee-item">
|
|
114
|
+
<t-checkbox v-model="item.checked" @change="handleCheckChange(item)"></t-checkbox>
|
|
153
115
|
<div class="employee-avatar">
|
|
154
116
|
<t-avatar v-if="item.avatar" :image="item.avatar" size="small" />
|
|
155
117
|
<t-avatar v-else size="small">{{ getAvatarText(item.name) }}</t-avatar>
|
|
156
118
|
</div>
|
|
157
119
|
<div class="employee-info">
|
|
158
|
-
<div class="employee-code">{{ item.no }}
|
|
120
|
+
<div class="employee-code">{{ item.no }} - </div>
|
|
159
121
|
<div class="employee-name">{{ item.name }}</div>
|
|
160
122
|
</div>
|
|
161
123
|
</div>
|
|
@@ -167,6 +129,7 @@
|
|
|
167
129
|
</div>
|
|
168
130
|
</div>
|
|
169
131
|
|
|
132
|
+
|
|
170
133
|
<!-- 底部按钮区域 -->
|
|
171
134
|
<template #footer>
|
|
172
135
|
<div class="dialog-footer">
|
|
@@ -195,7 +158,7 @@
|
|
|
195
158
|
</template>
|
|
196
159
|
|
|
197
160
|
<script setup>
|
|
198
|
-
import { ref, computed, watch, onMounted } from 'vue'
|
|
161
|
+
import { ref, computed, watch, onMounted } from 'vue';
|
|
199
162
|
import {
|
|
200
163
|
Dialog as TDialog,
|
|
201
164
|
Button as TButton,
|
|
@@ -211,8 +174,8 @@ import {
|
|
|
211
174
|
List as TList,
|
|
212
175
|
ListItem as TListItem,
|
|
213
176
|
MessagePlugin
|
|
214
|
-
} from 'tdesign-vue-next'
|
|
215
|
-
import dataService from '../apiService/simpleDataService'
|
|
177
|
+
} from 'tdesign-vue-next';
|
|
178
|
+
import dataService from '../apiService/simpleDataService';
|
|
216
179
|
|
|
217
180
|
// 定义组件属性
|
|
218
181
|
const props = defineProps({
|
|
@@ -263,16 +226,16 @@ const props = defineProps({
|
|
|
263
226
|
type: String,
|
|
264
227
|
default: '选择人员'
|
|
265
228
|
}
|
|
266
|
-
})
|
|
229
|
+
});
|
|
267
230
|
|
|
268
231
|
// 定义组件事件
|
|
269
|
-
const emit = defineEmits(['update:modelValue', 'change', 'update:visible', 'confirm'])
|
|
270
|
-
const tempVisible = ref(false)
|
|
232
|
+
const emit = defineEmits(['update:modelValue', 'change', 'update:visible', 'confirm']);
|
|
233
|
+
const tempVisible = ref(false);
|
|
271
234
|
// 内部状态变量
|
|
272
235
|
const dialogVisible = computed({
|
|
273
236
|
set(val) {
|
|
274
237
|
if (props.visible == null) {
|
|
275
|
-
tempVisible.value = val
|
|
238
|
+
tempVisible.value = val;
|
|
276
239
|
return
|
|
277
240
|
}
|
|
278
241
|
emit('update:visible', val)
|
|
@@ -280,75 +243,79 @@ const dialogVisible = computed({
|
|
|
280
243
|
get() {
|
|
281
244
|
return props.visible ?? tempVisible.value
|
|
282
245
|
}
|
|
283
|
-
})
|
|
246
|
+
});
|
|
284
247
|
|
|
285
|
-
const searchText = ref('')
|
|
286
|
-
const activeTab = ref(props.defaultTab)
|
|
287
|
-
const loading = ref(false)
|
|
288
|
-
const selectedItems = ref([])
|
|
248
|
+
const searchText = ref('');
|
|
249
|
+
const activeTab = ref(props.defaultTab);
|
|
250
|
+
const loading = ref(false);
|
|
251
|
+
const selectedItems = ref([]);
|
|
289
252
|
// 对话框中临时保存的选中员工列表
|
|
290
|
-
const tempSelectedEmployees =
|
|
253
|
+
const tempSelectedEmployees = ref([]);
|
|
291
254
|
// 是否查询子部门
|
|
292
|
-
const childDeptEnable = ref(false)
|
|
255
|
+
const childDeptEnable = ref(false);
|
|
293
256
|
|
|
294
257
|
// 数据源
|
|
295
|
-
const organizationData = ref([])
|
|
296
|
-
const roleData = ref([])
|
|
297
|
-
const positionData = ref([])
|
|
298
|
-
const departmentData = ref([])
|
|
299
|
-
const subordinateData = ref([])
|
|
300
|
-
const employeeList = ref([])
|
|
301
|
-
const currentActive = ref([])
|
|
302
|
-
const currentNodeName = ref('')
|
|
303
|
-
const selectAll =
|
|
258
|
+
const organizationData = ref([]);
|
|
259
|
+
const roleData = ref([]);
|
|
260
|
+
const positionData = ref([]);
|
|
261
|
+
const departmentData = ref([]);
|
|
262
|
+
const subordinateData = ref([]);
|
|
263
|
+
const employeeList = ref([]);
|
|
264
|
+
const currentActive = ref([]);
|
|
265
|
+
const currentNodeName = ref('');
|
|
266
|
+
const selectAll = ref(false);
|
|
304
267
|
|
|
305
268
|
// 从名称中获取头像显示文本
|
|
306
269
|
const getAvatarText = (name) => {
|
|
307
|
-
return name ? name.substring(0, 1) : ''
|
|
308
|
-
}
|
|
270
|
+
return name ? name.substring(0, 1) : '';
|
|
271
|
+
};
|
|
309
272
|
|
|
310
273
|
// 处理组织数据,转换为树形结构
|
|
311
274
|
const _processOrgData = (data) => {
|
|
312
275
|
// 转换数据结构为树形结构
|
|
313
|
-
const map = {}
|
|
314
|
-
const result = []
|
|
276
|
+
const map = {};
|
|
277
|
+
const result = [];
|
|
315
278
|
|
|
316
|
-
data.forEach(
|
|
279
|
+
data.forEach(item => {
|
|
317
280
|
map[item.id] = {
|
|
318
281
|
...item,
|
|
319
282
|
name: item.name,
|
|
320
283
|
id: item.id,
|
|
321
284
|
children: []
|
|
322
|
-
}
|
|
323
|
-
})
|
|
285
|
+
};
|
|
286
|
+
});
|
|
324
287
|
|
|
325
|
-
data.forEach(
|
|
326
|
-
const node = map[item.id]
|
|
288
|
+
data.forEach(item => {
|
|
289
|
+
const node = map[item.id];
|
|
327
290
|
|
|
328
291
|
if (item.manager_dept && map[item.manager_dept]) {
|
|
329
|
-
map[item.manager_dept].children.push(node)
|
|
292
|
+
map[item.manager_dept].children.push(node);
|
|
330
293
|
} else {
|
|
331
294
|
// 只有在显示根组织或不存在父节点时才添加到结果中
|
|
332
295
|
if (props.showRootOrg || !item.manager_dept) {
|
|
333
|
-
result.push(node)
|
|
296
|
+
result.push(node);
|
|
334
297
|
}
|
|
335
298
|
}
|
|
336
|
-
})
|
|
299
|
+
});
|
|
337
300
|
|
|
338
|
-
return result
|
|
339
|
-
}
|
|
301
|
+
return result;
|
|
302
|
+
};
|
|
340
303
|
|
|
341
304
|
// 更新全选状态
|
|
305
|
+
const updateSelectAllStatus = () => {
|
|
306
|
+
selectAll.value = employeeList.value.length > 0 && employeeList.value.every(item => item.checked);
|
|
307
|
+
};
|
|
308
|
+
|
|
342
309
|
const updateSelectStatus = () => {
|
|
343
|
-
employeeList.value.forEach(
|
|
344
|
-
item.checked = props.modelValue.includes(item.id)
|
|
310
|
+
employeeList.value.forEach(item => {
|
|
311
|
+
item.checked = props.modelValue.includes(item.id);
|
|
345
312
|
})
|
|
346
313
|
}
|
|
347
314
|
|
|
348
315
|
// 选中的员工列表
|
|
349
316
|
const selectedEmployees = computed(() => {
|
|
350
|
-
return employeeList.value.filter((item) => item.checked)
|
|
351
|
-
})
|
|
317
|
+
return employeeList.value.filter((item) => item.checked);
|
|
318
|
+
});
|
|
352
319
|
|
|
353
320
|
// 根据搜索文本过滤的员工列表
|
|
354
321
|
const filteredEmployeeList = computed(() => {
|
|
@@ -366,68 +333,84 @@ const filteredEmployeeList = computed(() => {
|
|
|
366
333
|
// (item.code && item.code.toLowerCase().includes(keyword))
|
|
367
334
|
// );
|
|
368
335
|
// });
|
|
369
|
-
})
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
const allData = ref([])
|
|
339
|
+
|
|
340
|
+
const fetchAllData = async () => {
|
|
341
|
+
const response = await dataService.fetch({}, {}, '/process/deptList');
|
|
342
|
+
employeeList.value = response ?? [];
|
|
343
|
+
}
|
|
344
|
+
fetchAllData()
|
|
370
345
|
|
|
371
346
|
// 获取组织架构数据
|
|
372
347
|
const fetchOrganizationData = async () => {
|
|
373
|
-
loading.value = true
|
|
348
|
+
loading.value = true;
|
|
374
349
|
try {
|
|
375
350
|
const response = await dataService.fetch(
|
|
376
351
|
{},
|
|
377
352
|
{
|
|
378
353
|
apiId: 1933,
|
|
379
354
|
key: 'organizationalStructure'
|
|
380
|
-
},
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
// handleActive(response[0].id, 'organization')
|
|
355
|
+
}, "/process/deptList"
|
|
356
|
+
);
|
|
357
|
+
organizationData.value = response;
|
|
358
|
+
handleActive(response[0].id, 'organization')
|
|
385
359
|
// organizationData.value = processOrgData(response.data || []);
|
|
386
360
|
} catch (error) {
|
|
387
361
|
MessagePlugin.error({
|
|
388
362
|
content: '获取组织架构数据失败',
|
|
389
363
|
duration: 3000
|
|
390
|
-
})
|
|
364
|
+
});
|
|
391
365
|
} finally {
|
|
392
|
-
loading.value = false
|
|
366
|
+
loading.value = false;
|
|
393
367
|
}
|
|
394
|
-
}
|
|
368
|
+
};
|
|
395
369
|
|
|
396
370
|
// 获取角色数据
|
|
397
371
|
const fetchRoleData = async () => {
|
|
398
|
-
loading.value = true
|
|
372
|
+
loading.value = true;
|
|
399
373
|
try {
|
|
400
|
-
const response = await dataService.fetch(
|
|
401
|
-
|
|
374
|
+
const response = await dataService.fetch(
|
|
375
|
+
{},
|
|
376
|
+
{},
|
|
377
|
+
'/process/roleList'
|
|
378
|
+
);
|
|
379
|
+
roleData.value = response || [];
|
|
402
380
|
} catch (error) {
|
|
403
381
|
MessagePlugin.error({
|
|
404
382
|
content: '获取角色数据失败',
|
|
405
383
|
duration: 3000
|
|
406
|
-
})
|
|
384
|
+
});
|
|
407
385
|
} finally {
|
|
408
|
-
loading.value = false
|
|
386
|
+
loading.value = false;
|
|
409
387
|
}
|
|
410
|
-
}
|
|
388
|
+
};
|
|
411
389
|
|
|
412
390
|
// 获取岗位数据
|
|
413
391
|
const fetchPositionData = async () => {
|
|
414
|
-
loading.value = true
|
|
392
|
+
loading.value = true;
|
|
415
393
|
try {
|
|
416
|
-
const response = await dataService.fetch(
|
|
417
|
-
|
|
394
|
+
const response = await dataService.fetch(
|
|
395
|
+
{},
|
|
396
|
+
{
|
|
397
|
+
},
|
|
398
|
+
'/process/roleList'
|
|
399
|
+
);
|
|
400
|
+
positionData.value = response?.data || [];
|
|
418
401
|
} catch (error) {
|
|
419
402
|
MessagePlugin.error({
|
|
420
403
|
content: '获取岗位数据失败',
|
|
421
404
|
duration: 3000
|
|
422
|
-
})
|
|
405
|
+
});
|
|
423
406
|
} finally {
|
|
424
|
-
loading.value = false
|
|
407
|
+
loading.value = false;
|
|
425
408
|
}
|
|
426
|
-
}
|
|
409
|
+
};
|
|
427
410
|
|
|
428
411
|
// 获取部门数据
|
|
429
412
|
const fetchDepartmentData = async () => {
|
|
430
|
-
loading.value = true
|
|
413
|
+
loading.value = true;
|
|
431
414
|
try {
|
|
432
415
|
const response = await dataService.fetch(
|
|
433
416
|
{},
|
|
@@ -436,21 +419,21 @@ const fetchDepartmentData = async () => {
|
|
|
436
419
|
key: 'departmentList',
|
|
437
420
|
apiType: 'MULTIPLE_DATA_SEARCH'
|
|
438
421
|
}
|
|
439
|
-
)
|
|
440
|
-
departmentData.value = response?.data || []
|
|
422
|
+
);
|
|
423
|
+
departmentData.value = response?.data || [];
|
|
441
424
|
} catch (error) {
|
|
442
425
|
MessagePlugin.error({
|
|
443
426
|
content: '获取部门数据失败',
|
|
444
427
|
duration: 3000
|
|
445
|
-
})
|
|
428
|
+
});
|
|
446
429
|
} finally {
|
|
447
|
-
loading.value = false
|
|
430
|
+
loading.value = false;
|
|
448
431
|
}
|
|
449
|
-
}
|
|
432
|
+
};
|
|
450
433
|
|
|
451
434
|
// 获取下属数据
|
|
452
435
|
const fetchSubordinateData = async () => {
|
|
453
|
-
loading.value = true
|
|
436
|
+
loading.value = true;
|
|
454
437
|
try {
|
|
455
438
|
const response = await dataService.fetch(
|
|
456
439
|
{},
|
|
@@ -458,347 +441,390 @@ const fetchSubordinateData = async () => {
|
|
|
458
441
|
apiKey: 'subordinateList',
|
|
459
442
|
apiType: 'MULTIPLE_DATA_SEARCH'
|
|
460
443
|
}
|
|
461
|
-
)
|
|
462
|
-
subordinateData.value = response?.data || []
|
|
444
|
+
);
|
|
445
|
+
subordinateData.value = response?.data || [];
|
|
463
446
|
} catch (error) {
|
|
464
447
|
MessagePlugin.error({
|
|
465
448
|
content: '获取下属数据失败',
|
|
466
449
|
duration: 3000
|
|
467
|
-
})
|
|
450
|
+
});
|
|
468
451
|
} finally {
|
|
469
|
-
loading.value = false
|
|
452
|
+
loading.value = false;
|
|
470
453
|
}
|
|
471
|
-
}
|
|
454
|
+
};
|
|
472
455
|
|
|
473
456
|
// 根据节点ID获取员工列表
|
|
474
|
-
const fetchEmployeesByNode = async (nodeId, keyword = searchText.value) => {
|
|
475
|
-
loading.value = true
|
|
457
|
+
const fetchEmployeesByNode = async (nodeId, type, keyword = searchText.value) => {
|
|
458
|
+
loading.value = true;
|
|
476
459
|
try {
|
|
477
|
-
const params = {}
|
|
460
|
+
const params = {};
|
|
478
461
|
|
|
479
462
|
// 只有当nodeId不为空且type有效时,添加对应参数
|
|
480
|
-
if (nodeId &&
|
|
463
|
+
if (nodeId && type) {
|
|
481
464
|
// 根据不同类型设置不同的查询参数
|
|
482
|
-
switch (
|
|
465
|
+
switch (type) {
|
|
483
466
|
case 'organization':
|
|
484
|
-
params.deptId = Array.isArray(nodeId) ? nodeId[0] : nodeId
|
|
467
|
+
params.deptId = Array.isArray(nodeId) ? nodeId[0] : nodeId;
|
|
485
468
|
// 添加子部门查询参数
|
|
486
|
-
params.childDeptEnable = childDeptEnable.value
|
|
487
|
-
break
|
|
469
|
+
params.childDeptEnable = childDeptEnable.value;
|
|
470
|
+
break;
|
|
488
471
|
case 'role':
|
|
489
|
-
params.roleKeyWork = nodeId[0]
|
|
490
|
-
break
|
|
472
|
+
params.roleKeyWork = nodeId[0];
|
|
473
|
+
break;
|
|
491
474
|
case 'position':
|
|
492
|
-
params.positionId = nodeId
|
|
493
|
-
break
|
|
475
|
+
params.positionId = nodeId;
|
|
476
|
+
break;
|
|
494
477
|
case 'department':
|
|
495
|
-
params.departmentId = nodeId
|
|
496
|
-
break
|
|
478
|
+
params.departmentId = nodeId;
|
|
479
|
+
break;
|
|
497
480
|
case 'subordinate':
|
|
498
|
-
params.managerId = nodeId
|
|
499
|
-
break
|
|
481
|
+
params.managerId = nodeId;
|
|
482
|
+
break;
|
|
500
483
|
}
|
|
501
484
|
}
|
|
502
485
|
|
|
503
486
|
// 如果有搜索关键词,添加到查询参数中
|
|
504
487
|
if (keyword) {
|
|
505
|
-
params.keyWord = keyword
|
|
488
|
+
params.keyWord = keyword;
|
|
506
489
|
}
|
|
507
490
|
|
|
508
|
-
const response = await dataService.fetch(
|
|
491
|
+
const response = await dataService.fetch(
|
|
492
|
+
params,
|
|
493
|
+
{},
|
|
494
|
+
'/process/userList'
|
|
495
|
+
);
|
|
509
496
|
// 获取当前已选择的员工ID列表
|
|
510
|
-
const selectedIds = [...new Set(tempSelectedEmployees.value.map(
|
|
497
|
+
const selectedIds = [...new Set(tempSelectedEmployees.value.map(emp => emp.id))];
|
|
511
498
|
|
|
512
499
|
// 处理返回数据,添加checked属性,保留已选状态
|
|
513
|
-
const employees = (response || []).map(
|
|
500
|
+
const employees = (response || []).map(emp => ({
|
|
514
501
|
...emp,
|
|
515
502
|
checked: selectedIds.includes(emp.id)
|
|
516
|
-
}))
|
|
503
|
+
}));
|
|
517
504
|
|
|
518
|
-
employeeList.value = employees
|
|
505
|
+
employeeList.value = employees;
|
|
506
|
+
updateSelectAllStatus();
|
|
519
507
|
} catch (error) {
|
|
520
508
|
MessagePlugin.error({
|
|
521
509
|
content: '获取员工列表失败',
|
|
522
510
|
duration: 3000
|
|
523
|
-
})
|
|
511
|
+
});
|
|
524
512
|
} finally {
|
|
525
|
-
loading.value = false
|
|
513
|
+
loading.value = false;
|
|
526
514
|
}
|
|
527
|
-
}
|
|
515
|
+
};
|
|
528
516
|
|
|
529
517
|
// 根据ID列表批量获取员工信息
|
|
530
|
-
const fetchEmployeesByIds = (ids) => {
|
|
518
|
+
const fetchEmployeesByIds = async (ids) => {
|
|
531
519
|
if (!ids || ids.length === 0) {
|
|
532
|
-
selectedItems.value = []
|
|
533
|
-
return
|
|
520
|
+
selectedItems.value = [];
|
|
521
|
+
return;
|
|
534
522
|
}
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
523
|
+
|
|
524
|
+
loading.value = true;
|
|
525
|
+
try {
|
|
526
|
+
const response = await dataService.fetch(
|
|
538
527
|
{
|
|
539
528
|
userIds: ids // 使用新的接口参数格式
|
|
540
529
|
},
|
|
541
530
|
{},
|
|
542
531
|
'/process/userList' // 直接使用新的API路径
|
|
543
|
-
)
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
selectedItems.value = []
|
|
549
|
-
MessagePlugin.
|
|
550
|
-
content: '
|
|
532
|
+
);
|
|
533
|
+
|
|
534
|
+
if (response && Array.isArray(response)) {
|
|
535
|
+
selectedItems.value = response;
|
|
536
|
+
} else {
|
|
537
|
+
selectedItems.value = [];
|
|
538
|
+
MessagePlugin.warning({
|
|
539
|
+
content: '获取员工详情返回的数据格式不正确',
|
|
551
540
|
duration: 3000
|
|
552
|
-
})
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
541
|
+
});
|
|
542
|
+
}
|
|
543
|
+
} catch (error) {
|
|
544
|
+
selectedItems.value = [];
|
|
545
|
+
MessagePlugin.error({
|
|
546
|
+
content: '获取员工详情失败: ' + (error.message || '未知错误'),
|
|
547
|
+
duration: 3000
|
|
548
|
+
});
|
|
549
|
+
} finally {
|
|
550
|
+
loading.value = false;
|
|
551
|
+
}
|
|
552
|
+
};
|
|
558
553
|
|
|
559
554
|
// 处理节点激活
|
|
560
|
-
const handleActive = (
|
|
561
|
-
currentActive.value =
|
|
562
|
-
currentNodeName.value = node?.label || ''
|
|
555
|
+
const handleActive = (value, context) => {
|
|
556
|
+
currentActive.value = [value];
|
|
557
|
+
currentNodeName.value = context.node?.label || '';
|
|
558
|
+
|
|
563
559
|
// 获取该节点下的员工
|
|
564
|
-
fetchEmployeesByNode(
|
|
565
|
-
}
|
|
560
|
+
fetchEmployeesByNode(value, activeTab.value);
|
|
561
|
+
};
|
|
566
562
|
|
|
567
563
|
// 选择部门
|
|
568
564
|
const selectDepartment = (department) => {
|
|
569
|
-
currentNodeName.value = department.name
|
|
570
|
-
fetchEmployeesByNode(department.id)
|
|
571
|
-
}
|
|
565
|
+
currentNodeName.value = department.name;
|
|
566
|
+
fetchEmployeesByNode(department.id, activeTab.value);
|
|
567
|
+
};
|
|
572
568
|
|
|
573
569
|
// 处理全选
|
|
574
570
|
const handleSelectAll = (checked) => {
|
|
575
|
-
employeeList.value.forEach(
|
|
576
|
-
item.checked = checked
|
|
577
|
-
|
|
578
|
-
|
|
571
|
+
employeeList.value.forEach(item => {
|
|
572
|
+
item.checked = checked;
|
|
573
|
+
|
|
574
|
+
// 如果选中,确保添加到临时选中列表
|
|
575
|
+
if (checked && !tempSelectedEmployees.value.some(emp => emp.id === item.id)) {
|
|
576
|
+
tempSelectedEmployees.value.push(item);
|
|
577
|
+
}
|
|
578
|
+
});
|
|
579
|
+
};
|
|
579
580
|
|
|
580
581
|
// 处理选中状态变更
|
|
581
582
|
const handleCheckChange = (item) => {
|
|
582
583
|
// 单选模式下,取消其他选中
|
|
583
584
|
if (props.single) {
|
|
584
|
-
employeeList.value.forEach(
|
|
585
|
+
employeeList.value.forEach(emp => {
|
|
585
586
|
if (emp.id !== item.id) {
|
|
586
|
-
emp.checked = false
|
|
587
|
+
emp.checked = false;
|
|
587
588
|
}
|
|
588
|
-
})
|
|
589
|
-
|
|
589
|
+
});
|
|
590
|
+
// 单选模式下,直接替换tempSelectedEmployees
|
|
591
|
+
tempSelectedEmployees.value = item.checked ? [item] : [];
|
|
590
592
|
} else {
|
|
591
593
|
// 多选模式
|
|
592
594
|
// 如果选中,添加到临时选中列表
|
|
593
|
-
item.checked
|
|
595
|
+
if (item.checked && !tempSelectedEmployees.value.some(emp => emp.id === item.id)) {
|
|
596
|
+
tempSelectedEmployees.value.push(item);
|
|
597
|
+
} else if (!item.checked) {
|
|
598
|
+
// 如果取消选中,从临时选中列表中移除
|
|
599
|
+
const index = tempSelectedEmployees.value.findIndex(emp => emp.id === item.id);
|
|
600
|
+
if (index !== -1) {
|
|
601
|
+
tempSelectedEmployees.value.splice(index, 1);
|
|
602
|
+
}
|
|
603
|
+
}
|
|
594
604
|
}
|
|
595
605
|
|
|
596
606
|
// 检查最大选择数量限制
|
|
597
607
|
if (props.maxCount > 0) {
|
|
598
|
-
const checkedCount = tempSelectedEmployees.value.length
|
|
608
|
+
const checkedCount = tempSelectedEmployees.value.length;
|
|
599
609
|
if (checkedCount > props.maxCount) {
|
|
600
|
-
item.checked = false
|
|
610
|
+
item.checked = false;
|
|
611
|
+
const index = tempSelectedEmployees.value.findIndex(emp => emp.id === item.id);
|
|
612
|
+
if (index !== -1) {
|
|
613
|
+
tempSelectedEmployees.value.splice(index, 1);
|
|
614
|
+
}
|
|
601
615
|
MessagePlugin.warning({
|
|
602
616
|
content: `最多只能选择${props.maxCount}个人员`,
|
|
603
617
|
duration: 3000
|
|
604
|
-
})
|
|
618
|
+
});
|
|
605
619
|
}
|
|
606
620
|
}
|
|
607
|
-
|
|
621
|
+
|
|
622
|
+
updateSelectAllStatus();
|
|
623
|
+
};
|
|
608
624
|
|
|
609
625
|
// 移除已选择的项目
|
|
610
626
|
const removeItem = (index, id) => {
|
|
611
627
|
// 移除ID
|
|
612
|
-
const newIds = [...props.modelValue]
|
|
613
|
-
const idIndex = newIds.indexOf(id)
|
|
628
|
+
const newIds = [...props.modelValue];
|
|
629
|
+
const idIndex = newIds.indexOf(id);
|
|
614
630
|
if (idIndex !== -1) {
|
|
615
|
-
newIds.splice(idIndex, 1)
|
|
616
|
-
emit('update:modelValue', newIds)
|
|
617
|
-
emit('change', newIds)
|
|
631
|
+
newIds.splice(idIndex, 1);
|
|
632
|
+
emit('update:modelValue', newIds);
|
|
633
|
+
emit('change', newIds);
|
|
618
634
|
}
|
|
619
635
|
|
|
620
636
|
// 移除展示项
|
|
621
|
-
selectedItems.value.splice(index, 1)
|
|
622
|
-
}
|
|
637
|
+
selectedItems.value.splice(index, 1);
|
|
638
|
+
};
|
|
623
639
|
|
|
624
640
|
// 从已选列表中移除员工
|
|
625
641
|
const removeSelectedEmployee = (employee) => {
|
|
626
642
|
// 将员工的checked状态设为false
|
|
627
|
-
const foundEmployee = employeeList.value.find(
|
|
643
|
+
const foundEmployee = employeeList.value.find(item => item.id === employee.id);
|
|
628
644
|
if (foundEmployee) {
|
|
629
|
-
foundEmployee.checked = false
|
|
645
|
+
foundEmployee.checked = false;
|
|
630
646
|
}
|
|
631
|
-
|
|
647
|
+
|
|
648
|
+
// 从临时选中列表中移除
|
|
649
|
+
const index = tempSelectedEmployees.value.findIndex(emp => emp.id === employee.id);
|
|
650
|
+
if (index !== -1) {
|
|
651
|
+
tempSelectedEmployees.value.splice(index, 1);
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
// 更新全选状态
|
|
655
|
+
updateSelectAllStatus();
|
|
656
|
+
};
|
|
632
657
|
|
|
633
658
|
// 初始化选择器
|
|
634
659
|
const initSelector = async () => {
|
|
635
660
|
// 获取数据
|
|
636
661
|
if (activeTab.value === 'organization' && organizationData.value.length === 0) {
|
|
637
|
-
await fetchOrganizationData()
|
|
662
|
+
await fetchOrganizationData();
|
|
638
663
|
} else if (activeTab.value === 'role' && roleData.value.length === 0) {
|
|
639
|
-
await fetchRoleData()
|
|
664
|
+
await fetchRoleData();
|
|
640
665
|
} else if (activeTab.value === 'position' && positionData.value.length === 0) {
|
|
641
|
-
await fetchPositionData()
|
|
666
|
+
await fetchPositionData();
|
|
642
667
|
} else if (activeTab.value === 'department' && departmentData.value.length === 0) {
|
|
643
|
-
await fetchDepartmentData()
|
|
668
|
+
await fetchDepartmentData();
|
|
644
669
|
} else if (activeTab.value === 'subordinate' && subordinateData.value.length === 0) {
|
|
645
|
-
await fetchSubordinateData()
|
|
670
|
+
await fetchSubordinateData();
|
|
646
671
|
}
|
|
647
|
-
}
|
|
672
|
+
};
|
|
648
673
|
|
|
649
674
|
// 显示对话框
|
|
650
675
|
const showDialog = () => {
|
|
651
676
|
// 初始化临时选中列表
|
|
652
677
|
if (selectedItems.value.length > 0) {
|
|
653
|
-
tempSelectedEmployees.value = [...selectedItems.value]
|
|
678
|
+
tempSelectedEmployees.value = [...selectedItems.value];
|
|
654
679
|
updateSelectStatus()
|
|
655
680
|
} else {
|
|
656
|
-
tempSelectedEmployees.value = []
|
|
681
|
+
tempSelectedEmployees.value = [];
|
|
657
682
|
}
|
|
658
683
|
|
|
659
684
|
// 初始化数据
|
|
660
685
|
if (props.visible == null) {
|
|
661
|
-
initSelector()
|
|
686
|
+
initSelector();
|
|
662
687
|
}
|
|
663
|
-
dialogVisible.value = true
|
|
664
|
-
}
|
|
688
|
+
dialogVisible.value = true;
|
|
689
|
+
};
|
|
665
690
|
|
|
666
691
|
// 确认选择
|
|
667
692
|
const handleConfirm = () => {
|
|
668
|
-
const selectedEmployeeIds = tempSelectedEmployees.value.map(
|
|
693
|
+
const selectedEmployeeIds = tempSelectedEmployees.value.map(item => item.id);
|
|
669
694
|
|
|
670
|
-
emit('update:modelValue', selectedEmployeeIds)
|
|
671
|
-
emit('change', selectedEmployeeIds)
|
|
672
|
-
emit('confirm', selectedEmployeeIds)
|
|
673
|
-
dialogVisible.value = false
|
|
674
|
-
}
|
|
695
|
+
emit('update:modelValue', selectedEmployeeIds);
|
|
696
|
+
emit('change', selectedEmployeeIds);
|
|
697
|
+
emit('confirm', selectedEmployeeIds);
|
|
698
|
+
dialogVisible.value = false;
|
|
699
|
+
};
|
|
675
700
|
|
|
676
701
|
// 取消选择
|
|
677
702
|
const handleCancel = () => {
|
|
678
703
|
// 放弃临时选择
|
|
679
|
-
tempSelectedEmployees.value = []
|
|
680
|
-
dialogVisible.value = false
|
|
681
|
-
}
|
|
704
|
+
tempSelectedEmployees.value = [];
|
|
705
|
+
dialogVisible.value = false;
|
|
706
|
+
};
|
|
682
707
|
|
|
683
708
|
// 监听标签页切换
|
|
684
709
|
watch(activeTab, () => {
|
|
685
710
|
// 切换标签页时重新加载数据
|
|
686
|
-
initSelector()
|
|
687
|
-
})
|
|
711
|
+
initSelector();
|
|
712
|
+
});
|
|
688
713
|
|
|
689
714
|
// 监听modelValue变化,更新展示的员工信息
|
|
690
|
-
watch(
|
|
691
|
-
()
|
|
692
|
-
(newIds
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
()
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
currentNodeName.value = ''
|
|
710
|
-
|
|
711
|
-
if (val) {
|
|
712
|
-
fetchOrganizationData()
|
|
713
|
-
}
|
|
714
|
-
},
|
|
715
|
-
{ immediate: true }
|
|
716
|
-
)
|
|
715
|
+
watch(() => props.modelValue, (newIds, oldIds) => {
|
|
716
|
+
// 判断值是否真的变化了 (通过比较JSON字符串)
|
|
717
|
+
const newIdsStr = JSON.stringify(newIds || []);
|
|
718
|
+
const oldIdsStr = JSON.stringify(oldIds || []);
|
|
719
|
+
|
|
720
|
+
if (newIdsStr !== oldIdsStr) {
|
|
721
|
+
// 获取员工详情数据
|
|
722
|
+
fetchEmployeesByIds(newIds);
|
|
723
|
+
}
|
|
724
|
+
}, { immediate: true, deep: true });
|
|
725
|
+
watch(() => props.visible, (val) => {
|
|
726
|
+
tempSelectedEmployees.value = [];
|
|
727
|
+
currentActive.value = [];
|
|
728
|
+
currentNodeName.value = '';
|
|
729
|
+
|
|
730
|
+
if (val) {
|
|
731
|
+
fetchOrganizationData()
|
|
732
|
+
}
|
|
733
|
+
}, { immediate: true })
|
|
717
734
|
// 监听选中员工变化,更新临时已选列表
|
|
718
|
-
watch(
|
|
719
|
-
|
|
720
|
-
(newVal
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
})
|
|
735
|
-
},
|
|
736
|
-
{ deep: true }
|
|
737
|
-
)
|
|
735
|
+
watch(selectedEmployees, (newVal) => {
|
|
736
|
+
// 更新临时选中列表,保留之前不在当前列表中的已选员工
|
|
737
|
+
const currentIds = new Set(newVal.map(emp => emp.id));
|
|
738
|
+
|
|
739
|
+
// 移除tempSelectedEmployees中已经不再选中的员工
|
|
740
|
+
tempSelectedEmployees.value = tempSelectedEmployees.value.filter(emp =>
|
|
741
|
+
!currentIds.has(emp.id) || newVal.some(item => item.id === emp.id)
|
|
742
|
+
);
|
|
743
|
+
|
|
744
|
+
// 添加新选中的员工
|
|
745
|
+
newVal.forEach(emp => {
|
|
746
|
+
if (!tempSelectedEmployees.value.some(item => item.id === emp.id)) {
|
|
747
|
+
tempSelectedEmployees.value.push(emp);
|
|
748
|
+
}
|
|
749
|
+
});
|
|
750
|
+
}, { deep: true });
|
|
738
751
|
|
|
739
752
|
// 监听子部门查询开关变化
|
|
740
753
|
watch(childDeptEnable, () => {
|
|
741
754
|
// 如果当前在组织架构页面且有选中节点,重新加载员工列表
|
|
742
755
|
if (activeTab.value === 'organization' && currentActive.value && currentActive.value.length > 0) {
|
|
743
|
-
fetchEmployeesByNode(currentActive.value[0])
|
|
756
|
+
fetchEmployeesByNode(currentActive.value[0], activeTab.value);
|
|
744
757
|
}
|
|
745
|
-
})
|
|
758
|
+
});
|
|
746
759
|
|
|
747
760
|
// 防抖函数
|
|
748
761
|
const debounce = (fn, delay) => {
|
|
749
|
-
let timer = null
|
|
762
|
+
let timer = null;
|
|
750
763
|
return function (...args) {
|
|
751
|
-
if (timer) clearTimeout(timer)
|
|
764
|
+
if (timer) clearTimeout(timer);
|
|
752
765
|
timer = setTimeout(() => {
|
|
753
|
-
fn.apply(this, args)
|
|
754
|
-
}, delay)
|
|
755
|
-
}
|
|
756
|
-
}
|
|
766
|
+
fn.apply(this, args);
|
|
767
|
+
}, delay);
|
|
768
|
+
};
|
|
769
|
+
};
|
|
757
770
|
|
|
758
771
|
// 防抖处理过的搜索函数
|
|
759
772
|
const debouncedSearch = debounce((keyword) => {
|
|
760
773
|
if (keyword) {
|
|
761
|
-
const nodeId = currentActive.value && currentActive.value.length > 0 ? currentActive.value[0] : null
|
|
762
|
-
|
|
774
|
+
const nodeId = currentActive.value && currentActive.value.length > 0 ? currentActive.value[0] : null;
|
|
775
|
+
const type = nodeId ? activeTab.value : null;
|
|
776
|
+
fetchEmployeesByNode(nodeId, type, keyword);
|
|
763
777
|
} else if (currentActive.value && currentActive.value.length > 0) {
|
|
764
778
|
// 如果搜索框清空,恢复显示当前选中节点的员工列表
|
|
765
|
-
fetchEmployeesByNode(currentActive.value[0])
|
|
779
|
+
fetchEmployeesByNode(currentActive.value[0], activeTab.value);
|
|
766
780
|
} else {
|
|
767
781
|
// 如果没有选中节点,清空员工列表
|
|
768
|
-
employeeList.value = []
|
|
782
|
+
employeeList.value = [];
|
|
769
783
|
}
|
|
770
|
-
}, 300) // 300ms防抖
|
|
784
|
+
}, 300); // 300ms防抖
|
|
771
785
|
|
|
772
786
|
// 监听搜索文本变化,触发搜索
|
|
773
|
-
watch(
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
787
|
+
watch(searchText, (newValue) => {
|
|
788
|
+
debouncedSearch(newValue);
|
|
789
|
+
}, { immediate: false });
|
|
790
|
+
|
|
791
|
+
// 组件挂载时执行
|
|
792
|
+
onMounted(() => {
|
|
793
|
+
// 获取已选员工详情
|
|
794
|
+
fetchEmployeesByIds(props.modelValue);
|
|
795
|
+
});
|
|
780
796
|
|
|
781
797
|
// 处理搜索图标点击
|
|
782
|
-
const
|
|
798
|
+
const handleSearchClick = () => {
|
|
783
799
|
if (searchText.value) {
|
|
784
|
-
const nodeId = currentActive.value && currentActive.value.length > 0 ? currentActive.value[0] : null
|
|
785
|
-
|
|
800
|
+
const nodeId = currentActive.value && currentActive.value.length > 0 ? currentActive.value[0] : null;
|
|
801
|
+
const type = nodeId ? activeTab.value : null;
|
|
802
|
+
fetchEmployeesByNode(nodeId, type, searchText.value);
|
|
786
803
|
}
|
|
787
|
-
}
|
|
804
|
+
};
|
|
805
|
+
|
|
806
|
+
// 处理回车键搜索
|
|
807
|
+
const handleSearchEnter = () => {
|
|
808
|
+
if (searchText.value) {
|
|
809
|
+
const nodeId = currentActive.value && currentActive.value.length > 0 ? currentActive.value[0] : null;
|
|
810
|
+
const type = nodeId ? activeTab.value : null;
|
|
811
|
+
fetchEmployeesByNode(nodeId, type, searchText.value);
|
|
812
|
+
}
|
|
813
|
+
};
|
|
788
814
|
|
|
789
815
|
// 清除搜索
|
|
790
816
|
const clearSearch = () => {
|
|
791
|
-
searchText.value = ''
|
|
817
|
+
searchText.value = '';
|
|
792
818
|
if (currentActive.value && currentActive.value.length > 0) {
|
|
793
|
-
fetchEmployeesByNode(currentActive.value[0])
|
|
819
|
+
fetchEmployeesByNode(currentActive.value[0], activeTab.value);
|
|
794
820
|
} else {
|
|
795
821
|
// 如果没有选中节点,重置员工列表但保留选中状态
|
|
796
|
-
employeeList.value = employeeList.value.map(
|
|
822
|
+
employeeList.value = employeeList.value.map(emp => ({
|
|
797
823
|
...emp,
|
|
798
|
-
checked: tempSelectedEmployees.value.some(
|
|
799
|
-
}))
|
|
824
|
+
checked: tempSelectedEmployees.value.some(item => item.id === emp.id)
|
|
825
|
+
}));
|
|
800
826
|
}
|
|
801
|
-
}
|
|
827
|
+
};
|
|
802
828
|
</script>
|
|
803
829
|
|
|
804
830
|
<style scoped>
|
|
@@ -858,7 +884,7 @@ const clearSearch = () => {
|
|
|
858
884
|
}
|
|
859
885
|
|
|
860
886
|
.item-remove:hover {
|
|
861
|
-
color: #
|
|
887
|
+
color: #E34D59;
|
|
862
888
|
}
|
|
863
889
|
|
|
864
890
|
/* 选择弹窗 */
|
|
@@ -1070,6 +1096,6 @@ const clearSearch = () => {
|
|
|
1070
1096
|
}
|
|
1071
1097
|
|
|
1072
1098
|
.selected-people-item .item-remove:hover {
|
|
1073
|
-
color: #
|
|
1099
|
+
color: #E34D59;
|
|
1074
1100
|
}
|
|
1075
1101
|
</style>
|