ocr识别

This commit is contained in:
hongchao 2025-06-02 17:28:09 +08:00
parent cef73f23e7
commit 5c4222ece5
5 changed files with 618 additions and 9 deletions

View File

@ -247,6 +247,12 @@
"navigationBarTitleText": "编码出库"
}
},
{
"path": "pages/toolsLease/ocrScan/ocrOutScan",
"style": {
"navigationBarTitleText": "OCR出库"
}
},
// 4.
{
"path": "pages/picking/outbound/num-outbound",

View File

@ -8,7 +8,7 @@
status-bar
left-icon="left"
left-text="返回"
title="编码出库"
title="OCR出库"
@clickLeft="back"
/>
<view class="page-container">
@ -59,7 +59,7 @@
</button>
</uni-col>
<uni-col :span="6">
<button style="width: 100px" type="primary" @click="">
<button style="width: 100px" type="primary" @click="ocrClick">
OCR识别
</button>
</uni-col>
@ -132,7 +132,7 @@
</template>
<script setup>
import { ref, computed, onUnmounted } from 'vue'
import { ref, computed, onUnmounted,reactive } from 'vue'
import { onLoad, onShow } from '@dcloudio/uni-app'
import {
getCodeDetailAPI,
@ -141,13 +141,18 @@ import {
getCodeScanAPI,
} from '@/services/picking/outbound.js'
import { getBoxBindByCode } from '@/services/standard.js'
import { getInfoByQrcode } from '@/services/back.js'
import { getInfoByQrcode,getOutNum } from '@/services/back.js'
import { debounce } from 'lodash-es'
import ScanQrCode from '@/pages/devicesSearch/ScanQrCode.vue'
// const query = defineProps() //
// const queryParams = JSON.parse(query.queryParams)
const scanQrCodeRef = ref(null)
const queryParams = ref({})
const queryParamsTemp = ref({
id: '',
typeId: '',
isAddCode: false,
})
const formData = ref({})
const codeDeviceList = ref([])
const maxNum = ref(0)
@ -180,15 +185,35 @@ const back = () => {
//
onLoad((opt) => {
queryParams.value = opt.params ? JSON.parse(opt.params) : {}
console.log('🚀 ~ onLoad ~ queryParams.value:', queryParams.value)
queryParamsTemp.value = opt.params ? JSON.parse(opt.params) : {}
queryParamsTemp.value.id = queryParamsTemp.value.parentId
console.log("xxxxxxxx",queryParamsTemp.value)
queryParams.value.isAddCode = queryParamsTemp.value.isAddCode
getDetailsById()
// getDetailsById()
// console.log('🚀 ~ onLoad ~ queryParams.value:', queryParams.value)
})
onShow(() => {
console.log(queryParams.value)
getDetailsById()
// getCodeDetailData(queryParams.value.id, queryParams.value.publishTask, queryParams.value.typeId) //
})
//
const getDetailsById = async () => {
try {
console.log('🚀 ~ getDetailsById ~ queryParams.value:', queryParamsTemp.value)
const res = await getOutNum({id: queryParamsTemp.value.id,typeId: queryParamsTemp.value.typeId})
console.log('🚀 ~ getDetailsById ~ queryParams.value:', res.data)
queryParams.value = res.data[0]
queryParams.value.projectName = queryParamsTemp.value.projectName
queryParams.value.teamName = queryParamsTemp.value.teamName
} catch (error) {
console.log('🚀 ~ getDetailsById ~ error:', error)
}
}
const delMaterial = (item, index) => {
codeDeviceList.value.splice(index, 1)
//
@ -562,6 +587,22 @@ const confirmCodeOutBound = async () => {
}, 800)
}
}
//
const ocrClick = () => {
console.log('编码识别--')
// if(maxNum.value==0){
// uni.showToast({
// title: '0',
// icon: 'none',
// })
// }else{
uni.navigateTo({
url: `/pages/toolsLease/ocrScan/ocrOutScan?queryParams=${JSON.stringify(queryParams.value)}`,
})
// }
}
</script>
<style lang="scss" scoped>

View File

@ -0,0 +1,432 @@
<template>
<view class="page-container">
<view>
<live-pusher v-once id="livePusher" ref="livePusher" class="livePusher" mode="FHD" beauty="0" whiteness="0"
device-position="back" :auto-focus="false" :muted="true" :enable-camera="true" :enable-mic="true"
:zoom="true" :style="[{height: '450rpx' ,width:'750rpx'}]">
</live-pusher>
</view>
<view class="table-list-item">
<view class="scan-btn" @click="handleInstruct('shutter')">
<text style="color: #FFF;">开始识别</text>
</view>
</view>
<view class="table-list-item">
<uni-row :gutter="24" style="display: flex; align-items: center">
<uni-col :span="5">
<text> 设备编码 </text>
</uni-col>
<uni-col :span="10">
<view>
<uni-easyinput v-model="queryCodeParams.maCode" placeholder="请输入内容" />
</view>
</uni-col>
<uni-col :span="6">
<view class="coding-btn" style="padding: 10rpx 0;color: #fe9a09;background-color: #fff7eb;border: 1px solid #fe9a09;"
@click="getCode()">
<text style="color: #fe9a09;text-align: center;">编码检索</text>
</view>
</uni-col>
</uni-row>
</view>
<view class="table-list-item">
<scroll-view class="scroll-view" scroll-y="true" style="height: 500rpx;">
<uni-forms :model="codeData" label-width="100" :border="true">
<uni-forms-item label="物资名称:" name="materialType">
<text style="height: 100%;display: flex;align-items: center;">{{ codeData.materialType }}</text>
</uni-forms-item>
<uni-forms-item label="物资类型:" name="materialName">
<text style="height: 100%;display: flex;align-items: center;">{{ codeData.materialName }}</text>
</uni-forms-item>
<uni-forms-item label="规格型号:" name="materialModel">
<text style="height: 100%;display: flex;align-items: center;">{{ codeData.materialModel }}</text>
</uni-forms-item>
<uni-forms-item label="设备编码:" name="maCode">
<text style="height: 100%;display: flex;align-items: center;">{{ codeData.maCode }}</text>
</uni-forms-item>
<uni-forms-item label="设备状态:" name="statusName">
<text style="height: 100%;display: flex;align-items: center;">{{ codeData.statusName }}</text>
</uni-forms-item>
<!-- <uni-forms-item label="设备数量:">
<text class="form-view">1</text>
</uni-forms-item> -->
</uni-forms>
</scroll-view>
</view>
<view class="outbound-btn" @tap="onHandleOutbound">
<text style="color: #FFF;">出库</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
livePusher: null,
ready: true,
cameraHeight: '', //相机画面宽度
coverImage: null,
queryParams:{},
queryCodeParams:{
maCode:""
},
codeData:{}
}
},
onLoad(options) {
this.queryParams = JSON.parse(options.queryParams)
this.queryCodeParams.typeId = this.queryParams.typeId;
},
onReady() {
this.cameraHeight = uni.getSystemInfoSync().screenHeight * 0.22
console.log(this.cameraHeight)
this.init()
},
methods: {
//初始化相机
init() {
this.livePusher = uni.createLivePusherContext('livePusher', this);
console.log(this.livePusher)
setTimeout(() => {
this.startPreview()
}, 1000)
},
// 开始相机
startPreview() {
this.livePusher.startPreview({
success: () => {
console.log('相机初始化成功');
switch (plus.os.name) {
case 'Android':
break;
case 'iOS':
this.livePusher.switchCamera()
break
}
},
fail: (err) => {
console.log(err)
}
});
},
//截屏
handleInstruct(instruct) {
if (this.ready) {
this.ready = false
this.livePusher.snapshot({
success: async (res) => {
console.log('拍照成功', res)
this.ready = true
let base64 = await this.imgToBase64(res.message.tempImagePath)
// console.log('base64', base64)
let params = {
image: base64,
jiju_type: '',
auth_lic:
'xIWDlaDVdijcBB4mjhGCPYk5Kvk8tHZJbUn+vW+ih15+MYx98e/PXyBmKL5gFcWMPznLgDA15QuSAnZQSLddwdy9HkZgtuQDEEZZ351Eyb1eiDUccUnyoSGIrNimbx5TooBNNPYqU4qJeFrPJXAqjBHzRrxoBxuR2CEGKQPgHC4=',
}
uni.request({
url: '/material/app/ocr/getOcrCode',
method: 'post',
data: params,
header: {
'Content-Type': 'application/json', // 根据后端要求设置请求头,常见的 POST 请求数据格式为 JSON
},
success: (res) => {
console.log('88888888', res)
if (res.data.code == 200 && res.data.data.data.result) {
this.queryCodeParams.maCode = res.data.data.data.result
this.getCode()
} else {
uni.showToast({ title: '扫描失败!', icon: 'none' })
}
},
fail: (err) => {
uni.showToast({
title: err,
icon: 'none',
})
},
})
//this.$emit('getImage', res.message.tempImagePath)
},
})
}
},
imgToBase64(filePath) {
// return new Promise((resolve, reject) => {
// console.log('555555', filePath)
// plus.zip.compressImage(
// {
// src: filePath,
// dst: '_doc/a.jpg',
// overwrite: true,
// width: '1920px',
// height: '1080px',
// format: 'jpg',
// quality: 100,
// },
// function (e) {
// let reader = new plus.io.FileReader()
// reader.readAsDataURL(e.target)
// reader.onloadend = function (e) {
// // 使用 split 方法去除前缀
// // let base64 = e.target.result.split(',')[1]
// base64 = e.target.result.replace(/[\r\n]/g, '')
// console.log(base64)
// // 异步操作成功,将结果传递给 Promise
// resolve(base64)
// }
// },
// function (err) {
// plus.nativeUI.alert('未知错误!', function () {})
// // 异步操作失败,将错误传递给 Promise
// reject(err)
// },
// )
// })
return new Promise((resolve, reject) => {
plus.io.resolveLocalFileSystemURL(
filePath,
(entry) => {
entry.file((file) => {
const reader = new plus.io.FileReader()
reader.onloadend = (evt) => {
// 去掉 data:URL 前缀
const base64WithoutPrefix = evt.target.result.split(',')[1]
resolve(base64WithoutPrefix)
}
reader.onerror = reject
reader.readAsDataURL(file)
}, reject)
},
reject,
)
})
},
imgBase64Fun(tempFilePath) {
console.log('vvvvvvvvvvvvvvvv')
return new Promise((resolve, reject) => {
uni.getFileSystemManager().readFile({
filePath: tempFilePath, // 图片临时路径
encoding: 'base64', // 指定编码为base64
success: (res) => {
// 拼接完整Base64前缀根据图片类型
let base64 = ''
console.log('ttttttttt', res)
if (tempFilePath.endsWith('.png')) {
base64 = 'data:image/png;base64,' + res.data
} else if (
tempFilePath.endsWith('.jpg') ||
tempFilePath.endsWith('.jpeg')
) {
base64 = 'data:image/jpeg;base64,' + res.data
}
console.log('base642222', base64)
resolve(base64)
},
fail: (err) => {
reject(err)
},
})
})
},
//编码检索
async getCode(){
let param = {
maCode:this.queryCodeParams.maCode,
typeId:this.queryCodeParams.typeId,
maStatus:1
}
console.log("xxxxxxxx",param)
uni.request({
url: '/material/ma_machine/list',
method: 'get',
data: param,
success: res => {
res = res.data;
console.log(res)
if(res.data&&res.data.length>0){
this.codeData=res.data[0];
}else{
uni.showToast({
title: '未检索到有效的设备编码!',
icon: 'none',
})
}
},
fail: err => {
console.log(err)
}
})
// const res = await getCodeDeviceListAPI(param)
// console.log(res)
// this.codeData=res.rows[0];
},
//出库按钮
async onHandleOutbound(){
let maCodeList = []
maCodeList.push({
maId: this.codeData.maId,
maCode: this.codeData.maCode,
})
let paramsList = []
paramsList.push({
leaseType: 0,
maCode: this.codeData.maCode,
maId: this.codeData.maId,
manageType:0,
outNum:1,
typeId:this.codeData.typeId,
parentId: this.queryParams.parentId,
maCodeList,
isApp: 0,
isNew: this.queryParams.isNew,
})
console.log('333333333', paramsList)
uni.request({
url: '/material/lease_apply_info/leaseOut',
method: 'post',
data: { leaseOutDetailsList: paramsList },
success: res => {
res = res.data;
console.log(res)
if (res.code === 200) {
uni.showToast({
title: '出库成功!',
icon: 'none',
})
this.queryCodeParams.maCode = ''
this.codeData = {}
}
},
fail: err => {
console.log(err)
}
})
}
}
}
</script>
<style>
.page-container {
display: flex;
height: auto;
flex-direction: column;
background-color: #f7f8fa;
padding: 24rpx;
}
.table-list-item {
margin-top: 10rpx;
background: #fff;
padding: 20rpx;
border-radius: 20rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06);
margin-bottom: 20rpx;
}
.scan-btn {
/* width: 100%; */
height: 88rpx;
background: #4b8eff;
display: flex;
justify-content: center;
align-items: center;
border-radius: 12rpx;
font-size: 32rpx;
font-weight: 600;
box-shadow: 0 6rpx 20rpx rgba(55, 132, 251, 0.2);
/* transition: all 0.3s ease; */
margin: 0;
padding: 0;
}
.coding-btn {
/* padding: 12rpx 0; */
background: #fff;
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));
border-radius: 12rpx;
text-align: center;
font-size: 28rpx;
font-weight: 600;
letter-spacing: 1rpx;
/* transition: all 0.3s ease; */
/* &:active {
background: rgba(255, 152, 0, 0.15);
border-color: rgba(255, 152, 0, 0.6);
transform: translateY(1rpx);
} */
}
.outbound-btn {
position: fixed;
bottom: 40rpx;
left: 20%;
/* transform: translateX(-50%); */
/* width: 90%; */
height: 88rpx;
width: 620rpx;
margin: 0 10px;
/* background: linear-gradient(135deg, #4b8eff 0%, #3784fb 100%); */
background: #4b8eff;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
border-radius: 12rpx;
font-size: 32rpx;
font-weight: 600;
box-shadow: 0 6rpx 20rpx rgba(55, 132, 251, 0.2);
/* transition: all 0.3s ease; */
/* &:active {
transform: translateX(-50%) scale(0.98);
opacity: 0.9;
} */
}
.camera-background {
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.3);
}
.cover-image {
position: fixed;
top: 0;
left: 0;
z-index: 99;
}
.camera-options {
flex-direction: row;
align-items: center;
}
.camera-item {
flex: 1;
flex-direction: row;
justify-content: center;
align-items: center;
height: 100%;
}
.camera-item .camera-item-image {
width: 80rpx;
height: 80rpx;
}
.camera-options-center .camera-item-image {
width: 120rpx;
height: 120rpx;
}
</style>

