✨ 完善配载确认、承运商组织过滤司机与地址展示

配载草稿确认生成正式单并优化详情/列表地址市区展示;运单调度等按承运商联系人所属组织筛选司机车辆;统一地图搜索结果与登录默认账号清理。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-23 18:35:27 +08:00
parent 694fe1a433
commit a919781d4f
19 changed files with 1701 additions and 309 deletions
+96 -7
View File
@@ -11,7 +11,7 @@
{{ planData.businessStatusName || '-' }}
</span>
<span class="detail-status-text detail-transport-type">
{{ planData.transportTypeName || '公路运输' }}
{{ transportTypeLabel }}
</span>
</div>
<div class="transport-plan-dispatch-page__summary-grid">
@@ -123,16 +123,20 @@
</el-button>
</template>
<el-table
:data="dispatchList"
:data="pagedDispatchList"
border
height="100%"
row-key="id"
class="transport-plan-dispatch-page__table"
>
<el-table-column type="index" label="序号" width="70" align="center" fixed="left" />
<el-table-column label="序号" width="70" align="center" fixed="left">
<template #default="{ $index }">
{{ dispatchRowIndex($index) }}
</template>
</el-table-column>
<el-table-column label="运输方式" min-width="180" align="center" show-overflow-tooltip>
<template #default="{ row }">
{{ row.transportTypeName || '-' }}
{{ formatTransportType(row.transportTypeName || row.transportType) }}
</template>
</el-table-column>
<el-table-column prop="carrierType" label="承运类型" min-width="150" align="center" show-overflow-tooltip />
@@ -177,6 +181,17 @@
</template>
</el-table-column>
</el-table>
<div class="transport-plan-dispatch-page__pagination">
<el-pagination
v-model:current-page="dispatchPage.currentPage"
v-model:page-size="dispatchPage.pageSize"
:page-sizes="dispatchPage.pageSizes"
layout="total, sizes, prev, pager, next"
:total="dispatchList.length"
@current-change="handleDispatchCurrentChange"
@size-change="handleDispatchSizeChange"
/>
</div>
</section-card>
<!-- 底部按钮 -->
@@ -202,6 +217,7 @@
<script>
import { getDetail, dispatch } from '@/api/business/transport-plan';
import { getDictionary } from '@/api/system/dictbiz';
import SectionCard from '@/components/section-card/main.vue';
import TransportPlanPage from './components/transport-plan-page.vue';
import * as api from '@/api/business/transport-plan';
@@ -209,6 +225,12 @@ import { config, option } from '@/option/business/transport-plan';
const TRANSPORT_PLAN_QUANTITY_UNIT = '吨';
const normalizeDictOptions = (list = []) =>
(Array.isArray(list) ? list : []).map(item => ({
label: item.dictValue || item.label || '',
value: item.dictKey ?? item.value ?? '',
}));
export default {
name: 'TransportPlanDispatch',
components: {
@@ -223,6 +245,12 @@ export default {
dispatchList: [],
attachmentList: [],
transportPlanPageVisible: false,
transportTypeOptions: [],
dispatchPage: {
currentPage: 1,
pageSize: 10,
pageSizes: [10, 20, 50, 100],
},
api,
config,
option,
@@ -232,6 +260,15 @@ export default {
planId() {
return this.$route.query.planId;
},
transportTypeLabel() {
return this.formatTransportType(
this.planData.transportTypeName || this.planData.transportType
);
},
pagedDispatchList() {
const start = (this.dispatchPage.currentPage - 1) * this.dispatchPage.pageSize;
return this.dispatchList.slice(start, start + this.dispatchPage.pageSize);
},
statusTextClass() {
const status = this.planData.businessStatus;
if (status === 2 || status === '2') return 'status-text-success';
@@ -306,13 +343,34 @@ export default {
},
},
created() {
this.loadPlanData();
this.loadTransportTypeOptions().finally(() => {
this.loadPlanData();
});
},
mounted() {
// 初始化 transport-plan-page 组件用于打开弹窗
this.transportPlanPageVisible = true;
},
methods: {
loadTransportTypeOptions() {
return getDictionary({ code: 'transport_type' })
.then(res => {
this.transportTypeOptions = normalizeDictOptions(res.data?.data || []);
})
.catch(() => {
this.transportTypeOptions = [];
});
},
formatTransportType(value) {
const transportType = String(value || '').trim();
if (!transportType) return '-';
// 已是中文标签时直接展示
if (/[\u4e00-\u9fff]/.test(transportType)) return transportType;
const item = this.transportTypeOptions.find(
option => String(option.value ?? '').toLowerCase() === transportType.toLowerCase()
);
return item?.label || transportType;
},
loadPlanData() {
if (!this.planId) {
this.$message.error('缺少计划ID参数');
@@ -327,6 +385,7 @@ export default {
this.planData = res.data.data || {};
this.attachmentList = this.parseAttachments(this.planData.attachmentsJson);
this.dispatchList = this.parseDispatchList(this.planData);
this.dispatchPage.currentPage = 1;
} else {
this.$message.error(res.data?.msg || '加载数据失败');
}
@@ -448,8 +507,30 @@ export default {
}
this.openPageDispatchItemDialog(-1);
},
dispatchRowIndex(index) {
return (this.dispatchPage.currentPage - 1) * this.dispatchPage.pageSize + index + 1;
},
resolveDispatchGlobalIndex(pageIndex) {
return (this.dispatchPage.currentPage - 1) * this.dispatchPage.pageSize + pageIndex;
},
syncDispatchPage() {
const maxPage = Math.max(
1,
Math.ceil(this.dispatchList.length / this.dispatchPage.pageSize) || 1
);
if (this.dispatchPage.currentPage > maxPage) {
this.dispatchPage.currentPage = maxPage;
}
},
handleDispatchCurrentChange(currentPage) {
this.dispatchPage.currentPage = currentPage;
},
handleDispatchSizeChange(pageSize) {
this.dispatchPage.pageSize = pageSize;
this.dispatchPage.currentPage = 1;
},
handleEdit(row, index) {
this.openPageDispatchItemDialog(index, row);
this.openPageDispatchItemDialog(this.resolveDispatchGlobalIndex(index), row);
},
openPageDispatchItemDialog(index = -1, row) {
this.$nextTick(() => {
@@ -469,6 +550,7 @@ export default {
originalSave.apply(component, args);
if (!component.dispatchItemBox) {
this.dispatchList = [...(component.dispatchRows || [])];
this.syncDispatchPage();
}
};
component.__dispatchListSaveSynced = true;
@@ -479,7 +561,8 @@ export default {
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
this.dispatchList.splice(index, 1);
this.dispatchList.splice(this.resolveDispatchGlobalIndex(index), 1);
this.syncDispatchPage();
this.$message.success('删除成功');
});
},
@@ -782,6 +865,12 @@ export default {
flex: 1;
}
&__pagination {
display: flex;
justify-content: flex-end;
padding-top: 12px;
}
&__actions {
display: flex;
gap: 8px;