From 3320155416896f31e3a55eb12ac50680ce2558b6 Mon Sep 17 00:00:00 2001 From: weicw1996 Date: Wed, 7 Oct 2026 16:57:46 +0800 Subject: [PATCH] =?UTF-8?q?:sparkles:=20=E6=89=93=E5=8D=A1=E7=85=A7?= =?UTF-8?q?=E7=89=87=E6=8C=89=E5=87=AD=E8=AF=81=E7=B1=BB=E5=9E=8B=E5=88=86?= =?UTF-8?q?=E7=BB=84=EF=BC=8C=E7=BC=96=E8=BE=91=E5=BC=B9=E7=AA=97=E5=8E=BB?= =?UTF-8?q?=E6=8E=89=E6=89=93=E5=8D=A1=E7=8A=B6=E6=80=81=E5=BC=80=E5=85=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 打卡记录照片按类型分组展示与上传,每个类型各自最多 9 张,组内第一张标「主图」 - 打卡照片是每个打卡节点必有的类型,不由过程配置决定,与各凭证类型并列且互不替代 - 附件区抽出 punch-record-photos 组件,运单详情与配载单详情共用;编辑态沿用 96px 固定方图 - 弹窗上传体积上限由 5MB 提到 20MB,与小程序一致 - 弹窗不再提供「打卡状态」开关:未打卡的记录点「补卡」进来,保存即补出一条已打卡流水 --- .../components/punch-record-photos.vue | 305 ++++++++++++++++ .../components/waybill-manage-page.vue | 332 +++++++----------- src/views/business/loading-manage.vue | 23 +- 3 files changed, 443 insertions(+), 217 deletions(-) create mode 100644 src/views/business/components/punch-record-photos.vue diff --git a/src/views/business/components/punch-record-photos.vue b/src/views/business/components/punch-record-photos.vue new file mode 100644 index 0000000..455f7d1 --- /dev/null +++ b/src/views/business/components/punch-record-photos.vue @@ -0,0 +1,305 @@ + + + + + diff --git a/src/views/business/components/waybill-manage-page.vue b/src/views/business/components/waybill-manage-page.vue index 70b6a03..d46a264 100644 --- a/src/views/business/components/waybill-manage-page.vue +++ b/src/views/business/components/waybill-manage-page.vue @@ -2221,7 +2221,7 @@ type="primary" :underline="false" @click="openWaybillPunchRecordEdit(record)" - >编辑{{ record.punched ? '编辑打卡' : '补卡' }}
暂未打卡
@@ -2787,138 +2777,99 @@ > - + {{ waybillPunchEditRecord.nodeName || waybillPunchEditRecord.nodeCode || '-' }} - - - - 已打卡 - 未打卡 - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ 在途打卡只保留 1 张照片 +
+
-
@@ -3679,6 +3630,7 @@ import { trackVehicle, } from '@/api/business/waybill-manage'; import VoucherExecutionDetail from './voucher-execution-detail.vue'; +import PunchRecordPhotos from './punch-record-photos.vue'; import AddressMapPicker from '@/components/address-map-picker/main.vue'; import { getList as getDriverList } from '@/api/transportCapacity/driver'; import { @@ -3886,6 +3838,7 @@ export default { ElImageViewer, OpenFileViewer, VoucherExecutionDetail, + PunchRecordPhotos, AddressMapPicker, }, name: 'WaybillManagePage', @@ -3983,7 +3936,6 @@ export default { }, waybillPunchEditRecord: {}, waybillPunchEditForm: { - punched: true, punchTime: '', address: '', longitude: '', @@ -4386,11 +4338,21 @@ export default { return this.waybillPunchEditNode?.punch === false; }, waybillPunchEditRules() { - if (!this.waybillPunchEditForm.punched) return {}; return { punchTime: [{ required: true, message: '请选择打卡时间', trigger: 'change' }] }; }, - waybillPunchEditPhotoUrls() { - return (this.waybillPunchEditForm.photos || []).map(item => item.url).filter(Boolean); + // 照片类型只有两个来源:固定的「打卡照片」,和该节点过程配置勾选的凭证类型; + // 不接受配置外的类型。在途打卡表只有一个照片字段、也没有类型列,不按凭证类型分组 + waybillPunchEditPhotoTypes() { + if (this.waybillPunchEditRecord.type === 'enroute') return []; + const voucherTypes = Array.isArray(this.waybillPunchEditNode?.voucherTypes) + ? this.waybillPunchEditNode.voucherTypes + : []; + return ['打卡照片', ...voucherTypes]; + }, + // 打卡照片与各凭证类型各自最多 9 张,不另设节点总张数上限; + // 在途打卡用 0 表示不限制——它保存时只保留第一张,张数由那一步约束 + waybillPunchEditPhotoLimit() { + return this.waybillPunchEditRecord.type === 'enroute' ? 0 : 9; }, // 打卡时间轴按打卡时间先后展示:已打卡记录按打卡时间升序在前, // 未打卡记录保持流程节点原顺序排在其后。 @@ -5876,8 +5838,8 @@ export default { openWaybillPunchRecordEdit(record = {}) { if (!this.detailRow?.id || !record) return; this.waybillPunchEditRecord = { ...record }; + // 弹窗不提供打卡状态开关:未打卡的记录点「补卡」进来,保存即补出一条打卡流水 this.waybillPunchEditForm = { - punched: record.punched !== false, punchTime: record.punchTime || this.$dayjs().format('YYYY-MM-DD HH:mm:ss'), address: record.address || '', longitude: record.longitude || '', @@ -5914,26 +5876,40 @@ export default { this.waybillPunchEditForm.latitude = Number(selection.latitude).toFixed(6); } }, - beforeWaybillPunchPhotoUpload(file) { + beforeWaybillPunchPhotoUpload(file, type = '') { const validType = ['image/jpeg', 'image/png', 'image/jpg', 'image/bmp'].includes(file.type); if (!validType) { this.$message.error('仅支持 JPG、PNG、BMP 图片'); return false; } - if (file.size / 1024 / 1024 >= 5) { - this.$message.error('图片大小不能超过 5MB'); + // 单张 20MB 与司机端一致:凭证要原图,5MB 会把手机拍的正常凭证挡在门外 + if (file.size / 1024 / 1024 >= 20) { + this.$message.error('图片大小不能超过 20MB'); return false; } + // 每个照片类型各自最多 9 张。界面已经不给满员的类型「添加」入口,这里再兜一层。 + // 张数按界面上的分组口径统计:没带类型的照片算进兜底类型「凭证」 + const limit = this.waybillPunchEditPhotoLimit; + if (limit > 0 && type) { + const used = (this.waybillPunchEditForm.photos || []).filter( + photo => (String(photo?.type || '').trim() || '凭证') === type + ).length; + if (used >= limit) { + this.$message.error(`${type}最多上传 ${limit} 张`); + return false; + } + } return true; }, - handleWaybillPunchPhotoSuccess(res) { + handleWaybillPunchPhotoSuccess(res, type = '') { if (res.code !== 200 || !res.data) { this.$message.error(res.msg || '上传失败'); return; } const url = res.data.link || res.data.url || res.data.domain || ''; if (!url) return; - const photos = [...this.waybillPunchEditForm.photos, { url, type: '' }]; + // 照片落进点开的那一组并带上该类型的名字:类型写空,保存时会被按下标回推成别的类型 + const photos = [...this.waybillPunchEditForm.photos, { url, type }]; // 在途打卡表只有一个照片字段(单张),多传的保存时会被丢掉,这里先只留一张 this.waybillPunchEditForm.photos = this.waybillPunchEditRecord.type === 'enroute' ? photos.slice(0, 1) : photos; @@ -5950,7 +5926,6 @@ export default { await this.$refs.waybillPunchRecordEditFormRef.validate(); const record = this.waybillPunchEditRecord; const form = this.waybillPunchEditForm; - const keepDetail = form.punched; const submit = typeof this.api?.savePunchRecord === 'function' ? this.api.savePunchRecord : savePunchRecord; this.waybillPunchRecordEditDialog.submitting = true; @@ -5960,17 +5935,17 @@ export default { type: record.type === 'enroute' ? 'enroute' : 'node', nodeCode: record.nodeCode || '', nodeName: record.nodeName || '', - punched: form.punched, - // 未打卡时后端会清空该节点流水,明细项不再上传 - punchTime: keepDetail ? form.punchTime : '', - address: keepDetail ? form.address : '', - longitude: keepDetail ? form.longitude : '', - latitude: keepDetail ? form.latitude : '', - weight: keepDetail ? form.weight : '', - volume: keepDetail ? form.volume : '', - quantity: keepDetail ? form.quantity : '', - remark: keepDetail ? form.remark : '', - photos: keepDetail ? form.photos.map(photo => ({ url: photo.url, type: photo.type })) : [], + // 弹窗没有打卡状态开关:无论「补卡」还是「编辑打卡」,保存都落一条已打卡流水 + punched: true, + punchTime: form.punchTime, + address: form.address, + longitude: form.longitude, + latitude: form.latitude, + weight: form.weight, + volume: form.volume, + quantity: form.quantity, + remark: form.remark, + photos: form.photos.map(photo => ({ url: photo.url, type: photo.type })), }); this.$message.success('保存成功'); this.waybillPunchRecordEditDialog.visible = false; @@ -11606,50 +11581,6 @@ export default { color: #303133; } - &__punch-edit-photos { - display: flex; - flex-wrap: wrap; - gap: 10px; - } - - &__punch-edit-photo { - display: flex; - flex-direction: column; - align-items: center; - gap: 4px; - width: 96px; - - .el-image { - display: block; - width: 96px; - height: 96px; - border: 1px solid #eff1f7; - border-radius: 4px; - overflow: hidden; - } - } - - &__punch-edit-photo-label { - font-size: 12px; - line-height: 1.4; - color: #606266; - text-align: center; - word-break: break-all; - } - - &__punch-edit-photo-add { - display: flex; - align-items: center; - justify-content: center; - width: 96px; - height: 96px; - border: 1px dashed #dcdfe6; - border-radius: 4px; - font-size: 13px; - color: #909399; - cursor: pointer; - } - &__punch-edit-photo-tip { margin-top: 4px; font-size: 12px; @@ -11665,7 +11596,6 @@ export default { } } - &__punch-record-photos, &__driver-upload-grid { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); diff --git a/src/views/business/loading-manage.vue b/src/views/business/loading-manage.vue index 15a63a9..645472c 100644 --- a/src/views/business/loading-manage.vue +++ b/src/views/business/loading-manage.vue @@ -694,22 +694,12 @@ > 备注:{{ record.remark }} -
-
- -
- {{ photo.label || `${record.nodeName}-凭证` }} -
-
-
+ :photos="record.photos" + lazy + @preview="previewDriverUploadPhoto(record.photos, $event)" + />
暂未打卡
@@ -1715,6 +1705,7 @@ import { getVoucherImages as getProcessConfigVoucherImages, } from '@/api/business/process-config'; import VoucherExecutionDetail from './components/voucher-execution-detail.vue'; +import PunchRecordPhotos from './components/punch-record-photos.vue'; import { carrierTypeOptions, loadingManageConfig, @@ -1925,6 +1916,7 @@ export default { Rank, Search, VoucherExecutionDetail, + PunchRecordPhotos, }, data() { return { @@ -4921,7 +4913,6 @@ export default { margin-left: 12px; } } - .loading-detail__punch-record-photos, .loading-detail__driver-upload-grid, .loading-detail__voucher-image-grid { display: grid;