后期需求已修改

This commit is contained in:
xuqiuyun
2025-11-24 17:31:39 +08:00
parent f45a57fad6
commit 128a4b2c6b
13 changed files with 683 additions and 210 deletions

View File

@@ -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({

View File

@@ -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>

View File

@@ -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,

View File

@@ -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('请确认是否删除订单?删除后将不可恢复', '提示', {