From e66dc97ac362de45fd603c5ca250a5fd66497548 Mon Sep 17 00:00:00 2001 From: bb_pan Date: Wed, 30 Jul 2025 10:05:08 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/my/signature.vue | 44 +++++++-- src/pages/picking/outbound/details.vue | 109 ++++++++++++----------- src/pages/repair/testExamine/details.vue | 23 ++--- 3 files changed, 104 insertions(+), 72 deletions(-) diff --git a/src/pages/my/signature.vue b/src/pages/my/signature.vue index 1fa1c68..70eb1ac 100644 --- a/src/pages/my/signature.vue +++ b/src/pages/my/signature.vue @@ -204,8 +204,15 @@ const uploadSignUrl = async (base64Data) => { console.log('🚀 ~ success: ~ params:', params) const res = await updateLeaseApplyInfoSign(params) console.log('🚀 ~ uploadImg-领料 ~ res:', res) - uni.showToast({ title: '签名成功'}) - uni.navigateBack() + uni.showToast({ + title: '签名成功', + mask: true, + success: () => { + setTimeout(() => { + uni.navigateBack() + }, 1000) + }, + }) } else if (opts.isToolsLease) { const params = { id: opts.id, @@ -215,10 +222,17 @@ const uploadSignUrl = async (base64Data) => { publishTask: opts.publishTask || '', } console.log('🚀 ~ success: ~ params:', params) - uni.showToast({ title: '签名成功'}) const res = await toolsLeaseApplyInfoSign(params) console.log('🚀 ~ uploadImg-领料 ~ res:', res) - uni.navigateBack() + uni.showToast({ + title: '签名成功', + mask: true, + success: () => { + setTimeout(() => { + uni.navigateBack() + }, 1000) + }, + }) } else if (opts.isAuthorize) { const params = { parentId: opts.id, @@ -226,9 +240,16 @@ const uploadSignUrl = async (base64Data) => { signType: signType.value, } const res = await updateLeaseApplyInfoSignApi(params) - uni.showToast({ title: '签名成功'}) console.log('🚀 ~ uploadSignUrl ~ 项目部授权:', res) - uni.navigateBack() + uni.showToast({ + title: '签名成功', + mask: true, + success: () => { + setTimeout(() => { + uni.navigateBack() + }, 1000) + }, + }) } else if (opts.isBack) { const params = { id: opts.id, @@ -237,9 +258,16 @@ const uploadSignUrl = async (base64Data) => { } console.log('🚀 ~ success: ~ params:', params) const res = await updateSignById(params) - uni.showToast({ title: '签名成功'}) console.log('🚀 ~ uploadImg-退料 ~ res:', res) - uni.navigateBack() + uni.showToast({ + title: '签名成功', + mask: true, + success: () => { + setTimeout(() => { + uni.navigateBack() + }, 1000) + }, + }) } else { const params = { signUrl: signUrl, diff --git a/src/pages/picking/outbound/details.vue b/src/pages/picking/outbound/details.vue index 4f00f53..8fde695 100644 --- a/src/pages/picking/outbound/details.vue +++ b/src/pages/picking/outbound/details.vue @@ -145,57 +145,66 @@ const getOutboundDetailsData = async () => { console.log('publishTask:', leaseApplyInfo.value.publishTask); console.log('publishTask type:', typeof leaseApplyInfo.value.publishTask); - let res; - if (leaseApplyInfo.value.publishTask === null || leaseApplyInfo.value.publishTask == "") { - console.log("Condition: publishTask is null or empty string"); - // 如果 publishTask 为空,则只传递两个参数 - console.log("yyyyyyyyyyyyyyyyyyyy"); - const { data } = await getOutboundDetailsAPI( - leaseApplyInfo.value.parentId, - keyWord.value - ); - res = data; - console.log('🚀 ~ getOutboundDetailsData ~ res:', res); - } else { - console.log("Condition: publishTask is not null and not empty string"); - // 如果 publishTask 不为空,则传递三个参数 - const { data } = await getOutboundDetailsAPITwo( - leaseApplyInfo.value.parentId, - keyWord.value, - leaseApplyInfo.value.publishTask - ); - res = data; - console.log("xxxxxxxxxxx", res); + try { + uni.showLoading({ + title: '加载中...', + mask: true + }) + let res; + if (leaseApplyInfo.value.publishTask === null || leaseApplyInfo.value.publishTask == "") { + console.log("Condition: publishTask is null or empty string"); + // 如果 publishTask 为空,则只传递两个参数 + console.log("yyyyyyyyyyyyyyyyyyyy"); + const { data } = await getOutboundDetailsAPI( + leaseApplyInfo.value.parentId, + keyWord.value + ); + res = data; + console.log('🚀 ~ getOutboundDetailsData ~ res:', res); + } else { + console.log("Condition: publishTask is not null and not empty string"); + // 如果 publishTask 不为空,则传递三个参数 + const { data } = await getOutboundDetailsAPITwo( + leaseApplyInfo.value.parentId, + keyWord.value, + leaseApplyInfo.value.publishTask + ); + res = data; + console.log("xxxxxxxxxxx", res); + } + + detailsList.value = res.leaseApplyDetailsList; + leaseApplyInfo.value.taskId = res.leaseApplyInfo.taskId; + leaseApplyInfo.value.typeId = res.leaseApplyInfo.typeId; + leaseApplyInfo.value.leaseUnitId = res.leaseApplyInfo.leaseUnitId; + leaseApplyInfo.value.leaseUnit = res.leaseApplyInfo.leaseUnit; + leaseApplyInfo.value.leaseProjectId = res.leaseApplyInfo.leaseProjectId; + leaseApplyInfo.value.leaseProject = res.leaseApplyInfo.leaseProject; + taskStatus.value = res.leaseApplyInfo.taskStatus; + if(taskStatus.value==3){ + options.value = [ + { text: '出库',style: {backgroundColor: '#84c649',color: '#fff',fontSize: '28rpx'} }, + // { text: '退回',style: {backgroundColor: '#ed6042',color: '#fff',fontSize: '28rpx'} }, + { text: '查看',style: {backgroundColor: '#3784fb',color: '#fff',fontSize: '28rpx'} } + ]; + options2.value = [ + // { text: '退回',style: {backgroundColor: '#ed6042',color: '#fff',fontSize: '28rpx'}}, + { text: '查看',style: {backgroundColor: '#3784fb',color: '#fff',fontSize: '28rpx'}} + ] + }else if(taskStatus.value==4){ + options.value = [ + { text: '出库',style: {backgroundColor: '#84c649',color: '#fff',fontSize: '28rpx'} }, + { text: '查看',style: {backgroundColor: '#3784fb',color: '#fff',fontSize: '28rpx'} } + ]; + options2.value = [ + { text: '查看',style: {backgroundColor: '#3784fb',color: '#fff',fontSize: '28rpx'}} + ] + } + } catch (error) { + console.log('🚀 ~ getOutboundDetailsData ~ error:', error) + } finally { + uni.hideLoading() } - - detailsList.value = res.leaseApplyDetailsList; - leaseApplyInfo.value.taskId = res.leaseApplyInfo.taskId; - leaseApplyInfo.value.typeId = res.leaseApplyInfo.typeId; - leaseApplyInfo.value.leaseUnitId = res.leaseApplyInfo.leaseUnitId; - leaseApplyInfo.value.leaseUnit = res.leaseApplyInfo.leaseUnit; - leaseApplyInfo.value.leaseProjectId = res.leaseApplyInfo.leaseProjectId; - leaseApplyInfo.value.leaseProject = res.leaseApplyInfo.leaseProject; - taskStatus.value = res.leaseApplyInfo.taskStatus; - if(taskStatus.value==3){ - options.value = [ - { text: '出库',style: {backgroundColor: '#84c649',color: '#fff',fontSize: '28rpx'} }, - // { text: '退回',style: {backgroundColor: '#ed6042',color: '#fff',fontSize: '28rpx'} }, - { text: '查看',style: {backgroundColor: '#3784fb',color: '#fff',fontSize: '28rpx'} } - ]; - options2.value = [ - // { text: '退回',style: {backgroundColor: '#ed6042',color: '#fff',fontSize: '28rpx'}}, - { text: '查看',style: {backgroundColor: '#3784fb',color: '#fff',fontSize: '28rpx'}} - ] - }else if(taskStatus.value==4){ - options.value = [ - { text: '出库',style: {backgroundColor: '#84c649',color: '#fff',fontSize: '28rpx'} }, - { text: '查看',style: {backgroundColor: '#3784fb',color: '#fff',fontSize: '28rpx'} } - ]; - options2.value = [ - { text: '查看',style: {backgroundColor: '#3784fb',color: '#fff',fontSize: '28rpx'}} - ] - } - } // 数量退回 diff --git a/src/pages/repair/testExamine/details.vue b/src/pages/repair/testExamine/details.vue index b0a6909..5a6c690 100644 --- a/src/pages/repair/testExamine/details.vue +++ b/src/pages/repair/testExamine/details.vue @@ -89,49 +89,41 @@ - {{ index + 1 }} 规格型号: {{ item.specificationType }} - {{ index + 1 }} 单位: {{ item.unitName }} - {{ index + 1 }} - 退料数量: - - {{ item.repairNum }} - + 退料:{{ item.repairNum }} + 已修:{{ item.repairedNum }} + 报废:{{ item.scrapNum }} - - {{ index + 1 }} + - {{ index + 1 }} 设备编码: {{ item.maCode }} - {{ index + 1 }} 管理模式: { .table-list-item { background-color: #fff; border-radius: 20rpx; - padding: 24rpx; + padding: 6rpx 24rpx; margin-bottom: 24rpx; box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06); @@ -502,4 +494,7 @@ onUnmounted(() => { color: #8c8c8c; padding: 24rpx 0; } +.page-container .scroll-container .table-list-item .uni-row { + padding: 3px 0 !important; +} From 04816e1fd0c9e0c42b6c03fbd9465ea0bb9d4696 Mon Sep 17 00:00:00 2001 From: hayu <1604366271@qq.com> Date: Wed, 30 Jul 2025 14:35:01 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages.json | 11 + src/pages/devicesSearch/camera.vue | 646 +++++++++++++++++++++ src/pages/devicesSearch/ocrSearch.nvue | 751 ++++++++++--------------- src/services/utils/imageUtils.js | 197 +++++++ 4 files changed, 1143 insertions(+), 462 deletions(-) create mode 100644 src/pages/devicesSearch/camera.vue create mode 100644 src/services/utils/imageUtils.js diff --git a/src/pages.json b/src/pages.json index 12e6a5d..05d2808 100644 --- a/src/pages.json +++ b/src/pages.json @@ -580,6 +580,17 @@ "navigationBarTitleText": "OCR查询" } }, + { + "path": "pages/devicesSearch/camera", + "style": { + "navigationStyle": "custom", + "navigationBarTitleText": "相机识别", + "app-plus": { + "orientation": ["portrait-primary"], + "background": "#000000" + } + } + }, { "path": "pages/devicesSearch/codeSearch", "style": { diff --git a/src/pages/devicesSearch/camera.vue b/src/pages/devicesSearch/camera.vue new file mode 100644 index 0000000..8c2f834 --- /dev/null +++ b/src/pages/devicesSearch/camera.vue @@ -0,0 +1,646 @@ + + + + + diff --git a/src/pages/devicesSearch/ocrSearch.nvue b/src/pages/devicesSearch/ocrSearch.nvue index 8c4b80c..853af9f 100644 --- a/src/pages/devicesSearch/ocrSearch.nvue +++ b/src/pages/devicesSearch/ocrSearch.nvue @@ -1,491 +1,318 @@ diff --git a/src/services/utils/imageUtils.js b/src/services/utils/imageUtils.js new file mode 100644 index 0000000..5d71078 --- /dev/null +++ b/src/services/utils/imageUtils.js @@ -0,0 +1,197 @@ +// 图片处理工具类 +class ImageUtils { + /** + * 将图片转换为Base64字符串(相当于Android的bitmapToString) + * @param {string} imagePath 图片路径 + * @param {number} quality 压缩质量 0-100 + * @returns {Promise} Base64字符串 + */ + static async imageToBase64(imagePath, quality = 50) { + try { + // 如果已经是base64格式,直接返回数据部分 + if (imagePath.startsWith("data:image/")) { + return imagePath.split(",")[1] + } + + // 如果是纯base64字符串,直接返回 + if (!imagePath.includes("/") && !imagePath.includes("\\")) { + return imagePath + } + + // 压缩图片 + const compressResult = await new Promise((resolve, reject) => { + window.uni.compressImage({ + src: imagePath, + quality: quality, + success: resolve, + fail: reject, + }) + }) + + // 读取压缩后的文件并转换为base64 + const fileManager = window.uni.getFileSystemManager() + const base64Data = await new Promise((resolve, reject) => { + fileManager.readFile({ + filePath: compressResult.tempFilePath, + encoding: "base64", + success: (res) => resolve(res.data), + fail: reject, + }) + }) + + return base64Data + } catch (error) { + console.error("Image to base64 conversion failed:", error) + throw error + } + } + + /** + * 获取缩放后的图片(相当于Android的getSmallBitmap) + * @param {string} imagePath 图片路径 + * @param {number} maxWidth 最大宽度 + * @param {number} maxHeight 最大高度 + * @returns {Promise} 处理后的图片路径 + */ + static async getSmallImage(imagePath, maxWidth = 1024, maxHeight = 1024) { + try { + return await this.resizeImageWithCanvas(imagePath, maxWidth, maxHeight) + } catch (error) { + console.error("Get small image failed:", error) + // 如果canvas方法失败,尝试使用压缩API + return await this.fallbackCompress(imagePath, maxWidth, maxHeight) + } + } + + /** + * 使用Canvas调整图片尺寸 + * @param {string} imagePath 图片路径 + * @param {number} maxWidth 最大宽度 + * @param {number} maxHeight 最大高度 + * @returns {Promise} 处理后的图片路径 + */ + static async resizeImageWithCanvas(imagePath, maxWidth, maxHeight) { + return new Promise((resolve, reject) => { + // 获取图片信息 + window.uni.getImageInfo({ + src: imagePath, + success: (imageInfo) => { + const { width, height } = imageInfo + + // 计算缩放比例 + const scale = this.calculateScale(width, height, maxWidth, maxHeight) + const newWidth = Math.floor(width * scale) + const newHeight = Math.floor(height * scale) + + // 如果不需要缩放,直接返回原图 + if (scale >= 1) { + resolve(imagePath) + return + } + + // 创建canvas上下文 + const canvasId = "imageProcessCanvas_" + Date.now() + const ctx = window.uni.createCanvasContext(canvasId) + + // 绘制缩放后的图片 + ctx.drawImage(imagePath, 0, 0, newWidth, newHeight) + ctx.draw(false, () => { + // 导出canvas为临时文件 + window.uni.canvasToTempFilePath({ + canvasId: canvasId, + fileType: "jpg", + quality: 0.8, + success: (res) => { + resolve(res.tempFilePath) + }, + fail: reject, + }) + }) + }, + fail: reject, + }) + }) + } + + /** + * 备用压缩方法 + * @param {string} imagePath 图片路径 + * @param {number} maxWidth 最大宽度 + * @param {number} maxHeight 最大高度 + * @returns {Promise} 处理后的图片路径 + */ + static async fallbackCompress(imagePath, maxWidth, maxHeight) { + return new Promise((resolve, reject) => { + window.uni.compressImage({ + src: imagePath, + quality: 80, + compressedWidth: maxWidth, + compressedHeight: maxHeight, + success: (res) => resolve(res.tempFilePath), + fail: reject, + }) + }) + } + + /** + * 计算缩放比例(相当于Android的calculateInSampleSize) + * @param {number} originalWidth 原始宽度 + * @param {number} originalHeight 原始高度 + * @param {number} maxWidth 最大宽度 + * @param {number} maxHeight 最大高度 + * @returns {number} 缩放比例 + */ + static calculateScale(originalWidth, originalHeight, maxWidth, maxHeight) { + if (originalWidth <= maxWidth && originalHeight <= maxHeight) { + return 1 // 不需要缩放 + } + + const widthScale = maxWidth / originalWidth + const heightScale = maxHeight / originalHeight + + // 选择较小的缩放比例,确保图片完全适应限制尺寸 + return Math.min(widthScale, heightScale) + } + + /** + * 批量处理图片 + * @param {string} imagePath 图片路径 + * @param {object} options 处理选项 + * @returns {Promise} 处理后的Base64字符串 + */ + static async processImage(imagePath, options = {}) { + const { maxWidth = 1024, maxHeight = 1024, quality = 50, outputFormat = "base64" } = options + + try { + // 1. 先缩放图片 + const resizedImagePath = await this.getSmallImage(imagePath, maxWidth, maxHeight) + + // 2. 根据输出格式返回结果 + if (outputFormat === "base64") { + return await this.imageToBase64(resizedImagePath, quality) + } else { + return resizedImagePath + } + } catch (error) { + console.error("Process image failed:", error) + throw error + } + } + + /** + * 获取图片尺寸信息 + * @param {string} imagePath 图片路径 + * @returns {Promise} 图片信息 + */ + static async getImageInfo(imagePath) { + return new Promise((resolve, reject) => { + window.uni.getImageInfo({ + src: imagePath, + success: resolve, + fail: reject, + }) + }) + } +} + +export default ImageUtils