widget.qw 1.0.83 → 1.0.85

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 (108) hide show
  1. package/.env.development +10 -10
  2. package/.env.production +8 -8
  3. package/README.md +75 -75
  4. package/build/style.css +521 -471
  5. package/build/widget.qw.es.js +253 -84
  6. package/build/widget.qw.umd.js +252 -83
  7. package/index.html +17 -17
  8. package/package.json +47 -47
  9. package/src/App.vue +26 -26
  10. package/src/api/index.js +173 -165
  11. package/src/components/AuditBar.vue +396 -396
  12. package/src/components/BillCard.vue +164 -164
  13. package/src/components/CascaderPicker.vue +132 -132
  14. package/src/components/CascaderPop.vue +375 -371
  15. package/src/components/CheckGroup.vue +113 -113
  16. package/src/components/DatetimeDropdown.vue +62 -0
  17. package/src/components/{DatetimePicker/index.vue → DatetimePicker.vue} +124 -124
  18. package/src/components/DayDropdown.vue +56 -56
  19. package/src/components/FilePicker.vue +169 -169
  20. package/src/components/HeadBar.vue +130 -0
  21. package/src/components/Input.vue +80 -80
  22. package/src/components/MonthDropdown.vue +51 -51
  23. package/src/components/MultiPicker.vue +123 -123
  24. package/src/components/ObjsEditor.vue +334 -334
  25. package/src/components/SecretNotify.js +5 -5
  26. package/src/components/Sheet.vue +92 -92
  27. package/src/components/SingleApiPicker.vue +108 -108
  28. package/src/components/SinglePicker.vue +102 -102
  29. package/src/components/SingleUserSelector.vue +425 -425
  30. package/src/components/Switch.vue +64 -64
  31. package/src/components/TreePicker.vue +113 -113
  32. package/src/components/UserPicker.vue +106 -106
  33. package/src/components/UserProfile.vue +129 -129
  34. package/src/components/UsersPicker.vue +118 -118
  35. package/src/components/YearDropdown.vue +59 -59
  36. package/src/components/data_selector.vue +303 -303
  37. package/src/components/image_picker.vue +123 -123
  38. package/src/components/images_picker.vue +195 -195
  39. package/src/components/index.js +172 -162
  40. package/src/components/mult_list_selector.vue +155 -155
  41. package/src/components/subdepartment_selector.vue +481 -481
  42. package/src/components/user_selector.vue +639 -639
  43. package/src/components/widget/DataPop.vue +95 -95
  44. package/src/components/{DatetimePicker → widget}/DatetimePop.vue +342 -342
  45. package/src/components/widget/TreePop.vue +88 -88
  46. package/src/components/widget/UserPop.vue +347 -347
  47. package/src/main.js +117 -117
  48. package/src/router/index.ts +183 -173
  49. package/src/util/array_util.js +32 -32
  50. package/src/util/auth_util.js +72 -72
  51. package/src/util/bool_util.js +5 -5
  52. package/src/util/bus.js +1 -1
  53. package/src/util/cache_util.js +18 -18
  54. package/src/util/errer_code.js +6 -6
  55. package/src/util/eval_util.js +19 -19
  56. package/src/util/icon_util.js +36 -36
  57. package/src/util/image_util.js +27 -27
  58. package/src/util/index.js +57 -57
  59. package/src/util/num_util.js +70 -70
  60. package/src/util/obj_util.js +28 -28
  61. package/src/util/request.js +73 -73
  62. package/src/util/request_json.js +71 -71
  63. package/src/util/request_json_mute.js +65 -65
  64. package/src/util/request_upload.js +79 -79
  65. package/src/util/route_util.js +31 -31
  66. package/src/util/str_util.js +143 -143
  67. package/src/util/time_util.js +406 -406
  68. package/src/util/toast_util.js +24 -24
  69. package/src/util/tree_util.js +153 -153
  70. package/src/util/uuid_util.js +9 -9
  71. package/src/util/validate.js +182 -182
  72. package/src/util/vue_filter.js +223 -223
  73. package/src/views/auditbar/index.vue +78 -78
  74. package/src/views/billcard/index.vue +48 -48
  75. package/src/views/cascaderpicker/index.vue +0 -0
  76. package/src/views/cascaderpicker/userpicker.vue +183 -0
  77. package/src/views/cascaderpop/index.vue +90 -90
  78. package/src/views/checkgroup/index.vue +35 -35
  79. package/src/views/dataSelector/index.vue +48 -48
  80. package/src/views/datetimedropdown/index.vue +34 -0
  81. package/src/views/datetimepicker/index.vue +34 -34
  82. package/src/views/daydropdown/index.vue +31 -31
  83. package/src/views/filepicker/index.vue +32 -32
  84. package/src/views/headbar/index.vue +28 -0
  85. package/src/views/home/index.vue +0 -0
  86. package/src/views/imagepicker/index.vue +31 -31
  87. package/src/views/imagespicker/index.vue +37 -37
  88. package/src/views/input/index.vue +35 -35
  89. package/src/views/monthdropdown/index.vue +31 -31
  90. package/src/views/multListSelector/index.vue +61 -61
  91. package/src/views/multipicker/index.vue +36 -36
  92. package/src/views/objseditor/index.vue +277 -277
  93. package/src/views/productSelector/index.vue +35 -35
  94. package/src/views/projectpicker/index.vue +41 -41
  95. package/src/views/secretnotify/index.vue +27 -27
  96. package/src/views/sheet/index.vue +45 -45
  97. package/src/views/singlepicker/index.vue +35 -35
  98. package/src/views/subdepartmentSelector/index.vue +40 -40
  99. package/src/views/switch/index.vue +34 -34
  100. package/src/views/treepicker/index.vue +41 -41
  101. package/src/views/userSelector/index.vue +54 -54
  102. package/src/views/userSelectorNew/index.vue +45 -45
  103. package/src/views/userpicker/index.vue +43 -43
  104. package/src/views/userprofile/index.vue +30 -30
  105. package/src/views/userspicker/index.vue +43 -43
  106. package/src/views/yeardropdown/index.vue +32 -32
  107. package/src/vm/index.js +1 -1
  108. package/vite.config.ts +122 -122
