@uxda/appkit 4.0.3 → 4.0.14

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 (116) hide show
  1. package/.eslintrc.mjs +7 -7
  2. package/README.md +187 -187
  3. package/babel.config.js +12 -12
  4. package/package.json +75 -80
  5. package/project.config.json +15 -15
  6. package/project.tt.json +13 -13
  7. package/rollup.config.mjs +56 -56
  8. package/src/Appkit.ts +65 -65
  9. package/src/balance/api/endpoints.ts +126 -126
  10. package/src/balance/api/index.ts +82 -82
  11. package/src/balance/components/AccountView.vue +748 -748
  12. package/src/balance/components/BalanceCard.vue +205 -209
  13. package/src/balance/components/BalanceReminder.vue +85 -85
  14. package/src/balance/components/ConsumptionFilter.vue +218 -218
  15. package/src/balance/components/ConsumptionRules.vue +68 -68
  16. package/src/balance/components/DateFilter.vue +227 -226
  17. package/src/balance/components/DateRange.vue +78 -0
  18. package/src/balance/components/ListFilter.vue +64 -0
  19. package/src/balance/components/ListFilterPicker.vue +187 -0
  20. package/src/balance/components/SecondBalance.vue +71 -71
  21. package/src/balance/components/Tip.vue +45 -45
  22. package/src/balance/components/index.ts +13 -9
  23. package/src/balance/types.ts +91 -90
  24. package/src/components/bt-cropper/index.vue +774 -774
  25. package/src/components/bt-cropper/utils/calcCropper.js +42 -42
  26. package/src/components/bt-cropper/utils/calcImagePosition.js +23 -23
  27. package/src/components/bt-cropper/utils/calcImageSize.js +37 -37
  28. package/src/components/bt-cropper/utils/calcPointDistance.js +12 -12
  29. package/src/components/bt-cropper/utils/calcRightAndBottom.js +7 -7
  30. package/src/components/bt-cropper/utils/ratio.js +3 -3
  31. package/src/components/bt-cropper/utils/tools.js +25 -25
  32. package/src/components/dd-area/index.vue +225 -225
  33. package/src/components/dd-icon/doc.md +21 -21
  34. package/src/components/dd-icon/index.vue +23 -23
  35. package/src/components/dd-notice-bar/index.vue +78 -78
  36. package/src/components/dd-search/doc.md +34 -34
  37. package/src/components/dd-search/index.vue +168 -168
  38. package/src/components/dd-selector/index.vue +124 -124
  39. package/src/components/dd-skeleton/doc.md +19 -19
  40. package/src/components/dd-skeleton/index.vue +36 -36
  41. package/src/components/ocr-id/index.vue +114 -114
  42. package/src/components/ocr-id/types.d.ts +12 -12
  43. package/src/global.ts +6 -6
  44. package/src/index.ts +89 -89
  45. package/src/main.scss +1 -1
  46. package/src/notice/api/endpoints.ts +17 -17
  47. package/src/notice/api/index.ts +82 -82
  48. package/src/notice/components/NoticeBanner.vue +243 -243
  49. package/src/notice/components/NoticeEntry.vue +99 -99
  50. package/src/notice/components/NoticeList.vue +315 -315
  51. package/src/notice/components/NoticePopup.vue +161 -161
  52. package/src/notice/components/index.ts +5 -5
  53. package/src/notice/components/useCommonList.ts +86 -86
  54. package/src/notice/components/useNotice.ts +35 -35
  55. package/src/notice/index.ts +1 -1
  56. package/src/notice/types.ts +25 -25
  57. package/src/payment/api/config.ts +7 -7
  58. package/src/payment/api/endpoints.ts +103 -103
  59. package/src/payment/api/index.ts +71 -71
  60. package/src/payment/components/AmountPicker.vue +93 -93
  61. package/src/payment/components/RechargeResult.vue +69 -69
  62. package/src/payment/components/RechargeView.vue +154 -154
  63. package/src/payment/components/RightsPicker.vue +105 -105
  64. package/src/payment/components/TradeView.vue +298 -298
  65. package/src/payment/components/UserAgreement.vue +234 -234
  66. package/src/payment/components/index.ts +22 -22
  67. package/src/payment/index.ts +5 -5
  68. package/src/payment/services/index.ts +16 -16
  69. package/src/payment/services/invoke-recharge.ts +25 -25
  70. package/src/payment/services/request-payment.ts +58 -58
  71. package/src/payment/types.ts +28 -28
  72. package/src/register/components/SelfRegistration.vue +254 -254
  73. package/src/register/components/index.ts +2 -2
  74. package/src/shared/components/AppDrawer.vue +58 -58
  75. package/src/shared/components/AppVerify.vue +98 -0
  76. package/src/shared/components/DeviceVersion.vue +68 -68
  77. package/src/shared/components/EmptyView.vue +33 -33
  78. package/src/shared/components/OcrIcon.vue +119 -0
  79. package/src/shared/components/PageHeader.vue +79 -79
  80. package/src/shared/components/index.ts +7 -5
  81. package/src/shared/composables/index.ts +7 -5
  82. package/src/shared/composables/useCountdown.ts +46 -46
  83. package/src/shared/composables/useCrypto.ts +76 -0
  84. package/src/shared/composables/useDragBox.ts +97 -97
  85. package/src/shared/composables/useEncode.ts +43 -43
  86. package/src/shared/composables/useSafeArea.ts +46 -46
  87. package/src/shared/composables/useTabbar.ts +24 -24
  88. package/src/shared/composables/useUpload.ts +55 -0
  89. package/src/shared/composables/useValidator.ts +31 -31
  90. package/src/shared/http/Http.ts +136 -136
  91. package/src/shared/http/index.ts +1 -1
  92. package/src/shared/http/types.ts +157 -157
  93. package/src/shared/index.ts +3 -3
  94. package/src/shared/weixin/payment.ts +38 -38
  95. package/src/styles/fonts.scss +2 -2
  96. package/src/styles/vars.scss +3 -3
  97. package/src/user/api/endpoints.ts +17 -17
  98. package/src/user/api/index.ts +87 -87
  99. package/src/user/components/LoginSetting.vue +114 -114
  100. package/src/user/components/UserBinding.vue +307 -307
  101. package/src/user/components/UserBindingSuccess.vue +80 -80
  102. package/src/user/components/UserEntry.vue +137 -142
  103. package/src/user/components/UserFeedback.vue +440 -440
  104. package/src/user/components/UserFeedbackEntry.vue +192 -192
  105. package/src/user/components/UserHeadCrop.vue +65 -65
  106. package/src/user/components/UserInfo.vue +632 -632
  107. package/src/user/components/UserResourceEmpty.vue +75 -75
  108. package/src/user/components/index.ts +21 -21
  109. package/src/user/index.ts +1 -1
  110. package/tsconfig.json +30 -30
  111. package/types/global.d.ts +21 -21
  112. package/types/vue.d.ts +10 -10
  113. package/dist/appkit.css +0 -2331
  114. package/dist/assets/asset-3B_CoPto +0 -1
  115. package/dist/assets/asset-DcH8Kg-2 +0 -1
  116. package/dist/index.js +0 -7176
