@uxda/appkit 4.3.14 → 4.3.15
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.
- package/dist/appkit.css +12 -105
- package/dist/index.js +432 -1108
- package/package.json +5 -2
- package/src/balance/api/index.ts +1 -1
- package/src/balance/components/PromoterCard.vue +0 -1
- package/src/notice/api/index.ts +1 -1
- package/src/notice/components/NoticeList2.vue +73 -234
- package/src/notice/components/useCommonList.ts +0 -1
- package/src/payment/api/endpoints.ts +0 -2
- package/src/payment/api/index.ts +1 -2
- package/src/payment/components/RechargeResult.vue +1 -0
- package/src/payment/components/RechargeView.vue +2 -2
- package/src/payment/components/TradeView.vue +125 -334
- package/src/payment/services/request-payment.ts +3 -9
- package/src/payment/types.ts +0 -1
- package/src/register/components/SelfRegistration.vue +1 -1
- package/src/shared/components/AppVerify.vue +6 -15
- package/src/shared/components/OcrBusinessLicense.vue +37 -20
- package/src/shared/components/OcrIcon.vue +67 -105
- package/src/shared/components/index.ts +1 -3
- package/src/shared/composables/index.ts +0 -1
- package/src/shared/composables/useDeviceEnv.ts +35 -1
- package/src/shared/composables/useUpload.ts +51 -96
- package/src/shared/http/Http.ts +0 -1
- package/src/shared/tracking/tracking-sdk.ts +1 -0
- package/src/shared/weixin/jssdk.ts +0 -1
- package/src/user/api/index.ts +1 -1
- package/src/user/components/UserAuth.vue +1 -1
- package/src/user/components/UserFeedback.vue +0 -1
- package/src/user/components/UserInfo.vue +0 -2
- package/types/global.d.ts +0 -2
- package/src/shared/components/OcrBank.vue +0 -202
- package/src/shared/components/OcrInvoice.vue +0 -322
- package/src/shared/composables/useCompress.ts +0 -64
package/src/payment/types.ts
CHANGED
|
@@ -124,7 +124,7 @@ async function submit() {
|
|
|
124
124
|
<nut-form-item label="你的姓名" required>
|
|
125
125
|
<div class="self-registration__input">
|
|
126
126
|
<input v-model="formState.name" class="nut-input-text" placeholder="请输入或拍照识别" type="text" :maxlength="20" />
|
|
127
|
-
<OcrIcon
|
|
127
|
+
<OcrIcon @complete="onOCRInfo">
|
|
128
128
|
<template #icon>
|
|
129
129
|
<img style="width: 20px; height: 20px; margin-left: 5px;"
|
|
130
130
|
src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0MCIgaGVpZ2h0PSI0MCIgZmlsbD0ibm9uZSI+PHBhdGggb3BhY2l0eT0iLjAxIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTQwIDB2NDBIMFYwaDQweiIgZmlsbD0iI0M0QzRDNCIvPjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMzMuMDQ0IDE3LjM2M2MuOTYgMCAxLjczOS0uNzkgMS43MzktMS43NjYgMC0uOTc1LS43NzktMS43NjYtMS43NC0xLjc2Ni0uOTYgMC0xLjczOC43OS0xLjczOCAxLjc2NnMuNzc4IDEuNzY2IDEuNzM5IDEuNzY2eiIgZmlsbD0iIzRCQ0I5MyIvPjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMCAzMS44MTJWMTQuNzg4YzAtMi4yNTggMi4wNDktNC4wOTcgNC41NjQtNC4wOTdoMy44NDRsMS4xMzYtMy42NThDOS44ODggNS45MTMgMTEuMjM3IDUgMTIuNTQ4IDVIMjcuNDVjMS4zOSAwIDIuNjguODc2IDMuMDEgMi4wNDRsMS4xMzMgMy42NDdoMy44NDRjMi41MTUgMCA0LjU2NCAxLjgzOSA0LjU2NCA0LjA5N3YxLjczOWMwIC41MDMtLjQ1NC45MS0xLjAxNC45MXMtMS4wMTQtLjQwNy0xLjAxNC0uOTF2LTEuNzRjMC0xLjI1My0xLjEzOS0yLjI3NS0yLjUzNi0yLjI3NWgtMy44NDRjLS45MDcgMC0xLjcxMS0uNTQ5LTEuOTU1LTEuMzMybC0xLjEzNi0zLjY2YS4zNDIuMzQyIDAgMCAwLS4wMDctLjAyNWMtLjExLS4zOTYtLjYzOS0uNjc0LTEuMDQ1LS42NzRoLTE0LjljLS4zOTkgMC0uOTUuMzY2LTEuMDUzLjY5OWwtMS4xMzYgMy42NmMtLjI0Ny43ODYtMS4wNDUgMS4zMy0xLjk1NSAxLjMzMkg0LjU2NGMtMS4zOTcgMC0yLjUzNiAxLjAyMi0yLjUzNiAyLjI3NnYxNy4wMjRjMCAxLjI1NCAxLjEzOSAyLjI3NiAyLjUzNiAyLjI3NmgzMC44N2MxLjM5NyAwIDIuNTM1LTEuMDIyIDIuNTM1LTIuMjc2VjIxLjU5NmMwLS41MDMuNDU0LS45MSAxLjAxNC0uOTFzMS4wMTUuNDA3IDEuMDE1LjkxVjMxLjgxYy0uMDAzIDIuMjYtMi4wNSA0LjEtNC41NjcgNC4xSDQuNTY0QzIuMDQ5IDM1LjkxIDAgMzQuMDcgMCAzMS44MTF6IiBmaWxsPSIjNEJDQjkzIi8+PHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xMi4xNzQgMjEuNzc4YzAtNC44NyAzLjcwNS04LjgzIDguMjYtOC44MyA0LjU1NiAwIDguMjYyIDMuOTYgOC4yNjIgOC44M3MtMy43MDYgOC44MzItOC4yNjEgOC44MzJjLTQuNTU2IDAtOC4yNjEtMy45NjItOC4yNjEtOC44MzJ6bTEuNzc5LjEzYzAgMy43OTYgMi45MDcgNi44ODMgNi40ODIgNi44ODMgMy41NzQgMCA2LjQ4MS0zLjA4NyA2LjQ4MS02Ljg4M3MtMi45MDctNi44ODMtNi40ODItNi44ODNjLTMuNTc0IDAtNi40ODEgMy4wODctNi40ODEgNi44ODN6IiBmaWxsPSIjNEJDQjkzIi8+PC9zdmc+" />
|
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
</div>
|
|
18
18
|
</ns-form>
|
|
19
19
|
<div class="row buttons">
|
|
20
|
-
<ns-button class="cancel-btn" v-track-click="'手机号验证-取消'"
|
|
21
|
-
<ns-button color="primary" v-track-click="'手机号验证-确认'"
|
|
20
|
+
<ns-button class="cancel-btn" v-track-click="'手机号验证-取消'" @click="emits('cancel')">取消</ns-button>
|
|
21
|
+
<ns-button color="primary" v-track-click="'手机号验证-确认'" @click="onOk">确认</ns-button>
|
|
22
22
|
</div>
|
|
23
23
|
</div>
|
|
24
24
|
</template>
|
|
@@ -75,9 +75,9 @@ const props = defineProps<AppVerifyProps>();
|
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
.caption {
|
|
78
|
-
font-size:
|
|
79
|
-
color: #
|
|
80
|
-
|
|
78
|
+
font-size: 13px !important;
|
|
79
|
+
color: #ccc;
|
|
80
|
+
line-height: 21px;
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
.number {
|
|
@@ -97,20 +97,11 @@ const props = defineProps<AppVerifyProps>();
|
|
|
97
97
|
border-radius: 5px;
|
|
98
98
|
flex: 1;
|
|
99
99
|
padding-left: 12px;
|
|
100
|
-
.input-text {
|
|
101
|
-
text-align: left !important;
|
|
102
|
-
}
|
|
103
100
|
}
|
|
104
101
|
|
|
105
102
|
.form-btn {
|
|
106
103
|
margin-left: 12px;
|
|
107
|
-
width:
|
|
108
|
-
|
|
109
|
-
.caption {
|
|
110
|
-
font-size: 10px !important;
|
|
111
|
-
color: #ccc;
|
|
112
|
-
margin-bottom: 0;
|
|
113
|
-
}
|
|
104
|
+
width: 105px;
|
|
114
105
|
}
|
|
115
106
|
}
|
|
116
107
|
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div :class="['ocr-business-license', disabled ? 'disabled' : '']" class="ocr-icon" v-track-click="'营业执照识别-点击'" @click="
|
|
3
|
-
<
|
|
4
|
-
<ns-icon name="https://cdn.ddjf.com/static/images/beidouxing/ocr-icon.png" />
|
|
5
|
-
</slot>
|
|
2
|
+
<div :class="['ocr-business-license', disabled ? 'disabled' : '']" class="ocr-icon" v-track-click="'营业执照识别-点击'" @click="onIconClick">
|
|
3
|
+
<ns-icon name="https://cdn.ddjf.com/static/images/beidouxing/ocr-icon.png" />
|
|
6
4
|
</div>
|
|
7
5
|
</template>
|
|
8
6
|
|
|
@@ -10,7 +8,6 @@
|
|
|
10
8
|
import Taro, { showToast, showLoading, hideLoading, uploadFile, chooseMedia } from '@tarojs/taro';
|
|
11
9
|
import { NsIcon } from '@uxda/nutshell/taro';
|
|
12
10
|
import { useAppKitOptions } from '../../Appkit';
|
|
13
|
-
import { compressImage, getCompressQuality } from '../composables/useUpload';
|
|
14
11
|
|
|
15
12
|
const appKitOptions = useAppKitOptions();
|
|
16
13
|
|
|
@@ -18,29 +15,49 @@ const emits = defineEmits(['complete']);
|
|
|
18
15
|
|
|
19
16
|
type OcrBusinessLicenseProps = {
|
|
20
17
|
disabled: boolean;
|
|
21
|
-
customClick?: boolean
|
|
22
18
|
};
|
|
23
19
|
|
|
24
|
-
const props =
|
|
25
|
-
disabled: false,
|
|
26
|
-
customClick: false
|
|
27
|
-
});
|
|
20
|
+
const props = defineProps<OcrBusinessLicenseProps>();
|
|
28
21
|
|
|
29
22
|
export type OcrResult = {
|
|
30
23
|
companyName: string;
|
|
31
24
|
idCardNo: string;
|
|
32
25
|
legalPersonName: string;
|
|
33
|
-
[x: string]: any;
|
|
34
26
|
};
|
|
35
27
|
|
|
28
|
+
async function taroImgCompress(src: string, quality = 80) {
|
|
29
|
+
return new Promise((resolve, reject) => {
|
|
30
|
+
Taro.compressImage({
|
|
31
|
+
src: src,
|
|
32
|
+
quality: quality,
|
|
33
|
+
success: (res) => {
|
|
34
|
+
resolve(res)
|
|
35
|
+
},
|
|
36
|
+
fail: (res) => {
|
|
37
|
+
reject(res)
|
|
38
|
+
},
|
|
39
|
+
})
|
|
40
|
+
})
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function getCompressQuality(size: number) {
|
|
44
|
+
let quality = 100;
|
|
45
|
+
const curSize = size / (1024 * 1024);
|
|
46
|
+
if (curSize > 6) {
|
|
47
|
+
quality = quality - ((curSize - 6) / curSize) * 100;
|
|
48
|
+
}
|
|
49
|
+
return quality;
|
|
50
|
+
}
|
|
51
|
+
|
|
36
52
|
function allTrim(str: string) {
|
|
37
53
|
return str.replace(/\s+/g, '');
|
|
38
54
|
}
|
|
39
55
|
|
|
40
|
-
async function
|
|
56
|
+
async function onIconClick() {
|
|
41
57
|
if (props.disabled) {
|
|
42
58
|
return;
|
|
43
59
|
}
|
|
60
|
+
console.log('===onIconClick');
|
|
44
61
|
let result: OcrResult | null = null;
|
|
45
62
|
try {
|
|
46
63
|
const csRes = await chooseMedia({
|
|
@@ -48,10 +65,15 @@ async function onUpload() {
|
|
|
48
65
|
sourceType: ['album', 'camera']
|
|
49
66
|
});
|
|
50
67
|
let { size, tempFilePath } = csRes.tempFiles[0];
|
|
51
|
-
|
|
52
|
-
|
|
68
|
+
let filePath
|
|
69
|
+
if (Taro.getEnv() !== 'WEB') {
|
|
70
|
+
const compressImg: any = (await taroImgCompress(tempFilePath, getCompressQuality(size))) || {}
|
|
71
|
+
filePath = compressImg.tempFilePath
|
|
72
|
+
} else {
|
|
73
|
+
filePath = tempFilePath
|
|
74
|
+
}
|
|
53
75
|
|
|
54
|
-
showLoading({ title: '营业执照识别中..'
|
|
76
|
+
showLoading({ title: '营业执照识别中..' });
|
|
55
77
|
|
|
56
78
|
const session = appKitOptions.token();
|
|
57
79
|
const baseUrl = appKitOptions.baseUrl();
|
|
@@ -61,7 +83,6 @@ async function onUpload() {
|
|
|
61
83
|
name: 'file',
|
|
62
84
|
formData: {
|
|
63
85
|
objectNo: `min${Date.now()}`,
|
|
64
|
-
appCode: appKitOptions.app(),
|
|
65
86
|
},
|
|
66
87
|
header: {
|
|
67
88
|
token: session || '',
|
|
@@ -95,10 +116,6 @@ async function onUpload() {
|
|
|
95
116
|
}
|
|
96
117
|
emits('complete', result);
|
|
97
118
|
}
|
|
98
|
-
|
|
99
|
-
defineExpose({
|
|
100
|
-
onUpload
|
|
101
|
-
})
|
|
102
119
|
</script>
|
|
103
120
|
|
|
104
121
|
<style lang="scss">
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="ocr-icon" :class="[disabled ? 'disabled' : ''
|
|
2
|
+
<div class="ocr-icon" :class="[disabled ? 'disabled' : '']" v-track-click="'身份证识别-点击'" @click="onPhotograph">
|
|
3
3
|
<slot name="icon">
|
|
4
4
|
<ns-icon name="https://cdn.ddjf.com/static/images/beidouxing/ocr-icon.png" />
|
|
5
5
|
</slot>
|
|
@@ -11,44 +11,24 @@
|
|
|
11
11
|
|
|
12
12
|
<script lang="ts" setup>
|
|
13
13
|
import Taro, { showToast, showLoading, hideLoading, chooseMedia, chooseMessageFile, uploadFile } from '@tarojs/taro'
|
|
14
|
-
import { NsIcon
|
|
14
|
+
import { NsIcon } from '@uxda/nutshell/taro'
|
|
15
15
|
import { useAppKitOptions } from '../../Appkit'
|
|
16
16
|
import { ref } from 'vue';
|
|
17
|
-
import { useHttp } from '../../balance/api'
|
|
18
|
-
import { compressImage, getCompressQuality } from '../composables/useUpload'
|
|
19
17
|
|
|
20
18
|
const appKitOptions = useAppKitOptions()
|
|
21
|
-
const $http = useHttp(),
|
|
22
|
-
$n = useNutshell()
|
|
23
19
|
|
|
24
20
|
const emits = defineEmits(['complete'])
|
|
25
21
|
|
|
26
|
-
type
|
|
22
|
+
type OcrIconProps = {
|
|
27
23
|
disabled?: boolean,
|
|
28
24
|
side?: 'face' | 'back',
|
|
29
|
-
|
|
30
|
-
uploadUrl?: string
|
|
31
|
-
customUpload?: Function
|
|
32
|
-
hasUploadVo?: boolean
|
|
33
|
-
customClick?: boolean
|
|
34
|
-
}
|
|
35
|
-
type FileType = {
|
|
36
|
-
"downloadUrl": string,
|
|
37
|
-
"fileId": string,
|
|
38
|
-
"fileName": string,
|
|
39
|
-
"fileSize": number,
|
|
40
|
-
"fileSuffix": string,
|
|
41
|
-
"fileType": string,
|
|
42
|
-
"originalUrl": string
|
|
25
|
+
class?: string
|
|
43
26
|
}
|
|
44
27
|
|
|
45
|
-
const props = withDefaults(defineProps<
|
|
28
|
+
const props = withDefaults(defineProps<OcrIconProps>(), {
|
|
46
29
|
disabled: false,
|
|
47
30
|
side: 'face',
|
|
48
|
-
|
|
49
|
-
hasUploadVo: true,
|
|
50
|
-
customClick: false,
|
|
51
|
-
uploadUrl: '/saas-base/file/uploadPublic',
|
|
31
|
+
class: ''
|
|
52
32
|
})
|
|
53
33
|
|
|
54
34
|
type OcrResultType = {
|
|
@@ -69,6 +49,34 @@ type OcrResultType = {
|
|
|
69
49
|
}
|
|
70
50
|
}
|
|
71
51
|
|
|
52
|
+
async function taroImgCompress(src: string, quality = 80) {
|
|
53
|
+
if (Taro.getEnv() === 'WEB') {
|
|
54
|
+
return src;
|
|
55
|
+
} else {
|
|
56
|
+
return new Promise((resolve, reject) => {
|
|
57
|
+
Taro.compressImage({
|
|
58
|
+
src: src,
|
|
59
|
+
quality: quality,
|
|
60
|
+
success: (res) => {
|
|
61
|
+
resolve(res)
|
|
62
|
+
},
|
|
63
|
+
fail: (res) => {
|
|
64
|
+
reject(res)
|
|
65
|
+
},
|
|
66
|
+
})
|
|
67
|
+
})
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function getCompressQuality(size: number) {
|
|
72
|
+
let quality = 100
|
|
73
|
+
const curSize = size / (1024 * 1024)
|
|
74
|
+
if (curSize > 6) {
|
|
75
|
+
quality = quality - ((curSize - 6) / curSize) * 100
|
|
76
|
+
}
|
|
77
|
+
return quality
|
|
78
|
+
}
|
|
79
|
+
|
|
72
80
|
function allTrim(str: string) {
|
|
73
81
|
return str.replace(/\s+/g, '')
|
|
74
82
|
}
|
|
@@ -76,62 +84,59 @@ function allTrim(str: string) {
|
|
|
76
84
|
async function onUploadFile(csRes: any) {
|
|
77
85
|
let result: OcrResultType | null = null
|
|
78
86
|
try {
|
|
87
|
+
console.log('===上传', csRes)
|
|
79
88
|
let { path, size, tempFilePath } = csRes.tempFiles[0]
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
89
|
+
let filePath
|
|
90
|
+
if (Taro.getEnv() !== 'WEB') {
|
|
91
|
+
const compressImg: any = (await taroImgCompress(path || tempFilePath, getCompressQuality(size))) || {}
|
|
92
|
+
filePath = compressImg.tempFilePath || path
|
|
93
|
+
} else {
|
|
94
|
+
filePath = path || tempFilePath
|
|
86
95
|
}
|
|
87
96
|
|
|
88
|
-
|
|
97
|
+
console.log(filePath, 'filePath')
|
|
98
|
+
showLoading({ title: '身份证识别中..' })
|
|
89
99
|
|
|
90
100
|
const session = appKitOptions.token()
|
|
91
101
|
const baseUrl = appKitOptions.baseUrl()
|
|
92
102
|
const upRes: any = await uploadFile({
|
|
93
|
-
url:
|
|
103
|
+
url: baseUrl + '/hkapprove/ocr/idcard',
|
|
94
104
|
filePath,
|
|
95
105
|
name: 'file',
|
|
96
106
|
formData: {
|
|
97
107
|
objectNo: `min${Date.now()}`,
|
|
98
108
|
side: props.side,
|
|
99
|
-
appCode: appKitOptions.app(),
|
|
100
109
|
},
|
|
101
110
|
header: {
|
|
102
111
|
token: session || '',
|
|
103
112
|
},
|
|
104
113
|
})
|
|
114
|
+
hideLoading()
|
|
105
115
|
|
|
106
116
|
const res = JSON.parse(upRes.data)
|
|
107
117
|
if (res.code === '200') {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
showToast({ title: '识别失败,请重试', icon: 'none' })
|
|
129
|
-
}
|
|
130
|
-
} else {
|
|
131
|
-
await getOcrInfo(res.result)
|
|
118
|
+
const faceInfo = res.result.faceInfo || {}
|
|
119
|
+
const backInfo = res.result.backInfo || {}
|
|
120
|
+
result = {
|
|
121
|
+
faceInfo: {
|
|
122
|
+
name: allTrim(faceInfo.name || ''),
|
|
123
|
+
certNo: allTrim(faceInfo.num || ''),
|
|
124
|
+
address: allTrim(faceInfo.address || ''),
|
|
125
|
+
},
|
|
126
|
+
backInfo: {
|
|
127
|
+
startDate: backInfo?.startDate || '',
|
|
128
|
+
endDate: backInfo?.endDate || ''
|
|
129
|
+
},
|
|
130
|
+
fileUploadVO: res.result.fileUploadVO || {},
|
|
131
|
+
}
|
|
132
|
+
console.log('===识别', result)
|
|
133
|
+
if (props.side === 'face' && !result.faceInfo.name && !result.faceInfo.certNo) {
|
|
134
|
+
showToast({ title: '识别失败,请重试', icon: 'none' })
|
|
135
|
+
}
|
|
136
|
+
if (props.side === 'back' && !result.backInfo?.startDate && !result.backInfo?.endDate) {
|
|
137
|
+
showToast({ title: '识别失败,请重试', icon: 'none' })
|
|
132
138
|
}
|
|
133
139
|
} else {
|
|
134
|
-
hideLoading()
|
|
135
140
|
showToast({
|
|
136
141
|
title: res.msg,
|
|
137
142
|
icon: 'error',
|
|
@@ -141,48 +146,9 @@ async function onUploadFile(csRes: any) {
|
|
|
141
146
|
hideLoading()
|
|
142
147
|
console.log(err)
|
|
143
148
|
}
|
|
144
|
-
|
|
145
|
-
props.hasUploadVo && (result?.faceInfo.name || result?.backInfo.startDate) && emits('complete', result)
|
|
149
|
+
emits('complete', result)
|
|
146
150
|
}
|
|
147
151
|
|
|
148
|
-
// 根据证件路径获取证件信息
|
|
149
|
-
async function getOcrInfo(file: string | FileType) {
|
|
150
|
-
try {
|
|
151
|
-
const res: any = await $http.get('/hkbase/common/idCard', {
|
|
152
|
-
fileUrl: typeof file === 'string' ? file : file.originalUrl,
|
|
153
|
-
side: props.side,
|
|
154
|
-
})
|
|
155
|
-
hideLoading()
|
|
156
|
-
|
|
157
|
-
if ((props.side === 'face' && !res?.name) || (props.side === 'back' && !res?.signDate)) {
|
|
158
|
-
$n.dialog({
|
|
159
|
-
title: '识别失败',
|
|
160
|
-
message: `您上传的图片可能不够清晰或与当前功能不符,请重新上传一张清晰、完整的图片。谢谢!`,
|
|
161
|
-
okText: '我知道了',
|
|
162
|
-
cancelText: '',
|
|
163
|
-
})
|
|
164
|
-
return
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
emits('complete', {
|
|
168
|
-
faceInfo: {
|
|
169
|
-
name: allTrim(res?.name || ''),
|
|
170
|
-
certNo: allTrim(res?.cardNumber || ''),
|
|
171
|
-
address: allTrim(res?.address || ''),
|
|
172
|
-
},
|
|
173
|
-
backInfo: {
|
|
174
|
-
startDate: res?.expireDate || '',
|
|
175
|
-
endDate: res?.signDate || ''
|
|
176
|
-
},
|
|
177
|
-
fileUploadVO: {
|
|
178
|
-
fileUrl: typeof file === 'string' ? file : file.originalUrl,
|
|
179
|
-
fileKey: typeof file === 'string' ? file : file.fileId,
|
|
180
|
-
},
|
|
181
|
-
})
|
|
182
|
-
} catch (err) {
|
|
183
|
-
hideLoading()
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
152
|
|
|
187
153
|
// 上传图片操作面板
|
|
188
154
|
const activeSheetVisible = ref(false)
|
|
@@ -224,7 +190,7 @@ async function chooseImages(item: any) {
|
|
|
224
190
|
}
|
|
225
191
|
}
|
|
226
192
|
|
|
227
|
-
async function
|
|
193
|
+
async function onPhotograph() {
|
|
228
194
|
if (props.disabled) return
|
|
229
195
|
|
|
230
196
|
if (Taro.getEnv() === 'WEB') {
|
|
@@ -240,10 +206,6 @@ async function onUpload() {
|
|
|
240
206
|
|
|
241
207
|
activeSheetVisible.value = true
|
|
242
208
|
}
|
|
243
|
-
|
|
244
|
-
defineExpose({
|
|
245
|
-
onUpload
|
|
246
|
-
})
|
|
247
209
|
</script>
|
|
248
210
|
|
|
249
211
|
<style lang="scss">
|
|
@@ -3,8 +3,6 @@ import PageHeader from './PageHeader.vue'
|
|
|
3
3
|
import AppVerify from './AppVerify.vue'
|
|
4
4
|
import DeviceVersion from './DeviceVersion.vue'
|
|
5
5
|
import OcrIcon from './OcrIcon.vue'
|
|
6
|
-
import OcrBank from './OcrBank.vue'
|
|
7
6
|
import OcrBusinessLicense from './OcrBusinessLicense.vue'
|
|
8
|
-
import OcrInvoice from './OcrInvoice.vue'
|
|
9
7
|
|
|
10
|
-
export { AppDrawer, PageHeader, DeviceVersion, AppVerify, OcrIcon,
|
|
8
|
+
export { AppDrawer, PageHeader, DeviceVersion, AppVerify, OcrIcon, OcrBusinessLicense }
|
|
@@ -24,4 +24,38 @@ export const isAndroid = () => {
|
|
|
24
24
|
return /Android/i.test(window.navigator.userAgent)
|
|
25
25
|
}
|
|
26
26
|
return false
|
|
27
|
-
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** 浏览器类型 */
|
|
30
|
+
export type BrowserType = 'safari' | 'chrome' | 'other'
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* 获取当前浏览器类型
|
|
34
|
+
* @returns 'safari' | 'chrome' | 'other'
|
|
35
|
+
*/
|
|
36
|
+
export function getBrowser(): BrowserType {
|
|
37
|
+
if (typeof window === 'undefined') return 'other'
|
|
38
|
+
const ua = window.navigator.userAgent.toLowerCase()
|
|
39
|
+
// Edge、Opera 等基于 Chromium 的浏览器归为 other,优先判断
|
|
40
|
+
if (/edg\/|edge\//.test(ua) || /opr\/|opera/.test(ua)) return 'other'
|
|
41
|
+
// Chrome(含 iOS 端 CriOS)
|
|
42
|
+
if (/chrome\/|crios\//.test(ua)) return 'chrome'
|
|
43
|
+
// Safari:含 safari 且不含 chrome(Chrome 的 UA 同时包含两者)
|
|
44
|
+
if (/safari\//.test(ua) && !/chrome|crios/.test(ua)) return 'safari'
|
|
45
|
+
return 'other'
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** 是否 Safari 浏览器 */
|
|
49
|
+
export function isSafari(): boolean {
|
|
50
|
+
return getBrowser() === 'safari'
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** 是否 Chrome 浏览器(含 iOS 端) */
|
|
54
|
+
export function isChrome(): boolean {
|
|
55
|
+
return getBrowser() === 'chrome'
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** 是否其他浏览器(非 Safari、非 Chrome) */
|
|
59
|
+
export function isOtherBrowser(): boolean {
|
|
60
|
+
return getBrowser() === 'other'
|
|
61
|
+
}
|
|
@@ -1,106 +1,61 @@
|
|
|
1
|
-
import Taro from
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
return new Promise((resolve, reject) => {
|
|
11
|
-
const img = new Image();
|
|
12
|
-
img.crossOrigin = "anonymous";
|
|
13
|
-
|
|
14
|
-
img.onload = () => {
|
|
15
|
-
try {
|
|
16
|
-
const canvas = document.createElement("canvas");
|
|
17
|
-
const ctx = canvas.getContext("2d");
|
|
18
|
-
|
|
19
|
-
if (!ctx) {
|
|
20
|
-
reject(new Error("无法获取 canvas 上下文"));
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// 设置画布尺寸(可以根据需要限制最大尺寸)
|
|
25
|
-
const maxWidth = 850;
|
|
26
|
-
const maxHeight = 850;
|
|
27
|
-
let width = img.width;
|
|
28
|
-
let height = img.height;
|
|
29
|
-
|
|
30
|
-
// 计算压缩后的尺寸
|
|
31
|
-
if (width > maxWidth || height > maxHeight) {
|
|
32
|
-
const ratio = Math.min(maxWidth / width, maxHeight / height);
|
|
33
|
-
width = width * ratio;
|
|
34
|
-
height = height * ratio;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
canvas.width = width;
|
|
38
|
-
canvas.height = height;
|
|
1
|
+
import Taro, { uploadFile } from '@tarojs/taro'
|
|
2
|
+
import { Media } from '@uxda/nutshell/taro'
|
|
3
|
+
import { useAppKitOptions } from '../../Appkit'
|
|
4
|
+
|
|
5
|
+
export type UploadConfig = {
|
|
6
|
+
baseUrl: string
|
|
7
|
+
name?: string
|
|
8
|
+
headers?: Record<string, string>
|
|
9
|
+
}
|
|
39
10
|
|
|
40
|
-
|
|
41
|
-
|
|
11
|
+
const mappings: { [x: string]: keyof Media } = {
|
|
12
|
+
downloadUrl: 'thrumb',
|
|
13
|
+
fileId: 'id',
|
|
14
|
+
fileName: 'name',
|
|
15
|
+
fileSize: 'size',
|
|
16
|
+
fileSuffix: 'ext',
|
|
17
|
+
fileType: 'type',
|
|
18
|
+
originalUrl: 'url',
|
|
19
|
+
}
|
|
42
20
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
if (!blob) {
|
|
47
|
-
reject(new Error("图片压缩失败"));
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
// 创建 blob URL
|
|
51
|
-
const compressedUrl = URL.createObjectURL(blob);
|
|
52
|
-
resolve(compressedUrl);
|
|
53
|
-
},
|
|
54
|
-
"image/jpeg",
|
|
55
|
-
quality / 100
|
|
56
|
-
);
|
|
57
|
-
} catch (error) {
|
|
58
|
-
reject(error);
|
|
59
|
-
}
|
|
60
|
-
};
|
|
21
|
+
const transformFields = (row: any) => {
|
|
22
|
+
return Object.fromEntries(Object.entries(row).map(([k, v]) => [mappings[k] || k, v]))
|
|
23
|
+
}
|
|
61
24
|
|
|
62
|
-
|
|
63
|
-
reject(new Error("图片加载失败"));
|
|
64
|
-
};
|
|
25
|
+
type UploadFunction = (url: string, file: Media) => Promise<Media>
|
|
65
26
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
};
|
|
27
|
+
export const useUpload = (config: UploadConfig) => {
|
|
28
|
+
const appkitOptions = useAppKitOptions()
|
|
69
29
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
console.error("图片压缩失败:", error);
|
|
79
|
-
// 压缩失败时返回原图
|
|
80
|
-
return { tempFilePath: src };
|
|
81
|
-
}
|
|
82
|
-
} else {
|
|
83
|
-
return new Promise((resolve, reject) => {
|
|
84
|
-
Taro.compressImage({
|
|
85
|
-
src: src,
|
|
86
|
-
quality: quality,
|
|
87
|
-
success: (res) => {
|
|
88
|
-
resolve(res);
|
|
30
|
+
const upload: UploadFunction = (url: string, file: Media) => {
|
|
31
|
+
return new Promise<Media>((resolve, reject) => {
|
|
32
|
+
uploadFile({
|
|
33
|
+
url: config.baseUrl + url,
|
|
34
|
+
filePath: file.path!,
|
|
35
|
+
name: 'file',
|
|
36
|
+
formData: {
|
|
37
|
+
objectNo: `min${Date.now()}`,
|
|
89
38
|
},
|
|
90
|
-
|
|
91
|
-
|
|
39
|
+
header: {
|
|
40
|
+
...config.headers,
|
|
41
|
+
token: appkitOptions.tempToken() || appkitOptions.token(),
|
|
92
42
|
},
|
|
93
|
-
|
|
94
|
-
|
|
43
|
+
success: (rsp: any) => {
|
|
44
|
+
const { data } = rsp
|
|
45
|
+
try {
|
|
46
|
+
const response = JSON.parse(data)
|
|
47
|
+
console.log('===response', response)
|
|
48
|
+
resolve(transformFields(response.result))
|
|
49
|
+
} catch (e) {
|
|
50
|
+
reject({
|
|
51
|
+
message: '文件上传异常',
|
|
52
|
+
})
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
})
|
|
56
|
+
})
|
|
95
57
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
// 获取压缩质量
|
|
99
|
-
export function getCompressQuality(size: number) {
|
|
100
|
-
let quality = 100;
|
|
101
|
-
const curSize = size / (1024 * 1024);
|
|
102
|
-
if (curSize > 6) {
|
|
103
|
-
quality = quality - ((curSize - 6) / curSize) * 100;
|
|
58
|
+
return {
|
|
59
|
+
upload,
|
|
104
60
|
}
|
|
105
|
-
return quality;
|
|
106
61
|
}
|
package/src/shared/http/Http.ts
CHANGED