@uxda/appkit 4.1.40 → 4.1.42

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 (117) hide show
  1. package/.eslintrc.mjs +7 -7
  2. package/README.md +187 -187
  3. package/babel.config.js +12 -12
  4. package/dist/appkit.css +121 -43
  5. package/dist/assets/asset-3B_CoPto +1 -0
  6. package/dist/index.js +399 -246
  7. package/package.json +77 -77
  8. package/project.config.json +15 -15
  9. package/project.tt.json +13 -13
  10. package/rollup.config.mjs +56 -56
  11. package/src/Appkit.ts +66 -66
  12. package/src/balance/api/endpoints.ts +133 -126
  13. package/src/balance/api/index.ts +106 -106
  14. package/src/balance/components/AccountView.vue +747 -749
  15. package/src/balance/components/BalanceCard.vue +213 -205
  16. package/src/balance/components/BalanceReminder.vue +85 -85
  17. package/src/balance/components/ConsumptionFilter.vue +218 -218
  18. package/src/balance/components/ConsumptionRules.vue +68 -68
  19. package/src/balance/components/DateFilter.vue +250 -251
  20. package/src/balance/components/DateRange.vue +80 -80
  21. package/src/balance/components/ListFilter.vue +63 -63
  22. package/src/balance/components/ListFilterPicker.vue +188 -186
  23. package/src/balance/components/PromoterCard.vue +183 -0
  24. package/src/balance/components/SecondBalance.vue +71 -71
  25. package/src/balance/components/Tip.vue +45 -45
  26. package/src/balance/components/index.ts +8 -13
  27. package/src/balance/types.ts +97 -91
  28. package/src/components/bt-cropper/index.vue +774 -774
  29. package/src/components/bt-cropper/utils/calcCropper.js +42 -42
  30. package/src/components/bt-cropper/utils/calcImagePosition.js +23 -23
  31. package/src/components/bt-cropper/utils/calcImageSize.js +37 -37
  32. package/src/components/bt-cropper/utils/calcPointDistance.js +12 -12
  33. package/src/components/bt-cropper/utils/calcRightAndBottom.js +7 -7
  34. package/src/components/bt-cropper/utils/ratio.js +3 -3
  35. package/src/components/bt-cropper/utils/tools.js +25 -25
  36. package/src/components/dd-area/index.vue +225 -225
  37. package/src/components/dd-icon/doc.md +21 -21
  38. package/src/components/dd-icon/index.vue +23 -23
  39. package/src/components/dd-notice-bar/index.vue +78 -78
  40. package/src/components/dd-search/doc.md +34 -34
  41. package/src/components/dd-search/index.vue +168 -168
  42. package/src/components/dd-selector/index.vue +124 -124
  43. package/src/components/dd-skeleton/doc.md +19 -19
  44. package/src/components/dd-skeleton/index.vue +36 -36
  45. package/src/components/ocr-id/index.vue +114 -114
  46. package/src/components/ocr-id/types.d.ts +12 -12
  47. package/src/global.ts +6 -6
  48. package/src/index.ts +89 -89
  49. package/src/main.scss +1 -1
  50. package/src/notice/api/endpoints.ts +17 -17
  51. package/src/notice/api/index.ts +106 -106
  52. package/src/notice/components/NoticeBanner.vue +243 -243
  53. package/src/notice/components/NoticeEntry.vue +99 -99
  54. package/src/notice/components/NoticeList.vue +315 -315
  55. package/src/notice/components/NoticePopup.vue +162 -162
  56. package/src/notice/components/index.ts +5 -5
  57. package/src/notice/components/useCommonList.ts +86 -86
  58. package/src/notice/components/useNotice.ts +35 -35
  59. package/src/notice/index.ts +1 -1
  60. package/src/notice/types.ts +25 -25
  61. package/src/payment/api/config.ts +7 -7
  62. package/src/payment/api/endpoints.ts +103 -103
  63. package/src/payment/api/index.ts +100 -100
  64. package/src/payment/components/AmountPicker.vue +90 -93
  65. package/src/payment/components/RechargeResult.vue +69 -69
  66. package/src/payment/components/RechargeView.vue +154 -154
  67. package/src/payment/components/RightsPicker.vue +105 -105
  68. package/src/payment/components/TradeView.vue +294 -294
  69. package/src/payment/components/UserAgreement.vue +234 -234
  70. package/src/payment/components/index.ts +22 -22
  71. package/src/payment/index.ts +5 -5
  72. package/src/payment/services/index.ts +16 -16
  73. package/src/payment/services/invoke-recharge.ts +25 -25
  74. package/src/payment/services/request-payment.ts +58 -58
  75. package/src/payment/types.ts +28 -28
  76. package/src/register/components/SelfRegistration.vue +254 -254
  77. package/src/register/components/index.ts +2 -2
  78. package/src/shared/components/AppDrawer.vue +58 -54
  79. package/src/shared/components/AppVerify.vue +129 -126
  80. package/src/shared/components/DeviceVersion.vue +68 -68
  81. package/src/shared/components/EmptyView.vue +33 -33
  82. package/src/shared/components/OcrBusinessLicense.vue +133 -133
  83. package/src/shared/components/OcrIcon.vue +133 -133
  84. package/src/shared/components/PageHeader.vue +79 -79
  85. package/src/shared/components/index.ts +8 -8
  86. package/src/shared/composables/index.ts +8 -8
  87. package/src/shared/composables/useCountdown.ts +46 -46
  88. package/src/shared/composables/useCrypto.ts +76 -76
  89. package/src/shared/composables/useDragBox.ts +97 -97
  90. package/src/shared/composables/useEncode.ts +43 -43
  91. package/src/shared/composables/useLogger.ts +123 -123
  92. package/src/shared/composables/useSafeArea.ts +46 -46
  93. package/src/shared/composables/useTabbar.ts +24 -24
  94. package/src/shared/composables/useUpload.ts +54 -54
  95. package/src/shared/composables/useValidator.ts +31 -31
  96. package/src/shared/http/Http.ts +136 -136
  97. package/src/shared/http/index.ts +1 -1
  98. package/src/shared/http/types.ts +157 -157
  99. package/src/shared/index.ts +3 -3
  100. package/src/shared/weixin/payment.ts +38 -38
  101. package/src/styles/vars.scss +3 -3
  102. package/src/user/api/endpoints.ts +17 -17
  103. package/src/user/api/index.ts +111 -111
  104. package/src/user/components/LoginSetting.vue +114 -114
  105. package/src/user/components/UserBinding.vue +307 -307
  106. package/src/user/components/UserBindingSuccess.vue +80 -80
  107. package/src/user/components/UserEntry.vue +137 -137
  108. package/src/user/components/UserFeedback.vue +431 -431
  109. package/src/user/components/UserFeedbackEntry.vue +192 -192
  110. package/src/user/components/UserHeadCrop.vue +65 -65
  111. package/src/user/components/UserInfo.vue +637 -637
  112. package/src/user/components/UserResourceEmpty.vue +75 -75
  113. package/src/user/components/index.ts +21 -21
  114. package/src/user/index.ts +1 -1
  115. package/tsconfig.json +30 -30
  116. package/types/global.d.ts +21 -21
  117. package/types/vue.d.ts +10 -10
