@jari-ace/element-plus-component 0.2.1 → 0.2.2

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 (145) hide show
  1. package/README.md +1 -1
  2. package/dist/components/form/JaForm.vue.d.ts +3 -0
  3. package/dist/components/form/JaForm.vue.d.ts.map +1 -1
  4. package/dist/components/form/JaForm.vue.js +22 -68
  5. package/dist/components/form/JaForm.vue.js.map +1 -1
  6. package/dist/components/formItem/JaFormItem.vue.d.ts +4 -0
  7. package/dist/components/formItem/JaFormItem.vue.d.ts.map +1 -1
  8. package/dist/components/formItem/JaFormItem.vue.js +26 -8
  9. package/dist/components/formItem/JaFormItem.vue.js.map +1 -1
  10. package/dist/components/userPicker/src/JaUserList.vue.d.ts.map +1 -1
  11. package/dist/components/userPicker/src/JaUserList.vue.js +41 -7
  12. package/dist/components/userPicker/src/JaUserList.vue.js.map +1 -1
  13. package/dist/components/userPicker/src/JaUserPicker.vue.d.ts +9 -2
  14. package/dist/components/userPicker/src/JaUserPicker.vue.d.ts.map +1 -1
  15. package/dist/components/userPicker/src/JaUserPicker.vue.js +7 -2
  16. package/dist/components/userPicker/src/JaUserPicker.vue.js.map +1 -1
  17. package/dist/components/userPicker/src/UserPicker.vue.d.ts +33 -112
  18. package/dist/components/userPicker/src/UserPicker.vue.d.ts.map +1 -1
  19. package/dist/components/userPicker/src/UserPicker.vue.js +262 -288
  20. package/dist/components/userPicker/src/UserPicker.vue.js.map +1 -1
  21. package/dist/utils/formUtils.d.ts +7 -0
  22. package/dist/utils/formUtils.d.ts.map +1 -0
  23. package/dist/utils/formUtils.js +54 -0
  24. package/dist/utils/formUtils.js.map +1 -0
  25. package/lib/index.css +1 -1
  26. package/lib/index.js +2069 -2033
  27. package/lib/index.umd.cjs +2 -2
  28. package/package.json +61 -61
  29. package/packages/components/autoComplete/JaAutoComplete.vue +47 -47
  30. package/packages/components/autoComplete/index.ts +5 -5
  31. package/packages/components/avatar/JaAvatar.vue +126 -126
  32. package/packages/components/avatar/avatarToken.ts +11 -11
  33. package/packages/components/avatar/defaultImg.ts +14 -14
  34. package/packages/components/avatar/index.ts +7 -7
  35. package/packages/components/button/JaButton.vue +51 -51
  36. package/packages/components/button/index.ts +4 -4
  37. package/packages/components/channelPicker/index.ts +7 -7
  38. package/packages/components/channelPicker/src/ChannelPicker.vue +43 -43
  39. package/packages/components/channelPicker/src/JaChannelPicker.vue +42 -42
  40. package/packages/components/checkbox/JaCheckbox.vue +73 -73
  41. package/packages/components/checkbox/index.ts +4 -4
  42. package/packages/components/checkboxGroup/JaCheckboxGroup.vue +45 -45
  43. package/packages/components/checkboxGroup/index.ts +4 -4
  44. package/packages/components/customGroupTree/index.ts +10 -10
  45. package/packages/components/customGroupTree/src/customGroupTree.vue +91 -91
  46. package/packages/components/datePicker/JaDatePicker.vue +52 -52
  47. package/packages/components/datePicker/index.ts +4 -4
  48. package/packages/components/departmentPicker/index.ts +4 -4
  49. package/packages/components/departmentPicker/src/DepartmentPicker.vue +107 -107
  50. package/packages/components/departmentPicker/src/consts.ts +2 -2
  51. package/packages/components/departmentTree/index.ts +10 -10
  52. package/packages/components/departmentTree/src/departmentTree.vue +135 -135
  53. package/packages/components/dropdownButton/JaDropdownButton.vue +59 -59
  54. package/packages/components/dropdownButton/index.ts +4 -4
  55. package/packages/components/enumList/EnumListInput.vue +107 -107
  56. package/packages/components/enumList/JaEnumList.vue +39 -39
  57. package/packages/components/enumList/index.ts +7 -7
  58. package/packages/components/enumPicker/index.ts +5 -5
  59. package/packages/components/enumPicker/src/EnumPicker.vue +103 -103
  60. package/packages/components/form/JaForm.vue +146 -186
  61. package/packages/components/form/index.ts +5 -5
  62. package/packages/components/form/types.ts +4 -4
  63. package/packages/components/formItem/JaFormItem.vue +87 -68
  64. package/packages/components/formItem/index.ts +4 -4
  65. package/packages/components/index.ts +34 -34
  66. package/packages/components/input/JaInput.vue +143 -143
  67. package/packages/components/input/index.ts +4 -4
  68. package/packages/components/inputI18n/I18nBundleEditor.vue +76 -76
  69. package/packages/components/inputI18n/InputI18n.vue +146 -146
  70. package/packages/components/inputI18n/JaInputI18n.vue +50 -50
  71. package/packages/components/inputI18n/index.ts +8 -8
  72. package/packages/components/inputNumber/JaInputNumber.vue +98 -98
  73. package/packages/components/inputNumber/index.ts +4 -4
  74. package/packages/components/mapItemList/JaMapItemList.vue +35 -35
  75. package/packages/components/mapItemList/MapItemListInput.vue +191 -191
  76. package/packages/components/mapItemList/index.ts +7 -7
  77. package/packages/components/numberList/JaNumberList.vue +36 -36
  78. package/packages/components/numberList/NumberListInput.vue +111 -111
  79. package/packages/components/numberList/index.ts +7 -7
  80. package/packages/components/properyPicker/JaPropertyPicker.vue +38 -38
  81. package/packages/components/properyPicker/PropertyPicker.vue +314 -314
  82. package/packages/components/properyPicker/index.ts +7 -7
  83. package/packages/components/radioGroup/JaRadioGroup.vue +50 -50
  84. package/packages/components/radioGroup/index.ts +4 -4
  85. package/packages/components/rolePicker/RoleEditor.vue +129 -129
  86. package/packages/components/rolePicker/RolePicker.vue +44 -44
  87. package/packages/components/rolePicker/RolePickerRaw.vue +56 -56
  88. package/packages/components/rolePicker/baseRolePicker.vue +87 -87
  89. package/packages/components/rolePicker/index.ts +10 -10
  90. package/packages/components/scrollbar/Scrollbar.vue +89 -89
  91. package/packages/components/scrollbar/index.ts +5 -5
  92. package/packages/components/scrollbar/utils.ts +17 -17
  93. package/packages/components/select/JaSelect.vue +48 -48
  94. package/packages/components/select/index.ts +4 -4
  95. package/packages/components/stringList/JaStringList.vue +36 -36
  96. package/packages/components/stringList/StringListInput.vue +96 -96
  97. package/packages/components/stringList/index.ts +7 -7
  98. package/packages/components/switch/JaSwitch.vue +50 -50
  99. package/packages/components/switch/index.ts +4 -4
  100. package/packages/components/timePicker/JaTimePicker.vue +52 -52
  101. package/packages/components/timePicker/index.ts +5 -5
  102. package/packages/components/tip/index.ts +4 -4
  103. package/packages/components/tip/src/AceTip.vue +43 -43
  104. package/packages/components/upload/index.ts +6 -6
  105. package/packages/components/upload/src/Upload.vue +25 -25
  106. package/packages/components/upload/src/type.ts +3 -3
  107. package/packages/components/userGroupPicker/index.ts +4 -4
  108. package/packages/components/userGroupPicker/src/UserGroupPicker.vue +94 -94
  109. package/packages/components/userGroupTree/index.ts +10 -10
  110. package/packages/components/userGroupTree/src/userGroupTree.vue +149 -149
  111. package/packages/components/userPicker/index.ts +10 -10
  112. package/packages/components/userPicker/src/CustomGroupManager.vue +189 -189
  113. package/packages/components/userPicker/src/JaUserList.vue +317 -283
  114. package/packages/components/userPicker/src/JaUserPicker.vue +40 -37
  115. package/packages/components/userPicker/src/UserPicker.vue +472 -376
  116. package/packages/components/userSelectDialog/index.ts +6 -6
  117. package/packages/components/userSelectDialog/src/userSelectDialog.vue +462 -462
  118. package/packages/components/userTag/UserInfoTag.vue +397 -397
  119. package/packages/components/userTag/index.ts +6 -6
  120. package/packages/components/userTag/sharedAxios.ts +8 -8
  121. package/packages/directives/auth/index.ts +41 -41
  122. package/packages/directives/autofocus/index.ts +29 -29
  123. package/packages/directives/index.ts +10 -10
  124. package/packages/directives/shortcut/index.ts +192 -192
  125. package/packages/hooks/useAppInstances.ts +34 -34
  126. package/packages/hooks/useBackendValidations.ts +81 -81
  127. package/packages/hooks/useBridage.ts +157 -157
  128. package/packages/hooks/useClassificationLevels.ts +62 -62
  129. package/packages/hooks/useDateTimeShortCuts.ts +65 -65
  130. package/packages/hooks/useRealms.ts +28 -28
  131. package/packages/hooks/useTreeData.ts +45 -45
  132. package/packages/hooks/useUserRefQuery.ts +232 -232
  133. package/packages/index.ts +24 -24
  134. package/packages/list.json +7 -7
  135. package/packages/types/custom.d.ts +13 -13
  136. package/packages/types/window.d.ts +16 -16
  137. package/packages/utils/formUtils.ts +57 -0
  138. package/packages/utils/install.ts +43 -43
  139. package/packages/utils/objectUtils.ts +31 -31
  140. package/theme-style/fonts/iconfont.json +5196 -5196
  141. package/theme-style/index.scss +10 -10
  142. package/theme-style/styles/element-plus-var.scss +1419 -1419
  143. package/theme-style/styles/iconfont.css +2979 -2979
  144. package/theme-style/styles/theme-var.scss +72 -72
  145. package/theme-style/styles/transition.scss +122 -122