@@ -1,80 +1,80 @@
1
- <template>
2
- <div :class="[
3
- 'page-header',
4
- `color-mode-${colorMode}`
5
- ]" :style="cssVars">
6
- <h1 class="page-title" v-if="title">{{ title }}</h1>
7
- <view class="back-button" @click="onBackButtonClick"></view>
8
- <slot></slot>
9
- </div>
10
- </template>
11
-
12
- <script lang="ts" setup>
13
- import { useSafeArea } from '../composables'
14
-
15
-
16
- const safeArea = useSafeArea()
17
-
18
- const cssVars = {
19
- '--top': `${safeArea.status}px`,
20
- '--height': `${safeArea.nav}px`
21
- }
22
-
23
- export type PageHeaderColorMode = 'light' | 'dark'
24
-
25
- export interface PageHeaderProps {
26
- title?: string,
27
- colorMode?: PageHeaderColorMode
28
- }
29
-
30
- const emit = defineEmits<{
31
- (event: 'close'): void
32
- }>()
33
-
34
- withDefaults(
35
- defineProps<PageHeaderProps>(), {
36
- title: '',
37
- colorMode: 'light'
38
- }
39
- )
40
-
41
- const onBackButtonClick = () => {
42
- emit('close')
43
- }
44
- </script>
45
-
46
- <style lang="scss">
47
- .page-header {
48
- display: flex;
49
- position: relative;
50
- align-items: center;
51
- padding-top: var(--top);
52
- min-height: var(--height);
53
- .page-title {
54
- position: absolute;
55
- font-size: 18px;
56
- height: var(--height);
57
- line-height: var(--height);
58
- top: var(--top);
59
- width: 100%;
60
- text-align: center;
61
- }
62
- .back-button {
63
- position: absolute;
64
- top: var(--top);
65
- left: 10px;
66
- width: var(--height);
67
- height: var(--height);
68
- background-image: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDIiIGhlaWdodD0iNDIiIHZpZXdCb3g9IjAgMCA0MiA0MiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggb3BhY2l0eT0iMC4wMSIgZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0wLjk5OTg3OCA0MUw0MC45OTk5IDQxTDQwLjk5OTkgMUwwLjk5OTg3OCAxTDAuOTk5ODc4IDQxWiIgZmlsbD0iI0Q4RDhEOCIgc3Ryb2tlPSJibGFjayIgc3Ryb2tlLW9wYWNpdHk9IjAuMDEiLz4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xMi45OTMzIDE4Ljk0NzdDMTEuODYzMyAyMC4wMTQ1IDExLjgxMiAyMS43OTU0IDEyLjg3ODggMjIuOTI1NUwyNy45MTA1IDM3LjEzNDVDMjguNjkyNSAzNy44NzM0IDI5LjkyNTUgMzcuODM4NCAzMC42NjQ0IDM3LjA1NjRDMzEuMzY4MSAzNi4zMTE2IDMxLjM2OTkgMzUuMTU3OSAzMC42OTI5IDM0LjQxMTRMMTYuNTAxMiAyMC45OTM5TDMwLjU4NTcgNy42OTc4NUMzMS4zMzA4IDYuOTk0NDkgMzEuMjk4MiA1LjcyNzk1IDMwLjY2NDkgNC45NDQwMkMyOS45NjE2IDQuMTk4OTUgMjguODA5OCA0LjEzMTI5IDI4LjAyNTkgNC43NjQ1MkwxMi45OTMzIDE4Ljk0NzdaIiBmaWxsPSJibGFjayIgc3Ryb2tlPSJibGFjayIgc3Ryb2tlLW9wYWNpdHk9IjAuMDEiLz4KPC9zdmc+Cg==");
69
- background-size: 50%;
70
- background-repeat: no-repeat;
71
- background-position: center center;
72
- }
73
- &.color-mode-dark {
74
- color: var(--text-color-dark-mode, #fff);
75
- .back-button {
76
- background-image: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDIiIGhlaWdodD0iNDIiIHZpZXdCb3g9IjAgMCA0MiA0MiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggb3BhY2l0eT0iMC4wMSIgZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0wLjk5OTg0NyA0MUw0MC45OTk4IDQxTDQwLjk5OTggMUwwLjk5OTg0NyAxTDAuOTk5ODQ3IDQxWiIgZmlsbD0iI0Q4RDhEOCIgc3Ryb2tlPSJibGFjayIgc3Ryb2tlLW9wYWNpdHk9IjAuMDEiLz4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xMi45OTM0IDE4Ljk0NzVDMTEuODYzNCAyMC4wMTQzIDExLjgxMjEgMjEuNzk1MiAxMi44Nzg5IDIyLjkyNTJMMjcuOTEwNiAzNy4xMzQzQzI4LjY5MjcgMzcuODczMSAyOS45MjU2IDM3LjgzODIgMzAuNjY0NSAzNy4wNTYyQzMxLjM2ODIgMzYuMzExNCAzMS4zNyAzNS4xNTc2IDMwLjY5MyAzNC40MTExTDE2LjUwMTMgMjAuOTkzNkwzMC41ODU4IDcuNjk3NjFDMzEuMzMwOSA2Ljk5NDI0IDMxLjI5ODMgNS43Mjc3MSAzMC42NjUxIDQuOTQzNzdDMjkuOTYxNyA0LjE5ODcxIDI4LjgwOTkgNC4xMzEwNCAyOC4wMjYgNC43NjQyN0wxMi45OTM0IDE4Ljk0NzVaIiBmaWxsPSJ3aGl0ZSIgc3Ryb2tlPSJibGFjayIgc3Ryb2tlLW9wYWNpdHk9IjAuMDEiLz4KPC9zdmc+Cg==");
77
- }
78
- }
79
- }
1
+ <template>
2
+ <div :class="[
3
+ 'page-header',
4
+ `color-mode-${colorMode}`
5
+ ]" :style="cssVars">
6
+ <h1 class="page-title" v-if="title">{{ title }}</h1>
7
+ <view class="back-button" @click="onBackButtonClick"></view>
8
+ <slot></slot>
9
+ </div>
10
+ </template>
11
+
12
+ <script lang="ts" setup>
13
+ import { useSafeArea } from '../composables'
14
+
15
+
16
+ const safeArea = useSafeArea()
17
+
18
+ const cssVars = {
19
+ '--top': `${safeArea.status}px`,
20
+ '--height': `${safeArea.nav}px`
21
+ }
22
+
23
+ export type PageHeaderColorMode = 'light' | 'dark'
24
+
25
+ export interface PageHeaderProps {
26
+ title?: string,
27
+ colorMode?: PageHeaderColorMode
28
+ }
29
+
30
+ const emit = defineEmits<{
31
+ (event: 'close'): void
32
+ }>()
33
+
34
+ withDefaults(
35
+ defineProps<PageHeaderProps>(), {
36
+ title: '',
37
+ colorMode: 'light'
38
+ }
39
+ )
40
+
41
+ const onBackButtonClick = () => {
42
+ emit('close')
43
+ }
44
+ </script>
45
+
46
+ <style lang="scss">
47
+ .page-header {
48
+ display: flex;
49
+ position: relative;
50
+ align-items: center;
51
+ padding-top: var(--top);
52
+ min-height: var(--height);
53
+ .page-title {
54
+ position: absolute;
55
+ font-size: 18px;
56
+ height: var(--height);
57
+ line-height: var(--height);
58
+ top: var(--top);
59
+ width: 100%;
60
+ text-align: center;
61
+ }
62
+ .back-button {
63
+ position: absolute;
64
+ top: var(--top);
65
+ left: 10px;
66
+ width: var(--height);
67
+ height: var(--height);
68
+ background-image: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDIiIGhlaWdodD0iNDIiIHZpZXdCb3g9IjAgMCA0MiA0MiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggb3BhY2l0eT0iMC4wMSIgZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0wLjk5OTg3OCA0MUw0MC45OTk5IDQxTDQwLjk5OTkgMUwwLjk5OTg3OCAxTDAuOTk5ODc4IDQxWiIgZmlsbD0iI0Q4RDhEOCIgc3Ryb2tlPSJibGFjayIgc3Ryb2tlLW9wYWNpdHk9IjAuMDEiLz4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xMi45OTMzIDE4Ljk0NzdDMTEuODYzMyAyMC4wMTQ1IDExLjgxMiAyMS43OTU0IDEyLjg3ODggMjIuOTI1NUwyNy45MTA1IDM3LjEzNDVDMjguNjkyNSAzNy44NzM0IDI5LjkyNTUgMzcuODM4NCAzMC42NjQ0IDM3LjA1NjRDMzEuMzY4MSAzNi4zMTE2IDMxLjM2OTkgMzUuMTU3OSAzMC42OTI5IDM0LjQxMTRMMTYuNTAxMiAyMC45OTM5TDMwLjU4NTcgNy42OTc4NUMzMS4zMzA4IDYuOTk0NDkgMzEuMjk4MiA1LjcyNzk1IDMwLjY2NDkgNC45NDQwMkMyOS45NjE2IDQuMTk4OTUgMjguODA5OCA0LjEzMTI5IDI4LjAyNTkgNC43NjQ1MkwxMi45OTMzIDE4Ljk0NzdaIiBmaWxsPSJibGFjayIgc3Ryb2tlPSJibGFjayIgc3Ryb2tlLW9wYWNpdHk9IjAuMDEiLz4KPC9zdmc+Cg==");
69
+ background-size: 50%;
70
+ background-repeat: no-repeat;
71
+ background-position: center center;
72
+ }
73
+ &.color-mode-dark {
74
+ color: var(--text-color-dark-mode, #fff);
75
+ .back-button {
76
+ background-image: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDIiIGhlaWdodD0iNDIiIHZpZXdCb3g9IjAgMCA0MiA0MiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggb3BhY2l0eT0iMC4wMSIgZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0wLjk5OTg0NyA0MUw0MC45OTk4IDQxTDQwLjk5OTggMUwwLjk5OTg0NyAxTDAuOTk5ODQ3IDQxWiIgZmlsbD0iI0Q4RDhEOCIgc3Ryb2tlPSJibGFjayIgc3Ryb2tlLW9wYWNpdHk9IjAuMDEiLz4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xMi45OTM0IDE4Ljk0NzVDMTEuODYzNCAyMC4wMTQzIDExLjgxMjEgMjEuNzk1MiAxMi44Nzg5IDIyLjkyNTJMMjcuOTEwNiAzNy4xMzQzQzI4LjY5MjcgMzcuODczMSAyOS45MjU2IDM3LjgzODIgMzAuNjY0NSAzNy4wNTYyQzMxLjM2ODIgMzYuMzExNCAzMS4zNyAzNS4xNTc2IDMwLjY5MyAzNC40MTExTDE2LjUwMTMgMjAuOTkzNkwzMC41ODU4IDcuNjk3NjFDMzEuMzMwOSA2Ljk5NDI0IDMxLjI5ODMgNS43Mjc3MSAzMC42NjUxIDQuOTQzNzdDMjkuOTYxNyA0LjE5ODcxIDI4LjgwOTkgNC4xMzEwNCAyOC4wMjYgNC43NjQyN0wxMi45OTM0IDE4Ljk0NzVaIiBmaWxsPSJ3aGl0ZSIgc3Ryb2tlPSJibGFjayIgc3Ryb2tlLW9wYWNpdHk9IjAuMDEiLz4KPC9zdmc+Cg==");
77
+ }
78
+ }
79
+ }
80
80
  </style>
@@ -1,5 +1,7 @@
1
- import AppDrawer from './AppDrawer.vue'
2
- import PageHeader from './PageHeader.vue'
3
- import DeviceVersion from './DeviceVersion.vue'
4
-
5
- export { AppDrawer, PageHeader, DeviceVersion }
1
+ import AppDrawer from './AppDrawer.vue'
2
+ import PageHeader from './PageHeader.vue'
3
+ import AppVerify from './AppVerify.vue'
4
+ import DeviceVersion from './DeviceVersion.vue'
5
+ import OcrIcon from './OcrIcon.vue'
6
+
7
+ export { AppDrawer, PageHeader, DeviceVersion, AppVerify, OcrIcon }
@@ -1,5 +1,7 @@
1
- export * from './useSafeArea'
2
- export * from './useTabbar'
3
- export * from './useCountdown'
4
- export * from './useValidator'
5
- export * from './useEncode'
1
+ export * from './useSafeArea'
2
+ export * from './useTabbar'
3
+ export * from './useCountdown'
4
+ export * from './useValidator'
5
+ export * from './useEncode'
6
+ export * from './useUpload'
7
+ export * from './useCrypto'
@@ -1,46 +1,46 @@
1
- /**
2
- * @description: 倒计时
3
- * @param {number} time
4
- * @return {*}
5
- */
6
- import { ref, onUnmounted, computed } from 'vue'
7
-
8
- export function useCountdown() {
9
- let timer: any = null
10
- const countdown = ref(60)
11
- const countdownActive = computed(() => countdown.value > 0 && countdown.value < 60)
12
-
13
- const startCountdown = () => {
14
- countdown.value = 60
15
- timer = setInterval(() => {
16
- countdown.value--
17
- if (countdown.value <= 0) {
18
- stopCountdown()
19
- }
20
- }, 1000)
21
- }
22
-
23
- const stopCountdown = () => {
24
- clearInterval(timer)
25
- countdown.value = 60 // 重置倒计时
26
- }
27
-
28
- onUnmounted(() => {
29
- // stopCountdown() // 组件卸载时确保清除定时器
30
- })
31
-
32
- const countdownText = computed(() => {
33
- if (countdown.value === 60) {
34
- return '获取验证码'
35
- } else {
36
- return `重新发送(${countdown.value}s)`
37
- }
38
- })
39
-
40
- return {
41
- countdownActive,
42
- countdownText,
43
- startCountdown,
44
- stopCountdown,
45
- }
46
- }
1
+ /**
2
+ * @description: 倒计时
3
+ * @param {number} time
4
+ * @return {*}
5
+ */
6
+ import { ref, onUnmounted, computed } from 'vue'
7
+
8
+ export function useCountdown() {
9
+ let timer: any = null
10
+ const countdown = ref(60)
11
+ const countdownActive = computed(() => countdown.value > 0 && countdown.value < 60)
12
+
13
+ const startCountdown = () => {
14
+ countdown.value = 60
15
+ timer = setInterval(() => {
16
+ countdown.value--
17
+ if (countdown.value <= 0) {
18
+ stopCountdown()
19
+ }
20
+ }, 1000)
21
+ }
22
+
23
+ const stopCountdown = () => {
24
+ clearInterval(timer)
25
+ countdown.value = 60 // 重置倒计时
26
+ }
27
+
28
+ onUnmounted(() => {
29
+ // stopCountdown() // 组件卸载时确保清除定时器
30
+ })
31
+
32
+ const countdownText = computed(() => {
33
+ if (countdown.value === 60) {
34
+ return '获取验证码'
35
+ } else {
36
+ return `重新发送(${countdown.value}s)`
37
+ }
38
+ })
39
+
40
+ return {
41
+ countdownActive,
42
+ countdownText,
43
+ startCountdown,
44
+ stopCountdown,
45
+ }
46
+ }
@@ -0,0 +1,76 @@
1
+ // 解析脱敏姓名、手机号码等
2
+
3
+ export type CryptoConfig = {
4
+ maskField: string,
5
+ secretField: string,
6
+ }
7
+
8
+ export const defaultCryptoConfig: CryptoConfig = {
9
+ maskField: 'mask',
10
+ secretField: 'secretKey'
11
+ }
12
+
13
+ export type DecodeResult<T extends string> = {
14
+ [key in T | `${T}Secret`]: string
15
+ }
16
+
17
+ export type DefaultDecodeResult = DecodeResult<'masked'>
18
+
19
+ export type DecodeFunction = (encoded: string, key: string) => DecodeResult<`${key}`>
20
+
21
+ /**
22
+ * 解析以及解密脱敏数据
23
+ * @param config
24
+ * @returns
25
+ */
26
+ export function useCrypto (config?: CryptoConfig) {
27
+
28
+ const conf = config || defaultCryptoConfig
29
+
30
+ const parse: DecodeFunction = (data: string, key?: string) => {
31
+ let k = key || 'masked'
32
+ let result: Record<string, any> = {}
33
+ try {
34
+ result = JSON.parse(data)
35
+ result = {
36
+ [k]: result.mask,
37
+ // 字段后加$表示用于解密的 secret
38
+ [`${k}$`]: result.secretKey
39
+ }
40
+ } catch (e) {}
41
+ return result
42
+ }
43
+
44
+ /**
45
+ * 批量解析数组内的数据
46
+ * @param list
47
+ * @param field
48
+ * @returns
49
+ */
50
+ const resolve = (list: any[], field?: string | string[]) => {
51
+ const [first] = list,
52
+ f = field
53
+ ? Array.isArray(field) ? field : [field]
54
+ // 自动探测需要解密的字段
55
+ // '{"secretKey":"","mask":""}' 形式
56
+ : Object.entries(first)
57
+ .filter(([_, v]) => /^\{.*\}$/.test(v as string))
58
+ .map(([k]) => k)
59
+ return list
60
+ .map(item => {
61
+ let result = { ...item }
62
+ f.forEach(r => {
63
+ result = {
64
+ ...result,
65
+ ...parse(item[r], r)
66
+ }
67
+ })
68
+ return result
69
+ })
70
+ }
71
+
72
+ return {
73
+ parse,
74
+ resolve,
75
+ }
76
+ }
@@ -1,97 +1,97 @@
1
- /**
2
- * 元素拖拽功能
3
- */
4
- import Taro from '@tarojs/taro'
5
- import { reactive } from 'vue'
6
-
7
- export function useDragBox() {
8
- const dragData = reactive({
9
- left: 0, // 浮动按钮的左边距
10
- top: 0, // 浮动按钮的上边距
11
- width: 0, // 浮动按钮的宽度
12
- height: 0, // 浮动按钮的高度
13
- startX: 0, // 手指触摸起始点的横坐标
14
- startY: 0, // 手指触摸起始点的纵坐标
15
- screenWidth: 0, // 屏幕宽度
16
- screenHeight: 0, // 屏幕高度
17
- isDrag: false, // 是否开始拖拽
18
- oldLeft: 0,
19
- limitHorizontal: [0, 0], // 横向拖动限制范围
20
- limitVertical: [0, 0], // 纵向拖动限制范围
21
- })
22
-
23
- // 初始化元素拖拽模型
24
- function initDragData(data: any) {
25
- // 获取屏幕宽度和高度
26
- const res = Taro.getSystemInfoSync()
27
- dragData.screenWidth = res.windowWidth
28
- dragData.screenHeight = res.windowHeight
29
- if (!data) data = {}
30
-
31
- const scale = dragData.screenWidth / 375
32
- dragData.width = data.width * scale || 0
33
- dragData.height = data.height * scale || 0
34
- dragData.left = data.left * scale || 0
35
- dragData.top = data.top * scale || 0
36
- dragData.oldLeft = data.left * scale || 0
37
-
38
- if (data.limitHorizontal && data.limitHorizontal.length) {
39
- dragData.limitHorizontal = data.limitHorizontal
40
- }
41
- if (data.limitVertical && data.limitVertical.length) {
42
- dragData.limitVertical = data.limitVertical
43
- }
44
- }
45
-
46
- // 触屏开始
47
- function onDragStart(event: any) {
48
- dragData.startX = event.touches[0].clientX
49
- dragData.startY = event.touches[0].clientY
50
- dragData.isDrag = true
51
- }
52
-
53
- // 触屏移动
54
- function onDragMove(event: any) {
55
- const moveX = event.touches[0].clientX - dragData.startX
56
- const moveY = event.touches[0].clientY - dragData.startY
57
-
58
- let left = dragData.left + moveX
59
- let top = dragData.top + moveY
60
-
61
- // 防止浮动按钮移出屏幕
62
- if (left < dragData.limitHorizontal[0]) {
63
- left = dragData.limitHorizontal[0]
64
- } else if (left > dragData.screenWidth - dragData.width - dragData.limitHorizontal[1]) {
65
- left = dragData.screenWidth - dragData.width - dragData.limitHorizontal[1]
66
- }
67
-
68
- if (top < dragData.limitVertical[0]) {
69
- top = dragData.limitVertical[0]
70
- } else if (top > dragData.screenHeight - dragData.height - dragData.limitVertical[1]) {
71
- top = dragData.screenHeight - dragData.height - dragData.limitVertical[1]
72
- }
73
-
74
- dragData.left = left
75
- dragData.top = top
76
-
77
- dragData.startX = event.touches[0].clientX
78
- dragData.startY = event.touches[0].clientY
79
-
80
- // 阻止页面滚动
81
- event.preventDefault()
82
- }
83
-
84
- // 触屏结束
85
- function onDragEnd() {
86
- dragData.isDrag = false
87
- dragData.left = dragData.oldLeft
88
- }
89
-
90
- return {
91
- dragData,
92
- initDragData,
93
- onDragStart,
94
- onDragMove,
95
- onDragEnd,
96
- }
97
- }
1
+ /**
2
+ * 元素拖拽功能
3
+ */
4
+ import Taro from '@tarojs/taro'
5
+ import { reactive } from 'vue'
6
+
7
+ export function useDragBox() {
8
+ const dragData = reactive({
9
+ left: 0, // 浮动按钮的左边距
10
+ top: 0, // 浮动按钮的上边距
11
+ width: 0, // 浮动按钮的宽度
12
+ height: 0, // 浮动按钮的高度
13
+ startX: 0, // 手指触摸起始点的横坐标
14
+ startY: 0, // 手指触摸起始点的纵坐标
15
+ screenWidth: 0, // 屏幕宽度
16
+ screenHeight: 0, // 屏幕高度
17
+ isDrag: false, // 是否开始拖拽
18
+ oldLeft: 0,
19
+ limitHorizontal: [0, 0], // 横向拖动限制范围
20
+ limitVertical: [0, 0], // 纵向拖动限制范围
21
+ })
22
+
23
+ // 初始化元素拖拽模型
24
+ function initDragData(data: any) {
25
+ // 获取屏幕宽度和高度
26
+ const res = Taro.getSystemInfoSync()
27
+ dragData.screenWidth = res.windowWidth
28
+ dragData.screenHeight = res.windowHeight
29
+ if (!data) data = {}
30
+
31
+ const scale = dragData.screenWidth / 375
32
+ dragData.width = data.width * scale || 0
33
+ dragData.height = data.height * scale || 0
34
+ dragData.left = data.left * scale || 0
35
+ dragData.top = data.top * scale || 0
36
+ dragData.oldLeft = data.left * scale || 0
37
+
38
+ if (data.limitHorizontal && data.limitHorizontal.length) {
39
+ dragData.limitHorizontal = data.limitHorizontal
40
+ }
41
+ if (data.limitVertical && data.limitVertical.length) {
42
+ dragData.limitVertical = data.limitVertical
43
+ }
44
+ }
45
+
46
+ // 触屏开始
47
+ function onDragStart(event: any) {
48
+ dragData.startX = event.touches[0].clientX
49
+ dragData.startY = event.touches[0].clientY
50
+ dragData.isDrag = true
51
+ }
52
+
53
+ // 触屏移动
54
+ function onDragMove(event: any) {
55
+ const moveX = event.touches[0].clientX - dragData.startX
56
+ const moveY = event.touches[0].clientY - dragData.startY
57
+
58
+ let left = dragData.left + moveX
59
+ let top = dragData.top + moveY
60
+
61
+ // 防止浮动按钮移出屏幕
62
+ if (left < dragData.limitHorizontal[0]) {
63
+ left = dragData.limitHorizontal[0]
64
+ } else if (left > dragData.screenWidth - dragData.width - dragData.limitHorizontal[1]) {
65
+ left = dragData.screenWidth - dragData.width - dragData.limitHorizontal[1]
66
+ }
67
+
68
+ if (top < dragData.limitVertical[0]) {
69
+ top = dragData.limitVertical[0]
70
+ } else if (top > dragData.screenHeight - dragData.height - dragData.limitVertical[1]) {
71
+ top = dragData.screenHeight - dragData.height - dragData.limitVertical[1]
72
+ }
73
+
74
+ dragData.left = left
75
+ dragData.top = top
76
+
77
+ dragData.startX = event.touches[0].clientX
78
+ dragData.startY = event.touches[0].clientY
79
+
80
+ // 阻止页面滚动
81
+ event.preventDefault()
82
+ }
83
+
84
+ // 触屏结束
85
+ function onDragEnd() {
86
+ dragData.isDrag = false
87
+ dragData.left = dragData.oldLeft
88
+ }
89
+
90
+ return {
91
+ dragData,
92
+ initDragData,
93
+ onDragStart,
94
+ onDragMove,
95
+ onDragEnd,
96
+ }
97
+ }
@@ -1,43 +1,43 @@
1
- /**
2
- * @description: 脱敏相关方法
3
- */
4
-
5
- export function useEncode() {
6
- // 姓名脱敏
7
- function encodeName(name: string) {
8
- name = name.trim()
9
- if (name.length > 2) {
10
- return name[0].padEnd(name.length - 1, '*') + (name[name.length - 1] || '')
11
- }
12
- if (name.length == 0) {
13
- return ''
14
- } else {
15
- return name[0].padEnd(name.length, '*')
16
- }
17
- }
18
-
19
- // 证件脱敏
20
- function encodeCard(card: string) {
21
- if (card.length === 18) {
22
- return card.replace(/(\d{6})\d{8}(\d{3}.)/g, '$1********$2')
23
- } else {
24
- return card
25
- }
26
- }
27
-
28
- // 手机脱敏
29
- function encodePhone(phone: string) {
30
- phone = String(phone)
31
- if (phone.length === 11) {
32
- return phone.replace(/(1\d{2})\d{4}(\d{4})/g, '$1****$2')
33
- } else {
34
- return phone
35
- }
36
- }
37
-
38
- return {
39
- encodeName,
40
- encodeCard,
41
- encodePhone,
42
- }
43
- }
1
+ /**
2
+ * @description: 脱敏相关方法
3
+ */
4
+
5
+ export function useEncode() {
6
+ // 姓名脱敏
7
+ function encodeName(name: string) {
8
+ name = name.trim()
9
+ if (name.length > 2) {
10
+ return name[0].padEnd(name.length - 1, '*') + (name[name.length - 1] || '')
11
+ }
12
+ if (name.length == 0) {
13
+ return ''
14
+ } else {
15
+ return name[0].padEnd(name.length, '*')
16
+ }
17
+ }
18
+
19
+ // 证件脱敏
20
+ function encodeCard(card: string) {
21
+ if (card.length === 18) {
22
+ return card.replace(/(\d{6})\d{8}(\d{3}.)/g, '$1********$2')
23
+ } else {
24
+ return card
25
+ }
26
+ }
27
+
28
+ // 手机脱敏
29
+ function encodePhone(phone: string) {
30
+ phone = String(phone)
31
+ if (phone.length === 11) {
32
+ return phone.replace(/(1\d{2})\d{4}(\d{4})/g, '$1****$2')
33
+ } else {
34
+ return phone
35
+ }
36
+ }
37
+
38
+ return {
39
+ encodeName,
40
+ encodeCard,
41
+ encodePhone,
42
+ }
43
+ }