@uxda/appkit 4.2.14 → 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 +3 -7
  5. package/dist/index.js +1078 -1161
  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 -824
  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,824 +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="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
- }>(),
271
- {
272
- miniType: "05",
273
- app: "",
274
- userId: "",
275
- hasQiyezuhu: 0,
276
- }
277
- );
278
-
279
- const { encodePhone } = useEncode();
280
-
281
- useDidShow(() => {
282
- getUserInfoByUserId();
283
- });
284
- onMounted(() => {
285
- Taro.eventCenter.on("USER-HEAD-CROP-OK", updateImage);
286
- });
287
- onUnmounted(() => {
288
- Taro.eventCenter.off("USER-HEAD-CROP-OK");
289
- });
290
-
291
- const firstLoading = ref(true);
292
- const userInfo = ref<any>({});
293
- // 根据用户id,查询用户所在租户列表
294
- function getUserInfoByUserId() {
295
- const $http = useHttp();
296
-
297
- $http
298
- .get(`/cas/sysAccount/getAccountInfo/${props.userId}`)
299
- .then((result: any) => {
300
- userInfo.value = result;
301
- firstLoading.value = false;
302
- })
303
- .catch(() => {
304
- firstLoading.value = false;
305
- });
306
- }
307
-
308
- // 修改头像弹框
309
- const avatarVisible = ref(false);
310
-
311
- // 去上传头像
312
- async function toUpload() {
313
- if (!userInfo.value.avatar) {
314
- const profile = await Taro.getUserProfile({
315
- desc: "头像用于改变默认头像",
316
- });
317
-
318
- const res = await Taro.downloadFile({
319
- url: profile.userInfo.avatarUrl,
320
- });
321
-
322
- updateImage(res.tempFilePath);
323
- } else {
324
- let res = await Taro.chooseImage({
325
- count: 1,
326
- });
327
- if (res.tempFilePaths) {
328
- const filePath = res.tempFilePaths[0];
329
-
330
- emits("crop", filePath);
331
- }
332
- }
333
- }
334
-
335
- // 上传图片
336
- async function updateImage(filePath: string) {
337
- Taro.showLoading({
338
- title: "上传中...",
339
- });
340
- const appkitOptions = useAppKitOptions();
341
- const $http = useHttp();
342
-
343
- let Res: any = await Taro.uploadFile({
344
- url: `${appkitOptions.baseUrl()}/cas/file/uploadImg`,
345
- filePath: filePath,
346
- name: "file",
347
- formData: {
348
- objectNo: `${userInfo.value.mobile}${Date.now()}`,
349
- objectTypeCode: `MINI_HEADIMAGE${props.miniType}`,
350
- },
351
- header: {
352
- token: appkitOptions.tempToken() || appkitOptions.token(),
353
- },
354
- });
355
- avatarVisible.value = false;
356
-
357
- const res = JSON.parse(Res.data);
358
- if (res.success) {
359
- $http
360
- .post("/cas/sysUser/update", {
361
- appCode: props.app,
362
- avatar: res.result,
363
- userId: props.userId,
364
- })
365
- .then(() => {
366
- Taro.hideLoading();
367
- Taro.showToast({ title: "头像上传成功", icon: "none" });
368
- getUserInfoByUserId();
369
- emits("avatar-success", res.result);
370
- })
371
- .catch(() => {
372
- Taro.hideLoading();
373
- });
374
- } else {
375
- Taro.hideLoading();
376
- }
377
- }
378
-
379
- // 查看角色详情
380
- function toShowRole(item: any) {
381
- item.showRole = !item.showRole;
382
- }
383
-
384
- const nickNameState = reactive({
385
- visible: false,
386
- value: "",
387
- });
388
- // 更换用户名
389
- const userState = reactive({
390
- visible: false,
391
- value: "",
392
- oldName: "",
393
- tenantId: "",
394
- });
395
- function toUserNameChange(item: any) {
396
- userState.visible = true;
397
- userState.oldName = item.fullName;
398
- userState.tenantId = item.tenantId;
399
- }
400
- function onUserNameCancel() {
401
- userState.visible = false;
402
- userState.value = "";
403
- userState.oldName = "";
404
- userState.tenantId = "";
405
- }
406
-
407
- function onNickNameCancel() {
408
- nickNameState.visible = false;
409
- nickNameState.value = "";
410
- }
411
- function onNickNameChange() {
412
- nickNameState.visible = true;
413
- nickNameState.value = "";
414
- }
415
- function onUserNameOk() {
416
- if (!userState.value) {
417
- return Taro.showToast({
418
- title: "请输入用户名",
419
- icon: "none",
420
- });
421
- }
422
- if (userState.value === userState.oldName) {
423
- return Taro.showToast({
424
- title: "用户名不能与原用户名相同",
425
- icon: "none",
426
- });
427
- }
428
-
429
- const $http = useHttp();
430
-
431
- $http
432
- .post("/cas/sysUser/updateUserInfoByTenantId", {
433
- fullName: userState.value,
434
- tenantId: userState.tenantId,
435
- userId: props.userId,
436
- })
437
- .then(() => {
438
- Taro.showToast({ title: "用户名修改成功", icon: "none" });
439
- getUserInfoByUserId();
440
- onUserNameCancel();
441
- emits("username-success");
442
- });
443
- }
444
-
445
- function onNickNameOk() {
446
- if (!nickNameState.value) {
447
- return Taro.showToast({
448
- title: "请输入昵称",
449
- icon: "none",
450
- });
451
- }
452
- // if (userState.value === userState.oldName) {
453
- // return Taro.showToast({
454
- // title: "用户名不能与原用户名相同",
455
- // icon: "none",
456
- // });
457
- // }
458
-
459
- const $http = useHttp();
460
-
461
- $http
462
- .post("/cas/sysAccount/updateAccountInfo", {
463
- nickName: nickNameState.value,
464
- })
465
- .then(() => {
466
- Taro.showToast({ title: "昵称修改成功", icon: "none" });
467
- getUserInfoByUserId();
468
- onNickNameCancel();
469
- // emits("username-success");
470
- });
471
- }
472
- // 退出登录
473
- function toLogout() {
474
- Taro.showModal({
475
- title: "提示",
476
- content: "确定要退出登录吗?",
477
- confirmText: "确定",
478
- success: async (e: any) => {
479
- if (e.confirm) {
480
- emits("logout");
481
- }
482
- },
483
- });
484
- }
485
-
486
- // 去绑定手机号
487
- function toBinding() {
488
- emits("binding", userInfo.value.mobile || "");
489
- }
490
-
491
- // 去认证页
492
- function toAuth() {
493
- emits(
494
- "auth",
495
- props.userId,
496
- userInfo.value?.verifyResult,
497
- userInfo.value?.mobile
498
- );
499
- }
500
-
501
- // 父组件事件
502
- const emits = defineEmits([
503
- "avatar-success",
504
- "logout",
505
- "crop",
506
- "binding",
507
- "username-success",
508
- "auth",
509
- ]);
510
-
511
- // 外部访问
512
- defineExpose({
513
- updateImage,
514
- });
515
- </script>
516
-
517
- <style lang="scss">
518
- .user-info {
519
- height: 100vh;
520
- .nut-cell {
521
- border-radius: 0px;
522
- }
523
-
524
- &-wrap {
525
- padding: 0 12px;
526
- padding-bottom: calc(12px + env(safe-area-inset-bottom, 0px));
527
- box-sizing: border-box;
528
- min-height: 100%;
529
- }
530
-
531
- &-tit {
532
- height: 38px;
533
- display: flex;
534
- align-items: center;
535
- color: #666666;
536
- font-size: 12px;
537
- padding-left: 10px;
538
- }
539
-
540
- &-head {
541
- border-radius: 5px;
542
- background: #fff;
543
- padding: 30px 11px 0;
544
-
545
- &-avatar {
546
- position: relative;
547
- width: 80px;
548
- height: 80px;
549
- margin: 0 auto 25px;
550
- }
551
-
552
- &-img {
553
- width: 100%;
554
- height: 100%;
555
- overflow: hidden;
556
- border-radius: 50%;
557
- }
558
-
559
- &-upload {
560
- position: absolute;
561
- bottom: -2px;
562
- left: 52px;
563
- width: 29px;
564
- height: 29px;
565
- background: #333333;
566
- overflow: hidden;
567
- border-radius: 50%;
568
- display: flex;
569
- align-items: center;
570
- justify-content: center;
571
-
572
- &-icon {
573
- width: 17px;
574
- height: 17px;
575
- }
576
- }
577
- }
578
-
579
- &-team {
580
- &-item {
581
- border-radius: 5px;
582
- background: #fff;
583
- display: flex;
584
- padding: 15px;
585
- margin-bottom: 10px;
586
-
587
- &-avatar {
588
- width: 38px;
589
- height: 38px;
590
- margin-right: 15px;
591
- border-radius: 5px;
592
- background: rgba(1, 127, 255, 0.3);
593
- display: flex;
594
- align-items: center;
595
- justify-content: center;
596
-
597
- &-img {
598
- width: 100%;
599
- height: 100%;
600
- }
601
-
602
- .empty {
603
- width: 20px;
604
- height: 40px;
605
- }
606
- }
607
-
608
- &-title {
609
- font-size: 16px;
610
- font-weight: 500;
611
- margin-bottom: 5px;
612
- }
613
-
614
- &-app {
615
- display: flex;
616
- align-items: center;
617
- flex-wrap: wrap;
618
-
619
- &-tag {
620
- border: 1px solid rgba(53, 53, 53, 0.2);
621
- font-size: 10px;
622
- height: 18px;
623
- display: inline-flex;
624
- align-items: center;
625
- justify-content: center;
626
- padding: 0 6px;
627
- border-radius: 2px;
628
- margin: 0 10px 6px 0;
629
- }
630
- }
631
-
632
- &-bd {
633
- flex: 1;
634
- }
635
-
636
- &-role {
637
- padding: 10px;
638
- background: rgba(245, 245, 245, 0.5);
639
- border-radius: 5px;
640
- margin-bottom: 10px;
641
-
642
- &-btn {
643
- color: var(--app-primary-color, #017fff);
644
- font-size: 10px;
645
- display: inline-flex;
646
- align-items: center;
647
- margin-bottom: 6px;
648
-
649
- &-icon {
650
- width: 12px;
651
- height: 12px;
652
- position: relative;
653
- top: 1px;
654
-
655
- &.showRole {
656
- transform: rotate(180deg);
657
- }
658
- }
659
- }
660
-
661
- &-item {
662
- display: flex;
663
- font-size: 10px;
664
- margin-bottom: 10px;
665
-
666
- &:last-child {
667
- margin-bottom: 0;
668
- }
669
-
670
- &-name {
671
- opacity: 0.5;
672
- white-space: nowrap;
673
- margin-right: 10px;
674
- min-width: 40px;
675
- }
676
-
677
- &-info {
678
- flex: 1;
679
- color: #1a1a1a;
680
- }
681
- }
682
- }
683
-
684
- &-user {
685
- margin-bottom: 4px;
686
- font-size: 12px;
687
- display: flex;
688
- align-items: center;
689
-
690
- &-icon {
691
- width: 10px;
692
- height: 10px;
693
- margin-left: 4px;
694
- }
695
- }
696
-
697
- &-dept {
698
- display: flex;
699
- flex-wrap: wrap;
700
- font-size: 10px;
701
- color: rgba(26, 26, 26, 0.8);
702
-
703
- &-item {
704
- font-size: 10px;
705
- color: rgba(26, 26, 26, 0.5);
706
- margin: 4px 10px 4px 0;
707
-
708
- &:first-child {
709
- color: rgba(26, 26, 26, 0.8);
710
- }
711
- }
712
- }
713
- }
714
- }
715
-
716
- &-ft {
717
- &-btn {
718
- width: 100%;
719
- border-color: transparent !important;
720
- color: rgba(27, 63, 107, 0.8) !important;
721
- }
722
- }
723
-
724
- .nut-cell {
725
- padding: 11px 0;
726
- margin: 0;
727
- box-shadow: none;
728
- border-bottom: 1px solid #f0f0f0;
729
- font-size: 16px;
730
-
731
- .nut-cell__value {
732
- font-size: 16px;
733
- color: #000;
734
- }
735
-
736
- .nut-cell__link {
737
- color: #ccc;
738
- margin-left: 8px;
739
- }
740
- }
741
- }
742
-
743
- .upload-avatar-popup {
744
- &-box {
745
- display: flex;
746
- flex-direction: column;
747
- align-items: center;
748
- justify-content: center;
749
- }
750
-
751
- &-avatar {
752
- width: 320px;
753
- height: 320px;
754
- overflow: hidden;
755
- border-radius: 50%;
756
- margin-bottom: 50px;
757
- }
758
-
759
- &-btn {
760
- width: 106px;
761
- height: 37px;
762
- border-radius: 50px;
763
- border: 1px solid #ffffff;
764
- display: flex;
765
- justify-content: center;
766
- align-items: center;
767
- color: #ffffff;
768
- font-size: 16px;
769
- }
770
- }
771
-
772
- .change-username-popup {
773
- .nut-dialog {
774
- min-height: auto;
775
- }
776
-
777
- .nut-input {
778
- height: 40px;
779
- padding: 0;
780
- display: flex;
781
- align-items: center;
782
- font-size: 16px;
783
- border: none;
784
-
785
- .input-text {
786
- width: 100%;
787
- height: 100%;
788
- font-size: 14px;
789
- }
790
-
791
- .nut-input-value,
792
- .nut-input-inner,
793
- .nut-input-box {
794
- height: 100%;
795
- overflow: hidden;
796
- background: #f5f5f5;
797
- border-radius: 6px;
798
- }
799
-
800
- .nut-placeholder {
801
- color: #cccccc;
802
- line-height: 38px;
803
- height: 38px;
804
- }
805
-
806
- .nut-input-box {
807
- padding: 0 15px;
808
- }
809
- }
810
-
811
- &-cancel.nut-button {
812
- border-radius: 15px;
813
- font-size: 14px;
814
- height: 30px;
815
- }
816
-
817
- &-ok.nut-button {
818
- background: var(--app-primary-color, #017fff);
819
- height: 30px;
820
- font-size: 14px;
821
- border-radius: 15px;
822
- }
823
- }
824
- </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>