@@ -1,397 +1,397 @@
1
- <script setup lang="ts">
2
- import {onUnmounted, type Ref, ref} from "vue";
3
- import {Close, Star, StarFilled} from "@element-plus/icons-vue";
4
- import {type IAceAxios, useLoading, type User, useUserApi} from "@jari-ace/app-bolts";
5
- import {JaAvatar} from "../avatar";
6
- import {ElIcon, ElPopover, ElTooltip, vLoading} from "element-plus";
7
- import {useAxios} from "./sharedAxios";
8
-
9
- const themeClass = {
10
- primary: "user-info-tag--root theme-primary",
11
- success: "user-info-tag--root theme-success",
12
- warning: "user-info-tag--root theme-warning",
13
- danger: "user-info-tag--root theme-danger",
14
- info: "user-info-tag--root theme-info",
15
- lotusPink: "user-info-tag--root theme-lotus-pink",
16
- wineRed: "user-info-tag--root theme-wine-red",
17
- autumnOrange: "user-info-tag--root theme-autumn-orange",
18
- sunYellow: "user-info-tag--root theme-sun-yellow",
19
- seaBlue: "user-info-tag--root theme-sea-blue",
20
- moonlightBlue: "user-info-tag--root theme-moonlight-blue",
21
- clovePurple: "user-info-tag--root theme-clove-purple",
22
- skyGray: "user-info-tag--root theme-sky-gray"
23
- }
24
-
25
- const props = withDefaults(defineProps<{
26
- closable?: boolean,
27
- userId?: string,
28
- fullName?: string,
29
- realm?: string,
30
- username?: string,
31
- theme?: keyof typeof themeClass,
32
- hasAvatar?: boolean,
33
- placement?: 'top' | 'top-start' | 'top-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'left' | 'left-start' | 'left-end' | 'right' | 'right-start' | 'right-end'
34
- }>(), {
35
- closable: false,
36
- fullName: "无名氏",
37
- theme: "skyGray",
38
- placement: "bottom"
39
- })
40
-
41
- const user = ref<User>();
42
- let axios: IAceAxios | undefined = useAxios();
43
- let loading: Ref<Boolean> | undefined = useLoading(axios);
44
- let api: ReturnType<typeof useUserApi> | undefined = useUserApi(axios);
45
- const bookmarked = ref(false)
46
- const visible = ref(false);
47
- const emit = defineEmits<{
48
- (e: 'closed', userId?: string, realm?: string, userName?: string): void
49
- }>()
50
-
51
- onUnmounted(() => {
52
- axios = undefined;
53
- loading = undefined;
54
- api = undefined;
55
- });
56
-
57
- function onPop() {
58
- if (!user.value) {
59
- if (props.userId) {
60
- api?.getById(props.userId).then(r => {
61
- user.value = r;
62
- getBookmarkState();
63
- });
64
- } else if (props.username && props.realm) {
65
- let username = props.username;
66
- if (username.indexOf('\\') >= 0) {
67
- const arr = username.split('\\');
68
- username = arr[arr.length - 1];
69
- }
70
- api?.getByUserName(props.realm, username).then(r => {
71
- user.value = r;
72
- getBookmarkState();
73
- });
74
- } else {
75
- throw new Error("user-info-tag组件的userId和(realm, userName)属性不能都为空")
76
- }
77
- }
78
- }
79
-
80
- function getBookmarkState() {
81
- if (!user.value) return;
82
- api?.checkBookmarked(user.value.id).then(r => bookmarked.value = r);
83
- }
84
-
85
- function onClosed() {
86
- visible.value = false
87
- emit('closed', props.userId, props.realm, props.username)
88
- }
89
-
90
- function doBookmark() {
91
- if (!user.value) return;
92
- api?.bookmarkUser(user.value.id).then(() => bookmarked.value = true);
93
- }
94
-
95
- function doUnbookmark() {
96
- if (!user.value) return;
97
- api?.unbookmarkUser(user.value.id).then(() => bookmarked.value = false);
98
- }
99
-
100
- </script>
101
-
102
- <template>
103
- <el-popover width="auto" :hide-after="200" @before-enter="onPop" :placement="placement"
104
- v-model:visible="visible">
105
- <template #reference>
106
- <div :class="themeClass[props.theme]">
107
- <div class="portrait">
108
- <ja-avatar :size="24" :user-id="userId" :realm="realm"
109
- :username="username" :has-avatar="false"></ja-avatar>
110
- </div>
111
- <div class="user-info">
112
- {{ fullName }}
113
- <div v-if="closable" class="close-btn" @click="onClosed()">
114
- <el-icon :size="10">
115
- <Close/>
116
- </el-icon>
117
- </div>
118
- </div>
119
- </div>
120
- </template>
121
- <template #default>
122
- <div
123
- class="dropdown" v-show="visible" v-loading="!!loading">
124
- <div class="header">
125
- <ja-avatar :user-id="userId" :realm="realm"
126
- :username="username"
127
- :size="75"
128
- :has-avatar="user?.hasAvatar"
129
- style="margin-bottom: 8px"/>
130
- <div class="tools">
131
- <el-tooltip :content="bookmarked ? '取消常用人员': '设置为常用人员'">
132
- <el-icon v-if="!bookmarked" @click="doBookmark()" :size="16">
133
- <Star></Star>
134
- </el-icon>
135
- <el-icon v-else color="#FFBF29" @click="doUnbookmark()" :size="16">
136
- <star-filled></star-filled>
137
- </el-icon>
138
- </el-tooltip>
139
- </div>
140
- </div>
141
- <div>
142
- <p
143
- style="margin: 0; font-weight: 600">
144
- {{ fullName }}
145
- </p>
146
- <p
147
- style="margin: 0; font-size: 14px; color: var(--el-color-info-light-3)">
148
- @{{ user?.department?.name ?? "无归属部门" }}
149
- </p>
150
- </div>
151
- <p style="margin: 0;">
152
- <span class="label">手机:</span> {{
153
- !user?.mobile || user.mobile.length === 0 ? "(未填写手机号)" : user?.mobile
154
- }} <br/>
155
- <span class="label">邮箱:</span>
156
- {{ !user?.email || user.email.length === 0 ? "(未填写邮箱号)" : user?.email }}
157
- </p>
158
- </div>
159
- </template>
160
- </el-popover>
161
-
162
- </template>
163
-
164
- <style scoped lang="scss">
165
- .user-info-tag--root {
166
- align-items: center;
167
-
168
- border-radius: 28px;
169
- display: inline-flex;
170
- height: 28px;
171
- max-width: 100%;
172
- padding-right: 10px;
173
- position: relative;
174
- vertical-align: top;
175
- gap: 8px;
176
- cursor: default;
177
-
178
-
179
- &.theme-info {
180
- background-color: var(--el-color-info-light-9);
181
- color: var(--el-color-info);
182
- border: 1px solid var(--el-color-info-light-7);
183
- }
184
-
185
- &.theme-primary {
186
- background-color: var(--el-color-primary-light-9);
187
- color: var(--el-color-primary);
188
- border: 1px solid var(--el-color-primary-light-7);
189
- }
190
-
191
- &.theme-success {
192
- background-color: var(--el-color-success-light-9);
193
- color: var(--el-color-success);
194
- border: 1px solid var(--el-color-success-light-7);
195
- }
196
-
197
- &.theme-warning {
198
- background-color: var(--el-color-warning-light-9);
199
- color: var(--el-color-warning);
200
- border: 1px solid var(--el-color-warning-light-7);
201
- }
202
-
203
- &.theme-danger {
204
- background-color: var(--el-color-danger-light-9);
205
- color: var(--el-color-danger);
206
- border: 1px solid var(--el-color-danger-light-7);
207
- }
208
-
209
- &.theme-sky-gray {
210
- background-color: #E8F5FF;
211
- color: #00164D;
212
- border: 1px solid #C1CCD7;
213
- }
214
-
215
- &.theme-see-green {
216
- background-color: #E8FFFB;
217
- color: #00164D;
218
- border: 1px solid #8FEBE1;
219
- }
220
-
221
- &.theme-lotus-pink {
222
- background-color: #FFE8ED;
223
- color: #4D0028;
224
- border: 1px solid #F593AF;
225
- }
226
-
227
- &.theme-wine-red {
228
- background-color: #FFECE8;
229
- color: #4D000A;
230
- border: 1px solid #FAA298;
231
- }
232
-
233
- &.theme-autumn-orange {
234
- background-color: #FFF3E8;
235
- color: #4D0E00;
236
- border: 1px solid #FFC59C;
237
- }
238
-
239
- &.theme-sun-yellow {
240
- background-color: #FFFCE8;
241
- color: #4D2B00;
242
- border: 1px solid #FFEB9C;
243
- }
244
-
245
- &.theme-moonlight-blue {
246
- background-color: #E8F7FF;
247
- color: #001C4D;
248
- border: 1px solid #9CD7FF;
249
- }
250
-
251
- &.theme-sea-blue {
252
- background-color: #E8FCFF;
253
- color: #002B4D;
254
- border: 1px solid #98E6FA;
255
- }
256
-
257
- &.theme-clove-purple {
258
- background-color: #F5E8FF;
259
- color: #16004D;
260
- border: 1px solid #C396ED;
261
- }
262
-
263
- .portrait {
264
- display: inline-flex;
265
- align-items: center;
266
- justify-items: center;
267
- margin-left: 1px;
268
- color: #fff;
269
- width: 24px;
270
- height: 24px;
271
- border-radius: 50%;
272
- }
273
-
274
- .user-info {
275
- white-space: nowrap;
276
- text-overflow: ellipsis;
277
- overflow: hidden;
278
- }
279
-
280
- .close-btn {
281
- cursor: pointer;
282
- opacity: 0;
283
- position: absolute;
284
- right: -5px;
285
- top: -5px;
286
- width: 16px;
287
- height: 16px;
288
- border-radius: 8px;
289
- display: flex;
290
- align-items: center;
291
- justify-content: center;
292
- background-color: var(--el-color-danger-light-9);
293
- color: var(--el-color-danger-light-3);
294
- transition: all .2s ease-out;
295
- }
296
-
297
- .close-btn:hover {
298
- background-color: var(--el-color-danger-light-7);
299
- }
300
- ;
301
-
302
- &:hover {
303
- .close-btn {
304
- opacity: 1;
305
- }
306
-
307
- &.theme-info {
308
- background-color: var(--el-color-info-light-8);
309
- }
310
-
311
- &.theme-primary {
312
- background-color: var(--el-color-primary-light-8);
313
- }
314
-
315
- &.theme-success {
316
- background-color: var(--el-color-primary-light-8);
317
- }
318
-
319
- &.theme-danger {
320
- background-color: var(--el-color-primary-light-8);
321
- }
322
-
323
- &.theme-warning {
324
- background-color: var(--el-color-primary-light-8);
325
- }
326
-
327
- &.theme-sky-gray {
328
- background-color: #D4E1EB;
329
- }
330
-
331
- &.theme-see-green {
332
- background-color: #BAF5ED;
333
- }
334
-
335
- &.theme-lotus-pink {
336
- background-color: #FABDCC;
337
- }
338
-
339
- &.theme-wine-red {
340
- background-color: #FCC8C0;
341
- }
342
-
343
- &.theme-autumn-orange {
344
- background-color: #FFDDC2;
345
- }
346
-
347
- &.theme-sun-yellow {
348
- background-color: #FFF5C2;
349
- }
350
-
351
- &.theme-moonlight-blue {
352
- background-color: #C2E9FF;
353
- }
354
-
355
- &.theme-clove-purple {
356
- background-color: #DDBEF6;
357
- }
358
-
359
- &.theme-sea-blue {
360
- background-color: #C0F2FC;
361
- }
362
- }
363
- }
364
-
365
- .dropdown {
366
- display: flex;
367
- gap: 16px;
368
- flex-direction: column;
369
- user-select: none;
370
-
371
- .header {
372
- display: flex;
373
- flex-direction: row;
374
- width: 100%;
375
-
376
- .tools {
377
- flex: auto;
378
- display: flex;
379
- justify-content: end;
380
- align-items: start;
381
-
382
- .el-icon {
383
- cursor: pointer;
384
- }
385
- }
386
-
387
- .el-avatar {
388
- flex: none;
389
- }
390
- }
391
-
392
- .label {
393
- font-weight: 300;
394
- }
395
- }
396
-
397
- </style>
1
+ <script setup lang="ts">
2
+ import {onUnmounted, type Ref, ref} from "vue";
3
+ import {Close, Star, StarFilled} from "@element-plus/icons-vue";
4
+ import {type IAceAxios, useLoading, type User, useUserApi} from "@jari-ace/app-bolts";
5
+ import {JaAvatar} from "../avatar";
6
+ import {ElIcon, ElPopover, ElTooltip, vLoading} from "element-plus";
7
+ import {useAxios} from "./sharedAxios";
8
+
9
+ const themeClass = {
10
+ primary: "user-info-tag--root theme-primary",
11
+ success: "user-info-tag--root theme-success",
12
+ warning: "user-info-tag--root theme-warning",
13
+ danger: "user-info-tag--root theme-danger",
14
+ info: "user-info-tag--root theme-info",
15
+ lotusPink: "user-info-tag--root theme-lotus-pink",
16
+ wineRed: "user-info-tag--root theme-wine-red",
17
+ autumnOrange: "user-info-tag--root theme-autumn-orange",
18
+ sunYellow: "user-info-tag--root theme-sun-yellow",
19
+ seaBlue: "user-info-tag--root theme-sea-blue",
20
+ moonlightBlue: "user-info-tag--root theme-moonlight-blue",
21
+ clovePurple: "user-info-tag--root theme-clove-purple",
22
+ skyGray: "user-info-tag--root theme-sky-gray"
23
+ }
24
+
25
+ const props = withDefaults(defineProps<{
26
+ closable?: boolean,
27
+ userId?: string,
28
+ fullName?: string,
29
+ realm?: string,
30
+ username?: string,
31
+ theme?: keyof typeof themeClass,
32
+ hasAvatar?: boolean,
33
+ placement?: 'top' | 'top-start' | 'top-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'left' | 'left-start' | 'left-end' | 'right' | 'right-start' | 'right-end'
34
+ }>(), {
35
+ closable: false,
36
+ fullName: "无名氏",
37
+ theme: "skyGray",
38
+ placement: "bottom"
39
+ })
40
+
41
+ const user = ref<User>();
42
+ let axios: IAceAxios | undefined = useAxios();
43
+ let loading: Ref<Boolean> | undefined = useLoading(axios);
44
+ let api: ReturnType<typeof useUserApi> | undefined = useUserApi(axios);
45
+ const bookmarked = ref(false)
46
+ const visible = ref(false);
47
+ const emit = defineEmits<{
48
+ (e: 'closed', userId?: string, realm?: string, userName?: string): void
49
+ }>()
50
+
51
+ onUnmounted(() => {
52
+ axios = undefined;
53
+ loading = undefined;
54
+ api = undefined;
55
+ });
56
+
57
+ function onPop() {
58
+ if (!user.value) {
59
+ if (props.userId) {
60
+ api?.getById(props.userId).then(r => {
61
+ user.value = r;
62
+ getBookmarkState();
63
+ });
64
+ } else if (props.username && props.realm) {
65
+ let username = props.username;
66
+ if (username.indexOf('\\') >= 0) {
67
+ const arr = username.split('\\');
68
+ username = arr[arr.length - 1];
69
+ }
70
+ api?.getByUserName(props.realm, username).then(r => {
71
+ user.value = r;
72
+ getBookmarkState();
73
+ });
74
+ } else {
75
+ throw new Error("user-info-tag组件的userId和(realm, userName)属性不能都为空")
76
+ }
77
+ }
78
+ }
79
+
80
+ function getBookmarkState() {
81
+ if (!user.value) return;
82
+ api?.checkBookmarked(user.value.id).then(r => bookmarked.value = r);
83
+ }
84
+
85
+ function onClosed() {
86
+ visible.value = false
87
+ emit('closed', props.userId, props.realm, props.username)
88
+ }
89
+
90
+ function doBookmark() {
91
+ if (!user.value) return;
92
+ api?.bookmarkUser(user.value.id).then(() => bookmarked.value = true);
93
+ }
94
+
95
+ function doUnbookmark() {
96
+ if (!user.value) return;
97
+ api?.unbookmarkUser(user.value.id).then(() => bookmarked.value = false);
98
+ }
99
+
100
+ </script>
101
+
102
+ <template>
103
+ <el-popover width="auto" :hide-after="200" @before-enter="onPop" :placement="placement"
104
+ v-model:visible="visible">
105
+ <template #reference>
106
+ <div :class="themeClass[props.theme]">
107
+ <div class="portrait">
108
+ <ja-avatar :size="24" :user-id="userId" :realm="realm"
109
+ :username="username" :has-avatar="false"></ja-avatar>
110
+ </div>
111
+ <div class="user-info">
112
+ {{ fullName }}
113
+ <div v-if="closable" class="close-btn" @click="onClosed()">
114
+ <el-icon :size="10">
115
+ <Close/>
116
+ </el-icon>
117
+ </div>
118
+ </div>
119
+ </div>
120
+ </template>
121
+ <template #default>
122
+ <div
123
+ class="dropdown" v-show="visible" v-loading="!!loading">
124
+ <div class="header">
125
+ <ja-avatar :user-id="userId" :realm="realm"
126
+ :username="username"
127
+ :size="75"
128
+ :has-avatar="user?.hasAvatar"
129
+ style="margin-bottom: 8px"/>
130
+ <div class="tools">
131
+ <el-tooltip :content="bookmarked ? '取消常用人员': '设置为常用人员'">
132
+ <el-icon v-if="!bookmarked" @click="doBookmark()" :size="16">
133
+ <Star></Star>
134
+ </el-icon>
135
+ <el-icon v-else color="#FFBF29" @click="doUnbookmark()" :size="16">
136
+ <star-filled></star-filled>
137
+ </el-icon>
138
+ </el-tooltip>
139
+ </div>
140
+ </div>
141
+ <div>
142
+ <p
143
+ style="margin: 0; font-weight: 600">
144
+ {{ fullName }}
145
+ </p>
146
+ <p
147
+ style="margin: 0; font-size: 14px; color: var(--el-color-info-light-3)">
148
+ @{{ user?.department?.name ?? "无归属部门" }}
149
+ </p>
150
+ </div>
151
+ <p style="margin: 0;">
152
+ <span class="label">手机:</span> {{
153
+ !user?.mobile || user.mobile.length === 0 ? "(未填写手机号)" : user?.mobile
154
+ }} <br/>
155
+ <span class="label">邮箱:</span>
156
+ {{ !user?.email || user.email.length === 0 ? "(未填写邮箱号)" : user?.email }}
157
+ </p>
158
+ </div>
159
+ </template>
160
+ </el-popover>
161
+
162
+ </template>
163
+
164
+ <style scoped lang="scss">
165
+ .user-info-tag--root {
166
+ align-items: center;
167
+
168
+ border-radius: 28px;
169
+ display: inline-flex;
170
+ height: 28px;
171
+ max-width: 100%;
172
+ padding-right: 10px;
173
+ position: relative;
174
+ vertical-align: top;
175
+ gap: 8px;
176
+ cursor: default;
177
+
178
+
179
+ &.theme-info {
180
+ background-color: var(--el-color-info-light-9);
181
+ color: var(--el-color-info);
182
+ border: 1px solid var(--el-color-info-light-7);
183
+ }
184
+
185
+ &.theme-primary {
186
+ background-color: var(--el-color-primary-light-9);
187
+ color: var(--el-color-primary);
188
+ border: 1px solid var(--el-color-primary-light-7);
189
+ }
190
+
191
+ &.theme-success {
192
+ background-color: var(--el-color-success-light-9);
193
+ color: var(--el-color-success);
194
+ border: 1px solid var(--el-color-success-light-7);
195
+ }
196
+
197
+ &.theme-warning {
198
+ background-color: var(--el-color-warning-light-9);
199
+ color: var(--el-color-warning);
200
+ border: 1px solid var(--el-color-warning-light-7);
201
+ }
202
+
203
+ &.theme-danger {
204
+ background-color: var(--el-color-danger-light-9);
205
+ color: var(--el-color-danger);
206
+ border: 1px solid var(--el-color-danger-light-7);
207
+ }
208
+
209
+ &.theme-sky-gray {
210
+ background-color: #E8F5FF;
211
+ color: #00164D;
212
+ border: 1px solid #C1CCD7;
213
+ }
214
+
215
+ &.theme-see-green {
216
+ background-color: #E8FFFB;
217
+ color: #00164D;
218
+ border: 1px solid #8FEBE1;
219
+ }
220
+
221
+ &.theme-lotus-pink {
222
+ background-color: #FFE8ED;
223
+ color: #4D0028;
224
+ border: 1px solid #F593AF;
225
+ }
226
+
227
+ &.theme-wine-red {
228
+ background-color: #FFECE8;
229
+ color: #4D000A;
230
+ border: 1px solid #FAA298;
231
+ }
232
+
233
+ &.theme-autumn-orange {
234
+ background-color: #FFF3E8;
235
+ color: #4D0E00;
236
+ border: 1px solid #FFC59C;
237
+ }
238
+
239
+ &.theme-sun-yellow {
240
+ background-color: #FFFCE8;
241
+ color: #4D2B00;
242
+ border: 1px solid #FFEB9C;
243
+ }
244
+
245
+ &.theme-moonlight-blue {
246
+ background-color: #E8F7FF;
247
+ color: #001C4D;
248
+ border: 1px solid #9CD7FF;
249
+ }
250
+
251
+ &.theme-sea-blue {
252
+ background-color: #E8FCFF;
253
+ color: #002B4D;
254
+ border: 1px solid #98E6FA;
255
+ }
256
+
257
+ &.theme-clove-purple {
258
+ background-color: #F5E8FF;
259
+ color: #16004D;
260
+ border: 1px solid #C396ED;
261
+ }
262
+
263
+ .portrait {
264
+ display: inline-flex;
265
+ align-items: center;
266
+ justify-items: center;
267
+ margin-left: 1px;
268
+ color: #fff;
269
+ width: 24px;
270
+ height: 24px;
271
+ border-radius: 50%;
272
+ }
273
+
274
+ .user-info {
275
+ white-space: nowrap;
276
+ text-overflow: ellipsis;
277
+ overflow: hidden;
278
+ }
279
+
280
+ .close-btn {
281
+ cursor: pointer;
282
+ opacity: 0;
283
+ position: absolute;
284
+ right: -5px;
285
+ top: -5px;
286
+ width: 16px;
287
+ height: 16px;
288
+ border-radius: 8px;
289
+ display: flex;
290
+ align-items: center;
291
+ justify-content: center;
292
+ background-color: var(--el-color-danger-light-9);
293
+ color: var(--el-color-danger-light-3);
294
+ transition: all .2s ease-out;
295
+ }
296
+
297
+ .close-btn:hover {
298
+ background-color: var(--el-color-danger-light-7);
299
+ }
300
+ ;
301
+
302
+ &:hover {
303
+ .close-btn {
304
+ opacity: 1;
305
+ }
306
+
307
+ &.theme-info {
308
+ background-color: var(--el-color-info-light-8);
309
+ }
310
+
311
+ &.theme-primary {
312
+ background-color: var(--el-color-primary-light-8);
313
+ }
314
+
315
+ &.theme-success {
316
+ background-color: var(--el-color-primary-light-8);
317
+ }
318
+
319
+ &.theme-danger {
320
+ background-color: var(--el-color-primary-light-8);
321
+ }
322
+
323
+ &.theme-warning {
324
+ background-color: var(--el-color-primary-light-8);
325
+ }
326
+
327
+ &.theme-sky-gray {
328
+ background-color: #D4E1EB;
329
+ }
330
+
331
+ &.theme-see-green {
332
+ background-color: #BAF5ED;
333
+ }
334
+
335
+ &.theme-lotus-pink {
336
+ background-color: #FABDCC;
337
+ }
338
+
339
+ &.theme-wine-red {
340
+ background-color: #FCC8C0;
341
+ }
342
+
343
+ &.theme-autumn-orange {
344
+ background-color: #FFDDC2;
345
+ }
346
+
347
+ &.theme-sun-yellow {
348
+ background-color: #FFF5C2;
349
+ }
350
+
351
+ &.theme-moonlight-blue {
352
+ background-color: #C2E9FF;
353
+ }
354
+
355
+ &.theme-clove-purple {
356
+ background-color: #DDBEF6;
357
+ }
358
+
359
+ &.theme-sea-blue {
360
+ background-color: #C0F2FC;
361
+ }
362
+ }
363
+ }
364
+
365
+ .dropdown {
366
+ display: flex;
367
+ gap: 16px;
368
+ flex-direction: column;
369
+ user-select: none;
370
+
371
+ .header {
372
+ display: flex;
373
+ flex-direction: row;
374
+ width: 100%;
375
+
376
+ .tools {
377
+ flex: auto;
378
+ display: flex;
379
+ justify-content: end;
380
+ align-items: start;
381
+
382
+ .el-icon {
383
+ cursor: pointer;
384
+ }
385
+ }
386
+
387
+ .el-avatar {
388
+ flex: none;
389
+ }
390
+ }
391
+
392
+ .label {
393
+ font-weight: 300;
394
+ }
395
+ }
396
+
397
+ </style>