调整 业务

This commit is contained in:
2026-09-16 23:43:12 +08:00
parent c1c4fa18c9
commit 84d9e098ba
9 changed files with 795 additions and 366 deletions
@@ -10,107 +10,200 @@
:class="{ 'waybill-import-page': standalone }"
@closed="handleClosed"
>
<div class="waybill-import-toolbar">
<div class="waybill-import-toolbar__search">
<el-form :inline="true" :model="query" label-width="auto">
<el-form-item label="运单批次号"
><el-input v-model="query.batchNo" clearable
/></el-form-item>
<el-form-item label="承运商"
><el-select v-model="query.carrierId" clearable filterable
><el-option
<section v-show="searchVisible" class="waybill-import-toolbar__search">
<el-form :model="query" label-position="right" label-width="88px" @submit.prevent>
<div class="waybill-import-toolbar__search-grid">
<el-form-item label="运单批次号">
<el-input v-model="query.batchNo" clearable placeholder="请输入" />
</el-form-item>
<el-form-item label="承运商">
<el-select v-model="query.carrierId" clearable filterable placeholder="请选择">
<el-option
v-for="item in queryCarriers"
:key="item.id"
:label="item.name"
:value="item.id" /></el-select
></el-form-item>
<el-form-item label="创建时间"
><el-date-picker
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item label="创建时间">
<el-date-picker
v-model="query.createTimeRange"
type="datetimerange"
value-format="YYYY-MM-DD HH:mm:ss"
/></el-form-item>
<el-form-item label="创建人"
><el-select v-model="query.createUser" clearable filterable
><el-option
range-separator="~"
start-placeholder="开始时间"
end-placeholder="结束时间"
clearable
/>
</el-form-item>
<el-form-item label="创建人">
<el-select v-model="query.createUser" clearable filterable placeholder="请选择">
<el-option
v-for="item in creators"
:key="item.id"
:label="item.name"
:value="item.id" /></el-select
></el-form-item>
</el-form>
<div class="waybill-import-toolbar__search-actions">
<el-button type="primary" @click="loadBatches">查询</el-button
><el-button @click="resetQuery">重置</el-button>
:value="item.id"
/>
</el-select>
</el-form-item>
</div>
</div>
<div class="waybill-import-toolbar__actions">
<el-button type="primary" @click="handleCreate">新建导入</el-button
><el-button type="danger" plain :disabled="!selected.length" @click="removeBatches"
<div class="waybill-import-toolbar__search-actions">
<el-button type="primary" @click="loadBatches">查询</el-button>
<el-button @click="resetQuery">重置</el-button>
</div>
</el-form>
</section>
<div class="avue-crud__header waybill-import-toolbar__actions">
<div class="avue-crud__left">
<el-button type="primary" @click="handleCreate">新建导入</el-button>
<el-button type="danger" plain :disabled="!selected.length" @click="removeBatches"
>批量删除</el-button
>
</div>
<div class="avue-crud__right">
<el-button icon="el-icon-refresh" circle @click="loadBatches" />
<el-button icon="el-icon-operation" circle @click="columnSettingVisible = true" />
<el-button icon="el-icon-search" circle @click="searchVisible = !searchVisible" />
<el-button icon="el-icon-grid" circle @click="toggleTableSize" />
</div>
</div>
<el-table :data="batches" border @selection-change="selected = $event">
<el-table-column type="selection" width="50" /><el-table-column
type="index"
label="序号"
width="70"
/>
<el-table-column prop="batchNo" label="运单批次号" min-width="150" /><el-table-column
prop="projectName"
label="项目名称"
min-width="150"
/>
<el-table-column prop="carrierName" label="承运商" min-width="140" /><el-table-column
prop="carrierType"
label="承运类型"
min-width="120"
/>
<el-table-column prop="waybillCount" label="运单数" width="90" /><el-table-column
prop="importTypeName"
label="导入方式"
width="100"
/>
<el-table-column
prop="createTime"
label="创建时间"
min-width="170"
sortable
/><el-table-column prop="updateTime" label="更新时间" min-width="170" sortable />
<el-table-column prop="statusName" label="状态" width="100" /><el-table-column
label="操作"
width="180"
fixed="right"
<section class="waybill-import-toolbar__table-panel">
<el-table
:data="batches"
:size="tableSize"
border
@selection-change="selected = $event"
>
<template #default="{ row }"
><el-link type="primary" @click="openDetail(row)">查看</el-link
><el-link
v-if="row.importStatus === 'draft'"
type="primary"
@click="editBatch(row)"
>编辑</el-link
><el-link type="danger" @click="removeBatch(row)">删除</el-link></template
<el-table-column type="selection" width="50" /><el-table-column
type="index"
label="序号"
width="70"
/>
<el-table-column
v-if="columnVisible.batchNo"
prop="batchNo"
label="运单批次号"
min-width="150"
/><el-table-column
v-if="columnVisible.projectName"
prop="projectName"
label="项目名称"
min-width="150"
/>
<el-table-column
v-if="columnVisible.carrierName"
prop="carrierName"
label="承运商"
min-width="140"
/><el-table-column
v-if="columnVisible.carrierType"
prop="carrierType"
label="承运类型"
min-width="120"
/>
<el-table-column
v-if="columnVisible.waybillCount"
prop="waybillCount"
label="运单数"
width="90"
/> <el-table-column
v-if="columnVisible.importTypeName"
prop="importTypeName"
label="导入方式"
width="100"
/>
<el-table-column
v-if="columnVisible.createUserName"
prop="createUserName"
label="创建人"
min-width="120"
>
</el-table-column>
</el-table>
<el-pagination
v-model:current-page="page.current"
v-model:page-size="page.size"
layout="total, prev, pager, next, sizes"
:page-sizes="[10, 20, 50]"
:total="page.total"
@current-change="loadBatches"
@size-change="loadBatches"
/>
<template #default="{ row }">{{ row.createUserName || '-' }}</template>
</el-table-column>
<el-table-column
v-if="columnVisible.statusName"
prop="statusName"
label="状态"
width="100"
/>
<el-table-column
v-if="columnVisible.createTime"
prop="createTime"
label="创建时间"
min-width="170"
sortable
/><el-table-column
v-if="columnVisible.updateTime"
prop="updateTime"
label="更新时间"
min-width="170"
sortable
/>
<el-table-column
label="操作"
width="180"
fixed="right"
>
<template #default="{ row }">
<el-link
v-if="row.importStatus !== 'draft'"
type="primary"
@click="openDetail(row)"
>查看</el-link
>
<el-link
v-if="row.importStatus === 'draft'"
type="primary"
@click="editBatch(row)"
>编辑</el-link
>
<el-link
v-if="row.importStatus === 'draft'"
type="danger"
@click="removeBatch(row)"
>删除</el-link
>
</template>
</el-table-column>
</el-table>
<div class="waybill-import-toolbar__pagination">
<el-pagination
background
v-model:current-page="page.current"
v-model:page-size="page.size"
layout="total, sizes, prev, pager, next, jumper"
:page-sizes="[10, 20, 50, 100]"
:total="page.total"
@current-change="loadBatches"
@size-change="loadBatches"
/>
</div>
</section>
</component>
<el-dialog
v-model="columnSettingVisible"
title="列设置"
width="360px"
append-to-body
>
<el-checkbox-group v-model="visibleColumnKeys" class="waybill-import-toolbar__column-setting">
<el-checkbox v-for="item in columnOptions" :key="item.prop" :label="item.prop">
{{ item.label }}
</el-checkbox>
</el-checkbox-group>
<template #footer>
<el-button @click="columnSettingVisible = false">关闭</el-button>
</template>
</el-dialog>
<el-dialog v-model="detailVisible" title="导入运单详情" width="90%" append-to-body>
<el-form :inline="true" :model="detailQuery"
><el-form-item label="车牌号/船号"
><el-input v-model="detailQuery.vehicleNo" clearable /></el-form-item
><el-form-item label="货物名称"
><el-input v-model="detailQuery.cargoName" clearable /></el-form-item
><el-form-item label="司机/船长姓名"
><el-input v-model="detailQuery.driverName" clearable placeholder="请输入" /></el-form-item
><el-button type="primary" @click="loadDetails">查询</el-button></el-form
>
<el-table :data="details" border
@@ -126,7 +219,10 @@
prop="vehicleNo"
label="车牌号/航班号/船号/班列号"
min-width="190"
/><el-table-column prop="transportType" label="运输方式" width="110" /><el-table-column
/><el-table-column prop="transportType" label="运输方式" width="110">
<template #default="{ row }">{{ transportTypeLabel(row.transportType) }}</template>
</el-table-column>
<el-table-column
prop="driverName"
label="司机/船长姓名"
min-width="120"
@@ -200,17 +296,20 @@
prop="waybillIdentifier"
label="同一运单标识号"
min-width="140"
/><el-table-column label="操作" width="80">-</el-table-column></el-table
/></el-table
>
<el-pagination
v-model:current-page="detailPage.current"
v-model:page-size="detailPage.size"
layout="total, prev, pager, next, sizes"
:page-sizes="[10, 20, 50]"
:total="detailPage.total"
@current-change="loadDetails"
@size-change="loadDetails"
/>
<div class="waybill-import-toolbar__pagination">
<el-pagination
background
v-model:current-page="detailPage.current"
v-model:page-size="detailPage.size"
layout="total, sizes, prev, pager, next, jumper"
:page-sizes="[10, 20, 50, 100]"
:total="detailPage.total"
@current-change="loadDetails"
@size-change="loadDetails"
/>
</div>
</el-dialog>
<component
@@ -506,8 +605,32 @@ const handleClosed = () => emit('closed');
const createVisible = ref(props.createPage),
detailVisible = ref(false),
formRef = ref();
const searchVisible = ref(true);
const columnSettingVisible = ref(false);
const tableSize = ref('default');
const tableSizeOptions = ['default', 'large', 'small'];
const columnOptions = [
{ prop: 'batchNo', label: '运单批次号' },
{ prop: 'projectName', label: '项目名称' },
{ prop: 'carrierName', label: '承运商' },
{ prop: 'carrierType', label: '承运类型' },
{ prop: 'waybillCount', label: '运单数' },
{ prop: 'importTypeName', label: '导入方式' },
{ prop: 'createUserName', label: '创建人' },
{ prop: 'statusName', label: '状态' },
{ prop: 'createTime', label: '创建时间' },
{ prop: 'updateTime', label: '更新时间' },
];
const visibleColumnKeys = ref(columnOptions.map(item => item.prop));
const columnVisible = computed(() =>
Object.fromEntries(columnOptions.map(item => [item.prop, visibleColumnKeys.value.includes(item.prop)]))
);
const toggleTableSize = () => {
const index = tableSizeOptions.indexOf(tableSize.value);
tableSize.value = tableSizeOptions[(index + 1) % tableSizeOptions.length];
};
const query = reactive({ batchNo: '', carrierId: '', createUser: '', createTimeRange: [] });
const detailQuery = reactive({ vehicleNo: '', cargoName: '' });
const detailQuery = reactive({ vehicleNo: '', driverName: '' });
const createDefaultForm = () => ({
id: '',
batchNo: '',
@@ -862,6 +985,20 @@ const loadEditorOptions = async () => {
cargoTypeFlatOptions.value = flattenCargoTypeOptions(cargoTypeOptions.value);
driverOptions.value = extractRecords(driverRes);
};
const ensureTransportTypeOptions = async () => {
if (transportTypeOptions.value.length) return;
const dictRes = await getDictionary({ code: 'transport_type' });
transportTypeOptions.value = extractRecords(dictRes).map(item => ({
label: item.dictValue || item.label,
value: item.dictKey || item.value,
}));
};
const transportTypeLabel = value => {
if (value === null || value === undefined || value === '') return '-';
return (
transportTypeOptions.value.find(item => String(item.value) === String(value))?.label || value
);
};
const loadBatches = async () => {
const res = await api.getImportBatches({ ...query, current: page.current, size: page.size });
batches.value = res.data?.data?.records || [];
@@ -922,9 +1059,13 @@ const closeCreate = () => {
}
createVisible.value = false;
};
const openDetail = row => {
const openDetail = async row => {
detailQuery.batchId = row.id;
detailQuery.vehicleNo = '';
detailQuery.driverName = '';
detailPage.current = 1;
detailVisible.value = true;
await ensureTransportTypeOptions();
loadDetails();
};
// 草稿明细已落库为草稿运单,编辑时回填到明细表,避免重新上传附件。
@@ -1329,34 +1470,81 @@ const confirmImport = async () => {
<style scoped lang="scss">
.waybill-import-toolbar {
margin-bottom: 12px;
&__search {
display: flex;
align-items: flex-start;
gap: 12px;
padding: 18px 18px 8px;
margin-bottom: 8px;
background: #fff;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
}
.el-form {
flex: 1;
margin-bottom: 0;
}
&__search-grid {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 8px 24px;
}
&__search :deep(.el-form-item) {
margin-bottom: 8px;
}
&__search :deep(.el-form-item__label) {
white-space: nowrap;
}
&__search :deep(.el-input),
&__search :deep(.el-select),
&__search :deep(.el-date-editor),
&__search :deep(.el-date-editor.el-input),
&__search :deep(.el-date-editor.el-input__wrapper),
&__search :deep(.el-date-editor--datetimerange) {
width: 100%;
}
&__search-actions {
display: flex;
flex: none;
justify-content: flex-end;
gap: 8px;
margin-bottom: 8px;
}
&__actions {
margin-top: 8px;
margin-top: 12px;
background: transparent;
}
&__column-setting {
display: flex;
flex-direction: column;
gap: 8px;
}
&__table-panel {
padding: 0 12px 12px;
background: #fff;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
}
&__pagination {
display: flex;
justify-content: flex-end;
width: 100%;
box-sizing: border-box;
padding: 16px 0;
}
&__table-panel :deep(.el-table) {
--el-table-border-color: #eff1f7;
}
&__table-panel :deep(.el-table__body tr:nth-child(even) > td.el-table__cell),
&__table-panel :deep(.el-table__body tr:nth-child(even) > td.el-table-fixed-column--left),
&__table-panel :deep(.el-table__body tr:nth-child(even) > td.el-table-fixed-column--right) {
background: #fafafa;
}
}
.waybill-import-page {
min-height: calc(100vh - 120px);
padding: 12px 24px 24px;
background: #fff;
}
.waybill-import-create {