diff --git a/pc-cattle-transportation/src/api/shipping.js b/pc-cattle-transportation/src/api/shipping.js
index 8230717..4a82338 100644
--- a/pc-cattle-transportation/src/api/shipping.js
+++ b/pc-cattle-transportation/src/api/shipping.js
@@ -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({
diff --git a/pc-cattle-transportation/src/views/entry/details.vue b/pc-cattle-transportation/src/views/entry/details.vue
index 8bdd7be..f5cbac9 100644
--- a/pc-cattle-transportation/src/views/entry/details.vue
+++ b/pc-cattle-transportation/src/views/entry/details.vue
@@ -41,6 +41,7 @@
{{ data.baseInfo.endLocation || '-' }}
{{ data.baseInfo.estimatedDeliveryTime || '-' }}
{{ data.baseInfo.createTime || '' }}
+ {{ data.baseInfo.freight ? data.baseInfo.freight + ' 元' : '-' }}
{{ totalRegisteredDevices }} 个
diff --git a/pc-cattle-transportation/src/views/shipping/createDeliveryDialog.vue b/pc-cattle-transportation/src/views/shipping/createDeliveryDialog.vue
index 356fb6a..82820ac 100644
--- a/pc-cattle-transportation/src/views/shipping/createDeliveryDialog.vue
+++ b/pc-cattle-transportation/src/views/shipping/createDeliveryDialog.vue
@@ -14,10 +14,11 @@
>
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -224,6 +198,19 @@
/>
+
+
+
+ 元
+
+
+
@@ -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,
diff --git a/pc-cattle-transportation/src/views/shipping/loadingOrder.vue b/pc-cattle-transportation/src/views/shipping/loadingOrder.vue
index 7782b15..19f99dd 100644
--- a/pc-cattle-transportation/src/views/shipping/loadingOrder.vue
+++ b/pc-cattle-transportation/src/views/shipping/loadingOrder.vue
@@ -55,6 +55,26 @@
{{ scope.row.settlementTypeDesc || '--' }}
+
+
+ {{ scope.row.deliveryNumber || '--' }}
+
+
+
+
+ {{ scope.row.startLocation || '--' }}
+
+
+
+
+ {{ scope.row.endLocation || '--' }}
+
+
+
+
+ {{ (scope.row.firmPriceFromDelivery || scope.row.firmPrice) ? ((scope.row.firmPriceFromDelivery || scope.row.firmPrice) + ' 元/斤') : '--' }}
+
+
{{ scope.row.createdByName || '--' }}
@@ -65,10 +85,26 @@
{{ scope.row.createTime || '--' }}
-
+
编辑
删除
+
+ 详情
+
+
+ 查看轨迹
+
@@ -85,6 +121,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ 轨迹点数:{{ trackPath.length }}
+
+
+
+
+
@@ -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('请确认是否删除订单?删除后将不可恢复', '提示', {
diff --git a/tradeCattle/aiotagro-cattle-trade/src/main/java/com/aiotagro/cattletrade/business/controller/OrderController.java b/tradeCattle/aiotagro-cattle-trade/src/main/java/com/aiotagro/cattletrade/business/controller/OrderController.java
index d69518f..8f8794a 100644
--- a/tradeCattle/aiotagro-cattle-trade/src/main/java/com/aiotagro/cattletrade/business/controller/OrderController.java
+++ b/tradeCattle/aiotagro-cattle-trade/src/main/java/com/aiotagro/cattletrade/business/controller/OrderController.java
@@ -155,5 +155,49 @@ public class OrderController {
return AjaxResult.error("批量导入订单失败:" + e.getMessage());
}
}
+
+ /**
+ * 批量更新订单的delivery_id字段
+ */
+ @SaCheckPermission("order:edit")
+ @PostMapping("/updateDeliveryId")
+ public AjaxResult updateDeliveryId(@RequestBody Map 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 orderIds = (List) 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());
+ }
+ }
}
diff --git a/tradeCattle/aiotagro-cattle-trade/src/main/java/com/aiotagro/cattletrade/business/dto/DeliveryCreateDto.java b/tradeCattle/aiotagro-cattle-trade/src/main/java/com/aiotagro/cattletrade/business/dto/DeliveryCreateDto.java
index 84cad2f..438ab1f 100644
--- a/tradeCattle/aiotagro-cattle-trade/src/main/java/com/aiotagro/cattletrade/business/dto/DeliveryCreateDto.java
+++ b/tradeCattle/aiotagro-cattle-trade/src/main/java/com/aiotagro/cattletrade/business/dto/DeliveryCreateDto.java
@@ -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;
+
/**
* 检疫证号
*/
diff --git a/tradeCattle/aiotagro-cattle-trade/src/main/java/com/aiotagro/cattletrade/business/dto/DeliveryEditDto.java b/tradeCattle/aiotagro-cattle-trade/src/main/java/com/aiotagro/cattletrade/business/dto/DeliveryEditDto.java
index f143161..ade673d 100644
--- a/tradeCattle/aiotagro-cattle-trade/src/main/java/com/aiotagro/cattletrade/business/dto/DeliveryEditDto.java
+++ b/tradeCattle/aiotagro-cattle-trade/src/main/java/com/aiotagro/cattletrade/business/dto/DeliveryEditDto.java
@@ -69,6 +69,9 @@ public class DeliveryEditDto {
/** 落地过磅重量 */
private String landingEntruckWeight;
+ /** 司机运费(元) */
+ private java.math.BigDecimal freight;
+
/** 检疫票照片 */
private String quarantineTickeyUrl;
/** 传纸质磅单(双章) */
diff --git a/tradeCattle/aiotagro-cattle-trade/src/main/java/com/aiotagro/cattletrade/business/entity/Delivery.java b/tradeCattle/aiotagro-cattle-trade/src/main/java/com/aiotagro/cattletrade/business/entity/Delivery.java
index 21cd73e..ee4830c 100644
--- a/tradeCattle/aiotagro-cattle-trade/src/main/java/com/aiotagro/cattletrade/business/entity/Delivery.java
+++ b/tradeCattle/aiotagro-cattle-trade/src/main/java/com/aiotagro/cattletrade/business/entity/Delivery.java
@@ -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;
+
/**
* 检疫票
*/
diff --git a/tradeCattle/aiotagro-cattle-trade/src/main/java/com/aiotagro/cattletrade/business/entity/Order.java b/tradeCattle/aiotagro-cattle-trade/src/main/java/com/aiotagro/cattletrade/business/entity/Order.java
index 8ff6ba0..0747335 100644
--- a/tradeCattle/aiotagro-cattle-trade/src/main/java/com/aiotagro/cattletrade/business/entity/Order.java
+++ b/tradeCattle/aiotagro-cattle-trade/src/main/java/com/aiotagro/cattletrade/business/entity/Order.java
@@ -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;
}
diff --git a/tradeCattle/aiotagro-cattle-trade/src/main/java/com/aiotagro/cattletrade/business/service/IOrderService.java b/tradeCattle/aiotagro-cattle-trade/src/main/java/com/aiotagro/cattletrade/business/service/IOrderService.java
index 92294fd..b99605d 100644
--- a/tradeCattle/aiotagro-cattle-trade/src/main/java/com/aiotagro/cattletrade/business/service/IOrderService.java
+++ b/tradeCattle/aiotagro-cattle-trade/src/main/java/com/aiotagro/cattletrade/business/service/IOrderService.java
@@ -63,5 +63,14 @@ public interface IOrderService extends IService {
* @return AjaxResult
*/
AjaxResult batchImportOrders(List