@uxda/appkit 4.1.62 → 4.2.0

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