|
@@ -1,29 +1,32 @@
|
|
|
<script setup>
|
|
|
-import {Html5Qrcode, Html5QrcodeScanner, Html5QrcodeScanType, Html5QrcodeSupportedFormats} from "html5-qrcode";
|
|
|
+definePageMeta({
|
|
|
+ layout: 'scan'
|
|
|
+})
|
|
|
+
|
|
|
+import {Html5Qrcode, Html5QrcodeSupportedFormats} from "html5-qrcode";
|
|
|
+
|
|
|
+const router = useRouter()
|
|
|
|
|
|
const emit = defineEmits('oSuccess', 'onError')
|
|
|
-const slots = useSlots();
|
|
|
-// 判断是否有 default 插槽
|
|
|
-const hasDefaultSlot = computed(() => !!slots.default);
|
|
|
|
|
|
-let isShow = ref(false)
|
|
|
-let results = ref(null)
|
|
|
+let scanInstance = null; // 扫码实例
|
|
|
+let results = ref(null); // 扫码结果
|
|
|
|
|
|
-let scanInstance = null
|
|
|
+const initScanInstance = () => {
|
|
|
+ if (!scanInstance) {
|
|
|
+ // reader放置扫码功能的元素ID
|
|
|
+ scanInstance = new Html5Qrcode('qr-reader', {
|
|
|
+ formatsToSupport: [
|
|
|
+ Html5QrcodeSupportedFormats.QR_CODE,
|
|
|
+ ],
|
|
|
+ })
|
|
|
+ }
|
|
|
+}
|
|
|
const openQrcode = async () => {
|
|
|
Html5Qrcode.getCameras()
|
|
|
.then(devices => {
|
|
|
if (devices && devices.length) {// 当前环境下能识别出摄像头,并且摄像头的数据可能不止一个
|
|
|
- if (!scanInstance) {
|
|
|
- // reader 放置扫码功能的元素ID
|
|
|
- scanInstance = new Html5Qrcode('qr-reader', {
|
|
|
- formatsToSupport: [
|
|
|
- Html5QrcodeSupportedFormats.QR_CODE,
|
|
|
- ],
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- isShow.value = true
|
|
|
+ initScanInstance()
|
|
|
scanInstance.start(
|
|
|
{facingMode: "environment"},
|
|
|
{
|
|
@@ -42,29 +45,15 @@ const openQrcode = async () => {
|
|
|
},
|
|
|
(decodedText, decodedResult) => {
|
|
|
showToast('识别成功')
|
|
|
- // 扫描结果
|
|
|
- results.value = {
|
|
|
- decodedText,
|
|
|
- decodedResult
|
|
|
- }
|
|
|
- isShow.value = false
|
|
|
- scanInstance.stop()
|
|
|
- emit('oSuccess', {
|
|
|
- decodedText,
|
|
|
- decodedResult
|
|
|
- })
|
|
|
+ handleSuccess({decodedText, decodedResult})
|
|
|
},
|
|
|
(errorMessage, error) => {
|
|
|
- emit('onError', {
|
|
|
- errorMessage,
|
|
|
- error
|
|
|
- })
|
|
|
+ closeQrcode(errorMessage)
|
|
|
}
|
|
|
)
|
|
|
}
|
|
|
})
|
|
|
.catch((err) => {
|
|
|
- isShow.value = false
|
|
|
// 错误信息处理仅供参考,具体情况看输出!!!
|
|
|
let errorStr = ''
|
|
|
if (typeof err === "string") {
|
|
@@ -86,68 +75,84 @@ const openQrcode = async () => {
|
|
|
showToast(errorStr)
|
|
|
})
|
|
|
}
|
|
|
-const closeQrcode = () => {
|
|
|
- isShow.value = false
|
|
|
- if (scanInstance) scanInstance.stop()
|
|
|
+const scanLoadImg = (e) => {
|
|
|
+ try {
|
|
|
+ initScanInstance()
|
|
|
+ scanInstance.scanFile(e.file, false)
|
|
|
+ .then(result => {
|
|
|
+ // 二维码结果
|
|
|
+ console.log(result, '上传扫码成功')
|
|
|
+ handleSuccess(result)
|
|
|
+ })
|
|
|
+ .catch(err => {
|
|
|
+ console.error(err, '上传扫码失败')
|
|
|
+ })
|
|
|
+ } catch (e) {
|
|
|
+ console.error(e, '失败')
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
+const getResults = (result) => {
|
|
|
|
|
|
-let fileList = ref([])
|
|
|
-const uploadImg = () => {
|
|
|
- try {
|
|
|
- window.qrcode.callback = (result) => {
|
|
|
- showToast(result);
|
|
|
- };
|
|
|
- let file = state.fileList[0].file;
|
|
|
- let reader = new FileReader();
|
|
|
- reader.onload = (function () {
|
|
|
- return function (e) {
|
|
|
- window.qrcode.decode(e.target.result);
|
|
|
- };
|
|
|
- })(file);
|
|
|
- reader.readAsDataURL(file);
|
|
|
- } catch (error) {
|
|
|
- console.log(error);
|
|
|
- showToast({
|
|
|
- message: error+"识别失败!",
|
|
|
- duration: 2000,
|
|
|
- });
|
|
|
+ if (!result) {
|
|
|
+ return {success: false, groupId: null, overTime: false}
|
|
|
+ }
|
|
|
+
|
|
|
+ const url = new URL(result);
|
|
|
+ const urlParams = new URLSearchParams(url.search);
|
|
|
+
|
|
|
+ const hasGroupId = urlParams.has('groupId');
|
|
|
+ const hasTime = urlParams.has('time');
|
|
|
+ console.log(url.search, hasGroupId, hasTime, 'hasTime')
|
|
|
+ if (!hasGroupId || !hasTime) {
|
|
|
+ return {success: false, groupId: null, overTime: false}
|
|
|
+ }
|
|
|
+
|
|
|
+ const givenDate = new Date(urlParams.get('time'));
|
|
|
+ const currentDate = new Date();
|
|
|
+ const givenDateCst = new Date(givenDate.getTime() + (8 * 60 * 60 * 1000));
|
|
|
+ const currentDateCst = new Date(currentDate.getTime() + (8 * 60 * 60 * 1000));
|
|
|
+
|
|
|
+ const diffInMilliseconds = currentDateCst - givenDateCst;
|
|
|
+ const sevenDaysInMilliseconds = 7 * 24 * 60 * 60 * 1000;
|
|
|
+
|
|
|
+ return {
|
|
|
+ success: true,
|
|
|
+ groupId: urlParams.get('groupId'),
|
|
|
+ overTime: diffInMilliseconds > sevenDaysInMilliseconds
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-const selectFile = ()=> {
|
|
|
- let odeScanner = new Html5QrcodeScanner(
|
|
|
- "qr-code-file", { fps: 1 , qrbox: { // 扫描的UI框
|
|
|
- width: 250,
|
|
|
- height: 250
|
|
|
- },});
|
|
|
- odeScanner.render((e) => {
|
|
|
- console.log(e)
|
|
|
- });
|
|
|
- console.log(odeScanner, 'odeScanner')
|
|
|
+const handleSuccess = (result) => {
|
|
|
+ results.value = result
|
|
|
+ router.replace({
|
|
|
+ path: '/scan/scan-result',
|
|
|
+ query: result ? getResults(result) : result
|
|
|
+ })
|
|
|
}
|
|
|
|
|
|
+const closeQrcode = () => {
|
|
|
+ if (scanInstance && scanInstance.isScanning) scanInstance.stop()
|
|
|
+ router.back()
|
|
|
+}
|
|
|
|
|
|
-onMounted(() => {
|
|
|
- selectFile()
|
|
|
+onMounted(async () => {
|
|
|
+ initScanInstance()
|
|
|
+ await nextTick()
|
|
|
+ await openQrcode()
|
|
|
})
|
|
|
onUnmounted(() => {
|
|
|
- if (scanInstance) scanInstance.stop()
|
|
|
+ if (scanInstance && scanInstance.isScanning) scanInstance.stop()
|
|
|
})
|
|
|
+
|
|
|
</script>
|
|
|
|
|
|
<template>
|
|
|
<div>
|
|
|
- <template v-if="hasDefaultSlot">
|
|
|
- <slot></slot>
|
|
|
- </template>
|
|
|
- <template v-else>
|
|
|
- <van-button @click="openQrcode" size="mini">扫一扫</van-button>
|
|
|
- </template>
|
|
|
<div v-if="false" class="h-200">
|
|
|
{{ results }}
|
|
|
</div>
|
|
|
- <div class="overlay" v-show="isShow">
|
|
|
+ <div class="overlay">
|
|
|
<div class="absolute w-full z-30 flex flex-row items-center justify-center p-12">
|
|
|
<div class="absolute left-12 font-bold" @click="closeQrcode">
|
|
|
<span class="iconfont icon-left text-white"></span>
|
|
@@ -158,23 +163,18 @@ onUnmounted(() => {
|
|
|
</div>
|
|
|
<div class="relative qr-reader z-20" id="qr-reader"></div>
|
|
|
<p class="absolute w-full p-12 text-center bottom-100 z-30 text-sm text-[#fff]">请将二维码对准扫码框中心</p>
|
|
|
- <div id="qr-code-file" class="absolute w-54 h-54 grid place-items-center bottom-40 z-30 rounded-full bg-[#000]/80 text-white left-1/2 -translate-x-1/2">
|
|
|
- <img src="~/assets/img/scan/pic.png" height="32" width="32" alt=""/>
|
|
|
+ <div id="qr-code-file"
|
|
|
+ class="absolute w-54 h-54 grid place-items-center bottom-40 z-30 rounded-full bg-[#000]/80 text-white left-1/2 -translate-x-1/2">
|
|
|
+ <van-uploader
|
|
|
+ :preview-image="false"
|
|
|
+ :after-read="scanLoadImg"
|
|
|
+ accept="image/*"
|
|
|
+ :multiple="false"
|
|
|
+ :max-count="1"
|
|
|
+ ><img src="~/assets/img/scan/pic.png" height="32" width="32" alt=""/>
|
|
|
+ </van-uploader>
|
|
|
</div>
|
|
|
</div>
|
|
|
- <div id="qr-code-file" class="w-54 h-54 grid place-items-center bottom-40 z-30 rounded-full bg-[#000]/80 text-white">
|
|
|
- <img src="~/assets/img/scan/pic.png" height="32" width="32" alt=""/>
|
|
|
- </div>
|
|
|
- <van-uploader
|
|
|
- v-model="fileList"
|
|
|
- :preview-image="false"
|
|
|
- :after-read="uploadImg"
|
|
|
- accept="image/*"
|
|
|
- :multiple="false"
|
|
|
- :max-count="1"
|
|
|
- >
|
|
|
- <van-icon name="photo-o"
|
|
|
- /></van-uploader>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
@@ -185,11 +185,7 @@ onUnmounted(() => {
|
|
|
left: 0;
|
|
|
z-index: 999999;
|
|
|
width: 100%;
|
|
|
- height: calc(100% - 50px);
|
|
|
+ height: 100%;
|
|
|
background: rgba(0, 0, 0, 0.7);
|
|
|
-
|
|
|
- .scan-instruction {
|
|
|
-
|
|
|
- }
|
|
|
}
|
|
|
</style>
|