wl-design-mobile 0.8.19 → 0.8.21

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 (101) hide show
  1. package/README.md +6 -6
  2. package/api/doc.js +25 -25
  3. package/api/x1.js +56 -56
  4. package/btn/components/lambo-info-btn.vue +123 -123
  5. package/btn/components/lambo-primary-btn.vue +117 -117
  6. package/btn/components/lambo-text-btn.vue +116 -116
  7. package/btn/lambo-btn-divide.vue +35 -120
  8. package/btn/lambo-btn-group.vue +46 -46
  9. package/btn/lambo-btn-split-line.vue +41 -41
  10. package/btn/lambo-btn.vue +68 -68
  11. package/btn/lambo-extend-btn.vue +121 -121
  12. package/btn/lambo-icon-btn.vue +82 -82
  13. package/card-item/card-row-icon.vue +71 -71
  14. package/card-item/filtrate-row.vue +73 -73
  15. package/card-item/lambo-card-footer.vue +40 -40
  16. package/card-item/lambo-card-head.vue +66 -66
  17. package/card-item/lambo-card-row.vue +59 -59
  18. package/collapse/lambo-collapse.vue +93 -93
  19. package/config/config.js +14 -14
  20. package/detail/lambo-detail-grid.vue +58 -58
  21. package/detail/lambo-detail-row.vue +59 -59
  22. package/doc/file/compoents/lambo-file-list.vue +42 -42
  23. package/doc/file/compoents/lambo-file-row.vue +77 -77
  24. package/doc/file/lambo-file-upload-collapse.vue +107 -107
  25. package/doc/file-type/file-type.js +286 -286
  26. package/doc/img/comonents/lambo-img-grid.vue +109 -109
  27. package/doc/img/lambo-img-upload-collapse.vue +107 -107
  28. package/doc/img/styles/css/index.css +3 -3
  29. package/edit/list/Lambo-edit-list.vue +87 -87
  30. package/edit/list/lambo-edit-card-group.vue +100 -100
  31. package/edit/list/styles/css/index.css +39 -39
  32. package/edit/select/lambo-edit-date-range.vue +147 -147
  33. package/edit/select/lambo-edit-date-time.vue +122 -122
  34. package/edit/select/lambo-edit-date.vue +120 -120
  35. package/edit/select/lambo-edit-input-textarea.vue +91 -91
  36. package/edit/select/lambo-edit-input.vue +91 -91
  37. package/edit/select/lambo-edit-multi-select.vue +168 -168
  38. package/edit/select/lambo-edit-search-single-select.vue +186 -186
  39. package/edit/select/lambo-edit-single-select.vue +162 -162
  40. package/edit/select/styles/css/index.css +133 -133
  41. package/flow/approval/flow-approval.vue +552 -552
  42. package/flow/comps/flow-attachment-list.vue +230 -230
  43. package/flow/comps/flow-attachment-modal.vue +194 -194
  44. package/flow/comps/flow-copy-users.vue +358 -358
  45. package/flow/comps/flow-node-card.vue +150 -150
  46. package/flow/comps/flow-node-header.vue +172 -172
  47. package/flow/comps/flow-util.js +156 -156
  48. package/flow/comps/icons/approved.svg +11 -11
  49. package/flow/comps/icons/canceled.svg +11 -11
  50. package/flow/comps/icons/rejected.svg +11 -11
  51. package/flow/comps/icons/underway.svg +11 -11
  52. package/flow/detail/flow-detail.vue +467 -467
  53. package/flow/index.js +51 -51
  54. package/flow/lambo-flow-detail.vue +912 -912
  55. package/flow/lambo-flow-edit.vue +15 -15
  56. package/flow/submit/flow-submit.vue +383 -383
  57. package/icon/lambo-required-red-star.vue +47 -47
  58. package/icon/lambo-vector-icon.vue +71 -71
  59. package/list/lambo-list.vue +412 -413
  60. package/nav/lambo-top-nav.vue +81 -81
  61. package/order/comps/icons/approved.svg +10 -10
  62. package/order/comps/icons/underway.svg +10 -10
  63. package/order/comps/order-attachment-list.vue +228 -228
  64. package/order/comps/order-attachment-modal.vue +194 -194
  65. package/order/comps/order-node-card.vue +126 -126
  66. package/order/comps/order-node-header.vue +133 -133
  67. package/order/comps/order-util.js +132 -132
  68. package/order/detail/order-detail.vue +432 -432
  69. package/order/handle/order-handle.vue +517 -517
  70. package/order/index.js +33 -33
  71. package/package.json +38 -37
  72. package/search/lambo-date-range-page.vue +196 -196
  73. package/search/lambo-date-range.vue +111 -111
  74. package/search/lambo-date.vue +105 -105
  75. package/search/lambo-input.vue +74 -74
  76. package/search/lambo-multi-select.vue +129 -129
  77. package/search/lambo-org-select-page.vue +109 -109
  78. package/search/lambo-search-box.vue +61 -61
  79. package/search/lambo-search-single-select.vue +152 -152
  80. package/search/lambo-single-select.vue +123 -123
  81. package/search/lambo-week-date-select.vue +521 -521
  82. package/search/styles/css/index.css +138 -138
  83. package/styles/base.less +77 -77
  84. package/styles/components/btn.less +7 -7
  85. package/styles/components/search.less +33 -33
  86. package/styles/components/tag.less +181 -181
  87. package/styles/index.less +4 -4
  88. package/table/lambo-ag-table.vue +227 -227
  89. package/tag/lambo-tag.vue +23 -23
  90. package/title/lambo-title1.vue +151 -151
  91. package/title/lambo-title2.vue +37 -37
  92. package/title/lambo-title3.vue +77 -77
  93. package/util/assist.js +43 -43
  94. package/util/axios/cacheconf.js +19 -19
  95. package/util/axios/index.js +11 -11
  96. package/util/axios/interceptors.js +101 -101
  97. package/util/bus.js +4 -4
  98. package/util/jssdk-sczy.js +104 -104
  99. package/util/jssdk.js +608 -565
  100. package/util/math.js +76 -76
  101. package/util/token.js +36 -36
