优化项目细节和sql查询

This commit is contained in:
xuqiuyun
2025-11-28 17:12:36 +08:00
parent 128a4b2c6b
commit e968fcf52a
24 changed files with 1928 additions and 694 deletions

View File

@@ -326,4 +326,28 @@ export function updateDeliveryInfo(data) {
method: 'POST',
data,
});
}
// ==================== 订单关联管理 API ====================
// 解除订单与运送清单的关联
export function unbindOrderFromDelivery(orderId) {
return request({
url: '/order/unbindFromDelivery',
method: 'POST',
data: { orderId },
});
}
// 查询运送清单关联的订单列表
export function getOrdersByDeliveryId(deliveryId) {
return request({
url: '/order/list',
method: 'POST',
data: {
deliveryId: deliveryId,
pageNum: 1,
pageSize: 1000, // 获取所有关联的订单
},
});
}

View File

@@ -98,7 +98,7 @@ app.use(JsonViewer);
app.use(BaiduMap, {
// ak 是在百度地图开发者平台申请的密钥 详见 http://lbsyun.baidu.com/apiconsole/key */
ak: 'fLz8UwJSM3ayYl6dtsWYp7TQ8993R6kC', //
ak: 'xITbC7jegaAAuu4m9jC2Zx6eFbQJ29Rj', //
// v: '2.0', // 默认使用3.0
// type: 'WebGL' // ||API 默认API (使用此模式 BMap=BMapGL)
// type: 'WebGL', // ||API 默认API (使用此模式 BMap=BMapGL)

View File

@@ -237,18 +237,6 @@ export const constantRoutes: Array<RouteRecordRaw> = [
requireAuth: true,
},
children: [
{
path: 'loadingOrder', // ✅ 修复:使用相对路径
name: 'LoadingOrder',
meta: {
title: '装车订单',
keepAlive: true,
requireAuth: true,
},
component: () => import('~/views/shipping/loadingOrder.vue'),
},
{
path: 'shippinglist', // ✅ 修复:使用相对路径
name: 'ShippingList',
@@ -259,6 +247,19 @@ export const constantRoutes: Array<RouteRecordRaw> = [
},
component: () => import('~/views/entry/attestation.vue'),
},
{
path: 'loadingOrder', // ✅ 修复:使用相对路径
name: 'LoadingOrder',
meta: {
title: '订单信息',
keepAlive: true,
requireAuth: true,
},
component: () => import('~/views/shipping/loadingOrder.vue'),
},
],
},

View File

@@ -6,7 +6,7 @@ export function BMPGL(ak) {
};
const script = document.createElement('script');
script.type = 'text/javascript';
script.src = `http://api.map.baidu.com/api?v=3.0&type=webgl&ak=${ak}&callback=init`;
script.src = `https://api.map.baidu.com/api?v=3.0&type=webgl&ak=${ak}&callback=init`;
script.onerror = reject;
document.head.appendChild(script);
});

View File

