OCR 二维码 识别

This commit is contained in:
bb_pan 2025-10-31 13:22:00 +08:00
parent 40476d45b6
commit bd4ff86fdf
2 changed files with 915 additions and 1454 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,454 +1,447 @@
<template> <template>
<view class="page-container"> <view class="page-container">
<!-- 表单信息区域 --> <!-- 表单信息区域 -->
<scroll-view scroll-y style="height: 100vh;"> <scroll-view scroll-y style="height: 100vh;">
<view class="outbound-btn" @click="scanStart"> 二维码扫描 </view> <view class="outbound-btn" @click="scanStart"> 二维码扫描 </view>
<ScanQrCode ref="scanQrCodeRef" @scanSuccess="handleScanSuccess" @scanError="handleScanError" /> <!-- <ScanQrCode ref="scanQrCodeRef" @scanSuccess="handleScanSuccess" @scanError="handleScanError" />-->
<view class="form-section"> <view class="form-section">
<view class="section-header"> <view class="section-header">
<text class="title">设备信息</text> <text class="title">设备信息</text>
</view> </view>
<view class="form-content"> <view class="form-content">
<uni-forms :model="formData" label-width="100" :border="true"> <uni-forms :model="formData" label-width="100" :border="true">
<uni-forms-item label="设备类型:" name="maName"> <uni-forms-item label="设备类型:" name="maName">
<span class="form-view">{{codeData.maName}}</span> <span class="form-view">{{codeData.maName}}</span>
</uni-forms-item> </uni-forms-item>
<uni-forms-item label="规格型号:" name="maModel"> <uni-forms-item label="规格型号:" name="maModel">
<span class="form-view">{{codeData.maModel}}</span> <span class="form-view">{{codeData.maModel}}</span>
</uni-forms-item> </uni-forms-item>
<uni-forms-item label="二维码编码:" name="qrCode"> <uni-forms-item label="二维码编码:" name="qrCode">
<span class="form-view">{{codeData.qrCode}}</span> <span class="form-view">{{codeData.qrCode}}</span>
</uni-forms-item> </uni-forms-item>
<uni-forms-item label="设备编码:" name="maCode"> <uni-forms-item label="设备编码:" name="maCode">
<span class="form-view">{{codeData.maCode}}</span> <span class="form-view">{{codeData.maCode}}</span>
</uni-forms-item> </uni-forms-item>
<uni-forms-item label="设备状态:" name="maStatus"> <uni-forms-item label="设备状态:" name="maStatus">
<span class="form-view">{{codeData.maStatus}}</span> <span class="form-view">{{codeData.maStatus}}</span>
</uni-forms-item> </uni-forms-item>
<uni-forms-item label="本次检修时间:" name="checkTimeSynch"> <uni-forms-item label="本次检修时间:" name="checkTimeSynch">
<text class="form-view">{{codeData.thisCheckTime}}</text> <text class="form-view">{{codeData.thisCheckTime}}</text>
</uni-forms-item> </uni-forms-item>
<uni-forms-item label="下次检修时间:" name="nextCheckTimeSynch"> <uni-forms-item label="下次检修时间:" name="nextCheckTimeSynch">
<text class="form-view">{{codeData.nextCheckTime}}</text> <text class="form-view">{{codeData.nextCheckTime}}</text>
</uni-forms-item> </uni-forms-item>
<uni-forms-item label="出入库次数:" name="inOutNum"> <uni-forms-item label="出入库次数:" name="inOutNum">
<text class="form-view">{{codeData.inOutNum}}</text> <text class="form-view">{{codeData.inOutNum}}</text>
</uni-forms-item> </uni-forms-item>
<uni-forms-item label="初次入库:" name="inTime"> <uni-forms-item label="初次入库:" name="inTime">
<text class="form-view">{{codeData.inTime}}</text> <text class="form-view">{{codeData.inTime}}</text>
</uni-forms-item> </uni-forms-item>
<uni-forms-item label="服务工程次数:" name="serviceNum"> <uni-forms-item label="服务工程次数:" name="serviceNum">
<text class="form-view">{{codeData.serviceNum}}</text> <text class="form-view">{{codeData.serviceNum}}</text>
</uni-forms-item> </uni-forms-item>
<uni-forms-item label="检验次数:" name="serviceNum"> <uni-forms-item label="检验次数:" name="serviceNum">
<text class="form-view">{{codeData.serviceNum}}</text> <text class="form-view">{{codeData.serviceNum}}</text>
</uni-forms-item> </uni-forms-item>
<uni-forms-item label="更换配件次数:" name="checkNum"> <uni-forms-item label="更换配件次数:" name="checkNum">
<text class="form-view">{{codeData.checkNum}}</text> <text class="form-view">{{codeData.checkNum}}</text>
</uni-forms-item> </uni-forms-item>
<uni-forms-item label="报废:" name="scrapTime"> <uni-forms-item label="报废:" name="scrapTime">
<text class="form-view">{{codeData.scrapTime}}</text> <text class="form-view">{{codeData.scrapTime}}</text>
</uni-forms-item> </uni-forms-item>
<uni-forms-item label="生产厂家:" name="maVender"> <uni-forms-item label="生产厂家:" name="maVender">
<text class="form-view">{{codeData.maVender}}</text> <text class="form-view">{{codeData.maVender}}</text>
</uni-forms-item> </uni-forms-item>
<uni-forms-item label="领料单位:" name="leaseUnit"> <uni-forms-item label="领料单位:" name="leaseUnit">
<text class="form-view">{{codeData.leaseUnit}}</text> <text class="form-view">{{codeData.leaseUnit}}</text>
</uni-forms-item> </uni-forms-item>
<uni-forms-item label="领料工程:" name="leaseProject"> <uni-forms-item label="领料工程:" name="leaseProject">
<text class="form-view">{{codeData.leaseProject}}</text> <text class="form-view">{{codeData.leaseProject}}</text>
</uni-forms-item> </uni-forms-item>
<uni-forms-item label="领料时间:" name="leaseTime"> <uni-forms-item label="领料时间:" name="leaseTime">
<text class="form-view">{{codeData.leaseTime}}</text> <text class="form-view">{{codeData.leaseTime}}</text>
</uni-forms-item> </uni-forms-item>
<uni-forms-item label="退料单位:" name="backUnit"> <uni-forms-item label="退料单位:" name="backUnit">
<text class="form-view">{{codeData.backUnit}}</text> <text class="form-view">{{codeData.backUnit}}</text>
</uni-forms-item> </uni-forms-item>
<uni-forms-item label="退料工程:" name="backProject"> <uni-forms-item label="退料工程:" name="backProject">
<text class="form-view">{{codeData.backProject}}</text> <text class="form-view">{{codeData.backProject}}</text>
</uni-forms-item> </uni-forms-item>
<uni-forms-item label="退料时间:" name="backTime"> <uni-forms-item label="退料时间:" name="backTime">
<text class="form-view">{{codeData.backTime}}</text> <text class="form-view">{{codeData.backTime}}</text>
</uni-forms-item> </uni-forms-item>
</uni-forms> </uni-forms>
</view> </view>
</view> </view>
<div v-if="isOverToday && codeData.nextCheckTime">该工器具已临近下次检验时间请及时退还至机具物流分公司</div> <div v-if="isOverToday && codeData.nextCheckTime">该工器具已临近下次检验时间请及时退还至机具物流分公司</div>
<ElectronicSeal v-else v-show="codeData.maId" :maCode="codeData?.maCode" :maId="codeData?.maId" :devType="2" /> <ElectronicSeal v-else v-show="codeData.maId" :maCode="codeData?.maCode" :maId="codeData?.maId" :devType="2" />
</scroll-view> </scroll-view>
</view> </view>
</template> </template>
<script setup> <script setup>
import { ref, computed, onUnmounted } from 'vue' import { ref, computed, onUnmounted } from 'vue'
import { onLoad, onShow, } from '@dcloudio/uni-app' import { onLoad, onShow, } from '@dcloudio/uni-app'
import { debounce } from 'lodash-es' import { debounce } from 'lodash-es'
import ScanQrCode from '@/pages/devicesSearch/ScanQrCode.vue' import ScanQrCode from '@/pages/devicesSearch/ScanQrCode.vue'
import { getDeviceListAPI } from '@/services/picking/outbound.js' import { getDeviceListAPI } from '@/services/picking/outbound.js'
import ElectronicSeal from '@/components/ElectronicSeal/index.vue' import ElectronicSeal from '@/components/ElectronicSeal/index.vue'
const scanQrCodeRef = ref(null) const scanQrCodeRef = ref(null)
const queryParams = ref({}) const queryParams = ref({})
const formData = ref({}) const formData = ref({})
// const qrCodeScan = ref('')
const queryCodeParams = ref({ const codeData = ref({})
maCode: '', const isOverToday = ref(false)
})
const qrCodeScan = ref('') // 使 hwqrcodescan Cordova
const codeData = ref({}) let hwqrcodescan = null
const isOverToday = ref(false) if (typeof window !== 'undefined' && window.cordova) {
// try {
onLoad((options) => { hwqrcodescan = require('cordova/plugin/hwscan')
// scanStart() } catch (e) {
}) console.warn('HwQrcodeScan插件未正确加载', e)
}
onShow(() => { }
})
//
const handleIsOverToday = () => { onLoad(() => {
console.log('🚀 ~ .nextCheckTime:', codeData.value.nextCheckTime) //
if (!codeData.value.nextCheckTime) { if (!hwqrcodescan) {
isOverToday.value = true console.warn('HwQrcodeScan 插件不可用,请检查 Android 端是否已集成')
} else { }
const now = Date.now() })
const nextCheckTimestamp = new Date(codeData.value.nextCheckTime).getTime()
isOverToday.value = nextCheckTimestamp <= now onShow(() => {
// console.log('🚀 ~ isOverToday ~ :', nextCheckDate < today) })
}
} const handleIsOverToday = () => {
console.log('🚀 ~ .nextCheckTime:', codeData.value.nextCheckTime)
// // if (!codeData.value.nextCheckTime) {
// const scanStart = () => { isOverToday.value = true
// var mpaasScanModule = uni.requireNativePlugin("Mpaas-Scan-Module") } else {
// mpaasScanModule.mpaasScan({ const now = Date.now()
// // qrCodebarCode const nextCheckTimestamp = new Date(codeData.value.nextCheckTime).getTime()
// 'scanType': ['qrCode','barCode'], isOverToday.value = nextCheckTimestamp <= now
// // false // console.log('🚀 ~ isOverToday ~ :', nextCheckDate < today)
// 'hideAlbum': false, }
// //ios zh-Hansen }
// 'language' : 'en',
// //(ios) //
// 'failedMsg': '', // const scanStart = () => {
// //Android // qrCodeScan.value = ''
// 'screenType': 'full' // codeData.value = {}
// },(ret) => { // if (scanQrCodeRef.value) {
// if(ret.resp_code==10){ // scanQrCodeRef.value.scanQrCode()
// uni.showToast({ title: '', icon: 'none' }) // }
// } //
// if(ret.resp_code==11){ // // --
// uni.showToast({ title: '', icon: 'none' }) // // qrCodeScan.value = '201807-00009'
// } // // getMaInfoScan()
// if(ret.resp_code==1000){ // }
// // uni.showToast({ title: '', icon: 'none' })
// qrCodeScan.value = ret.resp_result.split("qrcode=")[1] //
// if (qrCodeScan.value=="") { const scanStart = () => {
// uni.showToast({ title: '', icon: 'none'}) qrCodeScan.value = ''
// }else{ codeData.value = {}
// getMaInfoScan()
// } if (hwqrcodescan && typeof hwqrcodescan.startScan === 'function') {
// } hwqrcodescan.startScan("QrCode", function (result) {
console.log('扫码成功:', result)
// }) handleScanSuccess({ data: result })
// } })
// } else {
const scanStart = () => { uni.showToast({
qrCodeScan.value = '' title: '扫码功能不可用请确认已集成HwQrcodeScan插件',
codeData.value = {} icon: 'none'
if (scanQrCodeRef.value) { })
scanQrCodeRef.value.scanQrCode() }
}
//
// -- // qrCodeScan.value = '201807-00009'
// qrCodeScan.value = '201807-00009' // getMaInfoScan()
// getMaInfoScan() }
}
//
// const handleScanSuccess = (result) => {
const handleScanSuccess = (result) => { console.log('🚀 ~ handleScanSuccess ~ result:', result)
console.log('🚀 ~ handleScanSuccess ~ result:', result) qrCodeScan.value = result?.data?.split('?qrcode=')[1] || result?.data || result
qrCodeScan.value = result?.data?.split('?qrcode=')[1] || result?.data console.log('🚀 ~ handleScanSuccess ~ qrCodeScan.value:', qrCodeScan.value)
console.log('🚀 ~ handleScanSuccess ~ qrCodeScan.value:', qrCodeScan.value) if (!qrCodeScan.value) {
if (qrCodeScan.value === '') { uni.showToast({ title: '扫码识别失败', icon: 'none' })
uni.showToast({ title: '扫码识别失败', icon: 'none' }) } else {
} else { getMaInfoScan()
getMaInfoScan() }
} }
}
//
// const handleScanError = (error) => {
const handleScanError = (error) => { console.error('扫描出错:', error.message)
console.error('扫描出错:', error.message) uni.showToast({ title: error.message, icon: 'none' })
uni.showToast({ title: error.message, icon: 'none' }) }
}
//
// const getMaInfoScan = async () => {
const getMaInfoScan = async () => { try {
try { uni.showLoading({ title: '加载中...', mask: true })
uni.showLoading({ title: '加载中...', mask: true }) let param = {
let param = { qrCode: qrCodeScan.value,
qrCode: qrCodeScan.value, }
} console.log(param)
console.log(param) const res = await getDeviceListAPI(param)
const res = await getDeviceListAPI(param) console.log(res)
console.log(res) if (res.code === 200 && res.data) {
if (res.code == 200) { codeData.value = res.data[0] || {}
if (res.data) { setTimeout(handleIsOverToday, 500)
codeData.value = res.data[0] } else {
setTimeout(() => { uni.showToast({ title: res?.msg || '未查询到设备信息', icon: 'none' })
handleIsOverToday() }
}, 500) } catch (error) {
}else{ console.log('🚀 ~ getMaInfoScan ~ error:', error)
uni.showToast({ title: res.data.msg, icon: 'none'}) } finally {
} uni.hideLoading()
} else { }
uni.showToast({ title: res.data.msg, icon: 'none' }) }
}
} catch (error) {
console.log('🚀 ~ getMaInfoScan ~ error:', error)
} finally {
uni.hideLoading() </script>
}
} <style lang="scss" scoped>
.uni-forms-item--border[data-v-4c3fe719] {
margin-bottom: 0;
padding: 0 0;
border-top: 1px #eee solid;
</script> }
.page-container {
<style lang="scss" scoped> display: flex;
.uni-forms-item--border[data-v-4c3fe719] { height: 100%;
margin-bottom: 0; flex-direction: column;
padding: 0 0; background-color: #f7f8fa;
border-top: 1px #eee solid; padding: 24rpx;
}
.page-container { .table-list-item {
display: flex; background: #fff;
height: 100%; padding: 32rpx;
flex-direction: column; border-radius: 20rpx;
background-color: #f7f8fa; box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06);
padding: 24rpx; margin-bottom: 24rpx;
.table-list-item { //
background: #fff; :deep(.uni-forms) {
padding: 32rpx; .uni-forms-item {
border-radius: 20rpx; margin-bottom: 24rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06); padding: 0;
margin-bottom: 24rpx;
&:last-child {
// margin-bottom: 0;
:deep(.uni-forms) { }
.uni-forms-item {
margin-bottom: 24rpx; .uni-forms-item__label {
padding: 0; color: #8c8c8c;
font-size: 28rpx;
&:last-child { font-weight: 500;
margin-bottom: 0; padding: 0;
} line-height: 1.8;
}
.uni-forms-item__label {
color: #8c8c8c; .uni-forms-item__content {
font-size: 28rpx; display: flex;
font-weight: 500; align-items: center;
padding: 0; min-height: unset;
line-height: 1.8; }
} }
}
.uni-forms-item__content {
display: flex; //
align-items: center; .coding-btn {
min-height: unset; padding: 16rpx 0;
} background: linear-gradient(135deg, #4b8eff 0%, #3784fb 100%);
} border-radius: 12rpx;
} text-align: center;
color: #fff;
// font-size: 28rpx;
.coding-btn { font-weight: 600;
padding: 16rpx 0; box-shadow: 0 6rpx 20rpx rgba(55, 132, 251, 0.2);
background: linear-gradient(135deg, #4b8eff 0%, #3784fb 100%); transition: all 0.3s ease;
border-radius: 12rpx;
text-align: center; &:active {
color: #fff; transform: scale(0.98);
font-size: 28rpx; opacity: 0.9;
font-weight: 600; }
box-shadow: 0 6rpx 20rpx rgba(55, 132, 251, 0.2);
transition: all 0.3s ease; //
&.search-btn {
&:active { padding: 12rpx 0;
transform: scale(0.98); background: #fff;
opacity: 0.9; color: #ff9800;
} border: 2rpx solid rgba(255, 152, 0, 0.5);
background: linear-gradient(to bottom, rgba(255, 152, 0, 0.05), rgba(255, 152, 0, 0.1));
// box-shadow: none;
&.search-btn { font-weight: 600;
padding: 12rpx 0; letter-spacing: 1rpx;
background: #fff;
color: #ff9800; &:active {
border: 2rpx solid rgba(255, 152, 0, 0.5); background: rgba(255, 152, 0, 0.15);
background: linear-gradient(to bottom, rgba(255, 152, 0, 0.05), rgba(255, 152, 0, 0.1)); border-color: rgba(255, 152, 0, 0.6);
box-shadow: none; transform: translateY(1rpx);
font-weight: 600; }
letter-spacing: 1rpx; }
}
&:active {
background: rgba(255, 152, 0, 0.15); //
border-color: rgba(255, 152, 0, 0.6); :deep(.uni-row) {
transform: translateY(1rpx); /* margin-bottom: 20rpx; */
}
} &:last-child {
} margin-bottom: 0;
}
//
:deep(.uni-row) { .uni-col-6 {
/* margin-bottom: 20rpx; */ color: #8c8c8c;
font-size: 28rpx;
&:last-child { font-weight: 500;
margin-bottom: 0; }
}
.cont {
.uni-col-6 { color: #262626;
color: #8c8c8c; font-size: 28rpx;
font-size: 28rpx; font-weight: 500;
font-weight: 500; line-height: 1.8;
} }
}
.cont {
color: #262626; //
font-size: 28rpx; :deep(.uni-easyinput__content) {
font-weight: 500; background-color: #f7f8fa;
line-height: 1.8; border: 2rpx solid #e8e8e8;
} border-radius: 12rpx;
} height: 75rpx;
transition: all 0.3s ease;
//
:deep(.uni-easyinput__content) { &:focus-within {
background-color: #f7f8fa; border-color: #3784fb;
border: 2rpx solid #e8e8e8; box-shadow: 0 0 0 2rpx rgba(55, 132, 251, 0.1);
border-radius: 12rpx; }
height: 75rpx;
transition: all 0.3s ease; .uni-easyinput__content-input {
font-size: 28rpx;
&:focus-within { color: #262626;
border-color: #3784fb; }
box-shadow: 0 0 0 2rpx rgba(55, 132, 251, 0.1); }
}
//
.uni-easyinput__content-input { :deep(checkbox) {
font-size: 28rpx; .wx-checkbox-input {
color: #262626; width: 36rpx;
} height: 36rpx;
} border-radius: 8rpx;
border: 2rpx solid #e8e8e8;
// background: transparent;
:deep(checkbox) {
.wx-checkbox-input { &.wx-checkbox-input-checked {
width: 36rpx; background: #3784fb;
height: 36rpx; border-color: #3784fb;
border-radius: 8rpx;
border: 2rpx solid #e8e8e8; &::before {
background: transparent; font-size: 28rpx;
color: #fff;
&.wx-checkbox-input-checked { }
background: #3784fb; }
border-color: #3784fb;
&.wx-checkbox-input-disabled {
&::before { background: #f5f5f5;
font-size: 28rpx; border-color: #e8e8e8;
color: #fff; }
} }
} }
}
&.wx-checkbox-input-disabled {
background: #f5f5f5; //
border-color: #e8e8e8; .outbound-btn {
} width: 96%;
} height: 88rpx;
} margin: 10rpx auto;
} background: linear-gradient(135deg, #4b8eff 0%, #3784fb 100%);
text-align: center;
// line-height: 88rpx;
.outbound-btn { color: #fff;
width: 96%; border-radius: 12rpx;
height: 88rpx; font-size: 32rpx;
margin: 10rpx auto; font-weight: 600;
background: linear-gradient(135deg, #4b8eff 0%, #3784fb 100%); box-shadow: 0 6rpx 20rpx rgba(55, 132, 251, 0.2);
text-align: center; transition: all 0.3s ease;
line-height: 88rpx; }
color: #fff; }
border-radius: 12rpx;
font-size: 32rpx; //
font-weight: 600; .loading-text {
box-shadow: 0 6rpx 20rpx rgba(55, 132, 251, 0.2); text-align: center;
transition: all 0.3s ease; font-size: 26rpx;
} color: #8c8c8c;
} padding: 32rpx 0;
letter-spacing: 1rpx;
// }
.loading-text {
text-align: center; .form-section {
font-size: 26rpx; background: #fff;
color: #8c8c8c; border-radius: 20rpx;
padding: 32rpx 0; margin-bottom: 24rpx;
letter-spacing: 1rpx; box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06);
}
//
.form-section { .section-header {
background: #fff; display: flex;
border-radius: 20rpx; justify-content: space-between;
margin-bottom: 24rpx; align-items: center;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06); padding: 24rpx 32rpx;
background: #fff;
// cursor: pointer;
.section-header { transition: all 0.3s ease;
display: flex;
justify-content: space-between; &:active {
align-items: center; background: #f7f8fa;
padding: 24rpx 32rpx; }
background: #fff;
cursor: pointer; .title {
transition: all 0.3s ease; font-size: 32rpx;
font-weight: 600;
&:active { color: #262626;
background: #f7f8fa; }
} }
.title { //
font-size: 32rpx; .form-content {
font-weight: 600; // max-height: 0;
color: #262626; overflow: auto;
} transition: max-height 0.3s ease-out;
}
:deep(.uni-forms) {
// padding: 0 32rpx 32rpx;
.form-content { }
// max-height: 0;
overflow: auto; :deep(.uni-forms-item) {
transition: max-height 0.3s ease-out; margin-bottom: 10rpx;
:deep(.uni-forms) { &:last-child {
padding: 0 32rpx 32rpx; margin-bottom: 0;
} }
:deep(.uni-forms-item) { .uni-forms-item__label {
margin-bottom: 10rpx; color: #8c8c8c;
}
&:last-child {
margin-bottom: 0; .form-view {
} height: 100%;
display: flex;
.uni-forms-item__label { align-items: center;
color: #8c8c8c; color: #262626;
} font-size: 28rpx;
}
.form-view { }
height: 100%; }
display: flex; }
align-items: center; </style>
color: #262626;
font-size: 28rpx;
}
}
}
}
</style>