View File

@ -85,7 +85,7 @@
<script setup>
import { onLoad, onShow } from '@dcloudio/uni-app'
import { ref, reactive, computed } from 'vue'
import { getPickingOutboundListAPI, deleteLeaseApplyApi } from '@/services/picking/outbound.js'
import { getPickingOutboundListAPI, deleteLeaseApplyApi,submitLeaseOut } from '@/services/picking/outbound.js'
const title = ref('工器具领料')
const opts = ref()
@ -101,6 +101,18 @@ const current = ref(0)
const tableList = ref([])
const total = ref(0)
const options = ref([
{
text: '电子签名',
style: {
backgroundColor: '#c6bf3b',
},
},
{
text: '提交',
style: {
backgroundColor: '#2c954f',
},
},
{
text: '编辑',
style: {
@ -175,9 +187,117 @@ const onScrollTolower = () => {
}
//
const onClickSwipe = (e, item) => {
const onClickSwipe = async (e, item) => {
console.log('🚀 ~ onClickSwipe ~ e:', e, item)
if (e.index == 0) {
//
const params = JSON.stringify({
id: item.id,
taskId: item.taskId,
isSign: true,
})
console.log('电子签名-e', e)
console.log('电子签名-item', item)
// const params = {
// id: item.id,
// leaseSignUrl: item.leaseSignUrl,
// leaseSignType: item.leaseSignType,
// isLease: true,
// }
uni.navigateTo({
url: `/pages/my/signature?params=${JSON.stringify(params)}`,
})
}else if(e.index == 1) {
//
try {
let paramsOne = {
id: item.id,
isSubmit: 0,
}
const submitRes = await submitLeaseOut(paramsOne)
console.log('🚀 ~ 提交成功 ~ submitRes:', submitRes)
if (submitRes.code === 200 && submitRes.msg === "该领料单无未出库领料数据,请确认是否提交") {
uni.showModal({
title: '提示',
content: "是否确认提交?",
success: async (res) => {
if (res.confirm) {
const params = {
id: item.id,
}
try {
const submitRes = await submitLeaseOut(params)
if (submitRes.code === 200) {
uni.showToast({
title: '提交成功', //
icon: 'success'
})
getList() //
} else {
uni.showToast({
title: '提交失败',
icon: 'none'
})
}
} catch (error) {
console.log('🚀 ~ 提交失败 ~ error:', error)
uni.showToast({
title: '提交失败',
icon: 'none'
})
}
} else if (res.cancel) {
console.log('用户取消提交')
}
}
})
} else if (submitRes.code === 200 && submitRes.msg === "该领料单有未出库领料数据,请确认是否提交") {
uni.showModal({
title: '提示',
content: "该领料单有未出库领料数据,是否确认提交?",
success: async (res) => {
if (res.confirm) {
const params = {
id: item.id,
}
try {
const submitRes = await submitLeaseOut(params)
if (submitRes.code === 200) {
uni.showToast({
title: '提交成功', //
icon: 'success'
})
getList() //
} else {
uni.showToast({
title: '提交失败',
icon: 'none'
})
}
} catch (error) {
console.log('🚀 ~ 提交失败 ~ error:', error)
uni.showToast({
title: '提交失败',
icon: 'none'
})
}
} else if (res.cancel) {
console.log('用户取消提交')
}
}
})
}
} catch (error) {
console.log('🚀 ~ 提交失败 ~ error:', error)
uni.showToast({
title: '提交失败',
icon: 'none'
})
}
}else if(e.index == 2){
//
const params = JSON.stringify({
id: item.id,

View File

@ -104,3 +104,13 @@ export const getBackListAPI = (data) => {
data,
})
}
//出库提交
export const submitLeaseOut = (data) => {
return http({
method: 'POSt',
url: '/material/lease_apply_info/submitLeaseOut',
data,
})
}