@@ -1,347 +1,347 @@
1
- <template>
2
- <van-popup v-model:show="show" round position="bottom" class="user-popup">
3
- <div class="department-selector">
4
- <div class="picker-header">
5
- <div class="header-left">
6
- <van-button @click="onBack" icon="arrow-left" size="small" />
7
- </div>
8
-
9
- <!-- 移除header-center包装,直接使用current-path -->
10
- <div class="current-path">{{ pathsLabel }}</div>
11
-
12
- <div class="header-right">
13
- <van-button size="small" @click="onCancel" class="cancel-btn">取消</van-button>
14
-
15
- <van-button type="primary" size="small" @click="onSubmit" class="confirm-btn">确定</van-button>
16
- </div>
17
- </div>
18
-
19
- <!-- 搜索框 -->
20
- <van-search v-model="data.keyword" placeholder="输入工号查询" @clear="onClear" @search="onSearch" @cancel="onClear"
21
- show-action>
22
- <template #action>
23
- <div @click="onSearch">搜索</div>
24
- </template>
25
- </van-search>
26
-
27
- <div class="scroll-container">
28
- <!-- 遍历部门列表 -->
29
- <van-cell-group>
30
- <van-cell v-for="dept in subDepts" :key="dept.id" :title="dept.name" is-link @click="onSelectDept(dept)" />
31
- </van-cell-group>
32
-
33
- <!-- 遍历人员列表 -->
34
- <van-radio-group v-model="data.selectedUser">
35
- <van-cell-group>
36
- <van-cell v-for="user in subUsers" :key="user.id" :title="`${user.userid} ${user.name}`">
37
- <template #right-icon>
38
- <van-radio :name="user.userid" />
39
- </template>
40
- </van-cell>
41
- </van-cell-group>
42
- </van-radio-group>
43
- </div>
44
- </div>
45
- </van-popup>
46
- </template>
47
- <script setup>
48
- import { ref, onMounted, watch, reactive, computed } from "vue";
49
- import util from "../../util"
50
- import { useVModel } from '@vueuse/core'
51
-
52
- const props = defineProps({
53
- show: {
54
- type: Boolean,
55
- default: false,
56
- },
57
- // 默认查询所有组织机构
58
- rootDeptId: {
59
- type: String,
60
- default: "1", //组织机构id
61
- },
62
- // 二级部门取值范围字典id
63
- // 取dictionary库.dict的配置id
64
- deptRangeId: {
65
- type: String,
66
- default: ''
67
- }
68
- });
69
- // 定义emit
70
- const emit = defineEmits(["update:show", "select"]);
71
- // 弹出?
72
- const show = useVModel(props, 'show', emit)
73
- const data = reactive({
74
- // 当前选中的机构
75
- selectedDeptId: '',
76
- // 所有的部门
77
- totalDepts: [],
78
- // 搜索关键字
79
- keyword: "",
80
- searchUsers: [],
81
- selectedUser: null
82
- })
83
-
84
-
85
- // 查找部门路径列表
86
- function findDeptPaths(targetDept, tree, path = []) {
87
- if (!tree || tree.length < 1 || !targetDept || !targetDept.id)
88
- return []
89
-
90
- for (const dept of tree) {
91
- if (dept.id === targetDept.id) {
92
- return [...path, dept];
93
- }
94
- if (dept.subDepartments?.length) {
95
- const found = findDeptPaths(targetDept, dept.subDepartments, [...path, dept]);
96
- if (found && found.length > 0) return found;
97
- }
98
- }
99
-
100
- return []
101
- }
102
-
103
- // 选中的部门
104
- const selectedDept = computed(()=>{
105
- if(!data.selectedDeptId)
106
- return null
107
-
108
- let targetDept = findDept(data.selectedDeptId,data.totalDepts)
109
- return targetDept
110
- })
111
-
112
- //选中部门的路径:部门/科室
113
- const pathsLabel = computed(() => {
114
- let paths = findDeptPaths(selectedDept.value, data.totalDepts)
115
- console.log("paths", paths);
116
- let res = ''
117
- paths.forEach((dept) => {
118
- res += dept.name + "/";
119
- })
120
- return res
121
- })
122
-
123
- const subDepts = computed(() => {
124
- if (data.keyword)
125
- return []
126
- else if (selectedDept.value)
127
- return selectedDept.value.subDepartments
128
- else
129
- return data.totalDepts
130
- })
131
-
132
- const subUsers = computed(() => {
133
- if (data.keyword)
134
- return data.searchUsers
135
- else if (selectedDept.value)
136
- return selectedDept.value.users
137
- else
138
- return []
139
- })
140
-
141
- // 获得部门列表
142
- const queryTotalDepts = async () => {
143
- // 查询所有部门
144
- const response = await util.get_subdepartments_users({ departmentId: props.rootDeptId, hasGrandson:false })
145
- let level2Depts = []
146
- if(response.data)
147
- level2Depts = response.data.subDepartments
148
-
149
- // 取配置的二级部门取值范围
150
- let level2DeptIds = []
151
- if (props.deptRangeId) {
152
- let res = await util.dictionary_dict({ id: props.deptRangeId })
153
- if (res.data.parseValue && res.data.parseValue.length > 0) {
154
- level2DeptIds = res.data.parseValue
155
- }
156
- }
157
-
158
- // 只保留指定二级部门列表
159
- if (props.deptRangeId) {
160
- if (level2DeptIds && level2DeptIds.length > 0) {
161
- level2Depts = level2Depts.filter(item => {
162
- return level2DeptIds.includes(item.id)
163
- })
164
- }
165
- }
166
-
167
- data.totalDepts = level2Depts || []
168
- }
169
-
170
- // 查找机构
171
- function findDept(deptId, tree) {
172
- if (!tree || tree.length < 1)
173
- return null
174
-
175
- for (const dept of tree) {
176
- if (dept.id === deptId) {
177
- return dept
178
- }
179
-
180
- const found = findDept(deptId, dept.subDepartments);
181
- if (found) return found
182
- }
183
-
184
- return null
185
- }
186
-
187
- // 查找父机构
188
- function findParentDept(deptId, tree) {
189
- if (!tree || tree.length < 1)
190
- return null
191
-
192
- for (const dept of tree) {
193
- if (!dept.subDepartments || dept.subDepartments.length < 1)
194
- continue
195
-
196
- let ary = dept.subDepartments.filter(item => item.id == deptId)
197
- if (ary && ary.length > 0)
198
- return dept
199
-
200
- const found = findParentDept(deptId, dept.subDepartments);
201
- if (found) return found
202
- }
203
-
204
- return null
205
- }
206
-
207
- // 搜索人员
208
- const onSearch = async () => {
209
- if (!data.keyword)
210
- return
211
-
212
- // 搜索用户
213
- const res = await util.wx_user_list({ keyword: data.keyword, page: 1, limit: 10000 })
214
- data.searchUsers = res.data.list
215
- }
216
-
217
- // 切换部门
218
- const onSelectDept = async(department) => {
219
- const res = await util.get_subdepartments_users({ departmentId: department.id, hasGrandson:false })
220
- let targetDept = findDept(department.id, data.totalDepts)
221
- targetDept.subDepartments = res.data.subDepartments
222
- targetDept.users = res.data.users
223
- data.selectedDeptId = department.id
224
- }
225
-
226
- // 返回上一级部门
227
- const onBack = () => {
228
- data.keyword = ""
229
-
230
- let paths = findDeptPaths(selectedDept.value, data.totalDepts)
231
- console.log('22222222', paths)
232
- if (!paths || paths.length <= 1){
233
- data.selectedDeptId = ''
234
- return
235
- }
236
-
237
- data.selectedDeptId = paths[paths.length - 2].id
238
- }
239
-
240
- // 清除掉选中部门及人
241
- const reset = () => {
242
- // 当前选中的机构
243
- data.selectedDeptId = ''
244
- // 搜索关键字
245
- data.keyword = ""
246
- data.searchUsers = []
247
- data.selectedUser = {}
248
- }
249
-
250
- // 确认按钮
251
- const onSubmit = () => {
252
- if (!data.selectedUser) {
253
- util.warnToast("请选择用户")
254
- return
255
- }
256
-
257
- emit('select', data.selectedUser)
258
- show.value = false
259
-
260
- reset()
261
- }
262
-
263
- // 取消按钮
264
- const onCancel = () => {
265
- show.value = false
266
- reset()
267
- };
268
-
269
- //首页加载
270
- onMounted(async () => {
271
- await queryTotalDepts()
272
- // 初始化当前父部门
273
- data.selectedDept = findDept(props.rootDeptId, data.totalDepts)
274
- })
275
- </script>
276
-
277
- <style scoped>
278
- .user-popup {
279
- width: 100%;
280
- overflow: hidden;
281
- }
282
-
283
- .department-selector {
284
- padding: 10px;
285
- }
286
-
287
- .search-buttons {
288
- display: flex;
289
- gap: 10px;
290
- }
291
-
292
- .clear-btn {
293
- background-color: #f2f3f5;
294
- border: none;
295
- border-radius: 4px;
296
- padding: 4px 8px;
297
- font-size: 14px;
298
- }
299
-
300
- .confirm-btn {
301
- background-color: #1989fa;
302
- color: white;
303
- border: none;
304
- border-radius: 4px;
305
- padding: 4px 8px;
306
- font-size: 14px;
307
- }
308
-
309
- .no-results {
310
- text-align: center;
311
- padding: 20px;
312
- color: #969799;
313
- }
314
-
315
- .picker-header {
316
- padding: 10px;
317
- border-bottom: 1px solid #ebedf0;
318
- display: flex;
319
- justify-content: space-between;
320
- align-items: center;
321
- }
322
-
323
- .current-path {
324
- flex: 1;
325
- font-size: 14px;
326
- color: #323233;
327
- white-space: nowrap;
328
- overflow: hidden;
329
- text-overflow: ellipsis;
330
- }
331
-
332
- .header-right {
333
- display: flex;
334
- gap: 8px;
335
- margin-left: auto;
336
- }
337
-
338
- .cancel-btn {
339
- color: #969799;
340
- margin-right: 5px;
341
- }
342
-
343
- .scroll-container {
344
- height: calc(80vh - 150px);
345
- overflow-y: auto;
346
- }
347
- </style>
1
+ <template>
2
+ <van-popup v-model:show="show" round position="bottom" class="user-popup">
3
+ <div class="department-selector">
4
+ <div class="picker-header">
5
+ <div class="header-left">
6
+ <van-button @click="onBack" icon="arrow-left" size="small" />
7
+ </div>
8
+
9
+ <!-- 移除header-center包装,直接使用current-path -->
10
+ <div class="current-path">{{ pathsLabel }}</div>
11
+
12
+ <div class="header-right">
13
+ <van-button size="small" @click="onCancel" class="cancel-btn">取消</van-button>
14
+
15
+ <van-button type="primary" size="small" @click="onSubmit" class="confirm-btn">确定</van-button>
16
+ </div>
17
+ </div>
18
+
19
+ <!-- 搜索框 -->
20
+ <van-search v-model="data.keyword" placeholder="输入工号查询" @clear="onClear" @search="onSearch" @cancel="onClear"
21
+ show-action>
22
+ <template #action>
23
+ <div @click="onSearch">搜索</div>
24
+ </template>
25
+ </van-search>
26
+
27
+ <div class="scroll-container">
28
+ <!-- 遍历部门列表 -->
29
+ <van-cell-group>
30
+ <van-cell v-for="dept in subDepts" :key="dept.id" :title="dept.name" is-link @click="onSelectDept(dept)" />
31
+ </van-cell-group>
32
+
33
+ <!-- 遍历人员列表 -->
34
+ <van-radio-group v-model="data.selectedUser">
35
+ <van-cell-group>
36
+ <van-cell v-for="user in subUsers" :key="user.id" :title="`${user.userid} ${user.name}`">
37
+ <template #right-icon>
38
+ <van-radio :name="user.userid" />
39
+ </template>
40
+ </van-cell>
41
+ </van-cell-group>
42
+ </van-radio-group>
43
+ </div>
44
+ </div>
45
+ </van-popup>
46
+ </template>
47
+ <script setup>
48
+ import { ref, onMounted, watch, reactive, computed } from "vue";
49
+ import util from "../../util"
50
+ import { useVModel } from '@vueuse/core'
51
+
52
+ const props = defineProps({
53
+ show: {
54
+ type: Boolean,
55
+ default: false,
56
+ },
57
+ // 默认查询所有组织机构
58
+ rootDeptId: {
59
+ type: String,
60
+ default: "1", //组织机构id
61
+ },
62
+ // 二级部门取值范围字典id
63
+ // 取dictionary库.dict的配置id
64
+ deptRangeId: {
65
+ type: String,
66
+ default: ''
67
+ }
68
+ });
69
+ // 定义emit
70
+ const emit = defineEmits(["update:show", "select"]);
71
+ // 弹出?
72
+ const show = useVModel(props, 'show', emit)
73
+ const data = reactive({
74
+ // 当前选中的机构
75
+ selectedDeptId: '',
76
+ // 所有的部门
77
+ totalDepts: [],
78
+ // 搜索关键字
79
+ keyword: "",
80
+ searchUsers: [],
81
+ selectedUser: null
82
+ })
83
+
84
+
85
+ // 查找部门路径列表
86
+ function findDeptPaths(targetDept, tree, path = []) {
87
+ if (!tree || tree.length < 1 || !targetDept || !targetDept.id)
88
+ return []
89
+
90
+ for (const dept of tree) {
91
+ if (dept.id === targetDept.id) {
92
+ return [...path, dept];
93
+ }
94
+ if (dept.subDepartments?.length) {
95
+ const found = findDeptPaths(targetDept, dept.subDepartments, [...path, dept]);
96
+ if (found && found.length > 0) return found;
97
+ }
98
+ }
99
+
100
+ return []
101
+ }
102
+
103
+ // 选中的部门
104
+ const selectedDept = computed(()=>{
105
+ if(!data.selectedDeptId)
106
+ return null
107
+
108
+ let targetDept = findDept(data.selectedDeptId,data.totalDepts)
109
+ return targetDept
110
+ })
111
+
112
+ //选中部门的路径:部门/科室
113
+ const pathsLabel = computed(() => {
114
+ let paths = findDeptPaths(selectedDept.value, data.totalDepts)
115
+ console.log("paths", paths);
116
+ let res = ''
117
+ paths.forEach((dept) => {
118
+ res += dept.name + "/";
119
+ })
120
+ return res
121
+ })
122
+
123
+ const subDepts = computed(() => {
124
+ if (data.keyword)
125
+ return []
126
+ else if (selectedDept.value)
127
+ return selectedDept.value.subDepartments
128
+ else
129
+ return data.totalDepts
130
+ })
131
+
132
+ const subUsers = computed(() => {
133
+ if (data.keyword)
134
+ return data.searchUsers
135
+ else if (selectedDept.value)
136
+ return selectedDept.value.users
137
+ else
138
+ return []
139
+ })
140
+
141
+ // 获得部门列表
142
+ const queryTotalDepts = async () => {
143
+ // 查询所有部门
144
+ const response = await util.get_subdepartments_users({ departmentId: props.rootDeptId, hasGrandson:false })
145
+ let level2Depts = []
146
+ if(response.data)
147
+ level2Depts = response.data.subDepartments
148
+
149
+ // 取配置的二级部门取值范围
150
+ let level2DeptIds = []
151
+ if (props.deptRangeId) {
152
+ let res = await util.dictionary_dict({ id: props.deptRangeId })
153
+ if (res.data.parseValue && res.data.parseValue.length > 0) {
154
+ level2DeptIds = res.data.parseValue
155
+ }
156
+ }
157
+
158
+ // 只保留指定二级部门列表
159
+ if (props.deptRangeId) {
160
+ if (level2DeptIds && level2DeptIds.length > 0) {
161
+ level2Depts = level2Depts.filter(item => {
162
+ return level2DeptIds.includes(item.id)
163
+ })
164
+ }
165
+ }
166
+
167
+ data.totalDepts = level2Depts || []
168
+ }
169
+
170
+ // 查找机构
171
+ function findDept(deptId, tree) {
172
+ if (!tree || tree.length < 1)
173
+ return null
174
+
175
+ for (const dept of tree) {
176
+ if (dept.id === deptId) {
177
+ return dept
178
+ }
179
+
180
+ const found = findDept(deptId, dept.subDepartments);
181
+ if (found) return found
182
+ }
183
+
184
+ return null
185
+ }
186
+
187
+ // 查找父机构
188
+ function findParentDept(deptId, tree) {
189
+ if (!tree || tree.length < 1)
190
+ return null
191
+
192
+ for (const dept of tree) {
193
+ if (!dept.subDepartments || dept.subDepartments.length < 1)
194
+ continue
195
+
196
+ let ary = dept.subDepartments.filter(item => item.id == deptId)
197
+ if (ary && ary.length > 0)
198
+ return dept
199
+
200
+ const found = findParentDept(deptId, dept.subDepartments);
201
+ if (found) return found
202
+ }
203
+
204
+ return null
205
+ }
206
+
207
+ // 搜索人员
208
+ const onSearch = async () => {
209
+ if (!data.keyword)
210
+ return
211
+
212
+ // 搜索用户
213
+ const res = await util.wx_user_list({ keyword: data.keyword, page: 1, limit: 10000 })
214
+ data.searchUsers = res.data.list
215
+ }
216
+
217
+ // 切换部门
218
+ const onSelectDept = async(department) => {
219
+ const res = await util.get_subdepartments_users({ departmentId: department.id, hasGrandson:false })
220
+ let targetDept = findDept(department.id, data.totalDepts)
221
+ targetDept.subDepartments = res.data.subDepartments
222
+ targetDept.users = res.data.users
223
+ data.selectedDeptId = department.id
224
+ }
225
+
226
+ // 返回上一级部门
227
+ const onBack = () => {
228
+ data.keyword = ""
229
+
230
+ let paths = findDeptPaths(selectedDept.value, data.totalDepts)
231
+ console.log('22222222', paths)
232
+ if (!paths || paths.length <= 1){
233
+ data.selectedDeptId = ''
234
+ return
235
+ }
236
+
237
+ data.selectedDeptId = paths[paths.length - 2].id
238
+ }
239
+
240
+ // 清除掉选中部门及人
241
+ const reset = () => {
242
+ // 当前选中的机构
243
+ data.selectedDeptId = ''
244
+ // 搜索关键字
245
+ data.keyword = ""
246
+ data.searchUsers = []
247
+ data.selectedUser = {}
248
+ }
249
+
250
+ // 确认按钮
251
+ const onSubmit = () => {
252
+ if (!data.selectedUser) {
253
+ util.warnToast("请选择用户")
254
+ return
255
+ }
256
+
257
+ emit('select', data.selectedUser)
258
+ show.value = false
259
+
260
+ reset()
261
+ }
262
+
263
+ // 取消按钮
264
+ const onCancel = () => {
265
+ show.value = false
266
+ reset()
267
+ };
268
+
269
+ //首页加载
270
+ onMounted(async () => {
271
+ await queryTotalDepts()
272
+ // 初始化当前父部门
273
+ data.selectedDept = findDept(props.rootDeptId, data.totalDepts)
274
+ })
275
+ </script>
276
+
277
+ <style scoped>
278
+ .user-popup {
279
+ width: 100%;
280
+ overflow: hidden;
281
+ }
282
+
283
+ .department-selector {
284
+ padding: 10px;
285
+ }
286
+
287
+ .search-buttons {
288
+ display: flex;
289
+ gap: 10px;
290
+ }
291
+
292
+ .clear-btn {
293
+ background-color: #f2f3f5;
294
+ border: none;
295
+ border-radius: 4px;
296
+ padding: 4px 8px;
297
+ font-size: 14px;
298
+ }
299
+
300
+ .confirm-btn {
301
+ background-color: #1989fa;
302
+ color: white;
303
+ border: none;
304
+ border-radius: 4px;
305
+ padding: 4px 8px;
306
+ font-size: 14px;
307
+ }
308
+
309
+ .no-results {
310
+ text-align: center;
311
+ padding: 20px;
312
+ color: #969799;
313
+ }
314
+
315
+ .picker-header {
316
+ padding: 10px;
317
+ border-bottom: 1px solid #ebedf0;
318
+ display: flex;
319
+ justify-content: space-between;
320
+ align-items: center;
321
+ }
322
+
323
+ .current-path {
324
+ flex: 1;
325
+ font-size: 14px;
326
+ color: #323233;
327
+ white-space: nowrap;
328
+ overflow: hidden;
329
+ text-overflow: ellipsis;
330
+ }
331
+
332
+ .header-right {
333
+ display: flex;
334
+ gap: 8px;
335
+ margin-left: auto;
336
+ }
337
+
338
+ .cancel-btn {
339
+ color: #969799;
340
+ margin-right: 5px;
341
+ }
342
+
343
+ .scroll-container {
344
+ height: calc(80vh - 150px);
345
+ overflow-y: auto;
346
+ }
347
+ </style>