ry_app/components/ScanView.vue

207 lines
4.4 KiB
Vue

<template>
<view class="scan-view-container">
<!-- 扫码控件容器 -->
<view class="scan-box" id="scan-box"></view>
<!-- 扫码状态 -->
<view class="scan-status" v-if="isScanning">
<view class="scan-line"></view>
<text class="scan-text">正在扫描...</text>
</view>
<!-- 扫码控制按钮 -->
<view class="scan-controls" v-if="isScanning">
<view class="control-btn" @click="toggleFlash">
<uni-icons type="flash" size="22" color="#fff"></uni-icons>
<text class="control-text">{{ flashOn ? '关闭手电' : '开启手电' }}</text>
</view>
<view class="control-btn" @click="pauseScan">
<uni-icons type="pause" size="22" color="#fff"></uni-icons>
<text class="control-text">{{ scanPaused ? '继续扫码' : '暂停扫码' }}</text>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'ScanView',
props: {
autoStart: {
type: Boolean,
default: false
}
},
data() {
return {
isScanning: false,
scanPaused: false,
flashOn: false,
barcodeInstance: null
};
},
mounted() {
if (this.autoStart) {
this.initScan();
}
},
beforeUnmount() {
this.closeScan();
},
methods: {
initScan() {
if (typeof plus === 'undefined') {
console.log('当前环境不支持plus扫码');
this.$emit('error', '扫码功能需要在App中使用');
return;
}
console.log('开始初始化扫码控件');
this.isScanning = true;
const barcode = plus.barcode.create('barcode', [plus.barcode.CODE_128, plus.barcode.EAN_13], {
top: '0',
left: '0',
width: '100%',
height: '100%',
position: 'absolute'
});
console.log('扫码控件创建成功');
barcode.onmarked = (type, result) => {
console.log('识别成功:', result);
this.isScanning = false;
this.$emit('success', result);
};
barcode.onerror = (error) => {
console.error('扫码错误:', error);
this.isScanning = false;
this.$emit('error', error || '扫码失败');
};
const scanBox = document.getElementById('scan-box');
if (scanBox) {
scanBox.appendChild(barcode);
}
barcode.start();
console.log('扫码已启动');
this.barcodeInstance = barcode;
},
closeScan() {
if (this.barcodeInstance) {
this.barcodeInstance.close();
this.barcodeInstance = null;
this.isScanning = false;
console.log('扫码控件已关闭');
}
},
pauseScan() {
this.scanPaused = !this.scanPaused;
if (this.barcodeInstance) {
this.scanPaused ? this.barcodeInstance.pause() : this.barcodeInstance.resume();
}
this.$emit('pause', this.scanPaused);
},
resumeScan() {
if (this.barcodeInstance && this.scanPaused) {
this.barcodeInstance.resume();
this.scanPaused = false;
this.isScanning = true;
}
},
toggleFlash() {
this.flashOn = !this.flashOn;
if (this.barcodeInstance) {
this.barcodeInstance.setFlash(this.flashOn);
}
this.$emit('flash', this.flashOn);
}
}
};
</script>
<style scoped>
.scan-view-container {
width: 100%;
height: 100%;
position: relative;
background-color: #000;
}
.scan-box {
width: 100%;
height: 100%;
position: relative;
}
.scan-status {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: rgba(0, 0, 0, 0.3);
}
.scan-line {
width: 80%;
height: 2px;
background-color: #e60012;
animation: scanMove 2s infinite;
}
@keyframes scanMove {
0% {
transform: translateY(0);
opacity: 0;
}
50% {
opacity: 1;
}
100% {
transform: translateY(250px);
opacity: 0;
}
}
.scan-text {
color: #fff;
font-size: 16px;
margin-top: 20px;
}
.scan-controls {
position: absolute;
bottom: 30px;
left: 0;
width: 100%;
display: flex;
justify-content: space-around;
padding: 0 20px;
}
.control-btn {
display: flex;
flex-direction: column;
align-items: center;
color: #fff;
cursor: pointer;
}
.control-text {
font-size: 12px;
margin-top: 5px;
}
</style>