@uxda/appkit 4.1.16 → 4.1.19

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/dist/appkit.css +25 -22
  5. package/dist/assets/asset-3B_CoPto +1 -0
  6. package/dist/index.js +1141 -1036
  7. package/package.json +77 -75
  8. package/project.config.json +15 -15
  9. package/project.tt.json +13 -13
  10. package/rollup.config.mjs +56 -56
  11. package/src/Appkit.ts +72 -65
  12. package/src/balance/api/endpoints.ts +126 -126
  13. package/src/balance/api/index.ts +82 -82
  14. package/src/balance/components/AccountView.vue +748 -748
  15. package/src/balance/components/BalanceCard.vue +205 -205
  16. package/src/balance/components/BalanceReminder.vue +85 -85
  17. package/src/balance/components/ConsumptionFilter.vue +218 -218
  18. package/src/balance/components/ConsumptionRules.vue +68 -68
  19. package/src/balance/components/DateFilter.vue +249 -227
  20. package/src/balance/components/DateRange.vue +80 -77
  21. package/src/balance/components/ListFilter.vue +63 -63
  22. package/src/balance/components/ListFilterPicker.vue +186 -186
  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 +13 -13
  26. package/src/balance/types.ts +91 -91
  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/components/ocr-id/index.vue +114 -114
  45. package/src/components/ocr-id/types.d.ts +12 -12
  46. package/src/global.ts +6 -6
  47. package/src/index.ts +93 -89
  48. package/src/main.scss +1 -1
  49. package/src/notice/api/endpoints.ts +17 -17
  50. package/src/notice/api/index.ts +82 -82
  51. package/src/notice/components/NoticeBanner.vue +243 -243
  52. package/src/notice/components/NoticeEntry.vue +99 -99
  53. package/src/notice/components/NoticeList.vue +315 -315
  54. package/src/notice/components/NoticePopup.vue +162 -162
  55. package/src/notice/components/index.ts +5 -5
  56. package/src/notice/components/useCommonList.ts +86 -86
  57. package/src/notice/components/useNotice.ts +35 -35
  58. package/src/notice/index.ts +1 -1
  59. package/src/notice/types.ts +25 -25
  60. package/src/payment/api/config.ts +7 -7
  61. package/src/payment/api/endpoints.ts +103 -103
  62. package/src/payment/api/index.ts +76 -71
  63. package/src/payment/components/AmountPicker.vue +93 -93
  64. package/src/payment/components/RechargeResult.vue +69 -69
  65. package/src/payment/components/RechargeView.vue +154 -151
  66. package/src/payment/components/RightsPicker.vue +105 -105
  67. package/src/payment/components/TradeView.vue +294 -294
  68. package/src/payment/components/UserAgreement.vue +234 -234
  69. package/src/payment/components/index.ts +22 -22
  70. package/src/payment/index.ts +5 -5
  71. package/src/payment/services/index.ts +16 -16
  72. package/src/payment/services/invoke-recharge.ts +25 -25
  73. package/src/payment/services/request-payment.ts +58 -58
  74. package/src/payment/types.ts +28 -28
  75. package/src/register/components/SelfRegistration.vue +254 -254
  76. package/src/register/components/index.ts +2 -2
  77. package/src/shared/components/AppDrawer.vue +58 -58
  78. package/src/shared/components/AppVerify.vue +129 -129
  79. package/src/shared/components/DeviceVersion.vue +68 -68
  80. package/src/shared/components/EmptyView.vue +33 -33
  81. package/src/shared/components/OcrBusinessLicense.vue +133 -130
  82. package/src/shared/components/OcrIcon.vue +133 -132
  83. package/src/shared/components/PageHeader.vue +79 -79
  84. package/src/shared/components/index.ts +8 -8
  85. package/src/shared/composables/index.ts +7 -7
  86. package/src/shared/composables/useCountdown.ts +46 -46
  87. package/src/shared/composables/useCrypto.ts +76 -76
  88. package/src/shared/composables/useDragBox.ts +97 -97
  89. package/src/shared/composables/useEncode.ts +43 -43
  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 +31 -31
  94. package/src/shared/http/Http.ts +136 -136
  95. package/src/shared/http/index.ts +1 -1
  96. package/src/shared/http/types.ts +157 -157
  97. package/src/shared/index.ts +3 -3
  98. package/src/shared/weixin/payment.ts +38 -38
  99. package/src/styles/fonts.scss +2 -2
  100. package/src/styles/vars.scss +3 -3
  101. package/src/user/api/endpoints.ts +17 -17
  102. package/src/user/api/index.ts +87 -87
  103. package/src/user/components/LoginSetting.vue +114 -114
  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 +137 -137
  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 +637 -637
  111. package/src/user/components/UserResourceEmpty.vue +75 -75
  112. package/src/user/components/index.ts +21 -21
  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
@@ -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,8 +1,8 @@
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
- import OcrBusinessLicense from './OcrBusinessLicense.vue'
7
-
8
- export { AppDrawer, PageHeader, DeviceVersion, AppVerify, OcrIcon, OcrBusinessLicense }
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
+ import OcrBusinessLicense from './OcrBusinessLicense.vue'
7
+
8
+ export { AppDrawer, PageHeader, DeviceVersion, AppVerify, OcrIcon, OcrBusinessLicense }
@@ -1,7 +1,7 @@
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
+ 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
+ }
@@ -1,77 +1,77 @@
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
- if (list.length === 0) return []
52
- const [first] = list,
53
- f = field
54
- ? Array.isArray(field) ? field : [field]
55
- // 自动探测需要解密的字段
56
- // '{"secretKey":"","mask":""}' 形式
57
- : Object.entries(first)
58
- .filter(([_, v]) => /^\{.*\}$/.test(v as string))
59
- .map(([k]) => k)
60
- return list
61
- .map(item => {
62
- let result = { ...item }
63
- f.forEach(r => {
64
- result = {
65
- ...result,
66
- ...parse(item[r], r)
67
- }
68
- })
69
- return result
70
- })
71
- }
72
-
73
- return {
74
- parse,
75
- resolve,
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
+ if (list.length === 0) return []
52
+ const [first] = list,
53
+ f = field
54
+ ? Array.isArray(field) ? field : [field]
55
+ // 自动探测需要解密的字段
56
+ // '{"secretKey":"","mask":""}' 形式
57
+ : Object.entries(first)
58
+ .filter(([_, v]) => /^\{.*\}$/.test(v as string))
59
+ .map(([k]) => k)
60
+ return list
61
+ .map(item => {
62
+ let result = { ...item }
63
+ f.forEach(r => {
64
+ result = {
65
+ ...result,
66
+ ...parse(item[r], r)
67
+ }
68
+ })
69
+ return result
70
+ })
71
+ }
72
+
73
+ return {
74
+ parse,
75
+ resolve,
76
+ }
77
77
  }
@@ -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
+ }