2025-04-14 10:57:27 +08:00
|
|
|
<template>
|
2025-07-11 11:03:39 +08:00
|
|
|
<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
|
|
|
|
|
? imgPath + 'static/scan/BarCodeScan.png'
|
|
|
|
|
: imgPath + 'static/scan/scan.png'
|
|
|
|
|
"
|
|
|
|
|
mode="widthFix"
|
|
|
|
|
>
|
|
|
|
|
<image
|
|
|
|
|
class="scanEffect"
|
|
|
|
|
:src="imgPath + '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'
|
|
|
|
|
? imgPath + 'static/scan/flash_close.png'
|
|
|
|
|
: imgPath + 'static/scan/flash_open.png'
|
|
|
|
|
"
|
|
|
|
|
>
|
|
|
|
|
</image>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</camera>
|
|
|
|
|
<view>
|
|
|
|
|
<uni-popup ref="message" type="message">
|
|
|
|
|
<uni-popup-message
|
|
|
|
|
type="success"
|
|
|
|
|
:message="code"
|
|
|
|
|
:duration="1000"
|
|
|
|
|
></uni-popup-message>
|
|
|
|
|
</uni-popup>
|
|
|
|
|
</view>
|
2025-04-14 10:57:27 +08:00
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup>
|
2025-07-11 11:03:39 +08:00
|
|
|
import { ref } from "vue";
|
|
|
|
|
import { onLoad } from "@dcloudio/uni-app";
|
|
|
|
|
import { useScanCodeStore } from "@/stores/scancode.js";
|
|
|
|
|
import config from "@/utils/config";
|
|
|
|
|
import { showMessage } from "../../utils/tools";
|
|
|
|
|
const imgPath = config.imgPath;
|
|
|
|
|
import { callOperateApi } from "@/utils/api.js";
|
|
|
|
|
const { isOnlyBarCode } = defineProps({
|
|
|
|
|
isOnlyBarCode: {
|
|
|
|
|
type: Boolean,
|
|
|
|
|
default: false,
|
|
|
|
|
},
|
|
|
|
|
});
|
2025-05-20 10:19:17 +08:00
|
|
|
|
2025-07-11 11:03:39 +08:00
|
|
|
const type = ref("");
|
|
|
|
|
const scanType = ref("");
|
|
|
|
|
const isInitDone = ref(false);
|
|
|
|
|
const flash = ref("off");
|
|
|
|
|
const message = ref(null);
|
|
|
|
|
const code = ref(null);
|
|
|
|
|
let lastTime = null;
|
2025-05-20 10:19:17 +08:00
|
|
|
|
2025-07-11 11:03:39 +08:00
|
|
|
onLoad((options) => {
|
|
|
|
|
if (options.type) {
|
|
|
|
|
type.value = options.type;
|
|
|
|
|
scanType.value = options.scanType;
|
|
|
|
|
}
|
|
|
|
|
});
|
2025-05-20 10:19:17 +08:00
|
|
|
|
2025-07-11 11:03:39 +08:00
|
|
|
const swithFlash = () => {
|
|
|
|
|
flash.value = flash.value === "off" ? "on" : "off";
|
|
|
|
|
uni.vibrateShort();
|
|
|
|
|
};
|
2025-05-20 10:19:17 +08:00
|
|
|
|
2025-07-11 11:03:39 +08:00
|
|
|
const scancode = useScanCodeStore();
|
|
|
|
|
const scanCode = (res) => {
|
|
|
|
|
const { result } = res.detail;
|
|
|
|
|
if (scanType.value == "bjrk") {
|
|
|
|
|
let componentType = "";
|
|
|
|
|
let componentCode = "";
|
|
|
|
|
if (type.value == "inBattery") {
|
|
|
|
|
componentType = "262711452730000";
|
|
|
|
|
componentCode = result;
|
|
|
|
|
} else if (type.value == "inHelmet") {
|
|
|
|
|
componentType = "262711452730001";
|
|
|
|
|
componentCode = result;
|
|
|
|
|
} else if (type.value == "inEcu") {
|
|
|
|
|
componentType = "262711452730008";
|
|
|
|
|
const arrCode = result.split(" ");
|
|
|
|
|
const imei = arrCode[0].replace("IMEI:", "");
|
|
|
|
|
const sn = arrCode[1].replace("SN:", "");
|
|
|
|
|
componentCode = sn;
|
|
|
|
|
}
|
|
|
|
|
const param = {
|
|
|
|
|
componentType,
|
|
|
|
|
componentCode,
|
|
|
|
|
isNew: true,
|
|
|
|
|
};
|
|
|
|
|
callOperateApi("ebikeComponent/validateComponentExistence", param).then(
|
|
|
|
|
(res) => {
|
|
|
|
|
if (res.code == 200) {
|
|
|
|
|
if (res.data) {
|
|
|
|
|
uni.showToast({
|
|
|
|
|
icon: "error",
|
|
|
|
|
title: "部件编号[" + componentCode + "]已有入库记录!",
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
const now = Date.now();
|
|
|
|
|
console.log("1111111111111111111", now - lastTime, result);
|
|
|
|
|
if (lastTime && now - lastTime < 1000) return;
|
|
|
|
|
lastTime = Date.now();
|
|
|
|
|
if (!scancode.code.includes(result)) {
|
|
|
|
|
code.value = result;
|
|
|
|
|
scancode.addCode(result, type.value);
|
|
|
|
|
message.value.open();
|
|
|
|
|
uni.vibrateShort();
|
|
|
|
|
} else if (now - lastTime < 2000) {
|
|
|
|
|
uni.showToast({
|
|
|
|
|
icon: "error",
|
|
|
|
|
title: "重复扫码,请返回或扫描下一个",
|
|
|
|
|
});
|
|
|
|
|
uni.vibrateShort();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
uni.showToast({
|
|
|
|
|
icon: "error",
|
|
|
|
|
title: res.message,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
} else if (scanType.value == "bjgh") {
|
|
|
|
|
let componentType = "";
|
|
|
|
|
let componentCode = "";
|
|
|
|
|
if (type.value == "inBattery") {
|
|
|
|
|
componentType = "262711452730000";
|
|
|
|
|
componentCode = result[0];
|
|
|
|
|
} else if (type.value == "inHelmet") {
|
|
|
|
|
componentType = "262711452730001";
|
|
|
|
|
componentCode = result[0];
|
|
|
|
|
} else if (type.value == "inEcu") {
|
|
|
|
|
componentType = "262711452730008";
|
|
|
|
|
const arrCode = result.split(" ");
|
|
|
|
|
const imei = arrCode[0].replace("IMEI:", "");
|
|
|
|
|
const sn = arrCode[1].replace("SN:", "");
|
|
|
|
|
componentCode = sn;
|
|
|
|
|
}
|
|
|
|
|
const param = {
|
|
|
|
|
componentType,
|
|
|
|
|
componentCode,
|
|
|
|
|
isNew: false,
|
|
|
|
|
};
|
|
|
|
|
callOperateApi("ebikeComponent/validateComponentExistence", param).then(
|
|
|
|
|
(res) => {
|
|
|
|
|
if (res.code == 200) {
|
|
|
|
|
if (res.data) {
|
|
|
|
|
uni.showToast({
|
|
|
|
|
icon: "error",
|
|
|
|
|
title: "部件编号[" + componentCode + "]已有入库记录!",
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
const now = Date.now();
|
|
|
|
|
console.log("1111111111111111111", now - lastTime, result);
|
|
|
|
|
if (lastTime && now - lastTime < 1000) return;
|
|
|
|
|
lastTime = Date.now();
|
|
|
|
|
if (!scancode.code.includes(result)) {
|
|
|
|
|
code.value = result;
|
|
|
|
|
scancode.addCode(result, type.value);
|
|
|
|
|
message.value.open();
|
|
|
|
|
uni.vibrateShort();
|
|
|
|
|
} else if (now - lastTime < 2000) {
|
|
|
|
|
uni.showToast({
|
|
|
|
|
icon: "error",
|
|
|
|
|
title: "重复扫码,请返回或扫描下一个",
|
|
|
|
|
});
|
|
|
|
|
uni.vibrateShort();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
uni.showToast({
|
|
|
|
|
icon: "error",
|
|
|
|
|
title: res.message,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
const now = Date.now();
|
|
|
|
|
console.log("1111111111111111111", now - lastTime, result);
|
|
|
|
|
if (lastTime && now - lastTime < 1000) return;
|
|
|
|
|
lastTime = Date.now();
|
|
|
|
|
if (!scancode.code.includes(result)) {
|
|
|
|
|
code.value = result;
|
|
|
|
|
scancode.addCode(result, type.value);
|
|
|
|
|
message.value.open();
|
|
|
|
|
uni.vibrateShort();
|
|
|
|
|
} else if (now - lastTime < 2000) {
|
|
|
|
|
uni.showToast({
|
|
|
|
|
icon: "error",
|
|
|
|
|
title: "重复扫码,请返回或扫描下一个",
|
|
|
|
|
});
|
|
|
|
|
uni.vibrateShort();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
2025-04-14 10:57:27 +08:00
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style lang="less" scoped>
|
2025-07-11 11:03:39 +08:00
|
|
|
.cameraUI {
|
|
|
|
|
width: 750rpx;
|
|
|
|
|
height: 100%;
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
align-items: center;
|
2025-05-20 10:19:17 +08:00
|
|
|
|
2025-07-11 11:03:39 +08:00
|
|
|
.scanBox {
|
|
|
|
|
width: 530rpx;
|
|
|
|
|
display: block;
|
|
|
|
|
position: relative;
|
2025-05-20 10:19:17 +08:00
|
|
|
|
2025-07-11 11:03:39 +08:00
|
|
|
.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;
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-05-20 10:19:17 +08:00
|
|
|
|
2025-07-11 11:03:39 +08:00
|
|
|
.BarCodeScanEffect {
|
|
|
|
|
top: 30%;
|
|
|
|
|
animation: BarCodeScan 1.5s ease-in-out infinite;
|
|
|
|
|
}
|
2025-05-20 10:19:17 +08:00
|
|
|
|
2025-07-11 11:03:39 +08:00
|
|
|
@keyframes scan {
|
|
|
|
|
0% {
|
|
|
|
|
top: 5%;
|
|
|
|
|
opacity: 0;
|
|
|
|
|
}
|
2025-05-20 10:19:17 +08:00
|
|
|
|
2025-07-11 11:03:39 +08:00
|
|
|
20% {
|
|
|
|
|
opacity: 1;
|
|
|
|
|
}
|
2025-05-20 10:19:17 +08:00
|
|
|
|
2025-07-11 11:03:39 +08:00
|
|
|
80% {
|
|
|
|
|
opacity: 1;
|
|
|
|
|
}
|
2025-05-20 10:19:17 +08:00
|
|
|
|
2025-07-11 11:03:39 +08:00
|
|
|
100% {
|
|
|
|
|
top: 70%;
|
|
|
|
|
opacity: 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-05-20 10:19:17 +08:00
|
|
|
|
2025-07-11 11:03:39 +08:00
|
|
|
.control {
|
|
|
|
|
margin-top: 80rpx;
|
|
|
|
|
height: 110rpx;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
2025-05-20 10:19:17 +08:00
|
|
|
|
2025-07-11 11:03:39 +08:00
|
|
|
.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;
|
2025-05-20 10:19:17 +08:00
|
|
|
|
2025-07-11 11:03:39 +08:00
|
|
|
image {
|
|
|
|
|
width: 60%;
|
|
|
|
|
height: 60%;
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-05-20 10:19:17 +08:00
|
|
|
|
2025-07-11 11:03:39 +08:00
|
|
|
.flashOpen {
|
|
|
|
|
backdrop-filter: blur(6px);
|
|
|
|
|
background: rgba(255, 255, 255, 0.5);
|
|
|
|
|
}
|
2025-05-20 10:19:17 +08:00
|
|
|
|
2025-07-11 11:03:39 +08:00
|
|
|
.flashClick {
|
|
|
|
|
transition: all 0.1s ease-in-out 0s;
|
|
|
|
|
transform: scale(1.2);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</style>
|