feat: add WebRTC camera component for in-app photo capture
Co-authored-by: aider (openai/DeepSeek-V3.2-Thinking) <aider@aider.chat>
This commit is contained in:
@ -374,9 +374,15 @@
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<input type="file" ref="cameraInputRef" accept="image/*" capture="environment" style="display: none" @change="handleCameraFile"/>
|
||||
|
||||
<el-dialog v-model="dialogVisibleImage" append-to-body width="50%"><img style="width: 100%" :src="dialogImageUrl" alt="Preview Image" /></el-dialog>
|
||||
<el-dialog v-model="cameraDialogVisible" title="拍照上传" width="500px" append-to-body destroy-on-close>
|
||||
<WebRtcCamera
|
||||
ref="cameraRef"
|
||||
@confirm="handleCameraConfirm"
|
||||
@cancel="cameraDialogVisible = false"
|
||||
/>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="printVisible" title="标签打印预览" width="400px" destroy-on-close append-to-body>
|
||||
<div style="text-align: center;">
|
||||
@ -408,6 +414,7 @@ import {
|
||||
deleteFile
|
||||
} from '@/api/inbound/buy'
|
||||
import {getLabelPreview, executePrint} from '@/api/common/print'
|
||||
import WebRtcCamera from '@/components/Camera/WebRtcCamera.vue'
|
||||
|
||||
// ------------------------------------
|
||||
// 状态与变量
|
||||
@ -779,25 +786,36 @@ const handleRemoveImage = async (uploadFile: any, targetField: 'arrival_photo' |
|
||||
}
|
||||
const handlePreviewPicture = (uploadFile: any) => { dialogImageUrl.value = uploadFile.url!; dialogVisibleImage.value = true }
|
||||
const triggerCamera = (field: 'arrival_photo' | 'inspection_report') => { currentCameraField.value = field; if (cameraInputRef.value) cameraInputRef.value.click() }
|
||||
const handleCameraFile = async (event: Event) => {
|
||||
const input = event.target as HTMLInputElement
|
||||
if (input.files && input.files[0]) {
|
||||
const file = input.files[0]
|
||||
if (!beforeAvatarUpload(file)) { input.value = ''; return }
|
||||
const formData = new FormData(); formData.append('file', file)
|
||||
const loadingMsg = ElMessage.loading({ message: '照片上传中...', duration: 0 })
|
||||
try {
|
||||
const res: any = await uploadFile(formData)
|
||||
if (res.code === 200) {
|
||||
const newUrl = res.data.url; const field = currentCameraField.value
|
||||
form[field].push(newUrl)
|
||||
if (field === 'arrival_photo') arrivalFileList.value.push({ name: newUrl.split('/').pop(), url: getImageUrl(newUrl) })
|
||||
else reportFileList.value.push({ name: newUrl.split('/').pop(), url: getImageUrl(newUrl) })
|
||||
ElMessage.success('拍照上传成功')
|
||||
} else { ElMessage.error(res.msg || '上传失败') }
|
||||
} catch (e) { ElMessage.error('网络错误,上传失败') } finally { loadingMsg.close(); input.value = '' }
|
||||
const handleCameraConfirm = async (file: File) => {
|
||||
if (!beforeAvatarUpload(file)) {
|
||||
cameraDialogVisible.value = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
const loadingMsg = ElMessage.loading({ message: '照片上传中...', duration: 0 });
|
||||
try {
|
||||
const res: any = await uploadFile(formData);
|
||||
if (res.code === 200) {
|
||||
const newUrl = res.data.url;
|
||||
const field = currentCameraField.value;
|
||||
form[field].push(newUrl);
|
||||
if (field === 'arrival_photo') {
|
||||
arrivalFileList.value.push({ name: newUrl.split('/').pop(), url: getImageUrl(newUrl) });
|
||||
} else if (field === 'inspection_report') {
|
||||
reportFileList.value.push({ name: newUrl.split('/').pop(), url: getImageUrl(newUrl) });
|
||||
}
|
||||
ElMessage.success('拍照上传成功');
|
||||
} else {
|
||||
ElMessage.error(res.msg || '上传失败');
|
||||
}
|
||||
} catch (e) {
|
||||
ElMessage.error('网络错误,上传失败');
|
||||
} finally {
|
||||
loadingMsg.close();
|
||||
cameraDialogVisible.value = false;
|
||||
}
|
||||
};
|
||||
const handleDelete = async (row: any) => { try { await deleteBuyInbound(row.id); ElMessage.success('删除成功'); fetchData() } catch (e) { ElMessage.error('删除失败') } }
|
||||
const handlePrint = async (row: any) => {
|
||||
printVisible.value = true; printLoading.value = true; previewUrl.value = ''
|
||||
@ -872,4 +890,4 @@ onMounted(() => fetchData())
|
||||
.camera-card:hover { border-color: #409EFF; color: #409EFF; }
|
||||
.camera-card .text { font-size: 12px; margin-top: 5px; }
|
||||
.camera-card .el-icon { font-size: 24px; }
|
||||
</style>
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user