完善新增运送清单和订单

This commit is contained in:
xuqiuyun
2025-10-28 17:31:19 +08:00
parent 42e0abcbe3
commit 6c86963418
12 changed files with 1629 additions and 465 deletions

View File

@@ -18,29 +18,29 @@
<div class="main-container">
<el-table :data="rows" :key="data.tableKey" border v-loading="data.dataListLoading" element-loading-text="数据加载中..." style="width: 100%">
<el-table-column label="订单编号" prop="deliveryNumber" width="180">
<el-table-column label="订单ID" prop="id" width="100">
<template #default="scope">
{{ scope.row.deliveryNumber || '--' }}
{{ scope.row.id || '--' }}
</template>
</el-table-column>
<el-table-column label="供应商" prop="supplierName" width="150">
<template #default="scope">
{{ scope.row.supplierName || '--' }}
</template>
</el-table-column>
<el-table-column label="采购商" prop="buyerName" width="150">
<el-table-column label="买方" prop="buyerName" width="200">
<template #default="scope">
{{ scope.row.buyerName || '--' }}
</template>
</el-table-column>
<el-table-column label="结算方式" prop="settlementMethod" width="150">
<el-table-column label="卖方" prop="sellerName" width="200">
<template #default="scope">
{{ getSettlementMethod(scope.row) }}
{{ scope.row.sellerName || '--' }}
</template>
</el-table-column>
<el-table-column label="创建人" prop="createByName" width="120">
<el-table-column label="结算方式" prop="settlementTypeDesc" width="150">
<template #default="scope">
{{ scope.row.createByName || '--' }}
{{ scope.row.settlementTypeDesc || '--' }}
</template>
</el-table-column>
<el-table-column label="创建人" prop="createdByName" width="120">
<template #default="scope">
{{ scope.row.createdByName || '--' }}
</template>
</el-table-column>
<el-table-column label="创建时间" prop="createTime" width="180">
@@ -48,15 +48,10 @@
{{ scope.row.createTime || '--' }}
</template>
</el-table-column>
<el-table-column label="操作" width="420">
<el-table-column label="操作" width="200" fixed="right">
<template #default="scope">
<el-button link type="primary" :disabled="scope.row.status != 1" v-hasPermi="['loading:edit']" @click="showEditDialog(scope.row)">编辑</el-button>
<el-button link type="primary" :disabled="scope.row.status != 1" v-hasPermi="['loading:assign']" @click="showAssignDialog(scope.row)">分配设备</el-button>
<el-button link type="primary" v-hasPermi="['loading:view']" @click="showDetailDialog(scope.row)">详情</el-button>
<el-button link type="primary" v-hasPermi="['loading:device']" @click="showLookDialog(scope.row)">查看设备</el-button>
<el-button link type="primary" v-hasPermi="['loading:status']" @click="editStatus(scope.row)">编辑状态</el-button>
<el-button link type="primary" :disabled="scope.row.status != 1" v-hasPermi="['loading:delete']" @click="del(scope.row.id)">删除</el-button>
<el-button link type="primary" :disabled="scope.row.status != 1" v-hasPermi="['loading:load']" @click="loadClick(scope.row)">装车</el-button>
<el-button link type="primary" v-hasPermi="['order:edit']" @click="showEditDialog(scope.row)">编辑</el-button>
<el-button link type="primary" v-hasPermi="['order:delete']" @click="del(scope.row.id)">删除</el-button>
</template>
</el-table-column>
<template #empty>
@@ -65,67 +60,56 @@
</el-table>
<pagination v-model:limit="form.pageSize" v-model:page="form.pageNum" :total="data.total" @pagination="getDataList" />
<OrderDialog ref="OrderDialogRef" @success="getDataList" />
<LookDialog ref="LookDialogRef" />
<AssignDialog ref="AssignDialogRef" @success="getDataList" />
<DetailDialog ref="DetailDialogRef" />
<editDialog ref="editDialogRef" @success="getDataList" />
<LoadDialog ref="LoadDialogRef" @success="getDataList" />
<CreateDeliveryDialog ref="CreateDeliveryDialogRef" @success="getDataList" />
</div>
</div>
</template>
<script setup>
import { ref, reactive, onMounted, nextTick, watch } from 'vue';
import { ref, reactive, onMounted } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import { Picture } from '@element-plus/icons-vue';
import baseSearch from '@/components/common/searchCustom/index.vue';
import { orderList, orderDel, updateDeliveryStatus, clearDeviceDeliveryId } from '@/api/shipping.js';
import { pageDeviceList } from '@/api/abroad.js';
import { getImageList, handleImageError } from '@/utils/imageUtils.js';
import { orderPageQuery, orderDelete } from '@/api/shipping.js';
import OrderDialog from './orderDialog.vue';
import LookDialog from './lookDialog.vue';
import AssignDialog from './assignDialog.vue';
import DetailDialog from './detailDialog.vue';
import editDialog from './editDialog.vue';
import LoadDialog from './loadDialog.vue';
import CreateDeliveryDialog from './createDeliveryDialog.vue';
const baseSearchRef = ref();
const DetailDialogRef = ref();
const OrderDialogRef = ref();
const LookDialogRef = ref();
const editDialogRef = ref();
const AssignDialogRef = ref();
const LoadDialogRef = ref();
const CreateDeliveryDialogRef = ref();
const formItemList = reactive([
{
label: '运单号',
type: 'input',
param: 'deliveryNumber',
span: 6,
placeholder: '请输入运单号',
},
{
label: '供应商',
type: 'input',
param: 'supplierName',
span: 6,
placeholder: '请输入供应商',
},
{
label: '采购商',
label: '买方',
type: 'input',
param: 'buyerName',
span: 6,
placeholder: '请输入采购商',
placeholder: '请输入买方',
},
{
label: '卖方',
type: 'input',
param: 'sellerName',
span: 6,
placeholder: '请输入卖方',
},
{
label: '结算方式',
type: 'select',
param: 'settlementType',
span: 6,
selectOptions: [
{ text: '上车重量', value: 1 },
{ text: '下车重量', value: 2 },
{ text: '按肉价结算', value: 3 }
],
placeholder: '请选择结算方式',
},
{
label: '创建时间',
type: 'daterange',
param: 'createTimeRange',
span: 6,
valueFormat: 'YYYY-MM-DD HH:mm:ss',
format: 'YYYY-MM-DD',
startPlaceholder: '开始日期',
endPlaceholder: '结束日期',
},
@@ -135,7 +119,6 @@ const data = reactive({
dataListLoading: false,
tableKey: 0, // 用于强制重新渲染表格
forceUpdate: 0, // 用于强制更新
deviceCounts: {}, // 存储每个订单的设备数量 {orderId: {host: 0, ear: 0, collar: 0, total: 0}}
});
// 使用ref确保响应式更新
@@ -144,62 +127,6 @@ const form = reactive({
pageNum: 1,
pageSize: 10,
});
// 获取指定订单的设备数量
const getDeviceCounts = async (deliveryId) => {
try {
console.log('=== 获取装车订单设备数量deliveryId:', deliveryId);
// 获取所有设备类型的数据
const [hostRes, earRes, collarRes] = await Promise.all([
pageDeviceList({ pageNum: 1, pageSize: 100, deliveryId: parseInt(deliveryId), deviceType: 1 }),
pageDeviceList({ pageNum: 1, pageSize: 100, deliveryId: parseInt(deliveryId), deviceType: 2 }),
pageDeviceList({ pageNum: 1, pageSize: 100, deliveryId: parseInt(deliveryId), deviceType: 4 })
]);
const hostCount = hostRes.code === 200 ? hostRes.data.length : 0;
const earCount = earRes.code === 200 ? earRes.data.length : 0;
const collarCount = collarRes.code === 200 ? collarRes.data.length : 0;
const totalCount = hostCount + earCount + collarCount;
console.log('=== 装车订单设备数量统计:', {
deliveryId,
hostCount,
earCount,
collarCount,
totalCount
});
// 存储设备数量
data.deviceCounts[deliveryId] = {
host: hostCount,
ear: earCount,
collar: collarCount,
total: totalCount
};
return {
host: hostCount,
ear: earCount,
collar: collarCount,
total: totalCount
};
} catch (error) {
console.error('获取装车订单设备数量失败:', error);
return { host: 0, ear: 0, collar: 0, total: 0 };
}
};
// 获取订单的设备总数
const getTotalDeviceCount = (deliveryId) => {
const counts = data.deviceCounts[deliveryId];
return counts ? counts.total : 0;
};
// 获取订单的耳标数量
const getEarTagCount = (deliveryId) => {
const counts = data.deviceCounts[deliveryId];
return counts ? counts.ear : 0;
};
const searchFrom = () => {
console.log('=== 搜索功能被触发 ===');
@@ -224,122 +151,37 @@ const getDataList = () => {
delete params.createTimeRange; // 删除原始参数
}
console.log('运送清单列表查询参数:', params);
console.log('=== 前端搜索参数调试 ===');
console.log('deliveryNumber:', params.deliveryNumber);
console.log('licensePlate:', params.licensePlate);
console.log('deliveryTitle:', params.deliveryTitle);
console.log('endLocation:', params.endLocation);
console.log('status:', params.status);
console.log('startTime:', params.startTime);
console.log('endTime:', params.endTime);
orderList(params)
// 清理字符串参数中的空白字符
if (params.buyerName && typeof params.buyerName === 'string') {
params.buyerName = params.buyerName.trim();
if (params.buyerName === '') delete params.buyerName;
}
if (params.sellerName && typeof params.sellerName === 'string') {
params.sellerName = params.sellerName.trim();
if (params.sellerName === '') delete params.sellerName;
}
console.log('订单列表查询参数:', params);
// 调用订单列表接口,而不是装车订单接口
orderPageQuery(params)
.then((res) => {
console.log('运送清单列表返回结果:', res);
console.log('单列表返回结果:', res);
data.dataListLoading = false;
// 调试:检查所有数据
console.log('=== 装车订单数据调试 ===');
console.log('API响应:', res);
console.log('数据行数:', res.data.rows ? res.data.rows.length : 0);
// 直接赋值订单数据
console.log('=== 订单数据 ===');
console.log('完整响应:', res);
console.log('res.data:', res.data);
console.log('数据行数:', res.data?.rows?.length || 0);
// 前端精确搜索:根据条件精确搜索
if (searchParams.buyerName && res.data.rows && res.data.rows.length > 0) {
// 精确匹配采购商名称
const filteredRows = res.data.rows.filter(row => row.buyerName === searchParams.buyerName);
if (filteredRows.length > 0) {
res.data.rows = filteredRows;
res.data.total = filteredRows.length;
} else {
res.data.rows = [];
res.data.total = 0;
}
}
if (searchParams.supplierName && res.data.rows && res.data.rows.length > 0) {
// 精确匹配供应商名称
const filteredRows = res.data.rows.filter(row => row.supplierName === searchParams.supplierName);
if (filteredRows.length > 0) {
res.data.rows = filteredRows;
res.data.total = filteredRows.length;
} else {
res.data.rows = [];
res.data.total = 0;
}
}
rows.value = res.data?.rows || [];
data.total = res.data?.total || 0;
if (res.data.rows && res.data.rows.length > 0) {
// 调试所有行的基本信息
res.data.rows.forEach((row, index) => {
console.log(`=== 第${index + 1}行数据 ===`);
console.log('车牌号:', row.licensePlate);
console.log('司机姓名:', row.driverName);
console.log('carFrontPhoto:', row.carFrontPhoto);
console.log('carBehindPhoto:', row.carBehindPhoto);
console.log('driverId:', row.driverId);
// 特别关注车牌号wwwww
if (row.licensePlate === 'wwwww') {
console.log('*** 找到车牌号wwwww的数据 ***');
console.log('完整行数据:', row);
// 前端测试分割逻辑
console.log('=== 前端测试分割逻辑 ===');
const testCarImg = "https://smart-1251449951.cos.ap-guangzhou.myqcloud.com/iotPlateform/2025/10/16/4c4e20251016142427.jpg,https://smart-1251449951.cos.ap-guangzhou.myqcloud.com/iotPlateform/2025/10/16/4c4e20251016142429.jpg";
console.log('测试car_img:', testCarImg);
const carImgUrls = testCarImg.split(',');
console.log('分割后数组:', carImgUrls);
console.log('分割后长度:', carImgUrls.length);
if (carImgUrls.length >= 2) {
const carBehindPhoto = carImgUrls[0].trim();
const carFrontPhoto = carImgUrls[1].trim();
console.log('车尾照片 (carBehindPhoto):', carBehindPhoto);
console.log('车头照片 (carFrontPhoto):', carFrontPhoto);
// 测试getImageList函数
console.log('车尾照片getImageList结果:', getImageList(carBehindPhoto));
console.log('车头照片getImageList结果:', getImageList(carFrontPhoto));
}
}
});
} else {
console.log('没有数据行');
console.log('更新后rows长度:', rows.value.length);
console.log('更新后total:', data.total);
if (rows.value.length > 0) {
console.log('第一行订单数据:', rows.value[0]);
}
// 使用setTimeout确保DOM完全更新
setTimeout(async () => {
// 强制重新赋值,确保响应式更新
rows.value = [...res.data.rows];
data.total = res.data.total;
// 为每个订单获取设备数量
if (res.data.rows && res.data.rows.length > 0) {
console.log('=== 开始为每个装车订单获取设备数量');
for (const row of res.data.rows) {
if (row.id) {
await getDeviceCounts(row.id);
}
}
console.log('=== 所有装车订单设备数量获取完成');
}
// 更新表格key强制重新渲染
data.tableKey = Date.now();
// 强制更新
data.forceUpdate = Date.now();
console.log('数据更新完成当前rows长度:', rows.value.length);
if (rows.value.length > 0) {
console.log('更新后的第一行数据:', rows.value[0]);
}
// 再次延迟更新,确保表格重新渲染
setTimeout(() => {
data.forceUpdate = Date.now();
console.log('二次强制更新完成');
}, 200);
}, 50);
})
.catch(() => {
data.dataListLoading = false;
@@ -351,10 +193,10 @@ const showAddDialog = (row) => {
OrderDialogRef.value.onShowDialog(row);
}
};
// 编辑装车订单
// 编辑订单
const showEditDialog = (row) => {
if (editDialogRef.value) {
editDialogRef.value.onShowDialog(row);
if (OrderDialogRef.value) {
OrderDialogRef.value.onShowDialog(row);
}
};
@@ -365,192 +207,27 @@ const showCreateDeliveryDialog = () => {
}
};
// 查看耳标设备
const showLookDialog = (row) => {
if (LookDialogRef.value) {
LookDialogRef.value.onShowLookDialog(row);
}
};
// 分配耳标设备
const showAssignDialog = (row) => {
if (AssignDialogRef.value) {
AssignDialogRef.value.onShowAssignDialog(row);
}
};
// 详情
const showDetailDialog = (row) => {
if (DetailDialogRef.value) {
DetailDialogRef.value.onShowDetailDialog(row);
}
};
// 删除
// 删除订单(逻辑删除)
const del = (id) => {
ElMessageBox.confirm('请确认是否删除订单?删除后将同时清空该订单关联的所有智能设备的delivery_id和weight字段', '提示', {
ElMessageBox.confirm('请确认是否删除订单?删除后将不可恢复', '提示', {
cancelButtonText: '取消',
confirmButtonText: '确定',
type: 'warning',
}).then(() => {
// 先清空设备的delivery_id
clearDeviceDeliveryId(id).then(() => {
console.log('设备delivery_id清空成功');
// 然后删除订单
orderDel(id).then(() => {
ElMessage.success('订单删除成功,相关设备的绑定和重量信息已清空');
// 调用订单删除接口
orderDelete(id).then((res) => {
if (res.code === 200) {
ElMessage.success('订单删除成功');
getDataList();
}).catch((error) => {
console.error('删除订单失败:', error);
ElMessage.error('删除订单失败');
});
} else {
ElMessage.error(res.msg || '删除订单失败');
}
}).catch((error) => {
console.error('清空设备delivery_id失败:', error);
ElMessage.error('清空设备绑定失败');
console.error('删除订单失败:', error);
ElMessage.error('删除订单失败');
});
});
};
// 装车
const loadClick = (row) => {
console.log('装车按钮点击row数据:', row);
if (LoadDialogRef.value) {
// 直接传递row数据作为API数据
LoadDialogRef.value.onShowDialog(row, row);
}
};
// 编辑状态
const editStatus = (row) => {
ElMessageBox.prompt('请输入状态(1-待装车 2-已装车/预付款已支付 3-已装车/尾款待支付 4-已核验/待买家付款 5-尾款已付款 6-发票待开/进项票 7-发票待开/销项)', '修改状态', {
confirmButtonText: '确定',
cancelButtonText: '取消',
inputPattern: /^[1234567]$/,
inputErrorMessage: '请输入1、2、3、4、5、6或7',
inputValue: String(row.status || 1)
}).then(({ value }) => {
updateDeliveryStatus({ id: row.id, status: parseInt(value) })
.then(res => {
if (res.code === 200) {
ElMessage.success('状态更新成功');
getDataList();
} else {
ElMessage.error(res.msg || '状态更新失败');
}
})
.catch(() => {
ElMessage.error('状态更新失败');
});
}).catch(() => {
// 用户取消
});
};
// 状态文本转换
const getStatusText = (status) => {
const statusMap = {
1: '待装车',
2: '已装车/预付款已支付',
3: '已装车/尾款待支付',
4: '已核验/待买家付款',
5: '尾款已付款',
6: '发票待开/进项票',
7: '发票待开/销项'
};
return statusMap[status] || '未知状态';
};
// 状态标签类型
const getStatusTagType = (status) => {
const typeMap = {
1: 'warning', // 待装车 - 橙色
2: 'info', // 已装车/预付款已支付 - 蓝色
3: 'warning', // 已装车/尾款待支付 - 橙色
4: 'success', // 已核验/待买家付款 - 绿色
5: 'success', // 尾款已付款 - 绿色
6: 'info', // 发票待开/进项票 - 蓝色
7: 'info' // 发票待开/销项 - 蓝色
};
return typeMap[status] || 'info';
};
// 前端处理车身照片分割逻辑
const getProcessedCarPhotos = (row) => {
console.log('=== 前端处理车身照片 ===');
console.log('输入行数据:', row);
console.log('carFrontPhoto:', row.carFrontPhoto);
console.log('carBehindPhoto:', row.carBehindPhoto);
// 检查是否有车身照片数据
if (!row.carFrontPhoto && !row.carBehindPhoto) {
console.log('没有车身照片数据');
return [];
}
// 如果后端已经正确分割,直接使用
if (row.carFrontPhoto && row.carBehindPhoto &&
!row.carFrontPhoto.includes(',') && !row.carBehindPhoto.includes(',')) {
console.log('后端已正确分割,直接使用');
return [row.carBehindPhoto, row.carFrontPhoto]; // 车尾在前,车头在后
}
// 如果后端没有正确分割,使用前端分割逻辑
let carImgUrls = [];
// 尝试从carFrontPhoto获取完整数据
if (row.carFrontPhoto && row.carFrontPhoto.includes(',')) {
console.log('从carFrontPhoto分割:', row.carFrontPhoto);
carImgUrls = row.carFrontPhoto.split(',').map(url => url.trim()).filter(url => url !== '');
}
// 尝试从carBehindPhoto获取完整数据
else if (row.carBehindPhoto && row.carBehindPhoto.includes(',')) {
console.log('从carBehindPhoto分割:', row.carBehindPhoto);
carImgUrls = row.carBehindPhoto.split(',').map(url => url.trim()).filter(url => url !== '');
}
// 如果都没有逗号,尝试合并两个字段
else if (row.carFrontPhoto && row.carBehindPhoto) {
console.log('合并两个字段:', row.carFrontPhoto, row.carBehindPhoto);
carImgUrls = [row.carBehindPhoto, row.carFrontPhoto].filter(url => url && url.trim() !== '');
}
// 单个字段
else if (row.carFrontPhoto) {
carImgUrls = [row.carFrontPhoto];
}
else if (row.carBehindPhoto) {
carImgUrls = [row.carBehindPhoto];
}
console.log('分割结果:', carImgUrls);
console.log('分割后长度:', carImgUrls.length);
return carImgUrls;
};
// 获取结算方式
const getSettlementMethod = (row) => {
// 根据现有字段判断结算方式
// 如果有空车磅重和装车磅重,使用上车重量结算
// 如果有落地磅重,使用下车重量结算
// 如果有约定单价,使用按照肉价结算
if (row.emptyWeight && row.entruckWeight) {
return '上车重量';
} else if (row.landingEntruckWeight) {
return '下车重量';
} else if (row.firmPrice) {
return '按照肉价';
}
return '--';
};
// 监听rows变化强制更新表格
watch(rows, (newRows) => {
console.log('rows数据变化:', newRows);
if (newRows && newRows.length > 0) {
console.log('第一行数据详情:', newRows[0]);
console.log('关键字段:', {
statusDesc: newRows[0].statusDesc,
registeredJbqCount: newRows[0].registeredJbqCount,
earTagCount: newRows[0].earTagCount
});
}
}, { deep: true, immediate: true });
onMounted(() => {
console.log('=== 装车订单页面已加载 ===');

View File

@@ -254,8 +254,33 @@ const onShowDialog = (orderData) => {
// 重置表单数据
ruleForm.id = orderData?.id || null;
ruleForm.buyerId = orderData?.buyerId ? orderData.buyerId.split(',') : [];
ruleForm.sellerId = orderData?.sellerId ? orderData.sellerId.split(',') : [];
// 处理buyerId支持字符串和数组两种格式
if (orderData?.buyerId) {
if (Array.isArray(orderData.buyerId)) {
ruleForm.buyerId = orderData.buyerId;
} else if (typeof orderData.buyerId === 'string' && orderData.buyerId.trim() !== '') {
ruleForm.buyerId = orderData.buyerId.split(',').map(id => id.trim()).filter(id => id !== '');
} else {
ruleForm.buyerId = [];
}
} else {
ruleForm.buyerId = [];
}
// 处理sellerId支持字符串和数组两种格式
if (orderData?.sellerId) {
if (Array.isArray(orderData.sellerId)) {
ruleForm.sellerId = orderData.sellerId;
} else if (typeof orderData.sellerId === 'string' && orderData.sellerId.trim() !== '') {
ruleForm.sellerId = orderData.sellerId.split(',').map(id => id.trim()).filter(id => id !== '');
} else {
ruleForm.sellerId = [];
}
} else {
ruleForm.sellerId = [];
}
ruleForm.settlementType = orderData?.settlementType || 1;
data.dialogVisible = true;