2025-04-14 10:57:27 +08:00

144 lines
3.2 KiB
Vue

<template>
<camera mode="scanCode" device-position="back" style="width: 100%; height: 100vh;" @scancode="scanCode" :flash="flash" :initdone="(isInitDone = true)">
<view class="cameraUI" v-if="isInitDone">
<image class="scanBox" :src=" isOnlyBarCode === true ? '../../static/scan/BarCodeScan.png' : '../../static/scan/scan.png'" mode="widthFix">
<image class="scanEffect" src="../../static/scan/scan-effect.png" mode="aspectFill"></image>
</image>
<view class="control">
<view :class="['flashLight', { flashOpen: flash === 'on' }]" @tap="swithFlash" hover-class="flashClick">
<image :src="flash === 'off' ? '../../static/scan/flash_close.png' : '../../static/scan/flash_open.png'"></image>
</view>
</view>
</view>
</camera>
</template>
<script setup>
import { ref } from 'vue';
import {onLoad} from '@dcloudio/uni-app';
import {
useScanCodeStore
} from '@/stores/scancode.js';
const { isOnlyBarCode } = defineProps({
isOnlyBarCode: {
type: Boolean,
default: false,
}
});
const type = ref("");
const list = ref([]);
const isInitDone = ref(false);
const flash = ref("off");
onLoad((options)=>{
if(options.type){
type.value=options.type;
}
})
const swithFlash = () => {
flash.value = flash.value === "off" ? "on" : "off";
uni.vibrateShort();
};
const scancode = useScanCodeStore();
scancode.clearCode();
const scanCode = (res) => {
const {
result
} = res.detail;
if (!list.includes(result)) {
list.push(result);
scancode.addCode(result, type.value);
}
else
{
uni.showToast({
icon: "error",
title: "重复扫码,请返回或扫描下一个",
});
uni.vibrateShort();
}
}
</script>
<style lang="less" scoped>
.cameraUI {
width: 750rpx;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.scanBox {
width: 636rpx;
display: block;
position: relative;
.scanEffect {
position: absolute;
left: 50%;
top: 5%;
width: 595rpx;
height: 86rpx;
transform: translateX(-50%);
z-index: 1;
animation: scan 1.5s ease-in-out infinite;
}
}
.BarCodeScanEffect {
top: 30%;
animation: BarCodeScan 1.5s ease-in-out infinite;
}
@keyframes scan {
0% {
top: 5%;
opacity: 0;
}
20% {
opacity: 1;
}
80% {
opacity: 1;
}
100% {
top: 70%;
opacity: 0;
}
}
.control {
margin-top: 80rpx;
height: 110rpx;
display: flex;
align-items: center;
justify-content: center;
.flashLight {
width: 90rpx;
height: 90rpx;
background: rgba(74, 74, 74, 0.8);
box-shadow: rgba(142, 142, 142, 0.19) 0px 6px 15px 0px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
image {
width: 60%;
height: 60%;
}
}
.flashOpen {
backdrop-filter: blur(6px);
background: rgba(255, 255, 255, 0.5);
}
.flashClick {
transition: all 0.1s ease-in-out 0s;
transform: scale(1.2);
}
}
}
</style>