@@ -1,637 +1,637 @@
1
- <template>
2
- <scroll-view :scroll-y="!userState.visible && !avatarVisible" class="user-info">
3
- <DdSkeleton v-if="firstLoading" :row="3"></DdSkeleton>
4
- <div v-else class="user-info-wrap">
5
- <div class="user-info-tit">账号信息</div>
6
- <div class="user-info-head">
7
- <div class="user-info-head-avatar" @click="avatarVisible = true">
8
- <img
9
- class="user-info-head-img"
10
- mode="aspectFit"
11
- v-if="userInfo.avatar"
12
- :src="userInfo.avatar"
13
- alt=""
14
- />
15
- <img
16
- class="user-info-head-img"
17
- mode="aspectFit"
18
- v-else
19
- src="https://cdn.ddjf.com/static/images/wx-yunservice/account-head.png"
20
- alt=""
21
- />
22
- <div class="user-info-head-upload">
23
- <img
24
- class="user-info-head-upload-icon"
25
- mode="aspectFit"
26
- src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzQiIGhlaWdodD0iMzQiIHZpZXdCb3g9IjAgMCAzNCAzNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0yMi4wOTk5IDE4LjQyMjRDMjIuMDk5OSAxNS41ODMyIDE5LjgxNjYgMTMuMjgxNiAxNi45OTk5IDEzLjI4MTZDMTQuMTgzMyAxMy4yODE2IDExLjg5OTkgMTUuNTgzMiAxMS44OTk5IDE4LjQyMjRDMTEuODk5OSAyMS4yNjE2IDE0LjE4MzMgMjMuNTYzMiAxNi45OTk5IDIzLjU2MzJDMTkuODE2NiAyMy41NjMyIDIyLjA5OTkgMjEuMjYxNiAyMi4wOTk5IDE4LjQyMjRWMTguNDIyNFoiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMi41NSIgc3Ryb2tlLWxpbmVjYXA9InNxdWFyZSIvPgo8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTIzLjc5OTkgNS45OTg4QzIzLjc5OTkgNi4yMzUzOSAyMy45OTAyIDYuNDI3MiAyNC4yMjQ5IDYuNDI3MkgyNS45MjVDMjkuNDQ1OCA2LjQyNzIgMzIuMyA5LjMwNDIxIDMyLjMgMTIuODUzMlYyMy45OTE2QzMyLjMgMjcuNTQwNiAyOS40NDU4IDMwLjQxNzYgMjUuOTI1IDMwLjQxNzZIOC4wNzQ5NEM0LjU1NDE0IDMwLjQxNzYgMS42OTk5NSAyNy41NDA2IDEuNjk5OTUgMjMuOTkxNlYxMi44NTMyQzEuNjk5OTUgOS4zMDQyMSA0LjU1NDE0IDYuNDI3MiA4LjA3NDk0IDYuNDI3Mkg5Ljc3NDk1QzEwLjAwOTcgNi40MjcyIDEwLjIgNi4yMzUzOSAxMC4yIDUuOTk4OEMxMC4yIDUuNzA5NDkgMTAuMjQwNiA1LjQyOTc1IDEwLjMxNjUgNS4xNjUwNkMxMC42NzQ4IDMuOTE0NTEgMTEuODE4OSAzIDEzLjE3NSAzSDIwLjgyNUMyMi40NjggMyAyMy43OTk5IDQuMzQyNjEgMjMuNzk5OSA1Ljk5ODhWNS45OTg4WiIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIyLjU1IiBzdHJva2UtbGluZWNhcD0ic3F1YXJlIi8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNNy42NDk5IDEwLjI4MjhDOC44MjM1MSAxMC4yODI4IDkuNzc0OSAxMS4yNDE4IDkuNzc0OSAxMi40MjQ4QzkuNzc0OSAxMy42MDc4IDguODIzNTEgMTQuNTY2OCA3LjY0OTkgMTQuNTY2OEM2LjQ3NjMgMTQuNTY2OCA1LjUyNDkgMTMuNjA3OCA1LjUyNDkgMTIuNDI0OEM1LjUyNDkgMTEuMjQxOCA2LjQ3NjMgMTAuMjgyOCA3LjY0OTkgMTAuMjgyOFoiIGZpbGw9IndoaXRlIi8+Cjwvc3ZnPgo="
27
- alt=""
28
- />
29
- </div>
30
- </div>
31
- <nut-cell
32
- title="登录手机号"
33
- is-link
34
- :desc="encodePhone(userInfo.mobile || '')"
35
- @click="toBinding"
36
- />
37
- </div>
38
-
39
- <div class="user-info-tit">企业/团队</div>
40
- <div class="user-info-team">
41
- <div v-for="(item, key) in userInfo.tenantInfoList" :key="key" class="user-info-team-item">
42
- <div class="user-info-team-item-avatar">
43
- <img
44
- v-if="item.tenantLogo"
45
- class="user-info-team-item-avatar-img"
46
- mode="aspectFit"
47
- :src="item.tenantLogo"
48
- alt=""
49
- />
50
- <img
51
- v-else
52
- class="user-info-team-item-avatar-img empty"
53
- mode="aspectFit"
54
- src="https://cdn.ddjf.com/static/images/customer-center/tenant-logo.png"
55
- alt=""
56
- />
57
- </div>
58
- <div class="user-info-team-item-bd">
59
- <div class="user-info-team-item-title">{{ item.tenantName }}</div>
60
- <div class="user-info-team-item-app" v-if="item.appRoleInfo">
61
- <div
62
- class="user-info-team-item-app-tag"
63
- v-for="(aitem, akey) in item.appRoleInfo || []"
64
- :key="akey"
65
- >
66
- {{ aitem.appAbbr }}
67
- </div>
68
- <div class="user-info-team-item-role-btn" @click="toShowRole(item)">
69
- 角色详情
70
- <img
71
- :class="{ showRole: item.showRole }"
72
- class="user-info-team-item-role-btn-icon"
73
- src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTE4IDlMMTIgMTVMNiA5IiBzdHJva2U9IiMwMTdGRkYiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+Cjwvc3ZnPgo="
74
- alt=""
75
- />
76
- </div>
77
- </div>
78
- <div class="user-info-team-item-role" v-if="item.showRole">
79
- <div
80
- class="user-info-team-item-role-item"
81
- v-for="(aitem, akey) in item.appRoleInfo || []"
82
- :key="akey"
83
- >
84
- <div class="user-info-team-item-role-item-name">{{ aitem.appAbbr }}</div>
85
- <div class="user-info-team-item-role-item-info">
86
- {{ aitem.roleName }}
87
- </div>
88
- </div>
89
- </div>
90
- <div class="user-info-team-item-user">
91
- {{ item.fullName }}
92
- <img
93
- @click="toUserNameChange(item)"
94
- class="user-info-team-item-user-icon"
95
- src="https://cdn.ddjf.com/static/images/appkit/edit.png"
96
- alt=""
97
- />
98
- </div>
99
- <div class="user-info-team-item-dept">
100
- <div
101
- v-for="(ditem, dkey) in item.deptNames"
102
- :key="dkey"
103
- class="user-info-team-item-dept-item"
104
- >
105
- {{ ditem }}
106
- </div>
107
- </div>
108
- </div>
109
- </div>
110
- </div>
111
-
112
- <div class="user-info-ft">
113
- <nut-button
114
- class="user-info-ft-btn"
115
- style="width: 100%"
116
- @click="toLogout"
117
- plain
118
- type="primary"
119
- >退出登录</nut-button
120
- >
121
- </div>
122
- </div>
123
- </scroll-view>
124
-
125
- <!-- 修改用户名弹框 -->
126
- <nut-dialog
127
- title="输入新的用户名"
128
- :border="false"
129
- pop-class="change-username-popup"
130
- v-model:visible="userState.visible"
131
- @cancel="onUserNameCancel"
132
- >
133
- <nut-input :max-length="20" placeholder="请输入新的用户名" v-model="userState.value" />
134
- <template #footer>
135
- <nut-button class="change-username-popup-cancel" type="default" @click="onUserNameCancel">
136
- 取消
137
- </nut-button>
138
- <nut-button class="change-username-popup-ok" type="primary" @click="onUserNameOk">
139
- 确定
140
- </nut-button>
141
- </template>
142
- </nut-dialog>
143
-
144
- <!-- 修改头像弹框 -->
145
- <nut-popup
146
- pop-class="upload-avatar-popup"
147
- style="background: transparent"
148
- v-model:visible="avatarVisible"
149
- :overlay-style="{ background: 'rgba(0, 0, 0, 0.9)' }"
150
- >
151
- <div class="upload-avatar-popup-box">
152
- <img
153
- class="upload-avatar-popup-avatar"
154
- mode="aspectFit"
155
- v-if="userInfo.avatar"
156
- :src="userInfo.avatar"
157
- alt=""
158
- />
159
- <img
160
- class="upload-avatar-popup-avatar"
161
- mode="aspectFit"
162
- v-else
163
- src="https://cdn.ddjf.com/static/images/wx-yunservice/account-head.png"
164
- alt=""
165
- />
166
- <div class="upload-avatar-popup-btn" @click="toUpload">更换头像</div>
167
- </div>
168
- </nut-popup>
169
- </template>
170
-
171
- <script lang="ts" setup>
172
- import Taro, { useDidShow } from '@tarojs/taro'
173
- import { ref, onMounted, reactive, onUnmounted } from 'vue'
174
- import { useAppKitOptions } from '../../Appkit'
175
- import { useEncode } from '../../shared/composables/useEncode'
176
- import DdSkeleton from '../../components/dd-skeleton/index.vue'
177
- import { useHttp } from '../api'
178
-
179
- const props = withDefaults(
180
- defineProps<{
181
- miniType?: string
182
- app?: string
183
- userId: string
184
- }>(),
185
- {
186
- miniType: '05',
187
- app: '',
188
- userId: '',
189
- }
190
- )
191
-
192
- const { encodePhone } = useEncode()
193
-
194
- useDidShow(() => {
195
- getUserInfoByUserId()
196
- })
197
- onMounted(() => {
198
- Taro.eventCenter.on('USER-HEAD-CROP-OK', updateImage)
199
- })
200
- onUnmounted(() => {
201
- Taro.eventCenter.off('USER-HEAD-CROP-OK')
202
- })
203
-
204
- const firstLoading = ref(true)
205
- const userInfo = ref<any>({})
206
- // 根据用户id,查询用户所在租户列表
207
- function getUserInfoByUserId() {
208
- const $http = useHttp()
209
-
210
- $http
211
- .get(`/cas/sysAccount/getAccountInfo/${props.userId}`)
212
- .then((result: any) => {
213
- userInfo.value = result
214
- firstLoading.value = false
215
- })
216
- .catch(() => {
217
- firstLoading.value = false
218
- })
219
- }
220
-
221
- // 修改头像弹框
222
- const avatarVisible = ref(false)
223
-
224
- // 去上传头像
225
- async function toUpload() {
226
- if (!userInfo.value.avatar) {
227
- const profile = await Taro.getUserProfile({
228
- desc: '头像用于改变默认头像',
229
- })
230
-
231
- const res = await Taro.downloadFile({
232
- url: profile.userInfo.avatarUrl,
233
- })
234
-
235
- updateImage(res.tempFilePath)
236
- } else {
237
- let res = await Taro.chooseImage({
238
- count: 1,
239
- })
240
- if (res.tempFilePaths) {
241
- const filePath = res.tempFilePaths[0]
242
-
243
- emits('crop', filePath)
244
- }
245
- }
246
- }
247
-
248
- // 上传图片
249
- async function updateImage(filePath: string) {
250
- Taro.showLoading({
251
- title: '上传中...',
252
- })
253
- const appkitOptions = useAppKitOptions()
254
- const $http = useHttp()
255
-
256
- let Res: any = await Taro.uploadFile({
257
- url: `${appkitOptions.baseUrl()}/cas/file/uploadImg`,
258
- filePath: filePath,
259
- name: 'file',
260
- formData: {
261
- objectNo: `${userInfo.value.mobile}${Date.now()}`,
262
- objectTypeCode: `MINI_HEADIMAGE${props.miniType}`,
263
- },
264
- header: {
265
- token: appkitOptions.tempToken() || appkitOptions.token(),
266
- },
267
- })
268
- avatarVisible.value = false
269
-
270
- const res = JSON.parse(Res.data)
271
- if (res.success) {
272
- $http
273
- .post('/cas/sysUser/update', {
274
- appCode: props.app,
275
- avatar: res.result,
276
- userId: props.userId,
277
- })
278
- .then(() => {
279
- Taro.hideLoading()
280
- Taro.showToast({ title: '头像上传成功', icon: 'none' })
281
- getUserInfoByUserId()
282
- emits('avatar-success', res.result)
283
- })
284
- .catch(() => {
285
- Taro.hideLoading()
286
- })
287
- } else {
288
- Taro.hideLoading()
289
- }
290
- }
291
-
292
- // 查看角色详情
293
- function toShowRole(item: any) {
294
- item.showRole = !item.showRole
295
- }
296
-
297
- // 更换用户名
298
- const userState = reactive({
299
- visible: false,
300
- value: '',
301
- oldName: '',
302
- tenantId: '',
303
- })
304
- function toUserNameChange(item: any) {
305
- userState.visible = true
306
- userState.oldName = item.fullName
307
- userState.tenantId = item.tenantId
308
- }
309
- function onUserNameCancel() {
310
- userState.visible = false
311
- userState.value = ''
312
- userState.oldName = ''
313
- userState.tenantId = ''
314
- }
315
- function onUserNameOk() {
316
- if (!userState.value) {
317
- return Taro.showToast({
318
- title: '请输入用户名',
319
- icon: 'none',
320
- })
321
- }
322
- if (userState.value === userState.oldName) {
323
- return Taro.showToast({
324
- title: '用户名不能与原用户名相同',
325
- icon: 'none',
326
- })
327
- }
328
-
329
- const $http = useHttp()
330
-
331
- $http
332
- .post('/cas/sysUser/updateUserInfoByTenantId', {
333
- fullName: userState.value,
334
- tenantId: userState.tenantId,
335
- userId: props.userId,
336
- })
337
- .then(() => {
338
- Taro.showToast({ title: '用户名修改成功', icon: 'none' })
339
- getUserInfoByUserId()
340
- onUserNameCancel()
341
- emits('username-success')
342
- })
343
- }
344
-
345
- // 退出登录
346
- function toLogout() {
347
- Taro.showModal({
348
- title: '提示',
349
- content: '确定要退出登录吗?',
350
- confirmText: '确定',
351
- success: async (e: any) => {
352
- if (e.confirm) {
353
- emits('logout')
354
- }
355
- },
356
- })
357
- }
358
-
359
- // 去绑定手机号
360
- function toBinding() {
361
- emits('binding', userInfo.value.mobile || '')
362
- }
363
-
364
- // 父组件事件
365
- const emits = defineEmits(['avatar-success', 'logout', 'crop', 'binding', 'username-success'])
366
-
367
- // 外部访问
368
- defineExpose({
369
- updateImage,
370
- })
371
- </script>
372
-
373
- <style lang="scss">
374
- .user-info {
375
- height: 100vh;
376
-
377
- &-wrap {
378
- padding: 0 12px;
379
- padding-bottom: calc(12px + env(safe-area-inset-bottom, 0px));
380
- box-sizing: border-box;
381
- min-height: 100%;
382
- }
383
- &-tit {
384
- height: 38px;
385
- display: flex;
386
- align-items: center;
387
- color: #666666;
388
- font-size: 12px;
389
- padding-left: 10px;
390
- }
391
- &-head {
392
- border-radius: 5px;
393
- background: #fff;
394
- padding: 30px 11px 0;
395
- &-avatar {
396
- position: relative;
397
- width: 80px;
398
- height: 80px;
399
- margin: 0 auto 25px;
400
- }
401
- &-img {
402
- width: 100%;
403
- height: 100%;
404
- overflow: hidden;
405
- border-radius: 50%;
406
- }
407
- &-upload {
408
- position: absolute;
409
- bottom: -2px;
410
- left: 52px;
411
- width: 29px;
412
- height: 29px;
413
- background: #333333;
414
- overflow: hidden;
415
- border-radius: 50%;
416
- display: flex;
417
- align-items: center;
418
- justify-content: center;
419
- &-icon {
420
- width: 17px;
421
- height: 17px;
422
- }
423
- }
424
- }
425
- &-team {
426
- &-item {
427
- border-radius: 5px;
428
- background: #fff;
429
- display: flex;
430
- padding: 15px;
431
- margin-bottom: 10px;
432
- &-avatar {
433
- width: 38px;
434
- height: 38px;
435
- margin-right: 15px;
436
- border-radius: 5px;
437
- background: rgba(1, 127, 255, 0.3);
438
- display: flex;
439
- align-items: center;
440
- justify-content: center;
441
- &-img {
442
- width: 100%;
443
- height: 100%;
444
- }
445
- .empty {
446
- width: 20px;
447
- height: 40px;
448
- }
449
- }
450
- &-title {
451
- font-size: 16px;
452
- font-weight: 500;
453
- margin-bottom: 5px;
454
- }
455
- &-app {
456
- display: flex;
457
- align-items: center;
458
- flex-wrap: wrap;
459
- &-tag {
460
- border: 1px solid rgba(53, 53, 53, 0.2);
461
- font-size: 10px;
462
- height: 18px;
463
- display: inline-flex;
464
- align-items: center;
465
- justify-content: center;
466
- padding: 0 6px;
467
- border-radius: 2px;
468
- margin: 0 10px 6px 0;
469
- }
470
- }
471
- &-bd {
472
- flex: 1;
473
- }
474
- &-role {
475
- padding: 10px;
476
- background: rgba(245, 245, 245, 0.5);
477
- border-radius: 5px;
478
- margin-bottom: 10px;
479
- &-btn {
480
- color: var(--app-primary-color, #017fff);
481
- font-size: 10px;
482
- display: inline-flex;
483
- align-items: center;
484
- margin-bottom: 6px;
485
- &-icon {
486
- width: 12px;
487
- height: 12px;
488
- position: relative;
489
- top: 1px;
490
- &.showRole {
491
- transform: rotate(180deg);
492
- }
493
- }
494
- }
495
- &-item {
496
- display: flex;
497
- font-size: 10px;
498
- margin-bottom: 10px;
499
- &:last-child {
500
- margin-bottom: 0;
501
- }
502
- &-name {
503
- opacity: 0.5;
504
- white-space: nowrap;
505
- margin-right: 10px;
506
- min-width: 40px;
507
- }
508
- &-info {
509
- flex: 1;
510
- color: #1a1a1a;
511
- }
512
- }
513
- }
514
- &-user {
515
- margin-bottom: 4px;
516
- font-size: 12px;
517
- display: flex;
518
- align-items: center;
519
- &-icon {
520
- width: 10px;
521
- height: 10px;
522
- margin-left: 4px;
523
- }
524
- }
525
- &-dept {
526
- display: flex;
527
- flex-wrap: wrap;
528
- font-size: 10px;
529
- color: rgba(26, 26, 26, 0.8);
530
- &-item {
531
- font-size: 10px;
532
- color: rgba(26, 26, 26, 0.5);
533
- margin: 4px 10px 4px 0;
534
- &:first-child {
535
- color: rgba(26, 26, 26, 0.8);
536
- }
537
- }
538
- }
539
- }
540
- }
541
-
542
- &-ft {
543
- &-btn {
544
- width: 100%;
545
- border-color: transparent !important;
546
- color: rgba(27, 63, 107, 0.8) !important;
547
- }
548
- }
549
-
550
- .nut-cell {
551
- padding: 11px 0;
552
- margin: 0;
553
- box-shadow: none;
554
- border-bottom: 1px solid #f0f0f0;
555
- font-size: 16px;
556
- .nut-cell__value {
557
- font-size: 16px;
558
- color: #000;
559
- }
560
- .nut-cell__link {
561
- color: #ccc;
562
- margin-left: 8px;
563
- }
564
- }
565
- }
566
- .upload-avatar-popup {
567
- &-box {
568
- display: flex;
569
- flex-direction: column;
570
- align-items: center;
571
- justify-content: center;
572
- }
573
- &-avatar {
574
- width: 320px;
575
- height: 320px;
576
- overflow: hidden;
577
- border-radius: 50%;
578
- margin-bottom: 50px;
579
- }
580
- &-btn {
581
- width: 106px;
582
- height: 37px;
583
- border-radius: 50px;
584
- border: 1px solid #ffffff;
585
- display: flex;
586
- justify-content: center;
587
- align-items: center;
588
- color: #ffffff;
589
- font-size: 16px;
590
- }
591
- }
592
- .change-username-popup {
593
- .nut-dialog {
594
- min-height: auto;
595
- }
596
- .nut-input {
597
- height: 40px;
598
- padding: 0;
599
- display: flex;
600
- align-items: center;
601
- font-size: 16px;
602
- border: none;
603
- .input-text {
604
- width: 100%;
605
- height: 100%;
606
- font-size: 14px;
607
- }
608
- .nut-input-value,
609
- .nut-input-inner,
610
- .nut-input-box {
611
- height: 100%;
612
- overflow: hidden;
613
- background: #f5f5f5;
614
- border-radius: 6px;
615
- }
616
- .nut-placeholder {
617
- color: #cccccc;
618
- line-height: 38px;
619
- height: 38px;
620
- }
621
- .nut-input-box {
622
- padding: 0 15px;
623
- }
624
- }
625
- &-cancel.nut-button {
626
- border-radius: 15px;
627
- font-size: 14px;
628
- height: 30px;
629
- }
630
- &-ok.nut-button {
631
- background: var(--app-primary-color, #017fff);
632
- height: 30px;
633
- font-size: 14px;
634
- border-radius: 15px;
635
- }
636
- }
637
- </style>
1
+ <template>
2
+ <scroll-view :scroll-y="!userState.visible && !avatarVisible" class="user-info">
3
+ <DdSkeleton v-if="firstLoading" :row="3"></DdSkeleton>
4
+ <div v-else class="user-info-wrap">
5
+ <div class="user-info-tit">账号信息</div>
6
+ <div class="user-info-head">
7
+ <div class="user-info-head-avatar" @click="avatarVisible = true">
8
+ <img
9
+ class="user-info-head-img"
10
+ mode="aspectFit"
11
+ v-if="userInfo.avatar"
12
+ :src="userInfo.avatar"
13
+ alt=""
14
+ />
15
+ <img
16
+ class="user-info-head-img"
17
+ mode="aspectFit"
18
+ v-else
19
+ src="https://cdn.ddjf.com/static/images/wx-yunservice/account-head.png"
20
+ alt=""
21
+ />
22
+ <div class="user-info-head-upload">
23
+ <img
24
+ class="user-info-head-upload-icon"
25
+ mode="aspectFit"
26
+ src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzQiIGhlaWdodD0iMzQiIHZpZXdCb3g9IjAgMCAzNCAzNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0yMi4wOTk5IDE4LjQyMjRDMjIuMDk5OSAxNS41ODMyIDE5LjgxNjYgMTMuMjgxNiAxNi45OTk5IDEzLjI4MTZDMTQuMTgzMyAxMy4yODE2IDExLjg5OTkgMTUuNTgzMiAxMS44OTk5IDE4LjQyMjRDMTEuODk5OSAyMS4yNjE2IDE0LjE4MzMgMjMuNTYzMiAxNi45OTk5IDIzLjU2MzJDMTkuODE2NiAyMy41NjMyIDIyLjA5OTkgMjEuMjYxNiAyMi4wOTk5IDE4LjQyMjRWMTguNDIyNFoiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMi41NSIgc3Ryb2tlLWxpbmVjYXA9InNxdWFyZSIvPgo8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTIzLjc5OTkgNS45OTg4QzIzLjc5OTkgNi4yMzUzOSAyMy45OTAyIDYuNDI3MiAyNC4yMjQ5IDYuNDI3MkgyNS45MjVDMjkuNDQ1OCA2LjQyNzIgMzIuMyA5LjMwNDIxIDMyLjMgMTIuODUzMlYyMy45OTE2QzMyLjMgMjcuNTQwNiAyOS40NDU4IDMwLjQxNzYgMjUuOTI1IDMwLjQxNzZIOC4wNzQ5NEM0LjU1NDE0IDMwLjQxNzYgMS42OTk5NSAyNy41NDA2IDEuNjk5OTUgMjMuOTkxNlYxMi44NTMyQzEuNjk5OTUgOS4zMDQyMSA0LjU1NDE0IDYuNDI3MiA4LjA3NDk0IDYuNDI3Mkg5Ljc3NDk1QzEwLjAwOTcgNi40MjcyIDEwLjIgNi4yMzUzOSAxMC4yIDUuOTk4OEMxMC4yIDUuNzA5NDkgMTAuMjQwNiA1LjQyOTc1IDEwLjMxNjUgNS4xNjUwNkMxMC42NzQ4IDMuOTE0NTEgMTEuODE4OSAzIDEzLjE3NSAzSDIwLjgyNUMyMi40NjggMyAyMy43OTk5IDQuMzQyNjEgMjMuNzk5OSA1Ljk5ODhWNS45OTg4WiIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIyLjU1IiBzdHJva2UtbGluZWNhcD0ic3F1YXJlIi8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNNy42NDk5IDEwLjI4MjhDOC44MjM1MSAxMC4yODI4IDkuNzc0OSAxMS4yNDE4IDkuNzc0OSAxMi40MjQ4QzkuNzc0OSAxMy42MDc4IDguODIzNTEgMTQuNTY2OCA3LjY0OTkgMTQuNTY2OEM2LjQ3NjMgMTQuNTY2OCA1LjUyNDkgMTMuNjA3OCA1LjUyNDkgMTIuNDI0OEM1LjUyNDkgMTEuMjQxOCA2LjQ3NjMgMTAuMjgyOCA3LjY0OTkgMTAuMjgyOFoiIGZpbGw9IndoaXRlIi8+Cjwvc3ZnPgo="
27
+ alt=""
28
+ />
29
+ </div>
30
+ </div>
31
+ <nut-cell
32
+ title="登录手机号"
33
+ is-link
34
+ :desc="encodePhone(userInfo.mobile || '')"
35
+ @click="toBinding"
36
+ />
37
+ </div>
38
+
39
+ <div class="user-info-tit">企业/团队</div>
40
+ <div class="user-info-team">
41
+ <div v-for="(item, key) in userInfo.tenantInfoList" :key="key" class="user-info-team-item">
42
+ <div class="user-info-team-item-avatar">
43
+ <img
44
+ v-if="item.tenantLogo"
45
+ class="user-info-team-item-avatar-img"
46
+ mode="aspectFit"
47
+ :src="item.tenantLogo"
48
+ alt=""
49
+ />
50
+ <img
51
+ v-else
52
+ class="user-info-team-item-avatar-img empty"
53
+ mode="aspectFit"
54
+ src="https://cdn.ddjf.com/static/images/customer-center/tenant-logo.png"
55
+ alt=""
56
+ />
57
+ </div>
58
+ <div class="user-info-team-item-bd">
59
+ <div class="user-info-team-item-title">{{ item.tenantName }}</div>
60
+ <div class="user-info-team-item-app" v-if="item.appRoleInfo">
61
+ <div
62
+ class="user-info-team-item-app-tag"
63
+ v-for="(aitem, akey) in item.appRoleInfo || []"
64
+ :key="akey"
65
+ >
66
+ {{ aitem.appAbbr }}
67
+ </div>
68
+ <div class="user-info-team-item-role-btn" @click="toShowRole(item)">
69
+ 角色详情
70
+ <img
71
+ :class="{ showRole: item.showRole }"
72
+ class="user-info-team-item-role-btn-icon"
73
+ src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTE4IDlMMTIgMTVMNiA5IiBzdHJva2U9IiMwMTdGRkYiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+Cjwvc3ZnPgo="
74
+ alt=""
75
+ />
76
+ </div>
77
+ </div>
78
+ <div class="user-info-team-item-role" v-if="item.showRole">
79
+ <div
80
+ class="user-info-team-item-role-item"
81
+ v-for="(aitem, akey) in item.appRoleInfo || []"
82
+ :key="akey"
83
+ >
84
+ <div class="user-info-team-item-role-item-name">{{ aitem.appAbbr }}</div>
85
+ <div class="user-info-team-item-role-item-info">
86
+ {{ aitem.roleName }}
87
+ </div>
88
+ </div>
89
+ </div>
90
+ <div class="user-info-team-item-user">
91
+ {{ item.fullName }}
92
+ <img
93
+ @click="toUserNameChange(item)"
94
+ class="user-info-team-item-user-icon"
95
+ src="https://cdn.ddjf.com/static/images/appkit/edit.png"
96
+ alt=""
97
+ />
98
+ </div>
99
+ <div class="user-info-team-item-dept">
100
+ <div
101
+ v-for="(ditem, dkey) in item.deptNames"
102
+ :key="dkey"
103
+ class="user-info-team-item-dept-item"
104
+ >
105
+ {{ ditem }}
106
+ </div>
107
+ </div>
108
+ </div>
109
+ </div>
110
+ </div>
111
+
112
+ <div class="user-info-ft">
113
+ <nut-button
114
+ class="user-info-ft-btn"
115
+ style="width: 100%"
116
+ @click="toLogout"
117
+ plain
118
+ type="primary"
119
+ >退出登录</nut-button
120
+ >
121
+ </div>
122
+ </div>
123
+ </scroll-view>
124
+
125
+ <!-- 修改用户名弹框 -->
126
+ <nut-dialog
127
+ title="输入新的用户名"
128
+ :border="false"
129
+ pop-class="change-username-popup"
130
+ v-model:visible="userState.visible"
131
+ @cancel="onUserNameCancel"
132
+ >
133
+ <nut-input :max-length="20" placeholder="请输入新的用户名" v-model="userState.value" />
134
+ <template #footer>
135
+ <nut-button class="change-username-popup-cancel" type="default" @click="onUserNameCancel">
136
+ 取消
137
+ </nut-button>
138
+ <nut-button class="change-username-popup-ok" type="primary" @click="onUserNameOk">
139
+ 确定
140
+ </nut-button>
141
+ </template>
142
+ </nut-dialog>
143
+
144
+ <!-- 修改头像弹框 -->
145
+ <nut-popup
146
+ pop-class="upload-avatar-popup"
147
+ style="background: transparent"
148
+ v-model:visible="avatarVisible"
149
+ :overlay-style="{ background: 'rgba(0, 0, 0, 0.9)' }"
150
+ >
151
+ <div class="upload-avatar-popup-box">
152
+ <img
153
+ class="upload-avatar-popup-avatar"
154
+ mode="aspectFit"
155
+ v-if="userInfo.avatar"
156
+ :src="userInfo.avatar"
157
+ alt=""
158
+ />
159
+ <img
160
+ class="upload-avatar-popup-avatar"
161
+ mode="aspectFit"
162
+ v-else
163
+ src="https://cdn.ddjf.com/static/images/wx-yunservice/account-head.png"
164
+ alt=""
165
+ />
166
+ <div class="upload-avatar-popup-btn" @click="toUpload">更换头像</div>
167
+ </div>
168
+ </nut-popup>
169
+ </template>
170
+
171
+ <script lang="ts" setup>
172
+ import Taro, { useDidShow } from '@tarojs/taro'
173
+ import { ref, onMounted, reactive, onUnmounted } from 'vue'
174
+ import { useAppKitOptions } from '../../Appkit'
175
+ import { useEncode } from '../../shared/composables/useEncode'
176
+ import DdSkeleton from '../../components/dd-skeleton/index.vue'
177
+ import { useHttp } from '../api'
178
+
179
+ const props = withDefaults(
180
+ defineProps<{
181
+ miniType?: string
182
+ app?: string
183
+ userId: string
184
+ }>(),
185
+ {
186
+ miniType: '05',
187
+ app: '',
188
+ userId: '',
189
+ }
190
+ )
191
+
192
+ const { encodePhone } = useEncode()
193
+
194
+ useDidShow(() => {
195
+ getUserInfoByUserId()
196
+ })
197
+ onMounted(() => {
198
+ Taro.eventCenter.on('USER-HEAD-CROP-OK', updateImage)
199
+ })
200
+ onUnmounted(() => {
201
+ Taro.eventCenter.off('USER-HEAD-CROP-OK')
202
+ })
203
+
204
+ const firstLoading = ref(true)
205
+ const userInfo = ref<any>({})
206
+ // 根据用户id,查询用户所在租户列表
207
+ function getUserInfoByUserId() {
208
+ const $http = useHttp()
209
+
210
+ $http
211
+ .get(`/cas/sysAccount/getAccountInfo/${props.userId}`)
212
+ .then((result: any) => {
213
+ userInfo.value = result
214
+ firstLoading.value = false
215
+ })
216
+ .catch(() => {
217
+ firstLoading.value = false
218
+ })
219
+ }
220
+
221
+ // 修改头像弹框
222
+ const avatarVisible = ref(false)
223
+
224
+ // 去上传头像
225
+ async function toUpload() {
226
+ if (!userInfo.value.avatar) {
227
+ const profile = await Taro.getUserProfile({
228
+ desc: '头像用于改变默认头像',
229
+ })
230
+
231
+ const res = await Taro.downloadFile({
232
+ url: profile.userInfo.avatarUrl,
233
+ })
234
+
235
+ updateImage(res.tempFilePath)
236
+ } else {
237
+ let res = await Taro.chooseImage({
238
+ count: 1,
239
+ })
240
+ if (res.tempFilePaths) {
241
+ const filePath = res.tempFilePaths[0]
242
+
243
+ emits('crop', filePath)
244
+ }
245
+ }
246
+ }
247
+
248
+ // 上传图片
249
+ async function updateImage(filePath: string) {
250
+ Taro.showLoading({
251
+ title: '上传中...',
252
+ })
253
+ const appkitOptions = useAppKitOptions()
254
+ const $http = useHttp()
255
+
256
+ let Res: any = await Taro.uploadFile({
257
+ url: `${appkitOptions.baseUrl()}/cas/file/uploadImg`,
258
+ filePath: filePath,
259
+ name: 'file',
260
+ formData: {
261
+ objectNo: `${userInfo.value.mobile}${Date.now()}`,
262
+ objectTypeCode: `MINI_HEADIMAGE${props.miniType}`,
263
+ },
264
+ header: {
265
+ token: appkitOptions.tempToken() || appkitOptions.token(),
266
+ },
267
+ })
268
+ avatarVisible.value = false
269
+
270
+ const res = JSON.parse(Res.data)
271
+ if (res.success) {
272
+ $http
273
+ .post('/cas/sysUser/update', {
274
+ appCode: props.app,
275
+ avatar: res.result,
276
+ userId: props.userId,
277
+ })
278
+ .then(() => {
279
+ Taro.hideLoading()
280
+ Taro.showToast({ title: '头像上传成功', icon: 'none' })
281
+ getUserInfoByUserId()
282
+ emits('avatar-success', res.result)
283
+ })
284
+ .catch(() => {
285
+ Taro.hideLoading()
286
+ })
287
+ } else {
288
+ Taro.hideLoading()
289
+ }
290
+ }
291
+
292
+ // 查看角色详情
293
+ function toShowRole(item: any) {
294
+ item.showRole = !item.showRole
295
+ }
296
+
297
+ // 更换用户名
298
+ const userState = reactive({
299
+ visible: false,
300
+ value: '',
301
+ oldName: '',
302
+ tenantId: '',
303
+ })
304
+ function toUserNameChange(item: any) {
305
+ userState.visible = true
306
+ userState.oldName = item.fullName
307
+ userState.tenantId = item.tenantId
308
+ }
309
+ function onUserNameCancel() {
310
+ userState.visible = false
311
+ userState.value = ''
312
+ userState.oldName = ''
313
+ userState.tenantId = ''
314
+ }
315
+ function onUserNameOk() {
316
+ if (!userState.value) {
317
+ return Taro.showToast({
318
+ title: '请输入用户名',
319
+ icon: 'none',
320
+ })
321
+ }
322
+ if (userState.value === userState.oldName) {
323
+ return Taro.showToast({
324
+ title: '用户名不能与原用户名相同',
325
+ icon: 'none',
326
+ })
327
+ }
328
+
329
+ const $http = useHttp()
330
+
331
+ $http
332
+ .post('/cas/sysUser/updateUserInfoByTenantId', {
333
+ fullName: userState.value,
334
+ tenantId: userState.tenantId,
335
+ userId: props.userId,
336
+ })
337
+ .then(() => {
338
+ Taro.showToast({ title: '用户名修改成功', icon: 'none' })
339
+ getUserInfoByUserId()
340
+ onUserNameCancel()
341
+ emits('username-success')
342
+ })
343
+ }
344
+
345
+ // 退出登录
346
+ function toLogout() {
347
+ Taro.showModal({
348
+ title: '提示',
349
+ content: '确定要退出登录吗?',
350
+ confirmText: '确定',
351
+ success: async (e: any) => {
352
+ if (e.confirm) {
353
+ emits('logout')
354
+ }
355
+ },
356
+ })
357
+ }
358
+
359
+ // 去绑定手机号
360
+ function toBinding() {
361
+ emits('binding', userInfo.value.mobile || '')
362
+ }
363
+
364
+ // 父组件事件
365
+ const emits = defineEmits(['avatar-success', 'logout', 'crop', 'binding', 'username-success'])
366
+
367
+ // 外部访问
368
+ defineExpose({
369
+ updateImage,
370
+ })
371
+ </script>
372
+
373
+ <style lang="scss">
374
+ .user-info {
375
+ height: 100vh;
376
+
377
+ &-wrap {
378
+ padding: 0 12px;
379
+ padding-bottom: calc(12px + env(safe-area-inset-bottom, 0px));
380
+ box-sizing: border-box;
381
+ min-height: 100%;
382
+ }
383
+ &-tit {
384
+ height: 38px;
385
+ display: flex;
386
+ align-items: center;
387
+ color: #666666;
388
+ font-size: 12px;
389
+ padding-left: 10px;
390
+ }
391
+ &-head {
392
+ border-radius: 5px;
393
+ background: #fff;
394
+ padding: 30px 11px 0;
395
+ &-avatar {
396
+ position: relative;
397
+ width: 80px;
398
+ height: 80px;
399
+ margin: 0 auto 25px;
400
+ }
401
+ &-img {
402
+ width: 100%;
403
+ height: 100%;
404
+ overflow: hidden;
405
+ border-radius: 50%;
406
+ }
407
+ &-upload {
408
+ position: absolute;
409
+ bottom: -2px;
410
+ left: 52px;
411
+ width: 29px;
412
+ height: 29px;
413
+ background: #333333;
414
+ overflow: hidden;
415
+ border-radius: 50%;
416
+ display: flex;
417
+ align-items: center;
418
+ justify-content: center;
419
+ &-icon {
420
+ width: 17px;
421
+ height: 17px;
422
+ }
423
+ }
424
+ }
425
+ &-team {
426
+ &-item {
427
+ border-radius: 5px;
428
+ background: #fff;
429
+ display: flex;
430
+ padding: 15px;
431
+ margin-bottom: 10px;
432
+ &-avatar {
433
+ width: 38px;
434
+ height: 38px;
435
+ margin-right: 15px;
436
+ border-radius: 5px;
437
+ background: rgba(1, 127, 255, 0.3);
438
+ display: flex;
439
+ align-items: center;
440
+ justify-content: center;
441
+ &-img {
442
+ width: 100%;
443
+ height: 100%;
444
+ }
445
+ .empty {
446
+ width: 20px;
447
+ height: 40px;
448
+ }
449
+ }
450
+ &-title {
451
+ font-size: 16px;
452
+ font-weight: 500;
453
+ margin-bottom: 5px;
454
+ }
455
+ &-app {
456
+ display: flex;
457
+ align-items: center;
458
+ flex-wrap: wrap;
459
+ &-tag {
460
+ border: 1px solid rgba(53, 53, 53, 0.2);
461
+ font-size: 10px;
462
+ height: 18px;
463
+ display: inline-flex;
464
+ align-items: center;
465
+ justify-content: center;
466
+ padding: 0 6px;
467
+ border-radius: 2px;
468
+ margin: 0 10px 6px 0;
469
+ }
470
+ }
471
+ &-bd {
472
+ flex: 1;
473
+ }
474
+ &-role {
475
+ padding: 10px;
476
+ background: rgba(245, 245, 245, 0.5);
477
+ border-radius: 5px;
478
+ margin-bottom: 10px;
479
+ &-btn {
480
+ color: var(--app-primary-color, #017fff);
481
+ font-size: 10px;
482
+ display: inline-flex;
483
+ align-items: center;
484
+ margin-bottom: 6px;
485
+ &-icon {
486
+ width: 12px;
487
+ height: 12px;
488
+ position: relative;
489
+ top: 1px;
490
+ &.showRole {
491
+ transform: rotate(180deg);
492
+ }
493
+ }
494
+ }
495
+ &-item {
496
+ display: flex;
497
+ font-size: 10px;
498
+ margin-bottom: 10px;
499
+ &:last-child {
500
+ margin-bottom: 0;
501
+ }
502
+ &-name {
503
+ opacity: 0.5;
504
+ white-space: nowrap;
505
+ margin-right: 10px;
506
+ min-width: 40px;
507
+ }
508
+ &-info {
509
+ flex: 1;
510
+ color: #1a1a1a;
511
+ }
512
+ }
513
+ }
514
+ &-user {
515
+ margin-bottom: 4px;
516
+ font-size: 12px;
517
+ display: flex;
518
+ align-items: center;
519
+ &-icon {
520
+ width: 10px;
521
+ height: 10px;
522
+ margin-left: 4px;
523
+ }
524
+ }
525
+ &-dept {
526
+ display: flex;
527
+ flex-wrap: wrap;
528
+ font-size: 10px;
529
+ color: rgba(26, 26, 26, 0.8);
530
+ &-item {
531
+ font-size: 10px;
532
+ color: rgba(26, 26, 26, 0.5);
533
+ margin: 4px 10px 4px 0;
534
+ &:first-child {
535
+ color: rgba(26, 26, 26, 0.8);
536
+ }
537
+ }
538
+ }
539
+ }
540
+ }
541
+
542
+ &-ft {
543
+ &-btn {
544
+ width: 100%;
545
+ border-color: transparent !important;
546
+ color: rgba(27, 63, 107, 0.8) !important;
547
+ }
548
+ }
549
+
550
+ .nut-cell {
551
+ padding: 11px 0;
552
+ margin: 0;
553
+ box-shadow: none;
554
+ border-bottom: 1px solid #f0f0f0;
555
+ font-size: 16px;
556
+ .nut-cell__value {
557
+ font-size: 16px;
558
+ color: #000;
559
+ }
560
+ .nut-cell__link {
561
+ color: #ccc;
562
+ margin-left: 8px;
563
+ }
564
+ }
565
+ }
566
+ .upload-avatar-popup {
567
+ &-box {
568
+ display: flex;
569
+ flex-direction: column;
570
+ align-items: center;
571
+ justify-content: center;
572
+ }
573
+ &-avatar {
574
+ width: 320px;
575
+ height: 320px;
576
+ overflow: hidden;
577
+ border-radius: 50%;
578
+ margin-bottom: 50px;
579
+ }
580
+ &-btn {
581
+ width: 106px;
582
+ height: 37px;
583
+ border-radius: 50px;
584
+ border: 1px solid #ffffff;
585
+ display: flex;
586
+ justify-content: center;
587
+ align-items: center;
588
+ color: #ffffff;
589
+ font-size: 16px;
590
+ }
591
+ }
592
+ .change-username-popup {
593
+ .nut-dialog {
594
+ min-height: auto;
595
+ }
596
+ .nut-input {
597
+ height: 40px;
598
+ padding: 0;
599
+ display: flex;
600
+ align-items: center;
601
+ font-size: 16px;
602
+ border: none;
603
+ .input-text {
604
+ width: 100%;
605
+ height: 100%;
606
+ font-size: 14px;
607
+ }
608
+ .nut-input-value,
609
+ .nut-input-inner,
610
+ .nut-input-box {
611
+ height: 100%;
612
+ overflow: hidden;
613
+ background: #f5f5f5;
614
+ border-radius: 6px;
615
+ }
616
+ .nut-placeholder {
617
+ color: #cccccc;
618
+ line-height: 38px;
619
+ height: 38px;
620
+ }
621
+ .nut-input-box {
622
+ padding: 0 15px;
623
+ }
624
+ }
625
+ &-cancel.nut-button {
626
+ border-radius: 15px;
627
+ font-size: 14px;
628
+ height: 30px;
629
+ }
630
+ &-ok.nut-button {
631
+ background: var(--app-primary-color, #017fff);
632
+ height: 30px;
633
+ font-size: 14px;
634
+ border-radius: 15px;
635
+ }
636
+ }
637
+ </style>