一、封装组件
<template>
<div class="page-scan">
<van-button @click="scanBarcode('EAN13')" type="primary" size="mini"
>条形码</van-button
>
<van-button @click="scanBarcode('QR')" type="primary" size="mini"
>二维码</van-button
>
<van-button @click="scanBarcode('and')" type="primary" size="mini"
>扫描头</van-button
>
<div class="content"></div>
</div>
</template>
<script>
var main, receiver, filter
var _codeQueryTag = false
export default {
name: 'ScanBarcode',
data () {
return {}
},
created () {
this.initScan()
this.startScan()
},
mounted () { },
destroyed () {
this.stopScan()
},
methods: {
initScan () {
let _this = this
// if (!window.plus) return
main = plus.android.runtimeMainActivity()
var IntentFilter = plus.android.importClass('android.content.IntentFilter')
filter = new IntentFilter()
//下面的addAction内改为自己的广播动作
filter.addAction("android.intent.ACTION_DECODE_DATA")
receiver = plus.android.implements('io.dcloud.feature.internal.reflect.BroadcastReceiver', {
onReceive: function (context, intent) {
plus.android.importClass(intent)
//下面的getStringExtra内改为自己的广播标签
let code = intent.getStringExtra("barcode_string")
_this.queryCode(code)
}
})
},
startScan () {
// if (!window.main) return
main.registerReceiver(receiver, filter)
},
stopScan () {
// if (!window.main) return
main.unregisterReceiver(receiver)
},
queryCode: function (code) {
if (_codeQueryTag) return false
_codeQueryTag = true
setTimeout(function () {
_codeQueryTag = false
}, 150)
var id = code
this.$emit('scanBarcodeVal', id)
},
scanBarcode (v) {
if (v == 'and') {
Toast({
message: '扫描头扫码请点击物理按键',
position: 'top',
})
return
}
this.scanCode({
onlyFromCamera: true,
type: v,
success: async (res) => {
this.$emit('scanBarcodeVal', res.result || res)
},
fail (e) {
uni.showToast({
icon: "none",
title: "扫码失败"
})
}
})
},
clickIndexLeft () { // 返回上一页
this.$router.back()
},
scanCode (option) {
if (!window.plus) return
let isFlash = false
// 创建一个空的webview
const webview = plus.webview.open(
'',
'webview', {
top: '0px',
width: '100%',
height: '100%',
backButtonAutoControl: "close",
titleNView: {
backgroundColor: 'rgba(0, 0, 0, 0.5)',
autoBackButton: true,
titleColor: '#ffffff',
titleText: "扫码"
}
})
// 创建barcode
const barcode = plus.barcode.create(
'barcode',
[plus.barcode[option.type]], // EAN13条码 QR二维码
{
top: 'auto',
left: '0',
width: '100%',
height: '100%',
position: 'static',
scanbarColor: '#f1c01f',
frameColor: '#c0ff01'
}
)
// 创建按钮“闪光灯”
const bFlash = new plus.nativeObj.View('nbutton', {
bottom: '20px',
left: option.onlyFromCamera ? '30%' : '5%',
width: '40%',
height: '44px'
}, [{
tag: 'rect',
id: 'rect',
rectStyles: {
radius: '8px',
color: 'rgba(0,0,0,0.5)'
}
}, {
tag: 'font',
id: 'text',
text: '闪光灯',
textStyles: {
color: '#FFFFFF'
}
}])
// 创建按钮“相册”
const bAlbum = (!option.onlyFromCamera) && new plus.nativeObj.View('nbutton', {
bottom: '20px',
left: '55%',
width: '40%',
height: '44px'
}, [{
tag: 'rect',
id: 'rect',
rectStyles: {
radius: '8px',
color: 'rgba(0,0,0,0.5)'
}
}, {
tag: 'font',
id: 'text',
text: '相册',
textStyles: {
color: '#FFFFFF'
}
}])
// 控制闪光灯按钮样式
bFlash.addEventListener('touchend', (e) => {
isFlash = !isFlash
isFlash && bFlash.drawText("闪光灯", null, { color: "#00ccff" }, 'text')
!isFlash && bFlash.drawText("闪光灯", null, { color: "#ffffff" }, 'text')
barcode.setFlash(isFlash)
}, false)
// 相册选取图片进行扫码识别
!option.onlyFromCamera && bAlbum.addEventListener('touchend', (e) => {
plus.gallery.pick(
(path) => {
plus.barcode.scan(path, barcode.onmarked, barcode.onerror)
},
barcode.onerror
)
}, false)
// 监听webview关闭,将相关控件都进行关闭
webview.addEventListener("close", () => {
barcode.close()
bFlash.close()
bAlbum && bAlbum.close()
})
// 扫码的成功回调:关闭webview,并执行success方法
barcode.onmarked = async (type, code, file, charset) => {
webview.close()
await option.success(code)
}
barcode.onerror = async (error) => {
webview.close()
await option.fail(error)
}
// 将相关控件添加至webview中
plus.webview.getWebviewById('webview').append(barcode)
plus.webview.getWebviewById('webview').append(bFlash)
!option.onlyFromCamera && plus.webview.getWebviewById('webview').append(bAlbum)
// start
barcode.start({
vibrate: true
})
}
}
}
</script>
<style scoped lang="scss">
.scan-index-bar {
background-image: linear-gradient(-45deg, #42a5ff, #59cfff);
}
/deep/.van-nav-bar__title {
color: #fff !important;
}
.scan-video {
height: 80vh;
}
.scan-tip {
width: 100vw;
text-align: center;
margin-bottom: 10vh;
color: white;
font-size: 5vw;
}
.wp_btn {
margin-top: 5px;
text-align: center;
padding: 0 10px;
}
</style>
二、引入组件
<template>
<div>
<van-nav-bar :title="warehouseName" left-arrow @click-left="onClickLeft" />
<div class="warp">
<van-form>
<van-field v-model="receiptNumberData" required name="来源单号" label="来源单号" placeholder="请输入或扫描来源单号" @blur="onBlur" :rules="[{ required: true, message: '' }]">
<template #button>
<van-icon name="scan" size="30" />
</template>
</van-field>
<div class="footer_box">
<van-button round class="btn" type="info" size="small" @click="onNext" :disabled="isDisabled">
下一步
</van-button>
</div>
</van-form>
</div>
<!-- 扫一扫 -->
<ScanBarcode v-show="false" @scanBarcodeVal="scanBarcodeVal"></ScanBarcode>
</div>
</template>
三、调用方法
// 扫码事件
scanBarcodeVal(e) {
this.pickingUnit = ''
this.isDisabled = true
this.getWhTaskData(e)
},
getWhTaskData(e) {
// e: 为扫码对象
// if (!e) {
// Notify({type: 'danger', message: '请扫描正确二维码'})
// return
// }
if (e) {
this.receiptNumberData = e
}
const receiptNumberData = e || this.receiptNumberData
CCMK.get_whTaskreceiptNumberData(
receiptNumberData,
this.warehouseId
).then((res) => {
if (res.code == 200) {
this.pickingUnit = res.data.pickingUnit
this.taskId = res.data.id
this.isDisabled = false
//提交
this.goPicking()
}
})
},