ocr
This commit is contained in:
parent
71c8111c55
commit
d23a3d4f92
|
|
@ -580,6 +580,30 @@
|
|||
"navigationBarTitleText": "OCR查询"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/devicesSearch/ocrSearch2",
|
||||
"style": {
|
||||
"navigationBarTitleText": "OCR查询2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/devicesSearch/ocrSearch3",
|
||||
"style": {
|
||||
"navigationBarTitleText": "OCR查询3"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/devicesSearch/ocrSearch4",
|
||||
"style": {
|
||||
"navigationBarTitleText": "OCR查询4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/devicesSearch/ocrSearch5",
|
||||
"style": {
|
||||
"navigationBarTitleText": "OCR查询5"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/devicesSearch/camera",
|
||||
"style": {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,983 @@
|
|||
<template>
|
||||
<view class="page-container">
|
||||
<!-- 相机预览页面 -->
|
||||
<view v-if="showCamera" class="camera-container">
|
||||
<!-- 底部控制区 -->
|
||||
<view class="bottom-controls">
|
||||
<view class="control-btn" @click="closeCamera">
|
||||
<text class="control-icon">✕</text>
|
||||
</view>
|
||||
<view class="photo-btn" @click="takePicture" :class="{ 'taking': isTaking, 'disabled': isFocusing }">
|
||||
<view class="photo-btn-inner"></view>
|
||||
</view>
|
||||
<view class="control-btn" @click="openGallery">
|
||||
<text class="control-icon">📷</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 加载提示 -->
|
||||
<view v-if="isProcessing" class="loading-overlay">
|
||||
<view class="loading-content">
|
||||
<view class="loading-spinner"></view>
|
||||
<text class="loading-text">正在识别中...</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 隐藏的canvas用于图片处理 -->
|
||||
<canvas
|
||||
canvas-id="imageCanvas"
|
||||
style="position: fixed; top: -9999px; left: -9999px; width: 1px; height: 1px;"
|
||||
></canvas>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ImageUtils from "../../services/utils/imageUtils";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
showCamera: false,
|
||||
isTaking: false,
|
||||
isProcessing: false,
|
||||
cameraStarted: false,
|
||||
queryParams: {},
|
||||
queryCodeParams: {
|
||||
maCode: "",
|
||||
maId: ""
|
||||
},
|
||||
codeData: {},
|
||||
optionList: [],
|
||||
cameraReady: false,
|
||||
deviceReadyTimeout: null,
|
||||
pluginCheckRetries: 0,
|
||||
maxRetries: 10,
|
||||
// 聚焦相关状态
|
||||
isFocusing: false,
|
||||
focusSuccess: false,
|
||||
showFocusIndicator: false,
|
||||
focusIndicatorStyle: {},
|
||||
autoFocusEnabled: true,
|
||||
focusTimeout: null,
|
||||
// 设备信息
|
||||
systemInfo: null
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
this.initializeCordova();
|
||||
// 获取设备信息用于相机配置
|
||||
this.getDeviceInfo();
|
||||
},
|
||||
onHide() {
|
||||
this.cleanup();
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.cleanup();
|
||||
},
|
||||
methods: {
|
||||
// 获取设备信息
|
||||
getDeviceInfo() {
|
||||
try {
|
||||
const systemInfo = uni.getSystemInfoSync();
|
||||
console.log('设备信息:', systemInfo);
|
||||
this.systemInfo = systemInfo;
|
||||
} catch (error) {
|
||||
console.error('获取设备信息失败:', error);
|
||||
}
|
||||
},
|
||||
|
||||
// 设置全屏模式(仅Android)
|
||||
setFullscreenMode(enable) {
|
||||
try {
|
||||
// #ifdef APP-PLUS
|
||||
if (this.systemInfo && this.systemInfo.platform === 'android') {
|
||||
if (enable) {
|
||||
// 隐藏状态栏和导航栏
|
||||
plus.navigator.setFullscreen(true);
|
||||
} else {
|
||||
// 恢复状态栏和导航栏
|
||||
plus.navigator.setFullscreen(false);
|
||||
}
|
||||
}
|
||||
// #endif
|
||||
} catch (error) {
|
||||
console.error('设置全屏模式失败:', error);
|
||||
}
|
||||
},
|
||||
|
||||
// 初始化Cordova - 改进版本
|
||||
initializeCordova() {
|
||||
console.log('开始初始化Cordova...');
|
||||
this.pluginCheckRetries = 0;
|
||||
// 清除之前的超时
|
||||
if (this.deviceReadyTimeout) {
|
||||
clearTimeout(this.deviceReadyTimeout);
|
||||
}
|
||||
// 如果Cordova已经准备好,直接检查插件
|
||||
if (this.isCordovaReady()) {
|
||||
this.onDeviceReady();
|
||||
return;
|
||||
}
|
||||
// 监听deviceready事件
|
||||
document.addEventListener('deviceready', this.onDeviceReady, false);
|
||||
// 设置超时,防止无限等待
|
||||
this.deviceReadyTimeout = setTimeout(() => {
|
||||
console.warn('Cordova初始化超时,尝试直接检查插件');
|
||||
this.checkCameraPlugin();
|
||||
}, 5000);
|
||||
},
|
||||
|
||||
// 检查Cordova是否准备好
|
||||
isCordovaReady() {
|
||||
return !!(window.cordova && (
|
||||
document.readyState === 'complete' ||
|
||||
window.cordova.platformId
|
||||
));
|
||||
},
|
||||
|
||||
// 设备准备就绪
|
||||
onDeviceReady() {
|
||||
console.log('Cordova设备准备就绪');
|
||||
// 清除超时
|
||||
if (this.deviceReadyTimeout) {
|
||||
clearTimeout(this.deviceReadyTimeout);
|
||||
this.deviceReadyTimeout = null;
|
||||
}
|
||||
// 移除事件监听器,避免重复调用
|
||||
document.removeEventListener('deviceready', this.onDeviceReady);
|
||||
// 检查相机插件
|
||||
this.checkCameraPlugin();
|
||||
},
|
||||
|
||||
// 检查相机插件 - 改进版本
|
||||
checkCameraPlugin() {
|
||||
console.log(`检查相机插件... (尝试 ${this.pluginCheckRetries + 1}/${this.maxRetries})`);
|
||||
// 按优先级检查插件可用性
|
||||
const pluginAvailable = this.getCameraPlugin();
|
||||
if (pluginAvailable) {
|
||||
console.log('相机插件可用:', pluginAvailable);
|
||||
this.cameraReady = true;
|
||||
return;
|
||||
}
|
||||
this.pluginCheckRetries++;
|
||||
if (this.pluginCheckRetries < this.maxRetries) {
|
||||
// 递增延迟重试
|
||||
const delay = Math.min(1000 * this.pluginCheckRetries, 5000);
|
||||
console.log(`插件未就绪,${delay}ms后重试...`);
|
||||
setTimeout(() => {
|
||||
this.checkCameraPlugin();
|
||||
}, delay);
|
||||
} else {
|
||||
console.error('相机插件检查失败,已达到最大重试次数');
|
||||
this.cameraReady = false;
|
||||
uni.showToast({
|
||||
title: '相机插件初始化失败',
|
||||
icon: 'none',
|
||||
duration: 3000
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// 获取相机插件引用 - 改进版本
|
||||
getCameraPlugin() {
|
||||
// 按照插件注册的实际路径检查
|
||||
const possiblePaths = [
|
||||
() => window.CameraPreview, // 全局注册的路径
|
||||
() => window.cordova?.plugins?.CameraPreview,
|
||||
() => window.plugins?.CameraPreview,
|
||||
() => cordova?.plugins?.CameraPreview
|
||||
];
|
||||
for (let getPlugin of possiblePaths) {
|
||||
try {
|
||||
const plugin = getPlugin();
|
||||
if (plugin && typeof plugin.startCamera === 'function') {
|
||||
console.log('找到相机插件:', plugin);
|
||||
return plugin;
|
||||
}
|
||||
} catch (e) {
|
||||
// 忽略访问错误,继续尝试下一个路径
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
// 打开相机 - 改进版本
|
||||
async openCamera() {
|
||||
console.log('尝试打开相机...');
|
||||
if (!this.cameraReady) {
|
||||
// 再次尝试检查插件
|
||||
this.checkCameraPlugin();
|
||||
if (!this.cameraReady) {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '相机插件未准备好,请确保应用已正确安装相机插件,或尝试重启应用',
|
||||
showCancel: false
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
try {
|
||||
// 显示相机界面
|
||||
this.showCamera = true;
|
||||
// 等待UI更新
|
||||
await this.$nextTick();
|
||||
// 初始化相机
|
||||
await this.initCamera();
|
||||
} catch (error) {
|
||||
console.error('打开相机失败:', error);
|
||||
this.showCamera = false;
|
||||
uni.showToast({
|
||||
title: error.message || '打开相机失败',
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// 初始化相机 - 改进版本,添加聚焦支持
|
||||
async initCamera() {
|
||||
return new Promise((resolve, reject) => {
|
||||
console.log('初始化相机预览...');
|
||||
const CameraPreview = this.getCameraPlugin();
|
||||
if (!CameraPreview) {
|
||||
reject(new Error('相机插件不可用'));
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取屏幕尺寸和状态栏高度
|
||||
const systemInfo = this.systemInfo || uni.getSystemInfoSync();
|
||||
const screenWidth = systemInfo.screenWidth;
|
||||
const screenHeight = systemInfo.screenHeight;
|
||||
const statusBarHeight = systemInfo.statusBarHeight || 0;
|
||||
|
||||
// 相机预览配置 - 始终使用全屏背景模式
|
||||
let cameraY = 0;
|
||||
let cameraHeight = screenHeight;
|
||||
let toBack = true; // 设置为背景层,让UI元素显示在上方
|
||||
|
||||
console.log('屏幕信息:', {
|
||||
platform: systemInfo.platform,
|
||||
screenWidth,
|
||||
screenHeight,
|
||||
statusBarHeight,
|
||||
cameraY,
|
||||
cameraHeight,
|
||||
toBack
|
||||
});
|
||||
|
||||
const options = {
|
||||
x: 0,
|
||||
y: cameraY,
|
||||
width: screenWidth,
|
||||
height: cameraHeight,
|
||||
camera: CameraPreview.CAMERA_DIRECTION?.BACK || 'back',
|
||||
tapPhoto: false,
|
||||
previewDrag: false,
|
||||
toBack: toBack, // 根据平台动态设置
|
||||
alpha: 1,
|
||||
tapFocus: true, // 启用点击聚焦
|
||||
disableExifHeaderStripping: false
|
||||
};
|
||||
|
||||
console.log('相机配置:', options);
|
||||
CameraPreview.startCamera(
|
||||
options,
|
||||
(result) => {
|
||||
console.log('相机启动成功:', result);
|
||||
this.cameraStarted = true;
|
||||
// 启动后进行一次自动聚焦
|
||||
this.performAutoFocus();
|
||||
resolve();
|
||||
},
|
||||
(error) => {
|
||||
console.error('相机启动失败:', error);
|
||||
this.cameraStarted = false;
|
||||
reject(new Error(`相机启动失败: ${error}`));
|
||||
}
|
||||
);
|
||||
});
|
||||
},
|
||||
|
||||
// 执行自动聚焦
|
||||
async performAutoFocus() {
|
||||
if (!this.cameraStarted || !this.autoFocusEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
const CameraPreview = this.getCameraPlugin();
|
||||
if (!CameraPreview || typeof CameraPreview.setFocus !== 'function') {
|
||||
console.log('相机插件不支持聚焦功能');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
this.isFocusing = true;
|
||||
this.focusSuccess = false;
|
||||
|
||||
// 清除之前的聚焦超时
|
||||
if (this.focusTimeout) {
|
||||
clearTimeout(this.focusTimeout);
|
||||
}
|
||||
|
||||
console.log('开始自动聚焦...');
|
||||
|
||||
await new Promise((resolve, reject)=> {
|
||||
// 设置聚焦超时
|
||||
this.focusTimeout = setTimeout(() => {
|
||||
console.log('聚焦超时');
|
||||
this.isFocusing = false;
|
||||
resolve();
|
||||
}, 3000);
|
||||
|
||||
CameraPreview.setFocus(
|
||||
(result) => {
|
||||
console.log('自动聚焦成功:', result);
|
||||
if (this.focusTimeout) {
|
||||
clearTimeout(this.focusTimeout);
|
||||
this.focusTimeout = null;
|
||||
}
|
||||
this.isFocusing = false;
|
||||
this.focusSuccess = true;
|
||||
// 显示聚焦成功状态一段时间
|
||||
setTimeout(() => {
|
||||
this.focusSuccess = false;
|
||||
}, 1000);
|
||||
resolve();
|
||||
},
|
||||
(error) => {
|
||||
console.error('自动聚焦失败:', error);
|
||||
if (this.focusTimeout) {
|
||||
clearTimeout(this.focusTimeout);
|
||||
this.focusTimeout = null;
|
||||
}
|
||||
this.isFocusing = false;
|
||||
resolve(); // 即使聚焦失败也继续
|
||||
}
|
||||
);
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('聚焦过程出错:', error);
|
||||
this.isFocusing = false;
|
||||
}
|
||||
},
|
||||
|
||||
// 处理点击聚焦
|
||||
async handleTapToFocus(event) {
|
||||
if (!this.cameraStarted || this.isFocusing) {
|
||||
return;
|
||||
}
|
||||
|
||||
const CameraPreview = this.getCameraPlugin();
|
||||
if (!CameraPreview || typeof CameraPreview.tapToFocus !== 'function') {
|
||||
console.log('相机插件不支持点击聚焦功能');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 获取点击位置
|
||||
const rect = event.currentTarget.getBoundingClientRect();
|
||||
const x = event.detail.x - rect.left;
|
||||
const y = event.detail.y - rect.top;
|
||||
|
||||
// 转换为相对坐标 (0-1)
|
||||
const relativeX = x / rect.width;
|
||||
const relativeY = y / rect.height;
|
||||
|
||||
console.log('点击聚焦位置:', { x: relativeX, y: relativeY });
|
||||
|
||||
// 显示聚焦指示器
|
||||
this.showFocusIndicator = true;
|
||||
this.focusIndicatorStyle = {
|
||||
left: `${x - 30}rpx`,
|
||||
top: `${y - 30}rpx`
|
||||
};
|
||||
|
||||
this.isFocusing = true;
|
||||
this.focusSuccess = false;
|
||||
|
||||
// 清除之前的聚焦超时
|
||||
if (this.focusTimeout) {
|
||||
clearTimeout(this.focusTimeout);
|
||||
}
|
||||
|
||||
await new Promise((resolve, reject)=> {
|
||||
// 设置聚焦超时
|
||||
this.focusTimeout = setTimeout(() => {
|
||||
console.log('点击聚焦超时');
|
||||
this.isFocusing = false;
|
||||
this.showFocusIndicator = false;
|
||||
resolve();
|
||||
}, 3000);
|
||||
|
||||
CameraPreview.tapToFocus(
|
||||
relativeX,
|
||||
relativeY,
|
||||
(result) => {
|
||||
console.log('点击聚焦成功:', result);
|
||||
if (this.focusTimeout) {
|
||||
clearTimeout(this.focusTimeout);
|
||||
this.focusTimeout = null;
|
||||
}
|
||||
this.isFocusing = false;
|
||||
this.focusSuccess = true;
|
||||
// 显示聚焦成功状态
|
||||
setTimeout(() => {
|
||||
this.focusSuccess = false;
|
||||
this.showFocusIndicator = false;
|
||||
}, 1000);
|
||||
resolve();
|
||||
},
|
||||
(error) => {
|
||||
console.error('点击聚焦失败:', error);
|
||||
if (this.focusTimeout) {
|
||||
clearTimeout(this.focusTimeout);
|
||||
this.focusTimeout = null;
|
||||
}
|
||||
this.isFocusing = false;
|
||||
this.showFocusIndicator = false;
|
||||
resolve(); // 即使聚焦失败也继续
|
||||
}
|
||||
);
|
||||
}
|
||||
)
|
||||
;
|
||||
} catch (error) {
|
||||
console.error('点击聚焦过程出错:', error);
|
||||
this.isFocusing = false;
|
||||
this.showFocusIndicator = false;
|
||||
}
|
||||
},
|
||||
|
||||
// 关闭相机
|
||||
async closeCamera() {
|
||||
console.log('关闭相机...');
|
||||
try {
|
||||
await this.stopCamera();
|
||||
} catch (error) {
|
||||
console.error('关闭相机出错:', error);
|
||||
} finally {
|
||||
this.showCamera = false;
|
||||
this.cameraStarted = false;
|
||||
this.resetFocusState();
|
||||
}
|
||||
},
|
||||
|
||||
// 重置聚焦状态
|
||||
resetFocusState() {
|
||||
this.isFocusing = false;
|
||||
this.focusSuccess = false;
|
||||
this.showFocusIndicator = false;
|
||||
if (this.focusTimeout) {
|
||||
clearTimeout(this.focusTimeout);
|
||||
this.focusTimeout = null;
|
||||
}
|
||||
},
|
||||
|
||||
// 停止相机
|
||||
async stopCamera() {
|
||||
if (!this.cameraStarted) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
const CameraPreview = this.getCameraPlugin();
|
||||
if (!CameraPreview) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
return new Promise((resolve) => {
|
||||
CameraPreview.stopCamera(
|
||||
() => {
|
||||
console.log('相机已停止');
|
||||
this.cameraStarted = false;
|
||||
resolve();
|
||||
},
|
||||
(error) => {
|
||||
console.error('停止相机失败:', error);
|
||||
this.cameraStarted = false;
|
||||
resolve(); // 即使失败也继续
|
||||
}
|
||||
);
|
||||
});
|
||||
},
|
||||
|
||||
// 拍照 - 添加聚焦逻辑
|
||||
async takePicture() {
|
||||
if (!this.cameraStarted || this.isTaking || this.isFocusing) {
|
||||
if (this.isFocusing) {
|
||||
uni.showToast({
|
||||
title: '正在聚焦,请稍候...',
|
||||
icon: 'none',
|
||||
duration: 1000
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('开始拍照流程...');
|
||||
this.isTaking = true;
|
||||
|
||||
try {
|
||||
const CameraPreview = this.getCameraPlugin();
|
||||
if (!CameraPreview) {
|
||||
throw new Error('相机插件不可用');
|
||||
}
|
||||
|
||||
// 拍照前先进行聚焦
|
||||
console.log('拍照前聚焦...');
|
||||
await this.performFocusBeforeCapture();
|
||||
|
||||
console.log('开始拍照...');
|
||||
const imageData = await new Promise((resolve, reject)=>
|
||||
{
|
||||
const options = {
|
||||
quality: 85,
|
||||
targetHeight: 1920,
|
||||
targetWidth: 1080
|
||||
};
|
||||
|
||||
CameraPreview.takePicture(
|
||||
options,
|
||||
(imageData) => {
|
||||
console.log('拍照成功');
|
||||
resolve(imageData);
|
||||
},
|
||||
(error) => {
|
||||
console.error('拍照失败:', error);
|
||||
reject(new Error(`拍照失败: ${error}`));
|
||||
}
|
||||
);
|
||||
}
|
||||
)
|
||||
;
|
||||
|
||||
await this.processImage(imageData);
|
||||
} catch (error) {
|
||||
console.error('拍照过程出错:', error);
|
||||
uni.showToast({
|
||||
title: error.message || '拍照失败',
|
||||
icon: 'none'
|
||||
});
|
||||
} finally {
|
||||
this.isTaking = false;
|
||||
}
|
||||
},
|
||||
|
||||
// 拍照前聚焦
|
||||
async performFocusBeforeCapture() {
|
||||
const CameraPreview = this.getCameraPlugin();
|
||||
if (!CameraPreview || typeof CameraPreview.setFocus !== 'function') {
|
||||
console.log('相机插件不支持聚焦,直接拍照');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
this.isFocusing = true;
|
||||
|
||||
console.log('拍照前执行聚焦...');
|
||||
|
||||
await new Promise((resolve, reject)=>
|
||||
{
|
||||
// 设置聚焦超时
|
||||
const focusTimeout = setTimeout(() => {
|
||||
console.log('拍照前聚焦超时,继续拍照');
|
||||
this.isFocusing = false;
|
||||
resolve();
|
||||
}, 2000); // 拍照前聚焦时间稍短
|
||||
|
||||
CameraPreview.setFocus(
|
||||
(result) => {
|
||||
console.log('拍照前聚焦成功:', result);
|
||||
clearTimeout(focusTimeout);
|
||||
this.isFocusing = false;
|
||||
// 聚焦成功后稍等一下再拍照,确保聚焦稳定
|
||||
setTimeout(resolve, 200);
|
||||
},
|
||||
(error) => {
|
||||
console.error('拍照前聚焦失败:', error);
|
||||
clearTimeout(focusTimeout);
|
||||
this.isFocusing = false;
|
||||
resolve(); // 即使聚焦失败也继续拍照
|
||||
}
|
||||
);
|
||||
}
|
||||
)
|
||||
;
|
||||
} catch (error) {
|
||||
console.error('拍照前聚焦过程出错:', error);
|
||||
this.isFocusing = false;
|
||||
}
|
||||
},
|
||||
|
||||
// 处理图片 - 使用ImageUtils
|
||||
async processImage(imageData) {
|
||||
this.isProcessing = true;
|
||||
try {
|
||||
console.log('开始处理图片...');
|
||||
// 使用ImageUtils处理图片
|
||||
const processedBase64 = await ImageUtils.processImage(imageData, {
|
||||
maxWidth: 1024,
|
||||
maxHeight: 1024,
|
||||
quality: 50,
|
||||
outputFormat: 'base64'
|
||||
});
|
||||
|
||||
console.log('图片处理完成,开始OCR识别...');
|
||||
const response = await new Promise((resolve, reject)=>
|
||||
{
|
||||
uni.request({
|
||||
url: '/material/app/ocr/getOcrCode',
|
||||
method: 'POST',
|
||||
data: {
|
||||
image: processedBase64,
|
||||
jiju_type: '',
|
||||
auth_lic: 'xIWDlaDVdijcBB4mjhGCPYk5Kvk8tHZJbUn+vW+ih15+MYx98e/PXyBmKL5gFcWMPznLgDA15QuSAnZQSLddwdy9HkZgtuQDEEZZ351Eyb1eiDUccUnyoSGIrNimbx5TooBNNPYqU4qJeFrPJXAqjBHzRrxoBxuR2CEGKQPgHC4='
|
||||
},
|
||||
timeout: 30000,
|
||||
success: resolve,
|
||||
fail: reject
|
||||
});
|
||||
}
|
||||
)
|
||||
;
|
||||
|
||||
if (response.data?.data?.result) {
|
||||
this.queryCodeParams.maCode = response.data.data.result;
|
||||
await this.closeCamera();
|
||||
this.getCode();
|
||||
uni.showToast({
|
||||
title: '识别成功',
|
||||
icon: 'success'
|
||||
});
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: '未识别到有效编码',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('图片处理或OCR识别失败:', error);
|
||||
uni.showToast({
|
||||
title: '识别失败,请重试',
|
||||
icon: 'none'
|
||||
});
|
||||
} finally {
|
||||
this.isProcessing = false;
|
||||
}
|
||||
},
|
||||
|
||||
// 打开相册
|
||||
openGallery() {
|
||||
uni.chooseImage({
|
||||
count: 1,
|
||||
sourceType: ['album'],
|
||||
success: (res) => {
|
||||
if (res.tempFilePaths && res.tempFilePaths.length > 0) {
|
||||
this.convertImageToBase64(res.tempFilePaths[0]);
|
||||
}
|
||||
},
|
||||
fail: (error) => {
|
||||
console.error('选择图片失败:', error);
|
||||
uni.showToast({
|
||||
title: '选择图片失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 将图片转换为base64 - 使用ImageUtils处理
|
||||
async convertImageToBase64(filePath) {
|
||||
this.isProcessing = true;
|
||||
try {
|
||||
console.log('开始处理相册图片...');
|
||||
// 使用ImageUtils处理相册图片
|
||||
const processedBase64 = await ImageUtils.processImage(filePath, {
|
||||
maxWidth: 1024,
|
||||
maxHeight: 1024,
|
||||
quality: 50,
|
||||
outputFormat: 'base64'
|
||||
});
|
||||
|
||||
console.log('相册图片处理完成,开始OCR识别...');
|
||||
const response = await new Promise((resolve, reject)=>
|
||||
{
|
||||
uni.request({
|
||||
url: '/material/app/ocr/getOcrCode',
|
||||
method: 'POST',
|
||||
data: {
|
||||
image: processedBase64,
|
||||
jiju_type: '',
|
||||
auth_lic: 'xIWDlaDVdijcBB4mjhGCPYk5Kvk8tHZJbUn+vW+ih15+MYx98e/PXyBmKL5gFcWMPznLgDA15QuSAnZQSLddwdy9HkZgtuQDEEZZ351Eyb1eiDUccUnyoSGIrNimbx5TooBNNPYqU4qJeFrPJXAqjBHzRrxoBxuR2CEGKQPgHC4='
|
||||
},
|
||||
timeout: 30000,
|
||||
success: resolve,
|
||||
fail: reject
|
||||
});
|
||||
}
|
||||
)
|
||||
;
|
||||
|
||||
if (response.data?.data?.result) {
|
||||
this.queryCodeParams.maCode = response.data.data.result;
|
||||
await this.closeCamera();
|
||||
this.getCode();
|
||||
uni.showToast({
|
||||
title: '识别成功',
|
||||
icon: 'success'
|
||||
});
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: '未识别到有效编码',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('相册图片处理或OCR识别失败:', error);
|
||||
uni.showToast({
|
||||
title: '识别失败,请重试',
|
||||
icon: 'none'
|
||||
});
|
||||
} finally {
|
||||
this.isProcessing = false;
|
||||
}
|
||||
},
|
||||
|
||||
// 编码检索
|
||||
async getCode() {
|
||||
if (!this.queryCodeParams.maCode.trim()) {
|
||||
uni.showToast({
|
||||
title: '请输入设备编码',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const response = await new Promise((resolve, reject)=>
|
||||
{
|
||||
uni.request({
|
||||
url: '/material/ma_machine/getHisByCode',
|
||||
method: 'GET',
|
||||
data: {maCode: this.queryCodeParams.maCode},
|
||||
success: resolve,
|
||||
fail: reject
|
||||
});
|
||||
}
|
||||
)
|
||||
;
|
||||
|
||||
if (response.data?.data && response.data.data.length > 0) {
|
||||
this.optionList = response.data.data.map(option => ({
|
||||
value: option.maId,
|
||||
text: option.maCode
|
||||
}));
|
||||
if (response.data.data.length === 1) {
|
||||
this.codeData = response.data.data[0];
|
||||
}
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: '未查询到该编号信息',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('查询失败:', error);
|
||||
uni.showToast({
|
||||
title: '查询失败,请重试',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// 标签改变
|
||||
async changeTag() {
|
||||
if (!this.queryCodeParams.maId) return;
|
||||
try {
|
||||
const response = await new Promise((resolve, reject)=>
|
||||
{
|
||||
uni.request({
|
||||
url: '/material/ma_machine/getHisByCode',
|
||||
method: 'GET',
|
||||
data: {maId: this.queryCodeParams.maId},
|
||||
success: resolve,
|
||||
fail: reject
|
||||
});
|
||||
}
|
||||
)
|
||||
;
|
||||
|
||||
if (response.data?.data && response.data.data.length > 0) {
|
||||
this.codeData = response.data.data[0];
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: '获取编号信息失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("获取编号信息失败", error);
|
||||
uni.showToast({
|
||||
title: '获取信息失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// 清理资源
|
||||
cleanup() {
|
||||
console.log('清理资源...');
|
||||
// 清除超时
|
||||
if (this.deviceReadyTimeout) {
|
||||
clearTimeout(this.deviceReadyTimeout);
|
||||
this.deviceReadyTimeout = null;
|
||||
}
|
||||
if (this.focusTimeout) {
|
||||
clearTimeout(this.focusTimeout);
|
||||
this.focusTimeout = null;
|
||||
}
|
||||
// 移除事件监听
|
||||
document.removeEventListener('deviceready', this.onDeviceReady);
|
||||
// 停止相机
|
||||
if (this.cameraStarted) {
|
||||
this.stopCamera().catch(console.error);
|
||||
}
|
||||
// 重置聚焦状态
|
||||
this.resetFocusState();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.page-container {
|
||||
display: flex;
|
||||
height: auto;
|
||||
flex-direction: column;
|
||||
background-color: #f7f8fa;
|
||||
padding: 24rpx;
|
||||
}
|
||||
|
||||
/* 相机预览样式 */
|
||||
.camera-container {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background-color: #000000;
|
||||
z-index: 1000; /* 降低层级,让UI元素显示在上方 */
|
||||
}
|
||||
|
||||
.bottom-controls {
|
||||
position: absolute;
|
||||
bottom: 100rpx;
|
||||
left: 0;
|
||||
right: 0;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 100rpx;
|
||||
z-index: 10001; /* 提高底部控制按钮层级 */
|
||||
}
|
||||
|
||||
.control-btn {
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border: 2rpx solid rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
.control-icon {
|
||||
color: #fff;
|
||||
font-size: 40rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.photo-btn {
|
||||
width: 140rpx;
|
||||
height: 140rpx;
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border: 6rpx solid rgba(255, 255, 255, 0.5);
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.photo-btn.taking {
|
||||
transform: scale(0.9);
|
||||
background-color: rgba(75, 142, 255, 0.8);
|
||||
}
|
||||
|
||||
.photo-btn.disabled {
|
||||
opacity: 0.5;
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.photo-btn-inner {
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
background-color: rgba(255, 255, 255, 0.9);
|
||||
border-radius: 50%;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.photo-btn.taking .photo-btn-inner {
|
||||
background-color: #4b8eff;
|
||||
}
|
||||
|
||||
.photo-btn.disabled .photo-btn-inner {
|
||||
background-color: #ccc;
|
||||
}
|
||||
|
||||
.loading-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.7);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 10003; /* 加载层级最高 */
|
||||
}
|
||||
|
||||
.loading-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
background-color: rgba(255, 255, 255, 0.9);
|
||||
padding: 60rpx;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
|
||||
.loading-spinner {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
border: 6rpx solid #f3f3f3;
|
||||
border-top: 6rpx solid #4b8eff;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.loading-text {
|
||||
color: #333;
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -117,6 +117,26 @@ const newInfoList = ref([
|
|||
url: '/pages/devicesSearch/ocrSearch',
|
||||
iconSrc: '../../static/searchModel/qrCode.png',
|
||||
},
|
||||
{
|
||||
title: 'OCR查询2',
|
||||
url: '/pages/devicesSearch/ocrSearch2',
|
||||
iconSrc: '../../static/searchModel/qrCode.png',
|
||||
},
|
||||
{
|
||||
title: 'OCR查询3',
|
||||
url: '/pages/devicesSearch/ocrSearch3',
|
||||
iconSrc: '../../static/searchModel/qrCode.png',
|
||||
},
|
||||
{
|
||||
title: 'OCR查询4',
|
||||
url: '/pages/devicesSearch/ocrSearch4',
|
||||
iconSrc: '../../static/searchModel/qrCode.png',
|
||||
},
|
||||
{
|
||||
title: 'OCR查询5',
|
||||
url: '/pages/devicesSearch/ocrSearch5',
|
||||
iconSrc: '../../static/searchModel/qrCode.png',
|
||||
},
|
||||
{
|
||||
title: '设备编码查询',
|
||||
url: '/pages/devicesSearch/codeSearch',
|
||||
|
|
|
|||
|
|
@ -228,37 +228,44 @@ class ImageUtils {
|
|||
* @param {object} options 处理选项
|
||||
* @returns {Promise<string>} 处理后的Base64字符串
|
||||
*/
|
||||
static async processImage(imagePath, options = {}) {
|
||||
const { maxWidth = 1024, maxHeight = 1024, quality = 50, outputFormat = "base64" } = options
|
||||
static async processImage(imagePaths, options = {}) {
|
||||
const { maxWidth = 1024, maxHeight = 1024, quality = 50, outputFormat = "base64" } = options;
|
||||
|
||||
// 存储处理后的图片数据
|
||||
let processedImages = [];
|
||||
|
||||
try {
|
||||
console.log("开始处理图片:", imagePath)
|
||||
console.log("开始处理图片数组:", imagePaths);
|
||||
|
||||
// 如果已经是 base64 格式,直接处理
|
||||
if (imagePath.startsWith("data:image/")) {
|
||||
if (outputFormat === "base64") {
|
||||
return imagePath.split(",")[1]
|
||||
for (let imagePath of imagePaths) {
|
||||
if (imagePath.startsWith("data:image/")) {
|
||||
if (outputFormat === "base64") {
|
||||
// 如果需要的是 base64 格式,并且输入已经是 base64,则直接添加到结果列表中(去掉前缀)
|
||||
processedImages.push(imagePath.split(",")[1]);
|
||||
} else {
|
||||
// 如果需要其他格式,则可能需要转换
|
||||
processedImages.push(imagePath);
|
||||
}
|
||||
} else {
|
||||
return imagePath
|
||||
// 处理非 base64 图片路径
|
||||
const resizedImagePath = await this.getSmallImage(imagePath, maxWidth, maxHeight);
|
||||
console.log("图片缩放完成:", resizedImagePath);
|
||||
|
||||
if (outputFormat === "base64") {
|
||||
const base64Result = await this.imageToBase64(resizedImagePath, quality);
|
||||
console.log("图片转换为base64完成");
|
||||
processedImages.push(base64Result);
|
||||
} else {
|
||||
processedImages.push(resizedImagePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 1. 先缩放图片
|
||||
const resizedImagePath = await this.getSmallImage(imagePath, maxWidth, maxHeight)
|
||||
console.log("图片缩放完成:", resizedImagePath)
|
||||
|
||||
// 2. 根据输出格式返回结果
|
||||
if (outputFormat === "base64") {
|
||||
const base64Result = await this.imageToBase64(resizedImagePath, quality)
|
||||
console.log("图片转换为base64完成")
|
||||
return base64Result
|
||||
} else {
|
||||
return resizedImagePath
|
||||
}
|
||||
return processedImages;
|
||||
} catch (error) {
|
||||
console.error("Process image failed:", error)
|
||||
// 如果所有方法都失败,尝试简单的压缩
|
||||
return await this.simpleProcess(imagePath, options)
|
||||
console.error("Process image failed:", error);
|
||||
// 这里可以决定如何处理错误,比如返回部分成功的结果或者尝试简单的压缩等
|
||||
return await Promise.reject(error); // 抛出错误以便上层调用者处理
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue