@uxda/appkit 1.2.72 → 1.2.75

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