@@ -1,358 +1,358 @@
1
- <template>
2
- <div class="copy-users-wrapper">
3
- <span v-if="showLabel" class="copy-label">抄送人:</span>
4
- <div class="copy-content">
5
- <div v-if="editable" class="copy-tags">
6
- <van-tag v-for="(user, index) in internalCopyUsers" :key="getUserKey(user, index)" closeable @close="removeUser(index)">
7
- {{ getUserName(user) }}
8
- </van-tag>
9
- <div class="add-btn" @click="handleAddClick">
10
- <van-icon name="plus" size="14"></van-icon>
11
- 添加
12
- </div>
13
- <span v-if="internalCopyUsers.length === 0" class="empty-text">无</span>
14
- </div>
15
- <div v-else class="avatar-list">
16
- <template v-for="(user, index) in displayUsers">
17
- <van-popup
18
- :key="'popup-' + index"
19
- v-model="user.popupVisible"
20
- position="top"
21
- :style="{ padding: '12px 16px' }"
22
- >
23
- <div class="copy-popup-name">{{ getUserName(user) }}</div>
24
- <div v-if="getUserDept(user)" class="copy-popup-dept">{{ getUserDept(user) }}</div>
25
- </van-popup>
26
- <div
27
- :key="'avatar-' + index"
28
- class="copy-avatar"
29
- :style="getAvatarStyle(index)"
30
- @click="user.popupVisible = true"
31
- >
32
- <img v-if="user.avatar" :src="user.avatar" alt="" />
33
- <span v-else>{{ getUserName(user) ? getUserName(user).charAt(0) : '' }}</span>
34
- </div>
35
- </template>
36
- <van-popup v-if="internalCopyUsers.length > maxDisplay" v-model="moreCopyPopupVisible" position="top" :style="{ padding: '12px 16px' }">
37
- <div v-for="(user, index) in remainingUsers" :key="getUserKey(user, index)" class="copy-popup-name">
38
- {{ getUserName(user) }}
39
- </div>
40
- </van-popup>
41
- <div v-if="internalCopyUsers.length > maxDisplay" class="avatar-excess" @click="moreCopyPopupVisible = true">
42
- +{{ internalCopyUsers.length - maxDisplay }}
43
- </div>
44
- <span v-if="internalCopyUsers.length === 0" class="empty-text">无</span>
45
- </div>
46
- </div>
47
-
48
- <!-- 抄送人选择弹窗 -->
49
- <van-popup v-model="showSelector" position="bottom" round>
50
- <div class="user-selector">
51
- <div class="selector-header">
52
- <span class="selector-title">选择抄送人</span>
53
- <van-icon name="cross" class="close-icon" @click="handleSelectorCancel"></van-icon>
54
- </div>
55
- <van-checkbox-group v-model="selectedUsers" class="checkbox-group">
56
- <van-checkbox v-for="(user, index) in availableUsers" :key="getUserKey(user, index)" :name="getUserKey(user, index)" class="checkbox-item">
57
- {{ getUserName(user) }}
58
- </van-checkbox>
59
- </van-checkbox-group>
60
- <div class="selector-footer">
61
- <van-button type="primary" block @click="confirmAddUsers">确定</van-button>
62
- </div>
63
- </div>
64
- </van-popup>
65
- </div>
66
- </template>
67
-
68
- <script>
69
- export default {
70
- name: 'FlowCopyUsers',
71
- props: {
72
- copyUsers: {
73
- type: Array,
74
- default: () => []
75
- },
76
- availableUsers: {
77
- type: Array,
78
- default: () => [
79
- { id: '1', name: '张三' },
80
- { id: '2', name: '李四' },
81
- { id: '3', name: '王五' },
82
- { id: '4', name: '赵六' },
83
- { id: '5', name: '钱七' },
84
- { id: '6', name: '孙八' }
85
- ]
86
- },
87
- maxDisplay: {
88
- type: Number,
89
- default: 3
90
- },
91
- avatarSize: {
92
- type: Number,
93
- default: 24
94
- },
95
- editable: {
96
- type: Boolean,
97
- default: false
98
- },
99
- showLabel: {
100
- type: Boolean,
101
- default: true
102
- },
103
- rowKey: {
104
- type: String,
105
- default: 'id'
106
- },
107
- rowName: {
108
- type: String,
109
- default: 'name'
110
- }
111
- },
112
- data() {
113
- return {
114
- showSelector: false,
115
- moreCopyPopupVisible: false,
116
- selectedUsers: [],
117
- internalCopyUsers: []
118
- }
119
- },
120
- watch: {
121
- copyUsers: {
122
- immediate: true,
123
- deep: true,
124
- handler(val) {
125
- this.internalCopyUsers = [...val].map(u => ({ ...u, popupVisible: false }))
126
- }
127
- },
128
- showSelector(val) {
129
- if (val) {
130
- this.selectedUsers = this.internalCopyUsers.map((u, index) => this.getUserKey(u, index))
131
- }
132
- }
133
- },
134
- computed: {
135
- displayUsers() {
136
- return this.internalCopyUsers.slice(0, this.maxDisplay)
137
- },
138
- remainingUsers() {
139
- return this.internalCopyUsers.slice(this.maxDisplay)
140
- }
141
- },
142
- methods: {
143
- getUserKey(user, index = 0) {
144
- return user[this.rowKey] || user.id || user.loginName || String(index)
145
- },
146
- getUserName(user) {
147
- return user[this.rowName] || user.name || user.displayName || ''
148
- },
149
- getUserDept(user) {
150
- return user.dept || user.orgNodeName || ''
151
- },
152
- cleanUsers(users) {
153
- return users.map(user => {
154
- const item = { ...user }
155
- delete item.popupVisible
156
- return item
157
- })
158
- },
159
- getAvatarStyle(index) {
160
- if (index === 0) return {}
161
- return {
162
- marginLeft: '-10px'
163
- }
164
- },
165
- emitChange() {
166
- this.$emit('change', this.cleanUsers(this.internalCopyUsers))
167
- },
168
- removeUser(index) {
169
- this.internalCopyUsers.splice(index, 1)
170
- this.emitChange()
171
- },
172
- handleAddClick() {
173
- this.$emit('add-copy-users')
174
- this.showSelector = true
175
- },
176
- handleSelectorCancel() {
177
- this.selectedUsers = []
178
- this.showSelector = false
179
- },
180
- confirmAddUsers() {
181
- this.internalCopyUsers = this.selectedUsers.map(id =>
182
- this.availableUsers.find((user, index) => this.getUserKey(user, index) === id)
183
- ).filter(Boolean).map(u => ({ ...u, popupVisible: false }))
184
- this.emitChange()
185
- this.selectedUsers = []
186
- this.showSelector = false
187
- }
188
- }
189
- }
190
- </script>
191
-
192
- <style scoped>
193
- .copy-users-wrapper {
194
- display: flex;
195
- align-items: center;
196
- }
197
-
198
- .copy-label {
199
- font-size: 13px;
200
- color: #8c8c8c;
201
- flex-shrink: 0;
202
- }
203
-
204
- .copy-content {
205
- flex: 1;
206
- min-width: 0;
207
- }
208
-
209
- .copy-tags {
210
- display: flex;
211
- align-items: center;
212
- flex-wrap: wrap;
213
- gap: 6px;
214
- }
215
-
216
- .add-btn {
217
- display: inline-flex;
218
- align-items: center;
219
- gap: 4px;
220
- height: 26px;
221
- padding: 0 10px;
222
- border: 1px dashed #c8c9cc;
223
- border-radius: 4px;
224
- font-size: 12px;
225
- color: #646566;
226
- background: #fff;
227
- cursor: pointer;
228
- transition: all 0.2s;
229
- }
230
-
231
- .add-btn:hover {
232
- border-color: #1989fa;
233
- color: #1989fa;
234
- }
235
-
236
- .avatar-list {
237
- display: flex;
238
- align-items: center;
239
- }
240
-
241
- .copy-avatar {
242
- width: 24px;
243
- height: 24px;
244
- border-radius: 50%;
245
- display: flex;
246
- align-items: center;
247
- justify-content: center;
248
- background: #1989fa;
249
- color: #fff;
250
- font-size: 12px;
251
- border: 2px solid #fff;
252
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
253
- cursor: pointer;
254
- transition: transform 0.2s, box-shadow 0.2s;
255
- overflow: hidden;
256
- flex-shrink: 0;
257
- }
258
-
259
- .copy-avatar img {
260
- width: 100%;
261
- height: 100%;
262
- object-fit: cover;
263
- }
264
-
265
- .copy-avatar:hover {
266
- transform: scale(1.1);
267
- box-shadow: 0 2px 8px rgba(25, 137, 250, 0.3);
268
- z-index: 10;
269
- position: relative;
270
- }
271
-
272
- .avatar-excess {
273
- width: 24px;
274
- height: 24px;
275
- line-height: 20px;
276
- text-align: center;
277
- border-radius: 50%;
278
- background: #1989fa;
279
- color: #fff;
280
- font-size: 11px;
281
- margin-left: -10px;
282
- border: 2px solid #fff;
283
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
284
- cursor: pointer;
285
- transition: transform 0.2s, box-shadow 0.2s;
286
- flex-shrink: 0;
287
- }
288
-
289
- .avatar-excess:hover {
290
- transform: scale(1.1);
291
- box-shadow: 0 2px 8px rgba(25, 137, 250, 0.3);
292
- z-index: 10;
293
- position: relative;
294
- }
295
-
296
- .empty-text {
297
- font-size: 12px;
298
- color: #bfbfbf;
299
- }
300
-
301
- .copy-popup-name {
302
- font-size: 14px;
303
- color: #323233;
304
- line-height: 1.5;
305
- }
306
-
307
- .copy-popup-dept {
308
- font-size: 12px;
309
- color: #969799;
310
- line-height: 1.5;
311
- }
312
-
313
- .user-selector {
314
- max-height: 60vh;
315
- display: flex;
316
- flex-direction: column;
317
- }
318
-
319
- .selector-header {
320
- display: flex;
321
- align-items: center;
322
- justify-content: space-between;
323
- padding: 16px;
324
- border-bottom: 1px solid #f0f0f0;
325
- }
326
-
327
- .selector-title {
328
- font-size: 16px;
329
- font-weight: 600;
330
- color: #323233;
331
- }
332
-
333
- .close-icon {
334
- font-size: 20px;
335
- color: #c8c9cc;
336
- cursor: pointer;
337
- }
338
-
339
- .checkbox-group {
340
- flex: 1;
341
- overflow-y: auto;
342
- padding: 12px 16px;
343
- }
344
-
345
- .checkbox-item {
346
- padding: 12px 0;
347
- border-bottom: 1px solid #f7f8fa;
348
- }
349
-
350
- .checkbox-item:last-child {
351
- border-bottom: none;
352
- }
353
-
354
- .selector-footer {
355
- padding: 12px 16px;
356
- border-top: 1px solid #f0f0f0;
357
- }
358
- </style>
1
+ <template>
2
+ <div class="copy-users-wrapper">
3
+ <span v-if="showLabel" class="copy-label">抄送人:</span>
4
+ <div class="copy-content">
5
+ <div v-if="editable" class="copy-tags">
6
+ <van-tag v-for="(user, index) in internalCopyUsers" :key="getUserKey(user, index)" closeable @close="removeUser(index)">
7
+ {{ getUserName(user) }}
8
+ </van-tag>
9
+ <div class="add-btn" @click="handleAddClick">
10
+ <van-icon name="plus" size="14"></van-icon>
11
+ 添加
12
+ </div>
13
+ <span v-if="internalCopyUsers.length === 0" class="empty-text">无</span>
14
+ </div>
15
+ <div v-else class="avatar-list">
16
+ <template v-for="(user, index) in displayUsers">
17
+ <van-popup
18
+ :key="'popup-' + index"
19
+ v-model="user.popupVisible"
20
+ position="top"
21
+ :style="{ padding: '12px 16px' }"
22
+ >
23
+ <div class="copy-popup-name">{{ getUserName(user) }}</div>
24
+ <div v-if="getUserDept(user)" class="copy-popup-dept">{{ getUserDept(user) }}</div>
25
+ </van-popup>
26
+ <div
27
+ :key="'avatar-' + index"
28
+ class="copy-avatar"
29
+ :style="getAvatarStyle(index)"
30
+ @click="user.popupVisible = true"
31
+ >
32
+ <img v-if="user.avatar" :src="user.avatar" alt="" />
33
+ <span v-else>{{ getUserName(user) ? getUserName(user).charAt(0) : '' }}</span>
34
+ </div>
35
+ </template>
36
+ <van-popup v-if="internalCopyUsers.length > maxDisplay" v-model="moreCopyPopupVisible" position="top" :style="{ padding: '12px 16px' }">
37
+ <div v-for="(user, index) in remainingUsers" :key="getUserKey(user, index)" class="copy-popup-name">
38
+ {{ getUserName(user) }}
39
+ </div>
40
+ </van-popup>
41
+ <div v-if="internalCopyUsers.length > maxDisplay" class="avatar-excess" @click="moreCopyPopupVisible = true">
42
+ +{{ internalCopyUsers.length - maxDisplay }}
43
+ </div>
44
+ <span v-if="internalCopyUsers.length === 0" class="empty-text">无</span>
45
+ </div>
46
+ </div>
47
+
48
+ <!-- 抄送人选择弹窗 -->
49
+ <van-popup v-model="showSelector" position="bottom" round>
50
+ <div class="user-selector">
51
+ <div class="selector-header">
52
+ <span class="selector-title">选择抄送人</span>
53
+ <van-icon name="cross" class="close-icon" @click="handleSelectorCancel"></van-icon>
54
+ </div>
55
+ <van-checkbox-group v-model="selectedUsers" class="checkbox-group">
56
+ <van-checkbox v-for="(user, index) in availableUsers" :key="getUserKey(user, index)" :name="getUserKey(user, index)" class="checkbox-item">
57
+ {{ getUserName(user) }}
58
+ </van-checkbox>
59
+ </van-checkbox-group>
60
+ <div class="selector-footer">
61
+ <van-button type="primary" block @click="confirmAddUsers">确定</van-button>
62
+ </div>
63
+ </div>
64
+ </van-popup>
65
+ </div>
66
+ </template>
67
+
68
+ <script>
69
+ export default {
70
+ name: 'FlowCopyUsers',
71
+ props: {
72
+ copyUsers: {
73
+ type: Array,
74
+ default: () => []
75
+ },
76
+ availableUsers: {
77
+ type: Array,
78
+ default: () => [
79
+ { id: '1', name: '张三' },
80
+ { id: '2', name: '李四' },
81
+ { id: '3', name: '王五' },
82
+ { id: '4', name: '赵六' },
83
+ { id: '5', name: '钱七' },
84
+ { id: '6', name: '孙八' }
85
+ ]
86
+ },
87
+ maxDisplay: {
88
+ type: Number,
89
+ default: 3
90
+ },
91
+ avatarSize: {
92
+ type: Number,
93
+ default: 24
94
+ },
95
+ editable: {
96
+ type: Boolean,
97
+ default: false
98
+ },
99
+ showLabel: {
100
+ type: Boolean,
101
+ default: true
102
+ },
103
+ rowKey: {
104
+ type: String,
105
+ default: 'id'
106
+ },
107
+ rowName: {
108
+ type: String,
109
+ default: 'name'
110
+ }
111
+ },
112
+ data() {
113
+ return {
114
+ showSelector: false,
115
+ moreCopyPopupVisible: false,
116
+ selectedUsers: [],
117
+ internalCopyUsers: []
118
+ }
119
+ },
120
+ watch: {
121
+ copyUsers: {
122
+ immediate: true,
123
+ deep: true,
124
+ handler(val) {
125
+ this.internalCopyUsers = [...val].map(u => ({ ...u, popupVisible: false }))
126
+ }
127
+ },
128
+ showSelector(val) {
129
+ if (val) {
130
+ this.selectedUsers = this.internalCopyUsers.map((u, index) => this.getUserKey(u, index))
131
+ }
132
+ }
133
+ },
134
+ computed: {
135
+ displayUsers() {
136
+ return this.internalCopyUsers.slice(0, this.maxDisplay)
137
+ },
138
+ remainingUsers() {
139
+ return this.internalCopyUsers.slice(this.maxDisplay)
140
+ }
141
+ },
142
+ methods: {
143
+ getUserKey(user, index = 0) {
144
+ return user[this.rowKey] || user.id || user.loginName || String(index)
145
+ },
146
+ getUserName(user) {
147
+ return user[this.rowName] || user.name || user.displayName || ''
148
+ },
149
+ getUserDept(user) {
150
+ return user.dept || user.orgNodeName || ''
151
+ },
152
+ cleanUsers(users) {
153
+ return users.map(user => {
154
+ const item = { ...user }
155
+ delete item.popupVisible
156
+ return item
157
+ })
158
+ },
159
+ getAvatarStyle(index) {
160
+ if (index === 0) return {}
161
+ return {
162
+ marginLeft: '-10px'
163
+ }
164
+ },
165
+ emitChange() {
166
+ this.$emit('change', this.cleanUsers(this.internalCopyUsers))
167
+ },
168
+ removeUser(index) {
169
+ this.internalCopyUsers.splice(index, 1)
170
+ this.emitChange()
171
+ },
172
+ handleAddClick() {
173
+ this.$emit('add-copy-users')
174
+ this.showSelector = true
175
+ },
176
+ handleSelectorCancel() {
177
+ this.selectedUsers = []
178
+ this.showSelector = false
179
+ },
180
+ confirmAddUsers() {
181
+ this.internalCopyUsers = this.selectedUsers.map(id =>
182
+ this.availableUsers.find((user, index) => this.getUserKey(user, index) === id)
183
+ ).filter(Boolean).map(u => ({ ...u, popupVisible: false }))
184
+ this.emitChange()
185
+ this.selectedUsers = []
186
+ this.showSelector = false
187
+ }
188
+ }
189
+ }
190
+ </script>
191
+
192
+ <style scoped>
193
+ .copy-users-wrapper {
194
+ display: flex;
195
+ align-items: center;
196
+ }
197
+
198
+ .copy-label {
199
+ font-size: 13px;
200
+ color: #8c8c8c;
201
+ flex-shrink: 0;
202
+ }
203
+
204
+ .copy-content {
205
+ flex: 1;
206
+ min-width: 0;
207
+ }
208
+
209
+ .copy-tags {
210
+ display: flex;
211
+ align-items: center;
212
+ flex-wrap: wrap;
213
+ gap: 6px;
214
+ }
215
+
216
+ .add-btn {
217
+ display: inline-flex;
218
+ align-items: center;
219
+ gap: 4px;
220
+ height: 26px;
221
+ padding: 0 10px;
222
+ border: 1px dashed #c8c9cc;
223
+ border-radius: 4px;
224
+ font-size: 12px;
225
+ color: #646566;
226
+ background: #fff;
227
+ cursor: pointer;
228
+ transition: all 0.2s;
229
+ }
230
+
231
+ .add-btn:hover {
232
+ border-color: #1989fa;
233
+ color: #1989fa;
234
+ }
235
+
236
+ .avatar-list {
237
+ display: flex;
238
+ align-items: center;
239
+ }
240
+
241
+ .copy-avatar {
242
+ width: 24px;
243
+ height: 24px;
244
+ border-radius: 50%;
245
+ display: flex;
246
+ align-items: center;
247
+ justify-content: center;
248
+ background: #1989fa;
249
+ color: #fff;
250
+ font-size: 12px;
251
+ border: 2px solid #fff;
252
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
253
+ cursor: pointer;
254
+ transition: transform 0.2s, box-shadow 0.2s;
255
+ overflow: hidden;
256
+ flex-shrink: 0;
257
+ }
258
+
259
+ .copy-avatar img {
260
+ width: 100%;
261
+ height: 100%;
262
+ object-fit: cover;
263
+ }
264
+
265
+ .copy-avatar:hover {
266
+ transform: scale(1.1);
267
+ box-shadow: 0 2px 8px rgba(25, 137, 250, 0.3);
268
+ z-index: 10;
269
+ position: relative;
270
+ }
271
+
272
+ .avatar-excess {
273
+ width: 24px;
274
+ height: 24px;
275
+ line-height: 20px;
276
+ text-align: center;
277
+ border-radius: 50%;
278
+ background: #1989fa;
279
+ color: #fff;
280
+ font-size: 11px;
281
+ margin-left: -10px;
282
+ border: 2px solid #fff;
283
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
284
+ cursor: pointer;
285
+ transition: transform 0.2s, box-shadow 0.2s;
286
+ flex-shrink: 0;
287
+ }
288
+
289
+ .avatar-excess:hover {
290
+ transform: scale(1.1);
291
+ box-shadow: 0 2px 8px rgba(25, 137, 250, 0.3);
292
+ z-index: 10;
293
+ position: relative;
294
+ }
295
+
296
+ .empty-text {
297
+ font-size: 12px;
298
+ color: #bfbfbf;
299
+ }
300
+
301
+ .copy-popup-name {
302
+ font-size: 14px;
303
+ color: #323233;
304
+ line-height: 1.5;
305
+ }
306
+
307
+ .copy-popup-dept {
308
+ font-size: 12px;
309
+ color: #969799;
310
+ line-height: 1.5;
311
+ }
312
+
313
+ .user-selector {
314
+ max-height: 60vh;
315
+ display: flex;
316
+ flex-direction: column;
317
+ }
318
+
319
+ .selector-header {
320
+ display: flex;
321
+ align-items: center;
322
+ justify-content: space-between;
323
+ padding: 16px;
324
+ border-bottom: 1px solid #f0f0f0;
325
+ }
326
+
327
+ .selector-title {
328
+ font-size: 16px;
329
+ font-weight: 600;
330
+ color: #323233;
331
+ }
332
+
333
+ .close-icon {
334
+ font-size: 20px;
335
+ color: #c8c9cc;
336
+ cursor: pointer;
337
+ }
338
+
339
+ .checkbox-group {
340
+ flex: 1;
341
+ overflow-y: auto;
342
+ padding: 12px 16px;
343
+ }
344
+
345
+ .checkbox-item {
346
+ padding: 12px 0;
347
+ border-bottom: 1px solid #f7f8fa;
348
+ }
349
+
350
+ .checkbox-item:last-child {
351
+ border-bottom: none;
352
+ }
353
+
354
+ .selector-footer {
355
+ padding: 12px 16px;
356
+ border-top: 1px solid #f0f0f0;
357
+ }
358
+ </style>