this.ws.onopen = () => {
this.m_isConnectWS = true;
this.sendMsg({ function: 'InitDevs' });
this.$emit('ws-connected'); // 新增事件
setTimeout(() => {
this.sendMsg({
function: 'GetDeviceCount'
});
}, 500); // 初始化默认设备 setTimeout(() => { if (this.devices.length > 0) { this.GetResolution(); } }, 1000); };
this.ws.onerror = (error) => {
this.$message.error('高拍仪服务未启动');
this.m_isConnectWS = false;
};
this.ws.onmessage = (evt) => {
const data = JSON.parse(evt.data);
this.onResiveServerMsg(data);
};
this.ws.onclose = () => {
this.m_isConnectWS = false;
};
},
disconnect() {
if (this.ws) {
this.ws.close();
}
},
sendMsg(body) {
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
this.ws.send(JSON.stringify(body));
}
},
onResiveServerMsg(data) {
const name = data.function;
if (data.ret >= 0) {
if (name === 'GetDeviceCount') {
this.devices = Array.from({length: data.value}, (_, i) => ({
id: i,
name: `摄像头${i+1}`
}));
} else if (name === 'GetResolution') {
this.resolutions = data.value.split("|");
} else if (name === 'OpenCamera' || name === 'ImageCallback') {
const videoimg = document.getElementById("chrome_img");
videoimg.src = "data:image/jpeg;base64," + data.value;
} else if (name === 'ScanImage' || name === 'SelectImage') {
if (data.value) {
this.addImg(data.value);
}
}else if(name === 'ScanPDF'){
if (data.value) {
// 处理返回的PDF数据,可能是base64或URL
this.handlePDFResponse(data.value);
} else {
this.$message.error('PDF合成失败');
}
}else if (name === 'SetVideoProcAmp'|| name === 'GetVideoProcAmp') {
console.log(data);
if (data.prop === this.videoProcProps.brightness) {
if (name === 'GetVideoProcAmp') {
this.brightness = data.value;
this.isAuto = data.isAuto;
}
this.$emit('video-proc-result', data.ret);
}
} } }, handlePDFResponse(pdfData) { try { const pdfBlob = this.base64ToBlob(pdfData); const pdfUrl = URL.createObjectURL(pdfBlob);
// 创建下载链接
const a = document.createElement('a');
a.href = pdfUrl;
a.download = '合成文档.pdf';
document.body.appendChild(a);
a.click();
// 清理
setTimeout(() => {
document.body.removeChild(a);
URL.revokeObjectURL(pdfUrl);
}, 100);
this.$message.success('PDF合成成功,已开始下载');
} catch (error) { console.error('PDF处理错误:', error); this.$message.error('PDF处理失败: ' + error.message); } finally { this.pdfLoading = false; } }, // 点击按钮获取分辨率个数 GetResolutionCount(){ sendMsg({'function':'GetResolutionCount','device':this.deviceIndex}) }, // 点击按钮获取摄像头个数 GetDeviceCount(){ sendMsg({'function':'GetDeviceCount'}) }, initSelectionBox() { this.selectionBox = document.getElementById("selection-box"); const chromeDiv = document.getElementById("chrome_img").parentElement;
chromeDiv.onmousedown = (e) => {
this.startSelection(e);
};
chromeDiv.onmousemove = (e) => {
this.updateSelection(e);
};
chromeDiv.onmouseup = (e) => {
this.endSelection(e);
};
},
startSelection(e) {
this.isSelecting = true;
const rect = e.target.getBoundingClientRect();
this.startX = e.clientX - rect.left;
this.startY = e.clientY - rect.top;
this.selectionBox.style.display = "block";
},
updateSelection(e) {
if (!this.isSelecting) return;
const rect = e.target.getBoundingClientRect();
const currentX = e.clientX - rect.left;
const currentY = e.clientY - rect.top;
const left = Math.min(this.startX, currentX);
const top = Math.min(this.startY, currentY);
const width = Math.abs(currentX - this.startX);
const height = Math.abs(currentY - this.startY);
this.selectionBox.style.left = `${left}px`;
this.selectionBox.style.top = `${top}px`;
this.selectionBox.style.width = `${width}px`;
this.selectionBox.style.height = `${height}px`;
},
endSelection(e) {
if (!this.isSelecting) return;
this.isSelecting = false;
this.selectionBox.style.display = "none";
const rect = e.target.getBoundingClientRect();
const endX = e.clientX - rect.left;
const endY = e.clientY - rect.top;
const left = Math.min(this.startX, endX);
const right = Math.max(this.startX, endX);
const top = Math.min(this.startY, endY);
const bottom = Math.max(this.startY, endY);
if (left === right || top === bottom) {
this.$message.warning('框选范围过小,请重新框选');
return;
}
const imgDom = document.getElementById("chrome_img");
this.sendMsg({
function: 'SelectImage',
imagepath: '',
left: Math.round(left),
top: Math.round(top),
right: Math.round(right),
bottom: Math.round(bottom),
viewWidth: imgDom.clientWidth,
viewHeight: imgDom.clientHeight
});
},
addImg(imgData) {
const id = Date.now().toString(36) + Math.random().toString(36).substr(2);
this.imgList.push({
id,
data: imgData,
checked: false
});
},
deleteImg(index) {
this.imgList.splice(index, 1);
},
handleCheckChange(id) {
const index = this.imgIds.indexOf(id);
if (index === -1) {
this.imgIds.push(id);
} else {
this.imgIds.splice(index, 1);
}
},
base64ToBlob(base64) {
// 处理可能存在的 data URL 前缀 let base64Data = base64; const matches = base64.match(/^data:(.+?);base64,(.*)$/);
if (matches && matches.length === 3) { base64Data = matches[2]; // 提取纯 base64 部分 }
try { const raw = window.atob(base64Data); const uintArray = new Uint8Array(raw.length);
for (let i = 0; i < raw.length; i++) {
uintArray[i] = raw.charCodeAt(i);
}
// 如果有匹配的 MIME 类型则使用,否则默认使用 application/pdf
const contentType = matches ? matches[1] : 'application/pdf';
return new Blob([uintArray], { type: contentType });
} catch (e) { console.error('Base64 解码失败:', e); throw new Error('无效的 base64 数据'); } }, submitImages() { const images = this.imgList.map(img => img.url); console.log(images);
this.$emit('submitUploadImg', { uploadImg:images });
this.imgList = [];
this.imgIds = [];
},
// 设备控制方法
selectDevice() {
const select = document.getElementById("device");
this.deviceIndex = select.selectedIndex;
this.OpenCamera();
this.GetResolution();
},
selectResolution() {
const select = document.getElementById("resolution");
this.resolutionIndex = select.selectedIndex;
this.OpenCamera();
},
handleRotationChange(val) {
this.sendMsg({ function: 'SetRotation', value: val });
},
// 设备功能方法
InitDevs() {
this.sendMsg({ function: 'InitDevs' });
},
OpenCamera() {
this.sendMsg({
function: 'OpenCamera',
device: this.deviceIndex,
resolution: this.resolutionIndex,
datacallback: true
});
},
CloseCamera() {
this.sendMsg({ function: 'CloseCamera', device: this.deviceIndex });
var videoimg = document.getElementById("chrome_img"); // 摄像头
videoimg.src = ""
},
ScanImage() {
// 1. 设置加载状态
this.scanLoading = true;
// 2. 发送拍照指令
this.sendMsg({
function: 'ScanImage',
imagepath: '' // 空路径表示返回base64
});
// 3. 设置超时监控
const timeout = 5000; // 5秒超时
const startTime = Date.now();
const checkInterval = setInterval(() => {
// 超时处理
if (Date.now() - startTime > timeout) {
clearInterval(checkInterval);
this.scanLoading = false;
this.$message.error('拍照超时,请重试');
return;
}
// 检查最后一张图片是否已生成(假设最新图片在数组末尾)
if (this.imgList.length > 0) {
const latestImg = this.imgList[this.imgList.length - 1];
if (latestImg && latestImg.data) {
clearInterval(checkInterval);
this.uploadImage(latestImg.data); // 上传图片
}
}
}, 100);
}, // 单独的上传方法 uploadImage(base64Data) { console.log(this.base64Header,base64Data);
// 2. 显示上传中状态
this.$message.info('正在上传图片...');
// 3. 调用上传API
cloudUploadBase64Img({ base64:base64Data })
.then(res => {
if (res.code == "0") {
this.$message.success('上传成功');
// 可以在这里更新图片状态或处理返回的URL
this.updateImageWithUrl(res.data.url);
} else {
this.$message.error(res.data.msg || '上传失败');
}
})
.catch(err => {
console.error('上传错误:', err);
// this.$message.error('上传服务异常');
})
.finally(() => {
this.scanLoading = false;
});
}, // 更新图片信息 updateImageWithUrl(url) { if (this.imgList.length > 0) { const latestIndex = this.imgList.length - 1; this.$set(this.imgList, latestIndex, { ...this.imgList[latestIndex], url: url // 添加服务器返回的URL }); } },
GetResolution() {
this.sendMsg({ function: 'GetResolution', device: this.deviceIndex });
},
SetDeskew() {
this.isdeskew = this.isdeskew === 0 ? 1 : 0;
this.sendMsg({ function: 'SetDeskew', isdeskew: this.isdeskew });
},
SelectImage() {
this.$message.info('请在预览区域拖动鼠标进行框选');
},
SynthesizePDF() {
if (this.imgIds.length === 0) { this.$message.warning('请先选择要合成的图片'); return; }
this.pdfLoading = true;
// 获取选中的图片数据 const imagedata = this.imgList .filter(img => this.imgIds.includes(img.id)) .map(img => img.data);
this.sendMsg({ function: 'ScanPDF', imagedata: imagedata, pdfpath: '' });
// 设置超时监控 setTimeout(() => { if (this.pdfLoading) { this.pdfLoading = false; this.$message.error('PDF合成超时,请重试'); } }, 10000); }, // 设置视频处理属性 setVideoProc(prop, value, isAuto = false) { return new Promise((resolve, reject) => { this.sendMsg({ function: 'SetVideoProcAmp', device: this.deviceIndex, prop: prop, value: value, isAuto: isAuto });
// 假设WebSocket会返回操作结果
this.$once('video-proc-result', (result) => {
result ? resolve() : reject(new Error('设置失败'));
});
});
},
// 修改亮度控制方法 async changeBrightness(val) { try {
this.prevBrightness = this.brightness; // 保存当前值
await this.setVideoProc(
this.videoProcProps.brightness,
val,
this.isAuto
);
// 更新显示
const videoimg = document.getElementById("chrome_img");
videoimg.style.filter = `brightness(${val}%)`;
} catch (error) {
console.error('亮度设置失败:', error);
this.brightness = this.prevBrightness; // 恢复之前的值
this.$message.error(error.message);
} finally {
this.isBrightnessLoading = false;
}
},
// 获取当前亮度 getCurrentBrightness() { console.log(1111111111111);
this.sendMsg({
function: 'SetVideoProcAmp',
device: this.deviceIndex,
prop: this.videoProcProps.brightness
});
}
} }