@@ -749,7 +749,7 @@ const loadDeviceLogs = async (deviceId, deviceType, deliveryId) => {
const initMap = async () => {
try {
// 使用百度地图 API Key
const BMapGL = await BMPGL('fLz8UwJSM3ayYl6dtsWYp7TQ8993R6kC');
const BMapGL = await BMPGL('xITbC7jegaAAuu4m9jC2Zx6eFbQJ29Rj');
const lat = parseFloat(warningData.latitude);
const lon = parseFloat(warningData.longitude);
@@ -1054,7 +1054,7 @@ const initTrackMap = async () => {
}
try {
const BMapGL = await BMPGL('fLz8UwJSM3ayYl6dtsWYp7TQ8993R6kC');
const BMapGL = await BMPGL('xITbC7jegaAAuu4m9jC2Zx6eFbQJ29Rj');
trackBMapGL.value = BMapGL; // 保存 BMapGL 实例
// 创建地图实例
@@ -1147,7 +1147,7 @@ const drawStaticTrack = (BMapGL) => {
// 使用简单的圆形标记作为起点(绿色)
const startMarker = new BMapGL.Marker(startPoint, {
icon: new BMapGL.Icon(
'http://api.map.baidu.com/images/marker_red.png',
'https://api.map.baidu.com/images/marker_red.png',
new BMapGL.Size(32, 32),
{ anchor: new BMapGL.Size(16, 32) }
)
@@ -1174,7 +1174,7 @@ const drawStaticTrack = (BMapGL) => {
// 使用红色标记作为终点
const endMarker = new BMapGL.Marker(endPoint, {
icon: new BMapGL.Icon(
'http://api.map.baidu.com/images/marker_red.png',
'https://api.map.baidu.com/images/marker_red.png',
new BMapGL.Size(32, 32),
{ anchor: new BMapGL.Size(16, 32) }
)
@@ -1219,7 +1219,7 @@ const drawDynamicTrack = (BMapGL) => {
const startPoint = new BMapGL.Point(trackPath.value[0].lng, trackPath.value[0].lat);
const startMarker = new BMapGL.Marker(startPoint, {
icon: new BMapGL.Icon(
'http://api.map.baidu.com/images/marker_red.png',
'https://api.map.baidu.com/images/marker_red.png',
new BMapGL.Size(32, 32),
{ anchor: new BMapGL.Size(16, 32) }
)
@@ -1232,7 +1232,7 @@ const drawDynamicTrack = (BMapGL) => {
const currentPoint = new BMapGL.Point(trackPath.value[0].lng, trackPath.value[0].lat);
const playMarker = new BMapGL.Marker(currentPoint, {
icon: new BMapGL.Icon(
'http://api.map.baidu.com/images/marker_red.png',
'https://api.map.baidu.com/images/marker_red.png',
new BMapGL.Size(20, 20),
{ anchor: new BMapGL.Size(10, 20) }
)

View File

@@ -2,6 +2,21 @@
<div>
<base-search :formItemList="formItemList" @search="searchFrom" ref="baseSearchRef"> </base-search>
<!-- 横向滚动操作栏 -->
<div class="operation-scroll-bar">
<div class="operation-scroll-container">
<!-- <el-button type="primary" v-hasPermi="['loading:create']" @click="showAddOrderDialog(null)">创建订单</el-button> -->
<el-button
type="primary"
v-hasPermi="['loading:add']"
@click="showCreateDeliveryDialog"
style="margin-left: 10px"
>
新增运送清单
</el-button>
</div>
</div>
<div class="main-container">
<el-table v-loading="dataListLoading" :data="data.rows" border element-loading-text="数据加载中...">
<el-table-column label="运单号" prop="deliveryNumber"></el-table-column>
@@ -94,11 +109,12 @@
<el-table-column label="司机姓名" prop="driverName"> </el-table-column>
<el-table-column label="创建时间" prop="createTime"></el-table-column>
<el-table-column label="创建人" prop="createByName"></el-table-column>
<el-table-column label="操作" width="350">
<el-table-column label="操作" width="400">
<template #default="scope">
<div class="table_column_operation">
<el-button type="primary" link @click="details(scope.row, scope.row.warningTypeList ? scope.row.warningTypeList.length : 0)" v-hasPermi="['entry:view']">详情</el-button>
<el-button type="primary" link @click="viewDevices(scope.row)" v-hasPermi="['entry:device']">查看设备</el-button>
<el-button type="primary" link @click="showAddOrderDialog(scope.row.id)" v-hasPermi="['entry:order:create']">新增订单</el-button>
<el-button type="warning" link @click="editDelivery(scope.row)" v-hasPermi="['entry:edit']">编辑</el-button>
<el-button type="success" link @click="updateStatus(scope.row)" v-hasPermi="['entry:status']">修改状态</el-button>
<el-button type="info" link @click="downloadPackage(scope.row)" :loading="downLoading[scope.row.id]" v-hasPermi="['entry:download']">打包文件</el-button>
@@ -122,6 +138,8 @@
<!-- 编辑对话框 -->
<createDeliveryDialog ref="editDialogRef" @success="getDataList" />
<!-- 订单对话框 -->
<OrderDialog ref="OrderDialogRef" @success="handleOrderSuccess" />
</div>
</template>
@@ -132,6 +150,7 @@ import { ElMessage, ElMessageBox } from 'element-plus';
import baseSearch from '@/components/common/searchCustom/index.vue';
import Pagination from '@/components/Pagination/index.vue';
import createDeliveryDialog from '@/views/shipping/createDeliveryDialog.vue';
import OrderDialog from '@/views/shipping/orderDialog.vue';
import { inspectionList, downloadZip, pageDeviceList } from '@/api/abroad.js';
import { updateDeliveryStatus, deleteDeliveryLogic, downloadDeliveryPackage, getDeliveryDetail, downloadAcceptanceForm } from '@/api/shipping.js';
@@ -139,6 +158,7 @@ const router = useRouter();
const route = useRoute();
const baseSearchRef = ref();
const editDialogRef = ref();
const OrderDialogRef = ref();
const dataListLoading = ref(false);
const downLoading = reactive({});
const form = reactive({
@@ -837,9 +857,87 @@ const downloadAcceptanceFormHandler = async (row) => {
}
};
// 显示创建订单对话框
const showAddOrderDialog = (deliveryId) => {
if (OrderDialogRef.value) {
OrderDialogRef.value.onShowDialog(null, deliveryId);
}
};
// 显示新增运送清单对话框
const showCreateDeliveryDialog = () => {
if (editDialogRef.value) {
editDialogRef.value.open();
}
};
// 订单创建成功回调
const handleOrderSuccess = () => {
getDataList();
};
onMounted(() => {
getDataList();
});
</script>
<style lang="less" scoped></style>
<style lang="less" scoped>
/* 横向滚动操作栏样式 */
.operation-scroll-bar {
background: #fff;
border: 1px solid #e9ecef;
border-radius: 8px;
margin-bottom: 16px;
padding: 12px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}
.operation-scroll-container {
display: flex;
overflow-x: auto;
gap: 10px;
padding-bottom: 5px;
/* 自定义滚动条样式 */
&::-webkit-scrollbar {
height: 6px;
}
&::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 3px;
}
&::-webkit-scrollbar-thumb {
background: #c1c1c1;
border-radius: 3px;
&:hover {
background: #a8a8a8;
}
}
/* 确保按钮不会被压缩 */
.el-button {
flex-shrink: 0;
white-space: nowrap;
}
}
/* 响应式设计 */
@media (max-width: 768px) {
.operation-scroll-bar {
padding: 8px;
margin-bottom: 12px;
}
.operation-scroll-container {
gap: 8px;
.el-button {
font-size: 12px;
padding: 6px 12px;
}
}
}
</style>

View File

@@ -33,8 +33,8 @@
</template>
<el-descriptions :column="4" border size="large">
<el-descriptions-item label="运单号">{{ data.baseInfo.deliveryNumber || '-' }}</el-descriptions-item>
<el-descriptions-item label="卖方">{{ data.baseInfo.supplierName || '-' }}</el-descriptions-item>
<el-descriptions-item label="买方">{{ data.baseInfo.buyerName || '-' }}</el-descriptions-item>
<el-descriptions-item label="卖方">{{ getSupplierName() }}</el-descriptions-item>
<el-descriptions-item label="买方">{{ getBuyerName() }}</el-descriptions-item>
<el-descriptions-item label="车牌号">{{ data.baseInfo.licensePlate || '-' }}</el-descriptions-item>
<el-descriptions-item label="司机姓名">{{ data.baseInfo.driverName || '-' }}</el-descriptions-item>
<el-descriptions-item label="起始地">{{ data.baseInfo.startLocation || '-' }}</el-descriptions-item>
@@ -85,18 +85,41 @@
<!-- 重量信息分组 -->
<div v-if="hasValue(data.baseInfo.emptyWeight) || hasValue(data.baseInfo.entruckWeight) || hasValue(data.baseInfo.landingEntruckWeight)" class="info-group">
<div class="sub-title">重量信息</div>
<el-descriptions :column="3" border>
<el-descriptions-item v-if="hasValue(data.baseInfo.emptyWeight)" label="空车过磅重量">
{{ data.baseInfo.emptyWeight }}kg
</el-descriptions-item>
<el-descriptions-item v-if="hasValue(data.baseInfo.entruckWeight)" label="装车过磅重量">
{{ data.baseInfo.entruckWeight }}kg
</el-descriptions-item>
<el-descriptions-item v-if="hasValue(data.baseInfo.landingEntruckWeight)" label="落地过磅重量">
{{ data.baseInfo.landingEntruckWeight }}kg
</el-descriptions-item>
</el-descriptions>
<div class="card-header">
<span class="header-title">重量信息</span>
</div>
<div class="weight-info-container">
<!-- 基础重量信息 -->
<div class="weight-basic-info">
<el-descriptions :column="3" border size="large">
<el-descriptions-item v-if="hasValue(data.baseInfo.emptyWeight)" label="空车过磅重量">
{{ data.baseInfo.emptyWeight }}kg
</el-descriptions-item>
<el-descriptions-item v-if="hasValue(data.baseInfo.entruckWeight)" label="装车过磅重量">
{{ data.baseInfo.entruckWeight }}kg
</el-descriptions-item>
<el-descriptions-item v-if="hasValue(data.baseInfo.landingEntruckWeight)" label="落地过磅重量">
{{ data.baseInfo.landingEntruckWeight }}kg
</el-descriptions-item>
</el-descriptions>
</div>
<!-- 计算重量信息 -->
<div class="weight-calculated-info">
<el-descriptions :column="3" border size="large">
<el-descriptions-item v-if="departureCattleWeight !== null" label="发车牛只重量">
<span class="calculated-value">{{ departureCattleWeight }}kg</span>
</el-descriptions-item>
<el-descriptions-item v-if="landingCattleWeight !== null" label="落地牛只重量">
<span class="calculated-value">{{ landingCattleWeight }}kg</span>
</el-descriptions-item>
<el-descriptions-item v-if="weightLoss !== null" label="损耗">
<span class="calculated-value loss-value" :class="{ 'positive-loss': weightLoss < 0, 'negative-loss': weightLoss > 0 }">
{{ weightLoss > 0 ? '-' : weightLoss < 0 ? '+' : '' }}{{ Math.abs(weightLoss) }}kg
</span>
</el-descriptions-item>
</el-descriptions>
</div>
</div>
</div>
<!-- 照片信息分组 -->
@@ -185,7 +208,7 @@
/>
</div>
<div class="media-item" v-if="hasValue(data.baseInfo.destinationPoundListImg)">
<div class="media-label">地纸质磅单</div>
<div class="media-label">地纸质磅单</div>
<el-image
class="photo-img"
:src="data.baseInfo.destinationPoundListImg"
@@ -195,7 +218,7 @@
/>
</div>
<div class="media-item" v-if="hasValue(data.baseInfo.destinationVehicleFrontPhoto)">
<div class="media-label">地过重磅车头</div>
<div class="media-label">地过重磅车头</div>
<el-image
class="photo-img"
:src="data.baseInfo.destinationVehicleFrontPhoto"
@@ -236,7 +259,7 @@
<video controls :src="data.baseInfo.unloadCattleVideo" />
</div>
<div class="media-item video-item" v-if="hasValue(data.baseInfo.destinationWeightVideo)">
<div class="media-label">地过磅视频</div>
<div class="media-label">地过磅视频</div>
<video controls :src="data.baseInfo.destinationWeightVideo" />
</div>
</div>
@@ -1119,6 +1142,40 @@ const getStatusType = (status) => {
};
// 判断字段是否有有效值(用于隐藏空值字段)
// 计算发车牛只重量(装车过磅重量 - 空车过磅重量)
const departureCattleWeight = computed(() => {
const emptyWeight = parseFloat(data.baseInfo.emptyWeight);
const entruckWeight = parseFloat(data.baseInfo.entruckWeight);
if (!isNaN(emptyWeight) && !isNaN(entruckWeight) && emptyWeight > 0 && entruckWeight > 0) {
const result = entruckWeight - emptyWeight;
return result > 0 ? result.toFixed(2) : null;
}
return null;
});
// 计算落地牛只重量(落地过磅重量 - 空车过磅重量)
const landingCattleWeight = computed(() => {
const emptyWeight = parseFloat(data.baseInfo.emptyWeight);
const landingWeight = parseFloat(data.baseInfo.landingEntruckWeight);
if (!isNaN(emptyWeight) && !isNaN(landingWeight) && emptyWeight > 0 && landingWeight > 0) {
const result = landingWeight - emptyWeight;
return result > 0 ? result.toFixed(2) : null;
}
return null;
});
// 计算损耗(发车牛只重量 - 落地牛只重量)
// 正数表示损耗(减少),负数表示增重(增加)
const weightLoss = computed(() => {
const departure = departureCattleWeight.value;
const landing = landingCattleWeight.value;
if (departure !== null && landing !== null) {
const result = parseFloat(departure) - parseFloat(landing);
return result.toFixed(2);
}
return null;
});
const hasValue = (value) => {
if (value === null || value === undefined) {
return false;
@@ -1129,6 +1186,26 @@ const hasValue = (value) => {
return true;
};
// 获取卖方名称:如果是从订单页面进入的,使用订单的卖方;否则显示 '-'
const getSupplierName = () => {
// 检查是否从订单页面进入(通过路由参数 fromOrder 判断)
if (route.query.fromOrder === 'true' && route.query.sellerName) {
return route.query.sellerName;
}
// 不是从订单页面进入的,直接显示 '-'
return '-';
};
// 获取买方名称:如果是从订单页面进入的,使用订单的买方;否则显示 '-'
const getBuyerName = () => {
// 检查是否从订单页面进入(通过路由参数 fromOrder 判断)
if (route.query.fromOrder === 'true' && route.query.buyerName) {
return route.query.buyerName;
}
// 不是从订单页面进入的,直接显示 '-'
return '-';
};
onMounted(() => {
data.id = route.query.id;
data.status = route.query.status;
@@ -1260,6 +1337,44 @@ onMounted(() => {
}
}
.weight-info-container {
display: flex;
flex-direction: row;
gap: 20px;
flex-wrap: wrap;
}
.weight-basic-info,
.weight-calculated-info {
flex: 1;
min-width: 400px;
}
.weight-calculated-info {
.calculated-value {
font-weight: 600;
font-size: 16px;
color: #303133;
}
.loss-value {
&.positive-loss {
color: #67c23a; // 绿色表示增重
}
&.negative-loss {
color: #f56c6c; // 红色表示损耗
}
}
}
@media (max-width: 1200px) {
.weight-basic-info,
.weight-calculated-info {
min-width: 100%;
}
}
.media-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));

View File

@@ -22,12 +22,13 @@
clearable
filterable
style="width: 100%"
:key="`order-select-${orderList.length}`"
@change="handleOrderChange"
>
<el-option
v-for="item in orderList"
:key="item.id"
:label="`订单${item.id} - 买方: ${item.buyerName} | 卖方: ${item.sellerName} | 单价: ${item.firmPrice}元/斤`"
:key="`order-${item.id}`"
:label="`订单${item.id} - 买方: ${item.buyerName || '--'} | 卖方: ${item.sellerName || '--'} | 单价: ${item.firmPrice ? (item.firmPrice + '元/斤') : '--'}`"
:value="item.id"
/>
</el-select>
@@ -35,6 +36,54 @@
</el-col>
</el-row>
<!-- 已关联订单管理区域 -->
<el-row :gutter="20" v-if="formData.editId && associatedOrders.length > 0">
<el-col :span="24">
<el-form-item label="已关联订单">
<el-table :data="associatedOrders" border size="small" style="width: 100%">
<el-table-column label="订单ID" prop="id" width="100">
<template #default="scope">
{{ scope.row.id || '--' }}
</template>
</el-table-column>
<el-table-column label="买方" prop="buyerName" width="150">
<template #default="scope">
{{ scope.row.buyerName || '--' }}
</template>
</el-table-column>
<el-table-column label="卖方" prop="sellerName" width="150">
<template #default="scope">
{{ scope.row.sellerName || '--' }}
</template>
</el-table-column>
<el-table-column label="单价" prop="firmPrice" width="120">
<template #default="scope">
{{ scope.row.firmPrice ? (scope.row.firmPrice + ' 元/斤') : '--' }}
</template>
</el-table-column>
<el-table-column label="结算方式" prop="settlementTypeDesc" width="120">
<template #default="scope">
{{ scope.row.settlementTypeDesc || '--' }}
</template>
</el-table-column>
<el-table-column label="操作" width="100" fixed="right">
<template #default="scope">
<el-button
link
type="danger"
size="small"
@click="unbindOrder(scope.row.id)"
:loading="unbindingOrderId === scope.row.id"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="车牌号" prop="plateNumber">
@@ -219,26 +268,53 @@
<el-input v-model="formData.quarantineCertNo" placeholder="请输入检疫证号(可选)" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="空车过磅重量" prop="emptyWeight">
<el-input-number
v-model="formData.emptyWeight"
placeholder="请输入空车过磅重量kg"
:precision="2"
:min="0"
:step="0.01"
:controls-position="'right'"
style="width: 100%"
class="weight-input-number"
>
<template #append>kg</template>
</el-input-number>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="空车过磅重量" prop="emptyWeight">
<el-input-number v-model="formData.emptyWeight" placeholder="请输入空车过磅重量" :precision="2" style="width: 100%">
<template #append>kg</template>
</el-input-number>
</el-form-item>
</el-col>
<el-col :span="8">
<el-col :span="12">
<el-form-item label="装车过磅重量" prop="entruckWeight">
<el-input-number v-model="formData.entruckWeight" placeholder="请输入装车过磅重量" :precision="2" style="width: 100%">
<el-input-number
v-model="formData.entruckWeight"
placeholder="请输入装车过磅重量kg"
:precision="2"
:min="0"
:step="0.01"
:controls-position="'right'"
style="width: 100%"
class="weight-input-number"
>
<template #append>kg</template>
</el-input-number>
</el-form-item>
</el-col>
<el-col :span="8">
<el-col :span="12">
<el-form-item label="落地过磅重量" prop="landingEntruckWeight">
<el-input-number v-model="formData.landingEntruckWeight" placeholder="请输入落地过磅重量" :precision="2" style="width: 100%">
<el-input-number
v-model="formData.landingEntruckWeight"
placeholder="请输入落地过磅重量kg"
:precision="2"
:min="0"
:step="0.01"
:controls-position="'right'"
style="width: 100%"
class="weight-input-number"
>
<template #append>kg</template>
</el-input-number>
</el-form-item>
@@ -279,7 +355,7 @@
</el-divider>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="检疫票" prop="quarantineTickeyUrl">
<el-form-item label="检疫票" prop="quarantineTickeyUrl" label-width="180px">
<div class="photo-upload-wrapper">
<el-upload
class="avatar-uploader"
@@ -322,7 +398,7 @@
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="纸质磅单(双章)" prop="poundListImg">
<el-form-item label="发车纸质磅单(双章)" prop="poundListImg" label-width="180px">
<div class="photo-upload-wrapper">
<el-upload
class="avatar-uploader"
@@ -367,7 +443,7 @@
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="车辆空磅上磅车头照片" prop="emptyVehicleFrontPhoto">
<el-form-item label="车辆空磅上磅车头照片" prop="emptyVehicleFrontPhoto" label-width="180px">
<div class="photo-upload-wrapper">
<el-upload
class="avatar-uploader"
@@ -410,7 +486,7 @@
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="车辆过重磅车头照片" prop="loadedVehicleFrontPhoto">
<el-form-item label="车辆过重磅车头照片" prop="loadedVehicleFrontPhoto" label-width="180px">
<div class="photo-upload-wrapper">
<el-upload
class="avatar-uploader"
@@ -455,7 +531,7 @@
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="车辆重磅照片" prop="loadedVehicleWeightPhoto">
<el-form-item label="车辆重磅侧方照片" prop="loadedVehicleWeightPhoto" label-width="180px">
<div class="photo-upload-wrapper">
<el-upload
class="avatar-uploader"
@@ -498,7 +574,7 @@
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="驾驶员手持身份证站车头照片" prop="driverIdCardPhoto">
<el-form-item label="驾驶员手持身份证站车头照片" prop="driverIdCardPhoto" label-width="180px">
<div class="photo-upload-wrapper">
<el-upload
class="avatar-uploader"
@@ -543,7 +619,7 @@
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="地纸质磅单(双章)" prop="destinationPoundListImg">
<el-form-item label="地纸质磅单(双章)" prop="destinationPoundListImg" label-width="180px">
<div class="photo-upload-wrapper">
<el-upload
class="avatar-uploader"
@@ -586,7 +662,7 @@
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="地车辆过重磅车头照片" prop="destinationVehicleFrontPhoto">
<el-form-item label="地车辆过重磅车头照片" prop="destinationVehicleFrontPhoto" label-width="180px">
<div class="photo-upload-wrapper">
<el-upload
class="avatar-uploader"
@@ -636,7 +712,7 @@
</el-divider>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="装车过磅视频" prop="entruckWeightVideo">
<el-form-item label="装车过磅视频" prop="entruckWeightVideo" label-width="180px">
<el-upload
accept=".mp4,.avi,.rmvb,.mkv,.MP4,.AVI,.RMVB,.MKV"
class="upload-demo"
@@ -663,7 +739,7 @@
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="空车过磅视频" prop="emptyWeightVideo">
<el-form-item label="空车过磅视频" prop="emptyWeightVideo" label-width="180px">
<el-upload
accept=".mp4,.avi,.rmvb,.mkv,.MP4,.AVI,.RMVB,.MKV"
class="upload-demo"
@@ -692,7 +768,7 @@
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="装牛视频" prop="cattleLoadingVideo">
<el-form-item label="装牛视频" prop="cattleLoadingVideo" label-width="180px">
<el-upload
accept=".mp4,.avi,.rmvb,.mkv,.MP4,.AVI,.RMVB,.MKV"
class="upload-demo"
@@ -719,7 +795,7 @@
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="控槽视频" prop="controlSlotVideo">
<el-form-item label="控槽视频" prop="controlSlotVideo" label-width="180px">
<el-upload
accept=".mp4,.avi,.rmvb,.mkv,.MP4,.AVI,.RMVB,.MKV"
class="upload-demo"
@@ -748,7 +824,7 @@
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="装完牛绕车一圈视频" prop="cattleLoadingCircleVideo">
<el-form-item label="装完牛绕车一圈视频" prop="cattleLoadingCircleVideo" label-width="180px">
<el-upload
accept=".mp4,.avi,.rmvb,.mkv,.MP4,.AVI,.RMVB,.MKV"
class="upload-demo"
@@ -775,7 +851,7 @@
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="卸牛视频" prop="unloadCattleVideo">
<el-form-item label="卸牛视频" prop="unloadCattleVideo" label-width="180px">
<el-upload
accept=".mp4,.avi,.rmvb,.mkv,.MP4,.AVI,.RMVB,.MKV"
class="upload-demo"
@@ -804,7 +880,7 @@
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="地过磅视频" prop="destinationWeightVideo">
<el-form-item label="地过磅视频" prop="destinationWeightVideo" label-width="180px">
<el-upload
accept=".mp4,.avi,.rmvb,.mkv,.MP4,.AVI,.RMVB,.MKV"
class="upload-demo"
@@ -832,7 +908,7 @@
</el-col>
</el-row>
<el-form-item label="备注" prop="remark">
<el-form-item label="备注" prop="remark" label-width="180px">
<el-input
v-model="formData.remark"
type="textarea"
@@ -907,11 +983,11 @@
</template>
<script setup>
import { ref, reactive, computed, watch } from 'vue';
import { ref, reactive, computed, watch, nextTick } 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, updateOrderDeliveryId } from '@/api/shipping.js';
import { createDelivery, updateDeviceDeliveryId, orderPageQuery, getDeliveryDetail, updateOrderDeliveryId, getOrdersByDeliveryId, unbindOrderFromDelivery } from '@/api/shipping.js';
import * as shippingApi from '@/api/shipping.js';
import { driverList as fetchDriverList, vehicleList as fetchVehicleList } from '@/api/userManage.js';
import { iotDeviceQueryList } from '@/api/hardware.js';
@@ -934,6 +1010,8 @@ const collarList = ref([]);
const driverOptions = ref([]);
const vehicleOptions = ref([]);
const orderList = ref([]);
const associatedOrders = ref([]); // 已关联的订单列表
const unbindingOrderId = ref(null); // 正在解除关联的订单ID
const showStartLocationMap = ref(false);
const showEndLocationMap = ref(false);
@@ -973,7 +1051,7 @@ const formData = reactive({
loadedVehicleFrontPhoto: '',
loadedVehicleWeightPhoto: '',
driverIdCardPhoto: '',
// 地相关照片
// 地相关照片
destinationPoundListImg: '',
destinationVehicleFrontPhoto: '',
// 视频
@@ -1169,6 +1247,44 @@ const open = async (editData = null) => {
loadOrderList()
]);
// 如果是编辑模式,加载已关联的订单
if (editData && editData.id) {
await loadAssociatedOrders(editData.id);
// 将已关联的订单补充到订单列表中(确保下拉框能正确显示)
// 必须在填充表单之前完成这样formData.orderIds填充时orderList中已有完整信息
if (associatedOrders.value.length > 0) {
associatedOrders.value.forEach(associatedOrder => {
// 检查订单列表中是否已存在该订单
const exists = orderList.value.find(order => order.id === associatedOrder.id);
if (!exists) {
// 如果不存在,添加到订单列表中
orderList.value.push(associatedOrder);
console.log('[ORDER-LIST] 补充订单到列表:', associatedOrder);
} else {
// 如果存在但信息不完整,更新订单信息
let updated = false;
if (!exists.buyerName && associatedOrder.buyerName) {
exists.buyerName = associatedOrder.buyerName;
updated = true;
}
if (!exists.sellerName && associatedOrder.sellerName) {
exists.sellerName = associatedOrder.sellerName;
updated = true;
}
if (!exists.firmPrice && associatedOrder.firmPrice) {
exists.firmPrice = associatedOrder.firmPrice;
updated = true;
}
if (updated) {
console.log('[ORDER-LIST] 更新订单信息:', exists);
}
}
});
}
} else {
associatedOrders.value = [];
}
// 标记开始恢复缓存避免watch触发
isRestoringFromCache.value = true;
@@ -1176,6 +1292,38 @@ const open = async (editData = null) => {
// 如果传入了编辑数据,则填充表单(编辑模式)
if (editData) {
fillFormWithEditData(editData);
// 填充表单后再次确保orderList中有完整的订单信息使用nextTick确保DOM已更新
await nextTick();
if (formData.orderIds && formData.orderIds.length > 0) {
formData.orderIds.forEach(orderId => {
const existsInOrderList = orderList.value.find(order => order.id === orderId);
if (!existsInOrderList) {
// 从associatedOrders中查找并补充
const associatedOrder = associatedOrders.value.find(order => order.id === orderId);
if (associatedOrder) {
orderList.value.push(associatedOrder);
console.log('[AFTER-FILL] 补充订单到orderList:', associatedOrder);
}
} else {
// 如果存在但信息不完整从associatedOrders中更新
const associatedOrder = associatedOrders.value.find(order => order.id === orderId);
if (associatedOrder) {
if (!existsInOrderList.buyerName && associatedOrder.buyerName) {
existsInOrderList.buyerName = associatedOrder.buyerName;
}
if (!existsInOrderList.sellerName && associatedOrder.sellerName) {
existsInOrderList.sellerName = associatedOrder.sellerName;
}
if (!existsInOrderList.firmPrice && associatedOrder.firmPrice) {
existsInOrderList.firmPrice = associatedOrder.firmPrice;
}
console.log('[AFTER-FILL] 更新订单信息:', existsInOrderList);
}
}
});
}
// 编辑模式:尝试从缓存恢复数据(如果缓存存在,用于补充未填充的字段)
const delivery = editData.delivery || editData;
if (delivery.id) {
@@ -1239,16 +1387,58 @@ const fillFormWithEditData = (editData) => {
// 基本信息将逗号分隔的订单ID字符串转换为数组
if (delivery.orderId) {
let orderIdArray = [];
if (typeof delivery.orderId === 'string') {
// 如果是字符串,按逗号分割
formData.orderIds = delivery.orderId.split(',').map(id => parseInt(id.trim())).filter(id => !isNaN(id));
// 如果是字符串,按逗号分割并转换为整数数组
orderIdArray = delivery.orderId.split(',').map(id => parseInt(id.trim())).filter(id => !isNaN(id));
} else if (Array.isArray(delivery.orderId)) {
// 如果已经是数组,直接使用
formData.orderIds = delivery.orderId;
// 如果已经是数组,确保转换为整数数组
orderIdArray = delivery.orderId.map(id => {
if (typeof id === 'number') {
return id;
} else if (typeof id === 'string') {
const parsed = parseInt(id);
return isNaN(parsed) ? null : parsed;
}
return null;
}).filter(id => id !== null);
} else {
// 如果是单个数字,转换为数组
formData.orderIds = [delivery.orderId];
const id = typeof delivery.orderId === 'number' ? delivery.orderId : parseInt(delivery.orderId);
orderIdArray = isNaN(id) ? [] : [id];
}
formData.orderIds = orderIdArray;
// 确保orderList中包含这些订单的完整信息
// 如果orderList中没有对应的订单从associatedOrders中查找并补充
orderIdArray.forEach(orderId => {
const existsInOrderList = orderList.value.find(order => order.id === orderId);
if (!existsInOrderList) {
// 从associatedOrders中查找
const associatedOrder = associatedOrders.value.find(order => order.id === orderId);
if (associatedOrder) {
orderList.value.push(associatedOrder);
console.log('[FILL-FORM] 从associatedOrders补充订单到orderList:', associatedOrder);
} else {
console.warn('[FILL-FORM] 订单ID', orderId, '在orderList和associatedOrders中都不存在');
}
} else {
// 如果存在但信息不完整尝试从associatedOrders中更新
const associatedOrder = associatedOrders.value.find(order => order.id === orderId);
if (associatedOrder) {
if (!existsInOrderList.buyerName && associatedOrder.buyerName) {
existsInOrderList.buyerName = associatedOrder.buyerName;
}
if (!existsInOrderList.sellerName && associatedOrder.sellerName) {
existsInOrderList.sellerName = associatedOrder.sellerName;
}
if (!existsInOrderList.firmPrice && associatedOrder.firmPrice) {
existsInOrderList.firmPrice = associatedOrder.firmPrice;
}
}
}
});
} else {
formData.orderIds = [];
}
@@ -1318,6 +1508,30 @@ const fillFormWithEditData = (editData) => {
// 司机运费
formData.freight = delivery.freight || null;
// 检疫证号从quarantineTickey字段读取
// 支持多种可能的数据结构和字段名
// 1. 从 delivery 对象中读取
// 2. 从 editData 根级读取(如果 delivery 中没有)
// 3. 支持多种字段名quarantineTickey、quarantine_tickey、quarantineCertNo
const quarantineValue = delivery.quarantineTickey
|| delivery.quarantine_tickey
|| delivery.quarantineCertNo
|| (editData && editData.quarantineTickey)
|| (editData && editData.quarantine_tickey)
|| (editData && editData.quarantineCertNo)
|| '';
formData.quarantineCertNo = quarantineValue;
console.log('[FILL-FORM] 检疫证号填充:', {
'delivery.quarantineTickey': delivery.quarantineTickey,
'delivery.quarantine_tickey': delivery.quarantine_tickey,
'delivery.quarantineCertNo': delivery.quarantineCertNo,
'editData.quarantineTickey': editData?.quarantineTickey,
'editData.quarantine_tickey': editData?.quarantine_tickey,
'editData.quarantineCertNo': editData?.quarantineCertNo,
'finalValue': formData.quarantineCertNo,
'delivery对象': delivery
});
// 照片
formData.quarantineTickeyUrl = delivery.quarantineTickeyUrl || '';
formData.poundListImg = delivery.poundListImg || '';
@@ -1430,7 +1644,18 @@ const loadOrderList = async () => {
// 兼容运行时找不到函数引用的问题,优先从命名空间调用
const res = await (orderPageQuery ? orderPageQuery({ pageNum: 1, pageSize: 1000 }) : shippingApi.orderPageQuery({ pageNum: 1, pageSize: 1000 }));
if (res.code === 200) {
orderList.value = res.data?.rows || [];
const responseData = res.data || res;
if (responseData && typeof responseData === 'object' && 'rows' in responseData) {
orderList.value = responseData.rows || [];
} else if (responseData && responseData.data && 'rows' in responseData.data) {
orderList.value = responseData.data.rows || [];
} else {
orderList.value = [];
}
console.log('[ORDER-LIST] 加载订单列表成功,数量:', orderList.value.length);
if (orderList.value.length > 0) {
console.log('[ORDER-LIST] 第一个订单示例:', orderList.value[0]);
}
}
} catch (error) {
console.error('加载订单列表失败', error);
@@ -1445,6 +1670,69 @@ const handleOrderChange = async (orderIds) => {
}
};
// 加载已关联的订单列表
const loadAssociatedOrders = async (deliveryId) => {
try {
const res = await getOrdersByDeliveryId(deliveryId);
if (res.code === 200) {
const responseData = res.data || res;
if (responseData && typeof responseData === 'object' && 'rows' in responseData) {
associatedOrders.value = responseData.rows || [];
} else if (responseData && responseData.data && 'rows' in responseData.data) {
associatedOrders.value = responseData.data.rows || [];
} else {
associatedOrders.value = [];
}
console.log('[ASSOCIATED-ORDERS] 加载已关联订单成功,数量:', associatedOrders.value.length);
if (associatedOrders.value.length > 0) {
console.log('[ASSOCIATED-ORDERS] 第一个订单示例:', associatedOrders.value[0]);
console.log('[ASSOCIATED-ORDERS] 订单信息检查:', {
id: associatedOrders.value[0].id,
buyerName: associatedOrders.value[0].buyerName,
sellerName: associatedOrders.value[0].sellerName,
firmPrice: associatedOrders.value[0].firmPrice
});
}
} else {
associatedOrders.value = [];
}
} catch (error) {
console.error('加载已关联订单失败:', error);
associatedOrders.value = [];
}
};
// 解除订单关联
const unbindOrder = async (orderId) => {
try {
await ElMessageBox.confirm('确定要解除该订单与运送清单的关联吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
});
unbindingOrderId.value = orderId;
const res = await unbindOrderFromDelivery(orderId);
unbindingOrderId.value = null;
if (res.code === 200) {
ElMessage.success('解除关联成功');
// 刷新已关联订单列表
if (formData.editId) {
await loadAssociatedOrders(formData.editId);
}
} else {
ElMessage.error(res.msg || '解除关联失败');
}
} catch (error) {
unbindingOrderId.value = null;
if (error !== 'cancel') {
console.error('解除订单关联失败:', error);
ElMessage.error('解除关联失败,请重试');
}
}
};
// 司机选择变化时自动填充电话
const handleDriverChange = (driverId) => {
if (driverId) {
@@ -1610,7 +1898,38 @@ const handleSubmit = () => {
if (res.code === 200) {
// 获取运送清单ID新增返回data.id编辑直接用editId
const deliveryId = formData.editId || res.data?.id;
let deliveryId = formData.editId || res.data?.id;
// 如果res.data是Delivery对象从对象中获取id
if (!deliveryId && res.data && typeof res.data === 'object' && res.data.id) {
deliveryId = res.data.id;
}
// 确保deliveryId是整数
if (deliveryId) {
if (typeof deliveryId === 'string') {
// 如果是逗号分隔的字符串,取第一个(这种情况不应该发生,但做保护)
if (deliveryId.includes(',')) {
console.warn('[CREATE-DELIVERY] deliveryId包含逗号可能是orderId:', deliveryId);
deliveryId = deliveryId.split(',')[0];
}
const parsed = parseInt(deliveryId);
if (isNaN(parsed)) {
console.error('[CREATE-DELIVERY] deliveryId格式不正确:', deliveryId);
ElMessage.error('获取运送清单ID失败');
return;
}
deliveryId = parsed;
} else if (typeof deliveryId !== 'number') {
deliveryId = parseInt(deliveryId);
if (isNaN(deliveryId)) {
console.error('[CREATE-DELIVERY] deliveryId格式不正确:', deliveryId);
ElMessage.error('获取运送清单ID失败');
return;
}
}
console.log('[CREATE-DELIVERY] 获取到的deliveryId:', deliveryId, '类型:', typeof deliveryId);
}
if (deliveryId) {
// 更新设备的delivery_id
@@ -1619,9 +1938,20 @@ const handleSubmit = () => {
// 更新关联订单的delivery_id
if (formData.orderIds && formData.orderIds.length > 0) {
try {
// 确保orderIds是整数数组而不是字符串数组
const orderIdsArray = formData.orderIds.map(id => {
if (typeof id === 'string') {
const parsed = parseInt(id);
return isNaN(parsed) ? null : parsed;
}
return typeof id === 'number' ? id : parseInt(id);
}).filter(id => id !== null);
console.log('[ORDER-UPDATE] 准备更新订单关联, deliveryId:', deliveryId, 'orderIds:', orderIdsArray);
const updateOrderRes = await updateOrderDeliveryId({
deliveryId: deliveryId,
orderIds: formData.orderIds
orderIds: orderIdsArray
});
if (updateOrderRes.code === 200) {
console.log('[ORDER-UPDATE] 成功更新订单delivery_id订单数量', formData.orderIds.length);
@@ -2170,6 +2500,35 @@ let watchTimer = null;
height: 500px;
}
/* 重量输入框样式优化 */
:deep(.weight-input-number) {
width: 100%;
}
:deep(.weight-input-number .el-input__inner) {
font-size: 14px;
padding: 0 15px;
height: 40px;
line-height: 40px;
text-align: left;
}
:deep(.weight-input-number .el-input-number__decrease),
:deep(.weight-input-number .el-input-number__increase) {
width: 32px;
height: 40px;
line-height: 40px;
font-size: 16px;
}
:deep(.weight-input-number .el-input-group__append) {
padding: 0 12px;
font-size: 14px;
background-color: #f5f7fa;
color: #606266;
border-left: 1px solid #dcdfe6;
}
.dialog-footer {
display: flex;
justify-content: flex-end;

View File

@@ -4,19 +4,9 @@
<!-- 横向滚动操作栏 -->
<div class="operation-scroll-bar">
<div class="operation-scroll-container">
<el-button type="primary" v-hasPermi="['loading:create']" @click="showAddDialog(null)">创建订单</el-button>
<el-button
type="primary"
v-hasPermi="['loading:add']"
@click="showCreateDeliveryDialog"
style="margin-left: 10px"
>
新增运送清单
</el-button>
<el-dropdown
v-hasPermi="['order:import']"
@command="handleImportCommand"
style="margin-left: 10px"
>
<el-button type="success">
导入数据
@@ -34,58 +24,66 @@
</div>
<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="订单ID" prop="id" width="100">
<el-table
:data="rows"
:key="data.tableKey"
border
v-loading="data.dataListLoading"
element-loading-text="数据加载中..."
style="width: 100%"
:show-overflow-tooltip="true"
>
<el-table-column label="订单ID" prop="id" min-width="80" width="100">
<template #default="scope">
{{ scope.row.id || '--' }}
</template>
</el-table-column>
<el-table-column label="买方" prop="buyerName" width="200">
<el-table-column label="买方" prop="buyerName" min-width="120" show-overflow-tooltip>
<template #default="scope">
{{ scope.row.buyerName || '--' }}
</template>
</el-table-column>
<el-table-column label="卖方" prop="sellerName" width="200">
<el-table-column label="卖方" prop="sellerName" min-width="120" show-overflow-tooltip>
<template #default="scope">
{{ scope.row.sellerName || '--' }}
</template>
</el-table-column>
<el-table-column label="结算方式" prop="settlementTypeDesc" width="150">
<el-table-column label="结算方式" prop="settlementTypeDesc" min-width="100" width="120">
<template #default="scope">
{{ scope.row.settlementTypeDesc || '--' }}
</template>
</el-table-column>
<el-table-column label="运单号" prop="deliveryNumber" width="150">
<el-table-column label="运单号" prop="deliveryNumber" min-width="120" width="150" show-overflow-tooltip>
<template #default="scope">
{{ scope.row.deliveryNumber || '--' }}
</template>
</el-table-column>
<el-table-column label="起始地" prop="startLocation" width="200">
<el-table-column label="起始地" prop="startLocation" min-width="150" show-overflow-tooltip>
<template #default="scope">
{{ scope.row.startLocation || '--' }}
</template>
</el-table-column>
<el-table-column label="目的地" prop="endLocation" width="200">
<el-table-column label="目的地" prop="endLocation" min-width="150" show-overflow-tooltip>
<template #default="scope">
{{ scope.row.endLocation || '--' }}
</template>
</el-table-column>
<el-table-column label="单价" prop="firmPrice" width="120">
<el-table-column label="单价" prop="firmPrice" min-width="100" 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">
<el-table-column label="创建人" prop="createdByName" min-width="100" width="120" show-overflow-tooltip>
<template #default="scope">
{{ scope.row.createdByName || '--' }}
</template>
</el-table-column>
<el-table-column label="创建时间" prop="createTime" width="180">
<el-table-column label="创建时间" prop="createTime" min-width="160" width="180">
<template #default="scope">
{{ scope.row.createTime || '--' }}
</template>
</el-table-column>
<el-table-column label="操作" width="300" fixed="right">
<el-table-column label="操作" min-width="280" 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>
@@ -93,7 +91,7 @@
link
type="primary"
v-if="scope.row.deliveryId"
@click="viewDeliveryDetail(scope.row.deliveryId)"
@click="viewDeliveryDetail(scope.row)"
>
详情
</el-button>
@@ -361,16 +359,26 @@ const showCreateDeliveryDialog = () => {
};
// 查看运送清单详情
const viewDeliveryDetail = (deliveryId) => {
if (!deliveryId) {
const viewDeliveryDetail = (row) => {
if (!row || !row.deliveryId) {
ElMessage.warning('运单ID不存在');
return;
}
const query = {
id: row.deliveryId
};
// 如果是从订单页面进入,传递订单的买方和卖方信息
if (row.buyerName) {
query.buyerName = row.buyerName;
}
if (row.sellerName) {
query.sellerName = row.sellerName;
}
// 标记是从订单页面进入的
query.fromOrder = 'true';
router.push({
path: '/entry/details',
query: {
id: deliveryId
}
query: query
});
};
@@ -439,7 +447,7 @@ const initTrackMap = async () => {
}
try {
const BMapGL = await BMPGL('fLz8UwJSM3ayYl6dtsWYp7TQ8993R6kC');
const BMapGL = await BMPGL('xITbC7jegaAAuu4m9jC2Zx6eFbQJ29Rj');
// 创建地图实例
trackMapInstance.value = new BMapGL.Map('trackMap');
@@ -907,6 +915,21 @@ onMounted(() => {
}
}
/* 表格容器优化 */
.main-container {
width: 100%;
overflow-x: auto;
:deep(.el-table) {
width: 100%;
min-width: 1400px; /* 确保所有列都能显示 */
}
:deep(.el-table__body-wrapper) {
overflow-x: auto;
}
}
/* 响应式设计 */
@media (max-width: 768px) {
.operation-scroll-bar {
@@ -922,6 +945,12 @@ onMounted(() => {
padding: 6px 12px;
}
}
.main-container {
:deep(.el-table) {
min-width: 1200px;
}
}
}
</style>

View File

@@ -93,7 +93,7 @@
<script setup>
import { ref, reactive } from 'vue';
import { ElMessage } from 'element-plus';
import { orderAddNew, orderUpdate } from '@/api/shipping.js';
import { orderAddNew, orderUpdate, updateDeliveryInfo } from '@/api/shipping.js';
import { memberListByType } from '@/api/userManage.js';
const emits = defineEmits();
@@ -120,6 +120,7 @@ const ruleForm = reactive({
sellerId: null, // 卖方ID单选
settlementType: 1, // 结算方式1-上车重量2-下车重量3-按肉价结算
firmPrice: null, // 约定价格(元/斤)
deliveryId: null, // 运送清单ID关联时使用
});
// 验证买方和卖方不能是同一用户
@@ -165,6 +166,7 @@ const handleClose = () => {
ruleForm.sellerId = null;
ruleForm.settlementType = 1;
ruleForm.firmPrice = null;
ruleForm.deliveryId = null;
data.dialogVisible = false;
};
@@ -297,18 +299,64 @@ const onClickSave = () => {
firmPrice: ruleForm.firmPrice, // 约定价格(元/斤)
};
// 如果是新增订单且有deliveryId传递deliveryId参数
if (!ruleForm.id && ruleForm.deliveryId) {
params.deliveryId = ruleForm.deliveryId;
}
data.saveLoading = true;
// 根据是否有ID判断是新增还是编辑
const savePromise = ruleForm.id ? orderUpdate(params) : orderAddNew(params);
savePromise.then((res) => {
savePromise.then(async (res) => {
data.saveLoading = false;
if (res.code === 200) {
ElMessage({
message: res.msg,
type: 'success',
});
// 如果是新增订单且有deliveryId需要更新delivery表的order_id字段
if (!ruleForm.id && ruleForm.deliveryId) {
// 尝试从响应中获取订单ID
let orderId = null;
if (res.data) {
// 如果返回的是订单对象
if (res.data.id) {
orderId = res.data.id;
}
// 如果返回的是订单ID数字或字符串
else if (typeof res.data === 'number' || typeof res.data === 'string') {
orderId = res.data;
}
}
// 如果获取到了订单ID更新delivery表的order_id字段
if (orderId) {
try {
// 更新delivery表的order_id字段
const updateRes = await updateDeliveryInfo({
deliveryId: ruleForm.deliveryId, // 使用deliveryId而不是id
orderId: String(orderId) // 转为字符串格式
});
if (updateRes.code === 200) {
ElMessage({
message: '订单创建成功,已关联运送清单',
type: 'success',
});
} else {
ElMessage.warning('订单创建成功,但关联运送清单失败:' + (updateRes.msg || '未知错误'));
}
} catch (error) {
console.error('更新运送清单关联失败:', error);
ElMessage.warning('订单创建成功,但关联运送清单失败,请手动关联');
}
} else {
// 如果无法获取订单ID提示用户
ElMessage.warning('订单创建成功,但无法自动关联运送清单,请手动关联');
}
} else {
ElMessage({
message: res.msg,
type: 'success',
});
}
emits('success');
handleClose();
} else {
@@ -317,6 +365,7 @@ const onClickSave = () => {
})
.catch((err) => {
data.saveLoading = false;
ElMessage.error('保存失败:' + (err.message || '未知错误'));
});
} else {
@@ -325,7 +374,7 @@ const onClickSave = () => {
}
};
const onShowDialog = (orderData) => {
const onShowDialog = (orderData, deliveryId) => {
if (formDataRef.value) {
formDataRef.value.resetFields();
}
@@ -367,6 +416,8 @@ const onShowDialog = (orderData) => {
ruleForm.settlementType = orderData?.settlementType || 1;
ruleForm.firmPrice = orderData?.firmPrice != null ? orderData.firmPrice : null;
// 设置deliveryId如果提供
ruleForm.deliveryId = deliveryId || orderData?.deliveryId || null;
data.dialogVisible = true;
// 初始化时加载列表