后期需求已修改
This commit is contained in:
@@ -265,6 +265,15 @@ export function orderGetDetail(id) {
|
||||
});
|
||||
}
|
||||
|
||||
// 批量更新订单的delivery_id字段
|
||||
export function updateOrderDeliveryId(data) {
|
||||
return request({
|
||||
url: '/order/updateDeliveryId',
|
||||
method: 'POST',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
// 批量导入订单
|
||||
export function orderBatchImport(data) {
|
||||
return request({
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
<el-descriptions-item label="送达目的地">{{ data.baseInfo.endLocation || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="预计送达时间">{{ data.baseInfo.estimatedDeliveryTime || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="创建时间">{{ data.baseInfo.createTime || '' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="司机运费">{{ data.baseInfo.freight ? data.baseInfo.freight + ' 元' : '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="登记设备数量">{{ totalRegisteredDevices }} 个</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-card>
|
||||
|
||||
@@ -14,10 +14,11 @@
|
||||
>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="24">
|
||||
<el-form-item label="关联订单" prop="orderId">
|
||||
<el-form-item label="关联订单" prop="orderIds">
|
||||
<el-select
|
||||
v-model="formData.orderId"
|
||||
placeholder="请选择订单(可选择关联订单)"
|
||||
v-model="formData.orderIds"
|
||||
placeholder="请选择订单(可多选关联订单)"
|
||||
multiple
|
||||
clearable
|
||||
filterable
|
||||
style="width: 100%"
|
||||
@@ -34,33 +35,6 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="发货方" prop="shipper">
|
||||
<el-select v-model="formData.shipper" placeholder="请选择发货方" clearable filterable style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in supplierList"
|
||||
:key="item.id"
|
||||
:label="item.username || item.mobile"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="采购方" prop="buyer">
|
||||
<el-select v-model="formData.buyer" placeholder="请选择采购方" clearable filterable style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in buyerList"
|
||||
:key="item.id"
|
||||
:label="item.username || item.mobile"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="车牌号" prop="plateNumber">
|
||||
@@ -224,6 +198,19 @@
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="司机运费" prop="freight">
|
||||
<el-input-number
|
||||
v-model="formData.freight"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
placeholder="请输入司机运费"
|
||||
style="width: 100%"
|
||||
>
|
||||
<template #append>元</template>
|
||||
</el-input-number>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="20">
|
||||
@@ -924,9 +911,9 @@ import { ref, reactive, computed, watch } from 'vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { ElImageViewer } from 'element-plus';
|
||||
import { Plus, UploadFilled, Delete, ZoomIn } from '@element-plus/icons-vue';
|
||||
import { createDelivery, updateDeviceDeliveryId, orderPageQuery, getDeliveryDetail } from '@/api/shipping.js';
|
||||
import { createDelivery, updateDeviceDeliveryId, orderPageQuery, getDeliveryDetail, updateOrderDeliveryId } from '@/api/shipping.js';
|
||||
import * as shippingApi from '@/api/shipping.js';
|
||||
import { memberListByType, driverList as fetchDriverList, vehicleList as fetchVehicleList } from '@/api/userManage.js';
|
||||
import { driverList as fetchDriverList, vehicleList as fetchVehicleList } from '@/api/userManage.js';
|
||||
import { iotDeviceQueryList } from '@/api/hardware.js';
|
||||
import { BaiduMap, BmMapType, BmMarker } from 'vue-baidu-map-3x';
|
||||
import { useUserStore } from '../../store/user';
|
||||
@@ -944,8 +931,6 @@ const isSubmitSuccess = ref(false); // 标记是否刚刚提交成功
|
||||
const serverList = ref([]);
|
||||
const eartagList = ref([]);
|
||||
const collarList = ref([]);
|
||||
const supplierList = ref([]);
|
||||
const buyerList = ref([]);
|
||||
const driverOptions = ref([]);
|
||||
const vehicleOptions = ref([]);
|
||||
const orderList = ref([]);
|
||||
@@ -954,9 +939,7 @@ const showEndLocationMap = ref(false);
|
||||
|
||||
const formData = reactive({
|
||||
editId: null, // 编辑时的运单ID
|
||||
orderId: null,
|
||||
shipper: null,
|
||||
buyer: null,
|
||||
orderIds: [], // 关联订单ID数组(多选)
|
||||
plateNumber: null,
|
||||
driverId: null, // 司机ID(后端用)
|
||||
driverName: null,
|
||||
@@ -976,6 +959,7 @@ const formData = reactive({
|
||||
endLat: '',
|
||||
endLon: '',
|
||||
cattleCount: 1,
|
||||
freight: null, // 司机运费
|
||||
quarantineCertNo: '',
|
||||
remark: '',
|
||||
// 装车相关字段
|
||||
@@ -1039,9 +1023,7 @@ const validateArrivalTime = (rule, value, callback) => {
|
||||
};
|
||||
|
||||
const rules = {
|
||||
orderId: [{ required: false, message: '请选择订单', trigger: 'change' }],
|
||||
shipper: [{ required: true, message: '请选择发货方', trigger: 'change' }],
|
||||
buyer: [{ required: true, message: '请选择采购方', trigger: 'change' }],
|
||||
orderIds: [{ required: false, message: '请选择订单', trigger: 'change' }],
|
||||
plateNumber: [{ required: true, message: '请选择车牌号', trigger: 'change' }],
|
||||
driverId: [{ required: true, message: '请选择司机', trigger: 'change' }],
|
||||
driverPhone: [{ required: true, validator: validatePhone, trigger: 'blur' }],
|
||||
@@ -1086,15 +1068,13 @@ const buildSubmitData = () => {
|
||||
|
||||
const data = {
|
||||
// 基本信息
|
||||
shipperId: formData.shipper,
|
||||
buyerId: formData.buyer,
|
||||
plateNumber: formData.plateNumber,
|
||||
driverId: formData.driverId, // 传递司机ID给后端
|
||||
driverName: driverNameStr,
|
||||
driverPhone: formData.driverPhone,
|
||||
|
||||
// 关联信息
|
||||
orderId: formData.orderId,
|
||||
// 关联信息(将订单ID数组转换为逗号分隔的字符串)
|
||||
orderId: formData.orderIds && formData.orderIds.length > 0 ? formData.orderIds.join(',') : null,
|
||||
|
||||
// 设备ID
|
||||
serverId: formData.serverId,
|
||||
@@ -1120,6 +1100,7 @@ const buildSubmitData = () => {
|
||||
|
||||
// 其他信息
|
||||
cattleCount: formData.cattleCount,
|
||||
freight: formData.freight,
|
||||
quarantineCertNo: formData.quarantineCertNo,
|
||||
remark: formData.remark,
|
||||
|
||||
@@ -1157,7 +1138,7 @@ const buildSubmitData = () => {
|
||||
if (data[key] === undefined) {
|
||||
// 数值类型字段保留null,其他字段转换为空字符串
|
||||
if (key === 'cattleCount' ||
|
||||
key === 'orderId' || key === 'shipperId' || key === 'buyerId' ||
|
||||
key === 'orderIds' ||
|
||||
key === 'driverId' || key === 'serverId') {
|
||||
data[key] = null;
|
||||
} else {
|
||||
@@ -1182,7 +1163,6 @@ const open = async (editData = null) => {
|
||||
|
||||
// 并行加载所有下拉列表数据
|
||||
await Promise.all([
|
||||
loadSupplierAndBuyerList(),
|
||||
loadDeviceOptions(),
|
||||
loadDriverList(),
|
||||
loadVehicleList(),
|
||||
@@ -1257,12 +1237,21 @@ const fillFormWithEditData = (editData) => {
|
||||
|
||||
const delivery = editData.delivery || editData; // 兼容两种数据结构
|
||||
|
||||
// 基本信息
|
||||
formData.orderId = delivery.orderId || null;
|
||||
|
||||
// 发货方和采购方:优先使用根级的 supplierId 和 buyerId
|
||||
formData.shipper = editData.supplierId || (delivery.supplierId ? parseInt(delivery.supplierId) : null);
|
||||
formData.buyer = editData.buyerId || delivery.buyerId || null;
|
||||
// 基本信息(将逗号分隔的订单ID字符串转换为数组)
|
||||
if (delivery.orderId) {
|
||||
if (typeof delivery.orderId === 'string') {
|
||||
// 如果是字符串,按逗号分割
|
||||
formData.orderIds = delivery.orderId.split(',').map(id => parseInt(id.trim())).filter(id => !isNaN(id));
|
||||
} else if (Array.isArray(delivery.orderId)) {
|
||||
// 如果已经是数组,直接使用
|
||||
formData.orderIds = delivery.orderId;
|
||||
} else {
|
||||
// 如果是单个数字,转换为数组
|
||||
formData.orderIds = [delivery.orderId];
|
||||
}
|
||||
} else {
|
||||
formData.orderIds = [];
|
||||
}
|
||||
|
||||
// 车牌号
|
||||
formData.plateNumber = delivery.licensePlate || '';
|
||||
@@ -1326,6 +1315,9 @@ const fillFormWithEditData = (editData) => {
|
||||
// 牛只数量(从ratedQuantity字段映射)
|
||||
formData.cattleCount = delivery.ratedQuantity || 1;
|
||||
|
||||
// 司机运费
|
||||
formData.freight = delivery.freight || null;
|
||||
|
||||
// 照片
|
||||
formData.quarantineTickeyUrl = delivery.quarantineTickeyUrl || '';
|
||||
formData.poundListImg = delivery.poundListImg || '';
|
||||
@@ -1352,25 +1344,6 @@ const fillFormWithEditData = (editData) => {
|
||||
ElMessage.success('已加载运单数据');
|
||||
};
|
||||
|
||||
// 加载供应商和采购方列表
|
||||
const loadSupplierAndBuyerList = async () => {
|
||||
try {
|
||||
// 加载供应商列表 (type=2)
|
||||
const supplierRes = await memberListByType({ type: 2, pageNum: 1, pageSize: 9999 });
|
||||
if (supplierRes.code === 200) {
|
||||
supplierList.value = supplierRes.data?.rows || supplierRes.data || [];
|
||||
}
|
||||
|
||||
// 加载采购方列表 (type=4)
|
||||
const buyerRes = await memberListByType({ type: 4, pageNum: 1, pageSize: 9999 });
|
||||
if (buyerRes.code === 200) {
|
||||
buyerList.value = buyerRes.data?.rows || buyerRes.data || [];
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载供应商/采购方列表失败', error);
|
||||
}
|
||||
};
|
||||
|
||||
// 加载设备选项
|
||||
const loadDeviceOptions = async () => {
|
||||
try {
|
||||
@@ -1464,121 +1437,11 @@ const loadOrderList = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
// 订单选择变化时自动填充发货方和采购方
|
||||
const handleOrderChange = async (orderId) => {
|
||||
if (orderId) {
|
||||
try {
|
||||
// 从订单列表中查找选中的订单
|
||||
const order = orderList.value.find(item => item.id === orderId);
|
||||
if (order) {
|
||||
// 处理 buyerId:支持数字、字符串(逗号分隔)和数组格式,取第一个值
|
||||
let buyerId = null;
|
||||
if (order.buyerId) {
|
||||
if (typeof order.buyerId === 'number') {
|
||||
buyerId = order.buyerId;
|
||||
} else if (Array.isArray(order.buyerId) && order.buyerId.length > 0) {
|
||||
buyerId = parseInt(order.buyerId[0]);
|
||||
} else if (typeof order.buyerId === 'string' && order.buyerId.trim() !== '') {
|
||||
const ids = order.buyerId.split(',').map(id => id.trim()).filter(id => id !== '');
|
||||
buyerId = ids.length > 0 ? parseInt(ids[0]) : null;
|
||||
}
|
||||
}
|
||||
|
||||
// 处理 sellerId:支持数字、字符串(逗号分隔)和数组格式,取第一个值
|
||||
let sellerId = null;
|
||||
if (order.sellerId) {
|
||||
if (typeof order.sellerId === 'number') {
|
||||
sellerId = order.sellerId;
|
||||
} else if (Array.isArray(order.sellerId) && order.sellerId.length > 0) {
|
||||
sellerId = parseInt(order.sellerId[0]);
|
||||
} else if (typeof order.sellerId === 'string' && order.sellerId.trim() !== '') {
|
||||
const ids = order.sellerId.split(',').map(id => id.trim()).filter(id => id !== '');
|
||||
sellerId = ids.length > 0 ? parseInt(ids[0]) : null;
|
||||
}
|
||||
}
|
||||
|
||||
// 确保buyerId在buyerList中,如果不在则查询并添加
|
||||
if (buyerId && !buyerList.value.find(item => item.id === buyerId)) {
|
||||
try {
|
||||
// 查询所有类型的用户,找到对应的buyerId
|
||||
const allBuyerRes = await memberListByType({ pageNum: 1, pageSize: 9999 });
|
||||
if (allBuyerRes.code === 200) {
|
||||
const allBuyers = allBuyerRes.data?.rows || allBuyerRes.data || [];
|
||||
const buyerInfo = allBuyers.find(item => item.id === buyerId);
|
||||
if (buyerInfo) {
|
||||
// 如果找到,添加到buyerList中
|
||||
buyerList.value.push(buyerInfo);
|
||||
} else {
|
||||
// 如果找不到,使用订单中的buyerName创建一个临时对象
|
||||
if (order.buyerName) {
|
||||
buyerList.value.push({
|
||||
id: buyerId,
|
||||
username: order.buyerName,
|
||||
mobile: ''
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('查询采购方信息失败', error);
|
||||
// 如果查询失败,使用订单中的buyerName创建一个临时对象
|
||||
if (order.buyerName) {
|
||||
buyerList.value.push({
|
||||
id: buyerId,
|
||||
username: order.buyerName,
|
||||
mobile: ''
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 确保sellerId在supplierList中,如果不在则查询并添加
|
||||
if (sellerId && !supplierList.value.find(item => item.id === sellerId)) {
|
||||
try {
|
||||
// 查询所有类型的用户,找到对应的sellerId
|
||||
const allSupplierRes = await memberListByType({ pageNum: 1, pageSize: 9999 });
|
||||
if (allSupplierRes.code === 200) {
|
||||
const allSuppliers = allSupplierRes.data?.rows || allSupplierRes.data || [];
|
||||
const supplierInfo = allSuppliers.find(item => item.id === sellerId);
|
||||
if (supplierInfo) {
|
||||
// 如果找到,添加到supplierList中
|
||||
supplierList.value.push(supplierInfo);
|
||||
} else {
|
||||
// 如果找不到,使用订单中的sellerName创建一个临时对象
|
||||
if (order.sellerName) {
|
||||
supplierList.value.push({
|
||||
id: sellerId,
|
||||
username: order.sellerName,
|
||||
mobile: ''
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('查询发货方信息失败', error);
|
||||
// 如果查询失败,使用订单中的sellerName创建一个临时对象
|
||||
if (order.sellerName) {
|
||||
supplierList.value.push({
|
||||
id: sellerId,
|
||||
username: order.sellerName,
|
||||
mobile: ''
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 自动填充发货方(卖方)和采购方(买方)
|
||||
formData.shipper = sellerId || null;
|
||||
formData.buyer = buyerId || null;
|
||||
|
||||
|
||||
ElMessage.success('已自动填充发货方和采购方信息');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载订单详情失败', error);
|
||||
}
|
||||
} else {
|
||||
// 清除订单时不清除发货方和采购方,让用户手动选择
|
||||
// 订单选择变化时的处理(多选模式)
|
||||
const handleOrderChange = async (orderIds) => {
|
||||
// 多选模式下,orderIds 是数组
|
||||
if (orderIds && orderIds.length > 0) {
|
||||
console.log('已选择订单:', orderIds);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1752,6 +1615,24 @@ const handleSubmit = () => {
|
||||
if (deliveryId) {
|
||||
// 更新设备的delivery_id
|
||||
await updateSelectedDevicesDeliveryId(deliveryId);
|
||||
|
||||
// 更新关联订单的delivery_id
|
||||
if (formData.orderIds && formData.orderIds.length > 0) {
|
||||
try {
|
||||
const updateOrderRes = await updateOrderDeliveryId({
|
||||
deliveryId: deliveryId,
|
||||
orderIds: formData.orderIds
|
||||
});
|
||||
if (updateOrderRes.code === 200) {
|
||||
console.log('[ORDER-UPDATE] 成功更新订单delivery_id,订单数量:', formData.orderIds.length);
|
||||
} else {
|
||||
console.warn('[ORDER-UPDATE] 更新订单delivery_id失败:', updateOrderRes.msg);
|
||||
}
|
||||
} catch (orderError) {
|
||||
console.error('[ORDER-UPDATE] 更新订单delivery_id异常:', orderError);
|
||||
// 不阻止流程,只记录错误
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 提交成功后立即清除对应模式的缓存
|
||||
@@ -2037,9 +1918,7 @@ const handleClose = () => {
|
||||
// 编辑模式:保存到 editFormData[editId]
|
||||
deliveryFormStore.saveEditFormData(formData.editId, {
|
||||
editId: formData.editId,
|
||||
orderId: formData.orderId,
|
||||
shipper: formData.shipper,
|
||||
buyer: formData.buyer,
|
||||
orderIds: formData.orderIds,
|
||||
plateNumber: formData.plateNumber,
|
||||
driverId: formData.driverId,
|
||||
driverPhone: formData.driverPhone,
|
||||
@@ -2058,6 +1937,7 @@ const handleClose = () => {
|
||||
endLat: formData.endLat,
|
||||
endLon: formData.endLon,
|
||||
cattleCount: formData.cattleCount,
|
||||
freight: formData.freight,
|
||||
quarantineCertNo: formData.quarantineCertNo,
|
||||
remark: formData.remark,
|
||||
emptyWeight: formData.emptyWeight,
|
||||
@@ -2082,9 +1962,7 @@ const handleClose = () => {
|
||||
} else {
|
||||
// 新增模式:保存到 newFormData
|
||||
deliveryFormStore.saveNewFormData({
|
||||
orderId: formData.orderId,
|
||||
shipper: formData.shipper,
|
||||
buyer: formData.buyer,
|
||||
orderIds: formData.orderIds,
|
||||
plateNumber: formData.plateNumber,
|
||||
driverId: formData.driverId,
|
||||
driverPhone: formData.driverPhone,
|
||||
@@ -2103,6 +1981,7 @@ const handleClose = () => {
|
||||
endLat: formData.endLat,
|
||||
endLon: formData.endLon,
|
||||
cattleCount: formData.cattleCount,
|
||||
freight: formData.freight,
|
||||
quarantineCertNo: formData.quarantineCertNo,
|
||||
remark: formData.remark,
|
||||
emptyWeight: formData.emptyWeight,
|
||||
@@ -2133,7 +2012,9 @@ const handleClose = () => {
|
||||
formRef.value?.resetFields();
|
||||
// 清空所有表单字段
|
||||
Object.keys(formData).forEach(key => {
|
||||
if (key === 'orderId' || key === 'editId') {
|
||||
if (key === 'orderIds') {
|
||||
formData[key] = [];
|
||||
} else if (key === 'editId') {
|
||||
formData[key] = null;
|
||||
} else if (typeof formData[key] === 'number') {
|
||||
formData[key] = key === 'cattleCount' ? 1 : null;
|
||||
@@ -2177,9 +2058,7 @@ watch(
|
||||
// 编辑模式:保存到 editFormData[editId]
|
||||
deliveryFormStore.saveEditFormData(formData.editId, {
|
||||
editId: formData.editId,
|
||||
orderId: formData.orderId,
|
||||
shipper: formData.shipper,
|
||||
buyer: formData.buyer,
|
||||
orderIds: formData.orderIds,
|
||||
plateNumber: formData.plateNumber,
|
||||
driverId: formData.driverId,
|
||||
driverPhone: formData.driverPhone,
|
||||
@@ -2222,15 +2101,11 @@ watch(
|
||||
} else {
|
||||
// 新增模式:保存到 newFormData
|
||||
console.log('[CACHE] 保存新增模式数据:', {
|
||||
shipper: formData.shipper,
|
||||
buyer: formData.buyer,
|
||||
plateNumber: formData.plateNumber,
|
||||
driverId: formData.driverId,
|
||||
});
|
||||
deliveryFormStore.saveNewFormData({
|
||||
orderId: formData.orderId,
|
||||
shipper: formData.shipper,
|
||||
buyer: formData.buyer,
|
||||
orderIds: formData.orderIds,
|
||||
plateNumber: formData.plateNumber,
|
||||
driverId: formData.driverId,
|
||||
driverPhone: formData.driverPhone,
|
||||
|
||||
@@ -55,6 +55,26 @@
|
||||
{{ scope.row.settlementTypeDesc || '--' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="运单号" prop="deliveryNumber" width="150">
|
||||
<template #default="scope">
|
||||
{{ scope.row.deliveryNumber || '--' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="起始地" prop="startLocation" width="200">
|
||||
<template #default="scope">
|
||||
{{ scope.row.startLocation || '--' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="目的地" prop="endLocation" width="200">
|
||||
<template #default="scope">
|
||||
{{ scope.row.endLocation || '--' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="单价" prop="firmPrice" width="120">
|
||||
<template #default="scope">
|
||||
{{ (scope.row.firmPriceFromDelivery || scope.row.firmPrice) ? ((scope.row.firmPriceFromDelivery || scope.row.firmPrice) + ' 元/斤') : '--' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建人" prop="createdByName" width="120">
|
||||
<template #default="scope">
|
||||
{{ scope.row.createdByName || '--' }}
|
||||
@@ -65,10 +85,26 @@
|
||||
{{ scope.row.createTime || '--' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="200" fixed="right">
|
||||
<el-table-column label="操作" width="300" fixed="right">
|
||||
<template #default="scope">
|
||||
<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>
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
v-if="scope.row.deliveryId"
|
||||
@click="viewDeliveryDetail(scope.row.deliveryId)"
|
||||
>
|
||||
详情
|
||||
</el-button>
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
v-if="scope.row.deliveryId && scope.row.deliveryStatus >= 2"
|
||||
@click="viewTrack(scope.row.deliveryId, scope.row.deliveryStatus)"
|
||||
>
|
||||
查看轨迹
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<template #empty>
|
||||
@@ -85,6 +121,36 @@
|
||||
<OrderDialog ref="OrderDialogRef" @success="getDataList" />
|
||||
<CreateDeliveryDialog ref="CreateDeliveryDialogRef" @success="getDataList" />
|
||||
</div>
|
||||
|
||||
<!-- 轨迹定位对话框 -->
|
||||
<el-dialog
|
||||
v-model="trackDialogVisible"
|
||||
title="轨迹定位"
|
||||
width="1000px"
|
||||
:close-on-click-modal="false"
|
||||
@close="trackDialogVisible = false"
|
||||
>
|
||||
<div v-loading="trackLoading" style="min-height: 500px;">
|
||||
<div v-if="deliveryStatus === 1" class="status-tip">
|
||||
<el-alert
|
||||
title="运单尚未开始运输"
|
||||
description="当前运单状态为准备中,暂无轨迹数据"
|
||||
type="info"
|
||||
:closable="false"
|
||||
show-icon
|
||||
/>
|
||||
</div>
|
||||
<div v-else-if="trackPath.length === 0" class="empty-tip">
|
||||
<el-empty description="暂无轨迹数据" :image-size="100" />
|
||||
</div>
|
||||
<div v-else class="track-info">
|
||||
<el-tag type="info" style="margin-bottom: 15px;">
|
||||
轨迹点数:{{ trackPath.length }}
|
||||
</el-tag>
|
||||
<div id="trackMap" style="width: 100%; height: 500px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -92,18 +158,30 @@
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
import { ArrowDown } from '@element-plus/icons-vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import * as XLSX from 'xlsx';
|
||||
import baseSearch from '@/components/common/searchCustom/index.vue';
|
||||
import Pagination from '@/components/Pagination/index.vue';
|
||||
import { orderPageQuery, orderDelete, orderBatchImport } from '@/api/shipping.js';
|
||||
import { memberListByType, userAdd } from '@/api/userManage.js';
|
||||
import { getYingyanTrack, waybillDetail } from '@/api/abroad.js';
|
||||
import { BMPGL } from '@/utils/loadBmap.js';
|
||||
import { nextTick } from 'vue';
|
||||
import OrderDialog from './orderDialog.vue';
|
||||
import CreateDeliveryDialog from './createDeliveryDialog.vue';
|
||||
|
||||
const router = useRouter();
|
||||
const baseSearchRef = ref();
|
||||
const OrderDialogRef = ref();
|
||||
const CreateDeliveryDialogRef = ref();
|
||||
const fileInputRef = ref();
|
||||
|
||||
// 轨迹相关
|
||||
const trackDialogVisible = ref(false);
|
||||
const trackLoading = ref(false);
|
||||
const trackPath = ref([]);
|
||||
const deliveryStatus = ref(null);
|
||||
const trackMapInstance = ref(null);
|
||||
const formItemList = reactive([
|
||||
{
|
||||
label: '买方',
|
||||
@@ -119,6 +197,34 @@ const formItemList = reactive([
|
||||
span: 6,
|
||||
placeholder: '请输入卖方',
|
||||
},
|
||||
{
|
||||
label: '运单号',
|
||||
type: 'input',
|
||||
param: 'deliveryNumber',
|
||||
span: 6,
|
||||
placeholder: '请输入运单号',
|
||||
},
|
||||
{
|
||||
label: '起始地',
|
||||
type: 'input',
|
||||
param: 'startLocation',
|
||||
span: 6,
|
||||
placeholder: '请输入起始地',
|
||||
},
|
||||
{
|
||||
label: '目的地',
|
||||
type: 'input',
|
||||
param: 'endLocation',
|
||||
span: 6,
|
||||
placeholder: '请输入目的地',
|
||||
},
|
||||
{
|
||||
label: '单价',
|
||||
type: 'input',
|
||||
param: 'firmPrice',
|
||||
span: 6,
|
||||
placeholder: '请输入单价',
|
||||
},
|
||||
{
|
||||
label: '结算方式',
|
||||
type: 'select',
|
||||
@@ -254,6 +360,169 @@ const showCreateDeliveryDialog = () => {
|
||||
}
|
||||
};
|
||||
|
||||
// 查看运送清单详情
|
||||
const viewDeliveryDetail = (deliveryId) => {
|
||||
if (!deliveryId) {
|
||||
ElMessage.warning('运单ID不存在');
|
||||
return;
|
||||
}
|
||||
router.push({
|
||||
path: '/entry/details',
|
||||
query: {
|
||||
id: deliveryId
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 查看轨迹
|
||||
const viewTrack = async (deliveryId, status) => {
|
||||
if (!deliveryId) {
|
||||
ElMessage.warning('运单ID不存在,无法查看轨迹');
|
||||
return;
|
||||
}
|
||||
|
||||
// 判断状态:status >= 2 可查看轨迹
|
||||
if (status == null || status < 2) {
|
||||
ElMessage.warning('该运单尚未开始运输,暂无轨迹数据');
|
||||
return;
|
||||
}
|
||||
|
||||
trackDialogVisible.value = true;
|
||||
trackLoading.value = true;
|
||||
trackPath.value = [];
|
||||
deliveryStatus.value = status;
|
||||
|
||||
try {
|
||||
const res = await getYingyanTrack({ deliveryId: deliveryId });
|
||||
if (res.code === 200 && res.data) {
|
||||
const rawPoints = Array.isArray(res.data.trackPoints) ? res.data.trackPoints : [];
|
||||
trackPath.value = rawPoints
|
||||
.map(item => {
|
||||
const lng = parseFloat(item.longitude ?? item.lng ?? 0);
|
||||
const lat = parseFloat(item.latitude ?? item.lat ?? 0);
|
||||
if (Number.isNaN(lng) || Number.isNaN(lat) || lng === 0 || lat === 0) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
lng,
|
||||
lat,
|
||||
locTime: item.locTime
|
||||
};
|
||||
})
|
||||
.filter(Boolean);
|
||||
|
||||
if (trackPath.value.length === 0) {
|
||||
ElMessage.warning('暂无有效轨迹点');
|
||||
trackLoading.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// 初始化地图
|
||||
await nextTick();
|
||||
await initTrackMap();
|
||||
} else {
|
||||
ElMessage.warning(res.msg || '暂无轨迹数据');
|
||||
trackLoading.value = false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载轨迹数据失败:', error);
|
||||
ElMessage.error('加载轨迹数据失败');
|
||||
trackLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 初始化轨迹地图
|
||||
const initTrackMap = async () => {
|
||||
if (trackPath.value.length === 0) {
|
||||
trackLoading.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const BMapGL = await BMPGL('fLz8UwJSM3ayYl6dtsWYp7TQ8993R6kC');
|
||||
|
||||
// 创建地图实例
|
||||
trackMapInstance.value = new BMapGL.Map('trackMap');
|
||||
|
||||
// 计算地图中心点和缩放级别
|
||||
const bounds = calculateBounds(trackPath.value);
|
||||
const centerPoint = new BMapGL.Point(bounds.center.lng, bounds.center.lat);
|
||||
trackMapInstance.value.centerAndZoom(centerPoint, bounds.zoom);
|
||||
trackMapInstance.value.enableScrollWheelZoom(true);
|
||||
|
||||
// 绘制轨迹线
|
||||
const polyline = new BMapGL.Polyline(
|
||||
trackPath.value.map(p => new BMapGL.Point(p.lng, p.lat)),
|
||||
{
|
||||
strokeColor: '#3388ff',
|
||||
strokeWeight: 4,
|
||||
strokeOpacity: 0.8
|
||||
}
|
||||
);
|
||||
trackMapInstance.value.addOverlay(polyline);
|
||||
|
||||
// 添加起点标记
|
||||
if (trackPath.value.length > 0) {
|
||||
const startPoint = new BMapGL.Point(trackPath.value[0].lng, trackPath.value[0].lat);
|
||||
const startMarker = new BMapGL.Marker(startPoint);
|
||||
trackMapInstance.value.addOverlay(startMarker);
|
||||
}
|
||||
|
||||
// 添加终点标记
|
||||
if (trackPath.value.length > 1) {
|
||||
const endPoint = new BMapGL.Point(
|
||||
trackPath.value[trackPath.value.length - 1].lng,
|
||||
trackPath.value[trackPath.value.length - 1].lat
|
||||
);
|
||||
const endMarker = new BMapGL.Marker(endPoint);
|
||||
trackMapInstance.value.addOverlay(endMarker);
|
||||
}
|
||||
|
||||
trackLoading.value = false;
|
||||
} catch (error) {
|
||||
console.error('地图初始化失败:', error);
|
||||
ElMessage.error('地图加载失败');
|
||||
trackLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 计算轨迹边界
|
||||
const calculateBounds = (points) => {
|
||||
if (points.length === 0) {
|
||||
return { center: { lng: 116.404, lat: 39.915 }, zoom: 15 };
|
||||
}
|
||||
|
||||
let minLng = points[0].lng;
|
||||
let maxLng = points[0].lng;
|
||||
let minLat = points[0].lat;
|
||||
let maxLat = points[0].lat;
|
||||
|
||||
points.forEach(point => {
|
||||
minLng = Math.min(minLng, point.lng);
|
||||
maxLng = Math.max(maxLng, point.lng);
|
||||
minLat = Math.min(minLat, point.lat);
|
||||
maxLat = Math.max(maxLat, point.lat);
|
||||
});
|
||||
|
||||
const center = {
|
||||
lng: (minLng + maxLng) / 2,
|
||||
lat: (minLat + maxLat) / 2
|
||||
};
|
||||
|
||||
// 计算缩放级别(简单估算)
|
||||
const lngDiff = maxLng - minLng;
|
||||
const latDiff = maxLat - minLat;
|
||||
const maxDiff = Math.max(lngDiff, latDiff);
|
||||
let zoom = 15;
|
||||
if (maxDiff > 0.1) zoom = 10;
|
||||
else if (maxDiff > 0.05) zoom = 11;
|
||||
else if (maxDiff > 0.02) zoom = 12;
|
||||
else if (maxDiff > 0.01) zoom = 13;
|
||||
else if (maxDiff > 0.005) zoom = 14;
|
||||
|
||||
return { center, zoom };
|
||||
};
|
||||
|
||||
// 删除订单(逻辑删除)
|
||||
const del = (id) => {
|
||||
ElMessageBox.confirm('请确认是否删除订单?删除后将不可恢复', '提示', {
|
||||
|
||||
@@ -155,5 +155,49 @@ public class OrderController {
|
||||
return AjaxResult.error("批量导入订单失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量更新订单的delivery_id字段
|
||||
*/
|
||||
@SaCheckPermission("order:edit")
|
||||
@PostMapping("/updateDeliveryId")
|
||||
public AjaxResult updateDeliveryId(@RequestBody Map<String, Object> params) {
|
||||
try {
|
||||
logger.info("批量更新订单delivery_id,参数:{}", params);
|
||||
|
||||
Integer deliveryId = null;
|
||||
if (params.get("deliveryId") != null) {
|
||||
Object deliveryIdObj = params.get("deliveryId");
|
||||
if (deliveryIdObj instanceof Integer) {
|
||||
deliveryId = (Integer) deliveryIdObj;
|
||||
} else if (deliveryIdObj instanceof String) {
|
||||
try {
|
||||
deliveryId = Integer.parseInt((String) deliveryIdObj);
|
||||
} catch (NumberFormatException e) {
|
||||
logger.error("deliveryId格式不正确:{}", deliveryIdObj);
|
||||
return AjaxResult.error("deliveryId格式不正确");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Integer> orderIds = (List<Integer>) params.get("orderIds");
|
||||
|
||||
if (deliveryId == null) {
|
||||
logger.error("更新失败:运送清单ID不能为空");
|
||||
return AjaxResult.error("运送清单ID不能为空");
|
||||
}
|
||||
|
||||
if (orderIds == null || orderIds.isEmpty()) {
|
||||
logger.warn("订单ID列表为空,跳过更新");
|
||||
return AjaxResult.success("订单ID列表为空,无需更新");
|
||||
}
|
||||
|
||||
return orderService.updateOrderDeliveryId(deliveryId, orderIds);
|
||||
} catch (Exception e) {
|
||||
logger.error("批量更新订单delivery_id失败:{}", e.getMessage(), e);
|
||||
return AjaxResult.error("批量更新订单delivery_id失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,8 +14,8 @@ import java.util.List;
|
||||
*/
|
||||
@Data
|
||||
public class DeliveryCreateDto {
|
||||
/** 关联订单ID */
|
||||
private Integer orderId;
|
||||
/** 关联订单ID(多个订单ID用逗号分隔的字符串,如:"1,2,3") */
|
||||
private String orderId;
|
||||
|
||||
/**
|
||||
* 发货方ID
|
||||
@@ -107,6 +107,11 @@ public class DeliveryCreateDto {
|
||||
@Min(value = 1, message = "牛只数量至少为1")
|
||||
private Integer cattleCount;
|
||||
|
||||
/**
|
||||
* 司机运费(元)
|
||||
*/
|
||||
private java.math.BigDecimal freight;
|
||||
|
||||
/**
|
||||
* 检疫证号
|
||||
*/
|
||||
|
||||
@@ -69,6 +69,9 @@ public class DeliveryEditDto {
|
||||
/** 落地过磅重量 */
|
||||
private String landingEntruckWeight;
|
||||
|
||||
/** 司机运费(元) */
|
||||
private java.math.BigDecimal freight;
|
||||
|
||||
/** 检疫票照片 */
|
||||
private String quarantineTickeyUrl;
|
||||
/** 传纸质磅单(双章) */
|
||||
|
||||
@@ -34,10 +34,10 @@ public class Delivery implements Serializable {
|
||||
private Integer id;
|
||||
|
||||
/**
|
||||
* 订单ID(关联order表)
|
||||
* 订单ID(关联order表,多个订单ID用逗号分隔,如:1,2,3)
|
||||
*/
|
||||
@TableField("order_id")
|
||||
private Integer orderId;
|
||||
private String orderId;
|
||||
|
||||
/**
|
||||
* 运单号
|
||||
@@ -279,6 +279,12 @@ public class Delivery implements Serializable {
|
||||
@TableField("landingEntruck_weight")
|
||||
private String landingEntruckWeight;
|
||||
|
||||
/**
|
||||
* 司机运费(元)
|
||||
*/
|
||||
@TableField("freight")
|
||||
private java.math.BigDecimal freight;
|
||||
|
||||
/**
|
||||
* 检疫票
|
||||
*/
|
||||
|
||||
@@ -53,6 +53,12 @@ public class Order implements Serializable {
|
||||
@TableField("firm_price")
|
||||
private java.math.BigDecimal firmPrice;
|
||||
|
||||
/**
|
||||
* 运送清单ID(关联delivery表)
|
||||
*/
|
||||
@TableField("delivery_id")
|
||||
private Integer deliveryId;
|
||||
|
||||
/**
|
||||
* 逻辑删除标记(0-正常,1-已删除)
|
||||
*/
|
||||
@@ -109,5 +115,35 @@ public class Order implements Serializable {
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String settlementTypeDesc;
|
||||
|
||||
/**
|
||||
* 运单号(关联delivery表,不存储在数据库中,用于显示)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String deliveryNumber;
|
||||
|
||||
/**
|
||||
* 起始地(关联delivery表,不存储在数据库中,用于显示)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String startLocation;
|
||||
|
||||
/**
|
||||
* 目的地(关联delivery表,不存储在数据库中,用于显示)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String endLocation;
|
||||
|
||||
/**
|
||||
* 单价(关联delivery表,不存储在数据库中,用于显示)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private java.math.BigDecimal firmPriceFromDelivery;
|
||||
|
||||
/**
|
||||
* 运送清单状态(关联delivery表,不存储在数据库中,用于显示)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private Integer deliveryStatus;
|
||||
}
|
||||
|
||||
|
||||
@@ -63,5 +63,14 @@ public interface IOrderService extends IService<Order> {
|
||||
* @return AjaxResult
|
||||
*/
|
||||
AjaxResult batchImportOrders(List<Map<String, Object>> orders);
|
||||
|
||||
/**
|
||||
* 批量更新订单的delivery_id字段
|
||||
*
|
||||
* @param deliveryId 运送清单ID
|
||||
* @param orderIds 订单ID列表
|
||||
* @return AjaxResult
|
||||
*/
|
||||
AjaxResult updateOrderDeliveryId(Integer deliveryId, List<Integer> orderIds);
|
||||
}
|
||||
|
||||
|
||||
@@ -797,6 +797,8 @@ public class DeliveryServiceImpl extends ServiceImpl<DeliveryMapper, Delivery> i
|
||||
delivery.setEmptyWeight(StringUtils.isNotEmpty(dto.getEmptyWeight()) ? dto.getEmptyWeight() : null);
|
||||
delivery.setEntruckWeight(StringUtils.isNotEmpty(dto.getEntruckWeight()) ? dto.getEntruckWeight() : null);
|
||||
delivery.setLandingEntruckWeight(StringUtils.isNotEmpty(dto.getLandingEntruckWeight()) ? dto.getLandingEntruckWeight() : null);
|
||||
// 司机运费
|
||||
delivery.setFreight(dto.getFreight());
|
||||
// 照片
|
||||
delivery.setQuarantineTickeyUrl(dto.getQuarantineTickeyUrl());
|
||||
delivery.setPoundListImg(dto.getPoundListImg());
|
||||
@@ -1055,6 +1057,10 @@ public class DeliveryServiceImpl extends ServiceImpl<DeliveryMapper, Delivery> i
|
||||
if (dto.getLandingEntruckWeight() != null) {
|
||||
delivery.setLandingEntruckWeight(StringUtils.isNotEmpty(dto.getLandingEntruckWeight()) ? dto.getLandingEntruckWeight() : null);
|
||||
}
|
||||
// 更新司机运费
|
||||
if (dto.getFreight() != null) {
|
||||
delivery.setFreight(dto.getFreight());
|
||||
}
|
||||
|
||||
// 更新照片字段:将空字符串转换为null,避免前端显示问题
|
||||
// 注意:前端总是传递字段(即使是空字符串),只有在传递了有效URL时才更新
|
||||
|
||||
@@ -46,6 +46,9 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
|
||||
@Autowired
|
||||
private SysUserMapper sysUserMapper;
|
||||
|
||||
@Autowired
|
||||
private com.aiotagro.cattletrade.business.mapper.DeliveryMapper deliveryMapper;
|
||||
|
||||
/**
|
||||
* 分页查询订单列表
|
||||
*/
|
||||
@@ -58,9 +61,13 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
|
||||
String sellerName = params.get("sellerName") != null ? (String) params.get("sellerName") : null;
|
||||
String startTime = params.get("startTime") != null ? (String) params.get("startTime") : null;
|
||||
String endTime = params.get("endTime") != null ? (String) params.get("endTime") : null;
|
||||
String deliveryNumber = params.get("deliveryNumber") != null ? (String) params.get("deliveryNumber") : null;
|
||||
String startLocation = params.get("startLocation") != null ? (String) params.get("startLocation") : null;
|
||||
String endLocation = params.get("endLocation") != null ? (String) params.get("endLocation") : null;
|
||||
String firmPrice = params.get("firmPrice") != null ? (String) params.get("firmPrice") : null;
|
||||
|
||||
logger.info("分页查询订单列表,页码:{},每页数量:{},买方:{},卖方:{},结算方式:{}",
|
||||
pageNum, pageSize, buyerName, sellerName, settlementType);
|
||||
logger.info("分页查询订单列表,页码:{},每页数量:{},买方:{},卖方:{},结算方式:{},运单号:{},起始地:{},目的地:{},单价:{}",
|
||||
pageNum, pageSize, buyerName, sellerName, settlementType, deliveryNumber, startLocation, endLocation, firmPrice);
|
||||
|
||||
// 构建查询条件
|
||||
LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
|
||||
@@ -86,9 +93,13 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
|
||||
|
||||
queryWrapper.orderByDesc(Order::getCreateTime);
|
||||
|
||||
// 判断是否需要先过滤再分页(如果提供了买方或卖方名称搜索)
|
||||
// 判断是否需要先过滤再分页(如果提供了买方、卖方、运单号、起始地、目的地、单价搜索)
|
||||
boolean needFilter = (buyerName != null && !buyerName.trim().isEmpty()) ||
|
||||
(sellerName != null && !sellerName.trim().isEmpty());
|
||||
(sellerName != null && !sellerName.trim().isEmpty()) ||
|
||||
(deliveryNumber != null && !deliveryNumber.trim().isEmpty()) ||
|
||||
(startLocation != null && !startLocation.trim().isEmpty()) ||
|
||||
(endLocation != null && !endLocation.trim().isEmpty()) ||
|
||||
(firmPrice != null && !firmPrice.trim().isEmpty());
|
||||
|
||||
List<Order> filteredList;
|
||||
long total;
|
||||
@@ -112,6 +123,32 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
|
||||
.filter(order -> order.getSellerName() != null && order.getSellerName().contains(sellerName.trim()))
|
||||
.collect(java.util.stream.Collectors.toList());
|
||||
}
|
||||
if (deliveryNumber != null && !deliveryNumber.trim().isEmpty()) {
|
||||
filteredList = filteredList.stream()
|
||||
.filter(order -> order.getDeliveryNumber() != null && order.getDeliveryNumber().contains(deliveryNumber.trim()))
|
||||
.collect(java.util.stream.Collectors.toList());
|
||||
}
|
||||
if (startLocation != null && !startLocation.trim().isEmpty()) {
|
||||
filteredList = filteredList.stream()
|
||||
.filter(order -> order.getStartLocation() != null && order.getStartLocation().contains(startLocation.trim()))
|
||||
.collect(java.util.stream.Collectors.toList());
|
||||
}
|
||||
if (endLocation != null && !endLocation.trim().isEmpty()) {
|
||||
filteredList = filteredList.stream()
|
||||
.filter(order -> order.getEndLocation() != null && order.getEndLocation().contains(endLocation.trim()))
|
||||
.collect(java.util.stream.Collectors.toList());
|
||||
}
|
||||
if (firmPrice != null && !firmPrice.trim().isEmpty()) {
|
||||
filteredList = filteredList.stream()
|
||||
.filter(order -> {
|
||||
java.math.BigDecimal price = order.getFirmPriceFromDelivery() != null ? order.getFirmPriceFromDelivery() : order.getFirmPrice();
|
||||
if (price == null) {
|
||||
return false;
|
||||
}
|
||||
return price.toString().contains(firmPrice.trim());
|
||||
})
|
||||
.collect(java.util.stream.Collectors.toList());
|
||||
}
|
||||
|
||||
// 获取总数
|
||||
total = filteredList.size();
|
||||
@@ -143,6 +180,45 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
|
||||
logger.info("查询到{}条订单记录,分页后{}条", total, filteredList.size());
|
||||
}
|
||||
|
||||
// 优化排序:按运送清单分组排序
|
||||
// 排序规则:1. 有deliveryId的订单按deliveryId分组,相同deliveryId的订单放在一起
|
||||
// 2. 按deliveryId排序(null值放在最后)
|
||||
// 3. 同一deliveryId内的订单按创建时间排序
|
||||
filteredList.sort((o1, o2) -> {
|
||||
Integer deliveryId1 = o1.getDeliveryId();
|
||||
Integer deliveryId2 = o2.getDeliveryId();
|
||||
|
||||
// 如果两个订单都没有deliveryId,按创建时间倒序
|
||||
if (deliveryId1 == null && deliveryId2 == null) {
|
||||
if (o1.getCreateTime() != null && o2.getCreateTime() != null) {
|
||||
return o2.getCreateTime().compareTo(o1.getCreateTime());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 如果只有一个订单有deliveryId,有deliveryId的排在前面
|
||||
if (deliveryId1 == null) {
|
||||
return 1; // o1排在后面
|
||||
}
|
||||
if (deliveryId2 == null) {
|
||||
return -1; // o2排在后面
|
||||
}
|
||||
|
||||
// 两个订单都有deliveryId,先按deliveryId排序
|
||||
int deliveryIdCompare = deliveryId1.compareTo(deliveryId2);
|
||||
if (deliveryIdCompare != 0) {
|
||||
return deliveryIdCompare;
|
||||
}
|
||||
|
||||
// deliveryId相同,按创建时间倒序
|
||||
if (o1.getCreateTime() != null && o2.getCreateTime() != null) {
|
||||
return o2.getCreateTime().compareTo(o1.getCreateTime());
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
logger.info("订单列表排序完成,共{}条记录", filteredList.size());
|
||||
|
||||
// 构建分页结果
|
||||
return new PageResultResponse<>(total, filteredList);
|
||||
}
|
||||
@@ -336,6 +412,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
|
||||
java.util.Set<Integer> buyerIds = new java.util.HashSet<>();
|
||||
java.util.Set<Integer> sellerIds = new java.util.HashSet<>();
|
||||
java.util.Set<Integer> creatorIds = new java.util.HashSet<>();
|
||||
java.util.Set<Integer> deliveryIds = new java.util.HashSet<>();
|
||||
|
||||
for (Order order : orders) {
|
||||
// 收集买方ID
|
||||
@@ -368,6 +445,10 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
|
||||
if (order.getCreatedBy() != null) {
|
||||
creatorIds.add(order.getCreatedBy());
|
||||
}
|
||||
// 收集运送清单ID
|
||||
if (order.getDeliveryId() != null) {
|
||||
deliveryIds.add(order.getDeliveryId());
|
||||
}
|
||||
}
|
||||
|
||||
// 批量查询买方信息
|
||||
@@ -427,6 +508,21 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
|
||||
}
|
||||
}
|
||||
|
||||
// 批量查询运送清单信息
|
||||
java.util.Map<Integer, com.aiotagro.cattletrade.business.entity.Delivery> deliveryMap = new java.util.HashMap<>();
|
||||
if (!deliveryIds.isEmpty()) {
|
||||
try {
|
||||
List<com.aiotagro.cattletrade.business.entity.Delivery> deliveryList = deliveryMapper.selectBatchIds(new ArrayList<>(deliveryIds));
|
||||
for (com.aiotagro.cattletrade.business.entity.Delivery delivery : deliveryList) {
|
||||
if (delivery != null && delivery.getId() != null) {
|
||||
deliveryMap.put(delivery.getId(), delivery);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.warn("批量查询运送清单信息失败:{}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// 批量填充订单信息
|
||||
for (Order order : orders) {
|
||||
// 填充买方名称
|
||||
@@ -473,6 +569,24 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
|
||||
}
|
||||
}
|
||||
|
||||
// 填充运送清单信息
|
||||
if (order.getDeliveryId() != null) {
|
||||
com.aiotagro.cattletrade.business.entity.Delivery delivery = deliveryMap.get(order.getDeliveryId());
|
||||
if (delivery != null) {
|
||||
order.setDeliveryNumber(delivery.getDeliveryNumber());
|
||||
order.setStartLocation(delivery.getStartLocation());
|
||||
order.setEndLocation(delivery.getEndLocation());
|
||||
order.setDeliveryStatus(delivery.getStatus());
|
||||
// 如果订单本身没有firmPrice,使用运送清单的firmPrice
|
||||
if (order.getFirmPrice() == null && delivery.getFirmPrice() != null) {
|
||||
order.setFirmPriceFromDelivery(java.math.BigDecimal.valueOf(delivery.getFirmPrice()));
|
||||
} else if (delivery.getFirmPrice() != null) {
|
||||
// 如果订单有firmPrice,也填充运送清单的firmPrice用于显示
|
||||
order.setFirmPriceFromDelivery(java.math.BigDecimal.valueOf(delivery.getFirmPrice()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 填充结算方式描述
|
||||
if (order.getSettlementType() != null) {
|
||||
switch (order.getSettlementType()) {
|
||||
@@ -672,5 +786,87 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
|
||||
return AjaxResult.success("批量导入完成:成功" + successCount + "条,失败" + failCount + "条", result);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量更新订单的delivery_id字段
|
||||
*
|
||||
* @param deliveryId 运送清单ID
|
||||
* @param orderIds 订单ID列表
|
||||
* @return AjaxResult
|
||||
*/
|
||||
@Override
|
||||
@Transactional
|
||||
public AjaxResult updateOrderDeliveryId(Integer deliveryId, List<Integer> orderIds) {
|
||||
try {
|
||||
logger.info("批量更新订单delivery_id,运送清单ID:{},订单ID列表:{}", deliveryId, orderIds);
|
||||
|
||||
if (orderIds == null || orderIds.isEmpty()) {
|
||||
logger.warn("订单ID列表为空,跳过更新");
|
||||
return AjaxResult.success("订单ID列表为空,无需更新");
|
||||
}
|
||||
|
||||
if (deliveryId == null) {
|
||||
logger.error("运送清单ID不能为空");
|
||||
return AjaxResult.error("运送清单ID不能为空");
|
||||
}
|
||||
|
||||
// 批量更新订单的delivery_id
|
||||
int successCount = 0;
|
||||
int failCount = 0;
|
||||
List<String> failMessages = new ArrayList<>();
|
||||
|
||||
for (Integer orderId : orderIds) {
|
||||
try {
|
||||
Order order = orderMapper.selectById(orderId);
|
||||
if (order == null) {
|
||||
failCount++;
|
||||
failMessages.add("订单ID " + orderId + " 不存在");
|
||||
logger.warn("订单不存在,ID:{}", orderId);
|
||||
continue;
|
||||
}
|
||||
|
||||
order.setDeliveryId(deliveryId);
|
||||
order.setUpdateTime(new Date());
|
||||
try {
|
||||
order.setUpdatedBy(SecurityUtil.getCurrentUserId());
|
||||
} catch (Exception e) {
|
||||
logger.warn("获取当前用户失败,使用订单原有创建人:{}", e.getMessage());
|
||||
if (order.getCreatedBy() != null) {
|
||||
order.setUpdatedBy(order.getCreatedBy());
|
||||
}
|
||||
}
|
||||
|
||||
int result = orderMapper.updateById(order);
|
||||
if (result > 0) {
|
||||
successCount++;
|
||||
logger.info("更新订单delivery_id成功,订单ID:{},运送清单ID:{}", orderId, deliveryId);
|
||||
} else {
|
||||
failCount++;
|
||||
failMessages.add("订单ID " + orderId + " 更新失败");
|
||||
logger.warn("更新订单delivery_id失败,订单ID:{}", orderId);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
failCount++;
|
||||
failMessages.add("订单ID " + orderId + " 更新异常:" + e.getMessage());
|
||||
logger.error("更新订单delivery_id异常,订单ID:{},错误:{}", orderId, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
logger.info("批量更新订单delivery_id完成,成功:{}条,失败:{}条", successCount, failCount);
|
||||
|
||||
if (failCount == 0) {
|
||||
return AjaxResult.success("批量更新成功,共更新" + successCount + "条订单");
|
||||
} else {
|
||||
Map<String, Object> result = new java.util.HashMap<>();
|
||||
result.put("successCount", successCount);
|
||||
result.put("failCount", failCount);
|
||||
result.put("failMessages", failMessages);
|
||||
return AjaxResult.success("批量更新完成:成功" + successCount + "条,失败" + failCount + "条", result);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("批量更新订单delivery_id异常:{}", e.getMessage(), e);
|
||||
return AjaxResult.error("批量更新订单delivery_id失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
USE cattletrade;
|
||||
|
||||
-- 修改 delivery 表的 order_id 字段类型为 VARCHAR,用于存储多个订单ID(逗号分隔)
|
||||
-- 将原来的 INTEGER 类型改为 VARCHAR(500),支持存储多个订单ID,如 "1,2,3"
|
||||
|
||||
-- 注意:如果表中已有数据,需要先将现有的 order_id 值转换为字符串格式
|
||||
-- 例如:如果 order_id = 123,转换后仍为 "123"
|
||||
|
||||
ALTER TABLE `delivery`
|
||||
MODIFY COLUMN `order_id` VARCHAR(500) NULL DEFAULT NULL COMMENT '订单ID(多个订单ID用逗号分隔,如:1,2,3)';
|
||||
|
||||
-- 如果表中已有数据,将现有的整数 order_id 转换为字符串格式
|
||||
-- UPDATE delivery SET order_id = CAST(order_id AS CHAR) WHERE order_id IS NOT NULL;
|
||||
|
||||
Reference in New Issue
Block a user