@uxda/appkit 4.2.12 → 4.2.16

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