1、修复基础配置
2、修复业务模块 3、拆分页面代码
This commit is contained in:
@@ -10,7 +10,6 @@ export const submit = api.submit;
|
|||||||
export const dispatch = api.dispatch;
|
export const dispatch = api.dispatch;
|
||||||
export const remove = api.remove;
|
export const remove = api.remove;
|
||||||
export const copy = api.copy;
|
export const copy = api.copy;
|
||||||
export const cancel = api.cancel;
|
|
||||||
export const complete = api.complete;
|
export const complete = api.complete;
|
||||||
|
|
||||||
export const importTransportPlan = ({
|
export const importTransportPlan = ({
|
||||||
|
|||||||
+3
-2
@@ -34,7 +34,8 @@ export const exportBlob = (url, params, options = {}) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const importBlob = (url, file) => {
|
export const importBlob = (url, file, options = {}) => {
|
||||||
|
const { timeout = 60000 } = options;
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append('file', file);
|
formData.append('file', file);
|
||||||
return request({
|
return request({
|
||||||
@@ -42,6 +43,6 @@ export const importBlob = (url, file) => {
|
|||||||
method: 'post',
|
method: 'post',
|
||||||
data: formData,
|
data: formData,
|
||||||
responseType: 'blob',
|
responseType: 'blob',
|
||||||
timeout: 60000,
|
timeout,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ export const waybillStatusOptions = [
|
|||||||
export const dataSourceOptions = [
|
export const dataSourceOptions = [
|
||||||
{ label: '手工创建', value: '手工创建' },
|
{ label: '手工创建', value: '手工创建' },
|
||||||
{ label: '批量导入', value: '批量导入' },
|
{ label: '批量导入', value: '批量导入' },
|
||||||
{ label: '模板生成', value: '模板生成' },
|
|
||||||
{ label: '计划调度', value: '计划调度' },
|
{ label: '计划调度', value: '计划调度' },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -269,7 +269,7 @@ export const option = {
|
|||||||
order: 270,
|
order: 270,
|
||||||
hide: true,
|
hide: true,
|
||||||
labelWidth: '0px',
|
labelWidth: '0px',
|
||||||
className: 'business-crud-page__full-form-item',
|
className: 'shipping-template-page__full-form-item',
|
||||||
},
|
},
|
||||||
{ label: '运费信息', prop: 'freightJson', hide: true, display: false },
|
{ label: '运费信息', prop: 'freightJson', hide: true, display: false },
|
||||||
{
|
{
|
||||||
@@ -290,7 +290,7 @@ export const option = {
|
|||||||
order: 250,
|
order: 250,
|
||||||
hide: true,
|
hide: true,
|
||||||
labelWidth: '0px',
|
labelWidth: '0px',
|
||||||
className: 'business-crud-page__full-form-item',
|
className: 'shipping-template-page__full-form-item',
|
||||||
},
|
},
|
||||||
{ label: '项目ID', prop: 'projectId', hide: true, display: false },
|
{ label: '项目ID', prop: 'projectId', hide: true, display: false },
|
||||||
{ label: '客户合同ID', prop: 'contractId', hide: true, display: false },
|
{ label: '客户合同ID', prop: 'contractId', hide: true, display: false },
|
||||||
@@ -300,7 +300,14 @@ export const option = {
|
|||||||
{ label: '收货地', prop: 'arrivalName', hide: true, display: false },
|
{ label: '收货地', prop: 'arrivalName', hide: true, display: false },
|
||||||
{ label: '收货联系人', prop: 'arrivalContact', hide: true, display: false },
|
{ label: '收货联系人', prop: 'arrivalContact', hide: true, display: false },
|
||||||
{ label: '收货联系方式', prop: 'arrivalPhone', hide: true, display: false },
|
{ label: '收货联系方式', prop: 'arrivalPhone', hide: true, display: false },
|
||||||
{ label: '所属组织', prop: 'deptName', minWidth: 150, addDisplay: false, editDisplay: false, display: false },
|
{
|
||||||
|
label: '所属组织',
|
||||||
|
prop: 'deptName',
|
||||||
|
minWidth: 150,
|
||||||
|
addDisplay: false,
|
||||||
|
editDisplay: false,
|
||||||
|
display: false,
|
||||||
|
},
|
||||||
...auditColumns.map(column => ({
|
...auditColumns.map(column => ({
|
||||||
...column,
|
...column,
|
||||||
display: false,
|
display: false,
|
||||||
|
|||||||
@@ -66,14 +66,8 @@ const getSecondCargoTypeName = item =>
|
|||||||
'货物';
|
'货物';
|
||||||
|
|
||||||
const formatGoodsInfo = row => {
|
const formatGoodsInfo = row => {
|
||||||
const rows = [
|
const rows =
|
||||||
row.goodsJson,
|
[row.goodsJson, row.goodsList, row.goodsRows, row.cargoList, row.cargoRows, row.goods]
|
||||||
row.goodsList,
|
|
||||||
row.goodsRows,
|
|
||||||
row.cargoList,
|
|
||||||
row.cargoRows,
|
|
||||||
row.goods,
|
|
||||||
]
|
|
||||||
.map(source => parseGoodsRows(source))
|
.map(source => parseGoodsRows(source))
|
||||||
.filter(source => source.length)
|
.filter(source => source.length)
|
||||||
.sort((left, right) => right.length - left.length)[0] || [];
|
.sort((left, right) => right.length - left.length)[0] || [];
|
||||||
@@ -176,9 +170,12 @@ const formatDispatchProgress = row => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
const lines = Array.from(summary.entries()).map(
|
const lines = Array.from(summary.entries()).map(
|
||||||
([unit, item]) => `${formatDispatchQuantity(item.assigned)}/${formatDispatchQuantity(item.total)}${unit}`
|
([unit, item]) =>
|
||||||
|
`${formatDispatchQuantity(item.assigned)}/${formatDispatchQuantity(item.total)}${unit}`
|
||||||
);
|
);
|
||||||
return lines.length ? lines.join('\n') : row.dispatchProgressName || row.dispatchProgress || row.progress || '';
|
return lines.length
|
||||||
|
? lines.join('\n')
|
||||||
|
: row.dispatchProgressName || row.dispatchProgress || row.progress || '';
|
||||||
};
|
};
|
||||||
|
|
||||||
const auditColumn = prop => ({ ...auditColumns.find(item => item.prop === prop) });
|
const auditColumn = prop => ({ ...auditColumns.find(item => item.prop === prop) });
|
||||||
@@ -188,7 +185,6 @@ export const config = {
|
|||||||
permission: 'transport_plan',
|
permission: 'transport_plan',
|
||||||
exportUrl: '/blade-transport/transport-plan/export-transport-plan',
|
exportUrl: '/blade-transport/transport-plan/export-transport-plan',
|
||||||
exportName: '运输计划',
|
exportName: '运输计划',
|
||||||
enableAllDept: false,
|
|
||||||
enableProjectSelect: true,
|
enableProjectSelect: true,
|
||||||
projectQueryParams: {
|
projectQueryParams: {
|
||||||
approvalStatuses: 'approved,change_approved',
|
approvalStatuses: 'approved,change_approved',
|
||||||
@@ -202,7 +198,7 @@ export const config = {
|
|||||||
enableTransportPlanCreateActions: true,
|
enableTransportPlanCreateActions: true,
|
||||||
enableTransportPlanImport: true,
|
enableTransportPlanImport: true,
|
||||||
fixedTransportAddressType: true,
|
fixedTransportAddressType: true,
|
||||||
transportPlanImportTitle: '导入发货计划',
|
transportPlanImportTitle: '导入运输计划',
|
||||||
transportPlanTemplateUrl: '/blade-transport/transport-plan/export-template',
|
transportPlanTemplateUrl: '/blade-transport/transport-plan/export-template',
|
||||||
attachmentTitle: '附件',
|
attachmentTitle: '附件',
|
||||||
searchRangeMap: {
|
searchRangeMap: {
|
||||||
@@ -319,7 +315,6 @@ export const option = {
|
|||||||
prop: 'goodsInfo',
|
prop: 'goodsInfo',
|
||||||
formatter: row => formatGoodsInfo(row),
|
formatter: row => formatGoodsInfo(row),
|
||||||
minWidth: 320,
|
minWidth: 320,
|
||||||
className: 'business-crud-page__goods-info-cell',
|
|
||||||
overHidden: false,
|
overHidden: false,
|
||||||
showOverflowTooltip: false,
|
showOverflowTooltip: false,
|
||||||
addDisplay: false,
|
addDisplay: false,
|
||||||
@@ -331,7 +326,6 @@ export const option = {
|
|||||||
prop: 'dispatchProgress',
|
prop: 'dispatchProgress',
|
||||||
formatter: row => formatDispatchProgress(row),
|
formatter: row => formatDispatchProgress(row),
|
||||||
minWidth: 120,
|
minWidth: 120,
|
||||||
className: 'business-crud-page__dispatch-progress-cell',
|
|
||||||
overHidden: false,
|
overHidden: false,
|
||||||
showOverflowTooltip: false,
|
showOverflowTooltip: false,
|
||||||
addDisplay: false,
|
addDisplay: false,
|
||||||
@@ -397,6 +391,7 @@ export const option = {
|
|||||||
span: 6,
|
span: 6,
|
||||||
order: 350,
|
order: 350,
|
||||||
minWidth: 150,
|
minWidth: 150,
|
||||||
|
rules: [{ required: true, message: '请选择计划开始日期', trigger: 'change' }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '计划结束日期',
|
label: '计划结束日期',
|
||||||
@@ -407,6 +402,7 @@ export const option = {
|
|||||||
span: 6,
|
span: 6,
|
||||||
order: 340,
|
order: 340,
|
||||||
minWidth: 150,
|
minWidth: 150,
|
||||||
|
rules: [{ required: true, message: '请选择计划结束日期', trigger: 'change' }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '数据来源',
|
label: '数据来源',
|
||||||
@@ -606,7 +602,7 @@ export const option = {
|
|||||||
order: 270,
|
order: 270,
|
||||||
hide: true,
|
hide: true,
|
||||||
labelWidth: '0px',
|
labelWidth: '0px',
|
||||||
className: 'business-crud-page__full-form-item',
|
className: 'transport-plan-page__full-form-item',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '',
|
label: '',
|
||||||
@@ -627,7 +623,7 @@ export const option = {
|
|||||||
order: 260,
|
order: 260,
|
||||||
hide: true,
|
hide: true,
|
||||||
labelWidth: '0px',
|
labelWidth: '0px',
|
||||||
className: 'business-crud-page__full-form-item',
|
className: 'transport-plan-page__full-form-item',
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -867,7 +867,7 @@ export const option = {
|
|||||||
order: 760,
|
order: 760,
|
||||||
hide: true,
|
hide: true,
|
||||||
labelWidth: '0px',
|
labelWidth: '0px',
|
||||||
className: 'business-crud-page__full-form-item',
|
className: 'waybill-manage-page__full-form-item',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '实际发货时间',
|
label: '实际发货时间',
|
||||||
@@ -979,7 +979,7 @@ export const option = {
|
|||||||
order: 740,
|
order: 740,
|
||||||
hide: true,
|
hide: true,
|
||||||
labelWidth: '0px',
|
labelWidth: '0px',
|
||||||
className: 'business-crud-page__full-form-item',
|
className: 'waybill-manage-page__full-form-item',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '所属组织',
|
label: '所属组织',
|
||||||
|
|||||||
@@ -7,8 +7,20 @@ import 'nprogress/nprogress.css';
|
|||||||
const excelPattern = /\.(xls|xlsx)$/;
|
const excelPattern = /\.(xls|xlsx)$/;
|
||||||
|
|
||||||
const isExcelResponse = res => {
|
const isExcelResponse = res => {
|
||||||
const contentType = res.headers['content-type'] || res.data.type || '';
|
const headers = res.headers || {};
|
||||||
return contentType.includes('application/vnd.ms-excel');
|
const contentType = String(headers['content-type'] || res.data?.type || '').toLowerCase();
|
||||||
|
const contentDisposition = String(headers['content-disposition'] || '').toLowerCase();
|
||||||
|
if (
|
||||||
|
contentType.includes('application/vnd.ms-excel') ||
|
||||||
|
contentType.includes('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// 网关或对象存储可能将 Excel 流标记为二进制类型,此时通过下载文件名识别。
|
||||||
|
return (
|
||||||
|
contentType.includes('application/octet-stream') &&
|
||||||
|
/\.(xls|xlsx)(?:["';]|$)/.test(contentDisposition)
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const parseBlobJson = async blob => {
|
const parseBlobJson = async blob => {
|
||||||
@@ -44,9 +56,10 @@ const decorateFailExcel = async (blob, businessName, failDetailDecorator) => {
|
|||||||
* @param {Function} [onSuccess] 导入成功回调
|
* @param {Function} [onSuccess] 导入成功回调
|
||||||
* @param {Object} [options] 扩展项
|
* @param {Object} [options] 扩展项
|
||||||
* @param {Function} [options.failDetailDecorator] 失败明细加工函数,用于对后端返回的失败 Excel 标红/改写原因
|
* @param {Function} [options.failDetailDecorator] 失败明细加工函数,用于对后端返回的失败 Excel 标红/改写原因
|
||||||
|
* @param {Number} [options.timeout=60000] 导入请求超时时间(毫秒)
|
||||||
*/
|
*/
|
||||||
export const openImportDialog = (vm, businessName, onSuccess, options = {}) => {
|
export const openImportDialog = (vm, businessName, onSuccess, options = {}) => {
|
||||||
const { failDetailDecorator } = options;
|
const { failDetailDecorator, timeout = 60000 } = options;
|
||||||
const excelOption = vm.excelOption || vm.excelOptionConfig;
|
const excelOption = vm.excelOption || vm.excelOptionConfig;
|
||||||
const column = vm.findColumn(excelOption?.column || [], 'excelFile');
|
const column = vm.findColumn(excelOption?.column || [], 'excelFile');
|
||||||
if (!column) {
|
if (!column) {
|
||||||
@@ -54,12 +67,15 @@ export const openImportDialog = (vm, businessName, onSuccess, options = {}) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
column.httpRequest = (option, uploadColumn) =>
|
column.httpRequest = (option, uploadColumn) =>
|
||||||
handleImportExcel(vm, option, uploadColumn, businessName, onSuccess, { failDetailDecorator });
|
handleImportExcel(vm, option, uploadColumn, businessName, onSuccess, {
|
||||||
|
failDetailDecorator,
|
||||||
|
timeout,
|
||||||
|
});
|
||||||
vm.excelBox = true;
|
vm.excelBox = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const handleImportExcel = async (vm, option, column, businessName, onSuccess, options = {}) => {
|
export const handleImportExcel = async (vm, option, column, businessName, onSuccess, options = {}) => {
|
||||||
const { failDetailDecorator } = options;
|
const { failDetailDecorator, timeout = 60000 } = options;
|
||||||
const file = option.file;
|
const file = option.file;
|
||||||
const fileName = file && file.name ? file.name.toLowerCase() : '';
|
const fileName = file && file.name ? file.name.toLowerCase() : '';
|
||||||
if (!excelPattern.test(fileName)) {
|
if (!excelPattern.test(fileName)) {
|
||||||
@@ -77,7 +93,7 @@ export const handleImportExcel = async (vm, option, column, businessName, onSucc
|
|||||||
background: 'rgba(255, 255, 255, 0.7)',
|
background: 'rgba(255, 255, 255, 0.7)',
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
const res = await importBlob(column.action, file);
|
const res = await importBlob(column.action, file, { timeout });
|
||||||
if (isExcelResponse(res)) {
|
if (isExcelResponse(res)) {
|
||||||
const decorated = await decorateFailExcel(res.data, businessName, failDetailDecorator);
|
const decorated = await decorateFailExcel(res.data, businessName, failDetailDecorator);
|
||||||
downloadXls(
|
downloadXls(
|
||||||
|
|||||||
@@ -201,7 +201,7 @@ export default {
|
|||||||
},
|
},
|
||||||
onLoad() {
|
onLoad() {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
getList(this.page.currentPage, this.page.pageSize, this.query)
|
return getList(this.page.currentPage, this.page.pageSize, this.query)
|
||||||
.then(res => {
|
.then(res => {
|
||||||
const pageData = res.data.data || {};
|
const pageData = res.data.data || {};
|
||||||
this.data = pageData.records || [];
|
this.data = pageData.records || [];
|
||||||
@@ -268,10 +268,10 @@ export default {
|
|||||||
this.mappingRows.map(item => ({ key: item.key, value: String(item.value || '').trim() }))
|
this.mappingRows.map(item => ({ key: item.key, value: String(item.value || '').trim() }))
|
||||||
),
|
),
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(async () => {
|
||||||
this.$message.success('操作成功');
|
this.$message.success('操作成功');
|
||||||
this.dialogVisible = false;
|
this.dialogVisible = false;
|
||||||
this.onLoad();
|
await this.onLoad();
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
this.submitLoading = false;
|
this.submitLoading = false;
|
||||||
|
|||||||
@@ -555,9 +555,8 @@ export default {
|
|||||||
editDisplay: false,
|
editDisplay: false,
|
||||||
dicData: [
|
dicData: [
|
||||||
{ label: '全部', value: '' },
|
{ label: '全部', value: '' },
|
||||||
{ label: '初始化录入', value: '初始化录入' },
|
|
||||||
{ label: '批量导入', value: '批量导入' },
|
{ label: '批量导入', value: '批量导入' },
|
||||||
{ label: '手动录入', value: '手动录入' },
|
{ label: '手动输入', value: '手动录入' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ export default {
|
|||||||
};
|
};
|
||||||
const validateTelegraphCode = (rule, value, callback) => {
|
const validateTelegraphCode = (rule, value, callback) => {
|
||||||
if (!/^[A-Z]{3}$/.test(String(value || '').toUpperCase())) {
|
if (!/^[A-Z]{3}$/.test(String(value || '').toUpperCase())) {
|
||||||
callback(new Error('电报码格式不正确或已存在'));
|
callback(new Error('电报略码格式不正确或已存在'));
|
||||||
} else {
|
} else {
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
@@ -246,12 +246,12 @@ export default {
|
|||||||
change: ({ value }) => this.handleTmisChange(value),
|
change: ({ value }) => this.handleTmisChange(value),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '电报码',
|
label: '电报略码',
|
||||||
prop: 'telegraphCode',
|
prop: 'telegraphCode',
|
||||||
minWidth: 100,
|
minWidth: 100,
|
||||||
maxlength: 3,
|
maxlength: 3,
|
||||||
rules: [
|
rules: [
|
||||||
{ required: true, message: '电报码格式不正确或已存在', trigger: 'blur' },
|
{ required: true, message: '电报略码格式不正确或已存在', trigger: 'blur' },
|
||||||
{ validator: validateTelegraphCode, trigger: 'blur' },
|
{ validator: validateTelegraphCode, trigger: 'blur' },
|
||||||
],
|
],
|
||||||
change: ({ value }) => this.handleTelegraphChange(value),
|
change: ({ value }) => this.handleTelegraphChange(value),
|
||||||
@@ -454,9 +454,8 @@ export default {
|
|||||||
editDisplay: false,
|
editDisplay: false,
|
||||||
dicData: [
|
dicData: [
|
||||||
{ label: '全部', value: '' },
|
{ label: '全部', value: '' },
|
||||||
{ label: '初始化导入', value: '初始化导入' },
|
{ label: '批量导入', value: '批量' },
|
||||||
{ label: '批量', value: '批量' },
|
{ label: '手动导入', value: '手动' },
|
||||||
{ label: '手动', value: '手动' },
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -695,13 +694,13 @@ export default {
|
|||||||
return Promise.reject(new Error('该TMIS编码已存在'));
|
return Promise.reject(new Error('该TMIS编码已存在'));
|
||||||
}
|
}
|
||||||
if (telegraphExists) {
|
if (telegraphExists) {
|
||||||
return Promise.reject(new Error('电报码格式不正确或已存在'));
|
return Promise.reject(new Error('电报略码格式不正确或已存在'));
|
||||||
}
|
}
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
handleSubmitError(error, loading) {
|
handleSubmitError(error, loading) {
|
||||||
const uniqueMessages = ['该TMIS编码已存在', '电报码格式不正确或已存在'];
|
const uniqueMessages = ['该TMIS编码已存在', '电报略码格式不正确或已存在'];
|
||||||
if (uniqueMessages.includes(error.message)) {
|
if (uniqueMessages.includes(error.message)) {
|
||||||
this.$message.warning(error.message);
|
this.$message.warning(error.message);
|
||||||
}
|
}
|
||||||
@@ -782,10 +781,18 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
beforeOpen(done, type) {
|
beforeOpen(done, type) {
|
||||||
|
const tmisCodeColumn = this.findColumn('tmisCode');
|
||||||
|
if (tmisCodeColumn) {
|
||||||
|
// Avue 会复用列配置,打开不同记录前必须先清除上一次编辑状态。
|
||||||
|
tmisCodeColumn.disabled = false;
|
||||||
|
}
|
||||||
if (['edit', 'view'].includes(type)) {
|
if (['edit', 'view'].includes(type)) {
|
||||||
this.regionInitializing = true;
|
this.regionInitializing = true;
|
||||||
getDetail(this.form.id).then(res => {
|
getDetail(this.form.id).then(res => {
|
||||||
const detail = this.normalizeRegionForm(res.data.data || {});
|
const detail = this.normalizeRegionForm(res.data.data || {});
|
||||||
|
if (tmisCodeColumn) {
|
||||||
|
tmisCodeColumn.disabled = type === 'edit' && Number(detail.status) === 1;
|
||||||
|
}
|
||||||
this.loadCityOptions(detail.provinceCode)
|
this.loadCityOptions(detail.provinceCode)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.ensureCityOption(detail);
|
this.ensureCityOption(detail);
|
||||||
@@ -851,7 +858,7 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
handleImport() {
|
handleImport() {
|
||||||
openImportDialog(this, '铁路车站主数据');
|
openImportDialog(this, '铁路车站主数据', () => this.onLoad(this.page, this.query));
|
||||||
},
|
},
|
||||||
handleExport() {
|
handleExport() {
|
||||||
this.$confirm('是否导出铁路车站主数据?', '提示', {
|
this.$confirm('是否导出铁路车站主数据?', '提示', {
|
||||||
|
|||||||
+25
-22
@@ -4,7 +4,11 @@
|
|||||||
<div class="box">
|
<div class="box">
|
||||||
<el-scrollbar>
|
<el-scrollbar>
|
||||||
<basic-container>
|
<basic-container>
|
||||||
<avue-tree :option="treeOption" :data="treeData" @node-click="nodeClick" />
|
<avue-tree
|
||||||
|
:option="treeOption"
|
||||||
|
:data="treeData"
|
||||||
|
@node-click="nodeClick"
|
||||||
|
/>
|
||||||
</basic-container>
|
</basic-container>
|
||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
</div>
|
</div>
|
||||||
@@ -27,20 +31,8 @@
|
|||||||
<el-option label="区县" :value="3" />
|
<el-option label="区县" :value="3" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="数据来源">
|
|
||||||
<el-select v-model="searchForm.dataSource" clearable placeholder="请选择" style="width: 200px;">
|
|
||||||
<el-option label="手动录入" value="手动录入" />
|
|
||||||
<el-option label="初始化导入" value="初始化导入" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</div>
|
</div>
|
||||||
<div style="display: flex; flex-direction: row; align-items: center; justify-content: space-between;">
|
<div style="display: flex; flex-direction: row; align-items: center; justify-content: flex-end;">
|
||||||
<el-form-item label="启停状态">
|
|
||||||
<el-select v-model="searchForm.status" clearable placeholder="请选择" style="width: 200px;">
|
|
||||||
<el-option label="启用" :value="1" />
|
|
||||||
<el-option label="停用" :value="2" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item class="region-page__search-actions">
|
<el-form-item class="region-page__search-actions">
|
||||||
<el-button type="primary" @click="handleSearch">搜索</el-button>
|
<el-button type="primary" @click="handleSearch">搜索</el-button>
|
||||||
<el-button @click="handleSearchReset">清空</el-button>
|
<el-button @click="handleSearchReset">清空</el-button>
|
||||||
@@ -180,8 +172,6 @@ export default {
|
|||||||
code: '',
|
code: '',
|
||||||
name: '',
|
name: '',
|
||||||
regionLevel: undefined,
|
regionLevel: undefined,
|
||||||
dataSource: '',
|
|
||||||
status: undefined,
|
|
||||||
},
|
},
|
||||||
parentOptions: [],
|
parentOptions: [],
|
||||||
syncLoading: false,
|
syncLoading: false,
|
||||||
@@ -203,6 +193,7 @@ export default {
|
|||||||
},
|
},
|
||||||
addBtn: false,
|
addBtn: false,
|
||||||
menu: false,
|
menu: false,
|
||||||
|
defaultExpandAll: false,
|
||||||
size: 'default',
|
size: 'default',
|
||||||
props: {
|
props: {
|
||||||
labelText: '标题',
|
labelText: '标题',
|
||||||
@@ -458,7 +449,13 @@ export default {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
hasSearchCriteria() {
|
||||||
|
return Object.values(this.searchForm).some(
|
||||||
|
value => value !== '' && value !== undefined && value !== null
|
||||||
|
);
|
||||||
|
},
|
||||||
handleSearch() {
|
handleSearch() {
|
||||||
|
this.treeOption.defaultExpandAll = this.hasSearchCriteria();
|
||||||
this.initTree();
|
this.initTree();
|
||||||
this.regionForm = {};
|
this.regionForm = {};
|
||||||
},
|
},
|
||||||
@@ -467,8 +464,6 @@ export default {
|
|||||||
code: '',
|
code: '',
|
||||||
name: '',
|
name: '',
|
||||||
regionLevel: undefined,
|
regionLevel: undefined,
|
||||||
dataSource: '',
|
|
||||||
status: undefined,
|
|
||||||
};
|
};
|
||||||
this.handleSearch();
|
this.handleSearch();
|
||||||
},
|
},
|
||||||
@@ -507,6 +502,10 @@ export default {
|
|||||||
this.$message.warning('请先选择一项区划');
|
this.$message.warning('请先选择一项区划');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (Number(this.regionForm.regionLevel) >= 3) {
|
||||||
|
this.$message.warning('区县已是末级,不能新增下级');
|
||||||
|
return;
|
||||||
|
}
|
||||||
const parentCode = this.regionForm.code;
|
const parentCode = this.regionForm.code;
|
||||||
const parentName = this.regionForm.name;
|
const parentName = this.regionForm.name;
|
||||||
const parentGroupCode = this.regionForm.parentCode || this.topCode;
|
const parentGroupCode = this.regionForm.parentCode || this.topCode;
|
||||||
@@ -517,8 +516,7 @@ export default {
|
|||||||
this.regionForm.subCode = '';
|
this.regionForm.subCode = '';
|
||||||
this.regionForm.originalCode = '';
|
this.regionForm.originalCode = '';
|
||||||
this.regionForm.name = '';
|
this.regionForm.name = '';
|
||||||
this.regionForm.regionLevel =
|
this.regionForm.regionLevel = Number(this.regionForm.regionLevel) + 1;
|
||||||
this.regionForm.regionLevel === 5 ? 5 : this.regionForm.regionLevel + 1;
|
|
||||||
this.loadParentOptionsByGroup(parentGroupCode, parentCode, parentName);
|
this.loadParentOptionsByGroup(parentGroupCode, parentCode, parentName);
|
||||||
},
|
},
|
||||||
setRegionColumnDisplay(prop, display) {
|
setRegionColumnDisplay(prop, display) {
|
||||||
@@ -637,9 +635,14 @@ export default {
|
|||||||
},
|
},
|
||||||
handleImport() {
|
handleImport() {
|
||||||
this.syncImportAction();
|
this.syncImportAction();
|
||||||
openImportDialog(this, '行政区划', () => {
|
openImportDialog(
|
||||||
|
this,
|
||||||
|
'行政区划',
|
||||||
|
() => {
|
||||||
this.initTree();
|
this.initTree();
|
||||||
});
|
},
|
||||||
|
{ timeout: 180000 }
|
||||||
|
);
|
||||||
},
|
},
|
||||||
syncImportAction() {
|
syncImportAction() {
|
||||||
const column = this.findColumn(this.excelOption.column, 'excelFile');
|
const column = this.findColumn(this.excelOption.column, 'excelFile');
|
||||||
|
|||||||
@@ -2265,7 +2265,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="business-crud-page__transport-plan-detail-field">
|
<div class="business-crud-page__transport-plan-detail-field">
|
||||||
<span>合同编号</span>
|
<span>合同编号</span>
|
||||||
<strong>{{ detailRow.contractNo || detailRow.contractName || '-' }}</strong>
|
<strong>{{ detailRow.contractNo || '-' }}</strong>
|
||||||
</div>
|
</div>
|
||||||
<div class="business-crud-page__transport-plan-detail-field">
|
<div class="business-crud-page__transport-plan-detail-field">
|
||||||
<span>货物信息</span>
|
<span>货物信息</span>
|
||||||
@@ -3339,7 +3339,7 @@
|
|||||||
<div class="business-crud-page__dispatch-summary-item">
|
<div class="business-crud-page__dispatch-summary-item">
|
||||||
<div class="business-crud-page__dispatch-summary-label">合同编号</div>
|
<div class="business-crud-page__dispatch-summary-label">合同编号</div>
|
||||||
<div class="business-crud-page__dispatch-summary-value">
|
<div class="business-crud-page__dispatch-summary-value">
|
||||||
{{ dispatchRow.contractName || dispatchRow.contractNo || '-' }}
|
{{ dispatchRow.contractNo || '-' }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="business-crud-page__dispatch-summary-item">
|
<div class="business-crud-page__dispatch-summary-item">
|
||||||
@@ -3389,7 +3389,11 @@
|
|||||||
{{ parseDispatchRoutePoint(dispatchRow, 'start').name || '-' }}
|
{{ parseDispatchRoutePoint(dispatchRow, 'start').name || '-' }}
|
||||||
</div>
|
</div>
|
||||||
<div class="business-crud-page__dispatch-route-address">
|
<div class="business-crud-page__dispatch-route-address">
|
||||||
{{ parseDispatchRoutePoint(dispatchRow, 'start').address || '-' }}
|
{{
|
||||||
|
formatTransportPlanProvinceCityDistrict(
|
||||||
|
parseDispatchRoutePoint(dispatchRow, 'start').address
|
||||||
|
)
|
||||||
|
}}
|
||||||
</div>
|
</div>
|
||||||
<div class="business-crud-page__dispatch-route-contact">
|
<div class="business-crud-page__dispatch-route-contact">
|
||||||
{{ parseDispatchRoutePoint(dispatchRow, 'start').contact || '-' }}
|
{{ parseDispatchRoutePoint(dispatchRow, 'start').contact || '-' }}
|
||||||
@@ -3406,7 +3410,11 @@
|
|||||||
{{ parseDispatchRoutePoint(dispatchRow, 'end').name || '-' }}
|
{{ parseDispatchRoutePoint(dispatchRow, 'end').name || '-' }}
|
||||||
</div>
|
</div>
|
||||||
<div class="business-crud-page__dispatch-route-address">
|
<div class="business-crud-page__dispatch-route-address">
|
||||||
{{ parseDispatchRoutePoint(dispatchRow, 'end').address || '-' }}
|
{{
|
||||||
|
formatTransportPlanProvinceCityDistrict(
|
||||||
|
parseDispatchRoutePoint(dispatchRow, 'end').address
|
||||||
|
)
|
||||||
|
}}
|
||||||
</div>
|
</div>
|
||||||
<div class="business-crud-page__dispatch-route-contact">
|
<div class="business-crud-page__dispatch-route-contact">
|
||||||
{{ parseDispatchRoutePoint(dispatchRow, 'end').contact || '-' }}
|
{{ parseDispatchRoutePoint(dispatchRow, 'end').contact || '-' }}
|
||||||
@@ -3867,7 +3875,7 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item v-if="dispatchCarrierRequired" :label="dispatchCarrierLabel" required>
|
<el-form-item v-if="dispatchCarrierRequired" :label="dispatchCarrierLabel" required>
|
||||||
<el-select
|
<el-select
|
||||||
v-model="dispatchItemForm.carrierName"
|
v-model="dispatchCarrierSelection"
|
||||||
:placeholder="`请选择${dispatchCarrierLabel}`"
|
:placeholder="`请选择${dispatchCarrierLabel}`"
|
||||||
filterable
|
filterable
|
||||||
clearable
|
clearable
|
||||||
@@ -3880,8 +3888,8 @@
|
|||||||
:key="
|
:key="
|
||||||
item.id || item.customerName || item.carrierName || item.fullName || item.name
|
item.id || item.customerName || item.carrierName || item.fullName || item.name
|
||||||
"
|
"
|
||||||
:label="item.customerName || item.carrierName || item.fullName || item.name"
|
:label="item.label || item.customerName || item.carrierName || item.fullName || item.name"
|
||||||
:value="item.customerName || item.carrierName || item.fullName || item.name"
|
:value="dispatchIsCarrierMode ? item.carrierContractId : item.value || item.customerName || item.carrierName || item.fullName || item.name"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -4086,7 +4094,7 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item v-if="dispatchCarrierRequired" :label="dispatchCarrierLabel" required>
|
<el-form-item v-if="dispatchCarrierRequired" :label="dispatchCarrierLabel" required>
|
||||||
<el-select
|
<el-select
|
||||||
v-model="dispatchItemForm.carrierName"
|
v-model="dispatchCarrierSelection"
|
||||||
:placeholder="`请选择${dispatchCarrierLabel}`"
|
:placeholder="`请选择${dispatchCarrierLabel}`"
|
||||||
filterable
|
filterable
|
||||||
clearable
|
clearable
|
||||||
@@ -4099,8 +4107,8 @@
|
|||||||
:key="
|
:key="
|
||||||
item.id || item.customerName || item.carrierName || item.fullName || item.name
|
item.id || item.customerName || item.carrierName || item.fullName || item.name
|
||||||
"
|
"
|
||||||
:label="item.customerName || item.carrierName || item.fullName || item.name"
|
:label="item.label || item.customerName || item.carrierName || item.fullName || item.name"
|
||||||
:value="item.customerName || item.carrierName || item.fullName || item.name"
|
:value="dispatchIsCarrierMode ? item.carrierContractId : item.value || item.customerName || item.carrierName || item.fullName || item.name"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -5446,6 +5454,7 @@ const defaultDispatchRow = () => ({
|
|||||||
transportType: '',
|
transportType: '',
|
||||||
carrierType: '承运商',
|
carrierType: '承运商',
|
||||||
carrierId: '',
|
carrierId: '',
|
||||||
|
carrierContractId: '',
|
||||||
carrierName: '',
|
carrierName: '',
|
||||||
driverId: '',
|
driverId: '',
|
||||||
driverName: '',
|
driverName: '',
|
||||||
@@ -6255,6 +6264,16 @@ export default {
|
|||||||
dispatchCarrierLabel() {
|
dispatchCarrierLabel() {
|
||||||
return this.dispatchItemForm.carrierType === '网货平台' ? '承运方' : '承运商';
|
return this.dispatchItemForm.carrierType === '网货平台' ? '承运方' : '承运商';
|
||||||
},
|
},
|
||||||
|
dispatchCarrierSelection: {
|
||||||
|
get() {
|
||||||
|
return this.dispatchIsCarrierMode
|
||||||
|
? this.dispatchItemForm.carrierContractId || ''
|
||||||
|
: this.dispatchItemForm.carrierName || '';
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
this.handleDispatchCarrierChange(value);
|
||||||
|
},
|
||||||
|
},
|
||||||
dispatchStationMode() {
|
dispatchStationMode() {
|
||||||
return ['water', 'rail', 'air'].includes(this.dispatchTransportMode);
|
return ['water', 'rail', 'air'].includes(this.dispatchTransportMode);
|
||||||
},
|
},
|
||||||
@@ -12226,6 +12245,8 @@ export default {
|
|||||||
taskEntryMode: item.taskEntryMode || 'simple',
|
taskEntryMode: item.taskEntryMode || 'simple',
|
||||||
transportType: item.transportType || plan.transportType || '',
|
transportType: item.transportType || plan.transportType || '',
|
||||||
carrierType: item.carrierType || plan.carrierType || '承运商',
|
carrierType: item.carrierType || plan.carrierType || '承运商',
|
||||||
|
carrierId: item.carrierId || plan.carrierId || '',
|
||||||
|
carrierContractId: item.carrierContractId || plan.carrierContractId || '',
|
||||||
carrierName: item.carrierName || plan.carrierName || '',
|
carrierName: item.carrierName || plan.carrierName || '',
|
||||||
driverName: item.driverName || plan.driverName || '',
|
driverName: item.driverName || plan.driverName || '',
|
||||||
driverPhone: item.driverPhone || plan.driverPhone || '',
|
driverPhone: item.driverPhone || plan.driverPhone || '',
|
||||||
@@ -12643,11 +12664,15 @@ export default {
|
|||||||
this.dispatchItemForm.trailerVehicleNo = '';
|
this.dispatchItemForm.trailerVehicleNo = '';
|
||||||
this.dispatchItemForm.escortName = '';
|
this.dispatchItemForm.escortName = '';
|
||||||
this.dispatchItemForm.escortPhone = '';
|
this.dispatchItemForm.escortPhone = '';
|
||||||
} else if (!this.isDispatchCarrierRequired(nextValue)) {
|
} else {
|
||||||
|
this.dispatchItemForm.carrierContractId = '';
|
||||||
|
if (!this.isDispatchCarrierRequired(nextValue)) {
|
||||||
this.dispatchItemForm.carrierId = '';
|
this.dispatchItemForm.carrierId = '';
|
||||||
this.dispatchItemForm.carrierName = '';
|
this.dispatchItemForm.carrierName = '';
|
||||||
}
|
}
|
||||||
|
}
|
||||||
this.dispatchItemForm.carrierType = nextValue;
|
this.dispatchItemForm.carrierType = nextValue;
|
||||||
|
this.loadDispatchCarrierOptions(this.dispatchRow);
|
||||||
},
|
},
|
||||||
isDispatchCarrierRequired(carrierType) {
|
isDispatchCarrierRequired(carrierType) {
|
||||||
return ['承运商', '网货平台'].includes(String(carrierType || '').trim());
|
return ['承运商', '网货平台'].includes(String(carrierType || '').trim());
|
||||||
@@ -12708,11 +12733,47 @@ export default {
|
|||||||
if (this.dispatchCarrierLoading) return Promise.resolve(this.dispatchCarrierOptions);
|
if (this.dispatchCarrierLoading) return Promise.resolve(this.dispatchCarrierOptions);
|
||||||
const projectId = plan?.projectId;
|
const projectId = plan?.projectId;
|
||||||
const requestId = ++this.dispatchCarrierRequestId;
|
const requestId = ++this.dispatchCarrierRequestId;
|
||||||
|
const carrierTypeAtRequest = this.dispatchItemForm.carrierType || '承运商';
|
||||||
const project = this.projectOptions.find(item => String(item.id) === String(projectId));
|
const project = this.projectOptions.find(item => String(item.id) === String(projectId));
|
||||||
this.dispatchCarrierOptions = this.getProjectCarrierOptions({ ...project, ...plan });
|
this.dispatchCarrierOptions = this.getProjectCarrierOptions({ ...project, ...plan });
|
||||||
if (!projectId) return Promise.resolve(this.dispatchCarrierOptions);
|
if (!projectId) return Promise.resolve(this.dispatchCarrierOptions);
|
||||||
this.dispatchCarrierLoading = true;
|
this.dispatchCarrierLoading = true;
|
||||||
return getProjectDetail(projectId)
|
const carrierContractPromise = getContractList(1, 9999, {
|
||||||
|
projectId,
|
||||||
|
projectName: plan?.projectName || project?.projectName,
|
||||||
|
contractCategory: '承运商合同',
|
||||||
|
}).then(res => this.getWaybillCarrierContractOptions(extractRecords(res)));
|
||||||
|
if (carrierTypeAtRequest === '承运商') {
|
||||||
|
return carrierContractPromise
|
||||||
|
.then(options => {
|
||||||
|
if (requestId !== this.dispatchCarrierRequestId) return this.dispatchCarrierOptions;
|
||||||
|
this.dispatchCarrierOptions = options || [];
|
||||||
|
const current = this.dispatchCarrierOptions.find(
|
||||||
|
item =>
|
||||||
|
String(item.carrierContractId) ===
|
||||||
|
String(this.dispatchItemForm.carrierContractId || '')
|
||||||
|
);
|
||||||
|
if (current) {
|
||||||
|
this.dispatchItemForm.carrierName = current.carrierName;
|
||||||
|
} else if (!this.dispatchItemForm.carrierContractId) {
|
||||||
|
const matches = this.dispatchCarrierOptions.filter(
|
||||||
|
item => String(item.carrierName) === String(this.dispatchItemForm.carrierName || '')
|
||||||
|
);
|
||||||
|
if (matches.length === 1) {
|
||||||
|
this.dispatchItemForm.carrierContractId = matches[0].carrierContractId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.dispatchCarrierOptions;
|
||||||
|
})
|
||||||
|
.catch(() => this.dispatchCarrierOptions)
|
||||||
|
.finally(() => {
|
||||||
|
if (requestId === this.dispatchCarrierRequestId) {
|
||||||
|
this.dispatchCarrierLoading = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return Promise.all([
|
||||||
|
getProjectDetail(projectId)
|
||||||
.then(res => {
|
.then(res => {
|
||||||
if (requestId !== this.dispatchCarrierRequestId) return this.dispatchCarrierOptions;
|
if (requestId !== this.dispatchCarrierRequestId) return this.dispatchCarrierOptions;
|
||||||
const detail = res?.data?.data || {};
|
const detail = res?.data?.data || {};
|
||||||
@@ -12723,7 +12784,10 @@ export default {
|
|||||||
});
|
});
|
||||||
return this.dispatchCarrierOptions;
|
return this.dispatchCarrierOptions;
|
||||||
})
|
})
|
||||||
.catch(() => this.dispatchCarrierOptions)
|
.catch(() => this.dispatchCarrierOptions),
|
||||||
|
carrierContractPromise.catch(() => []),
|
||||||
|
])
|
||||||
|
.then(([options]) => options)
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
if (requestId === this.dispatchCarrierRequestId) {
|
if (requestId === this.dispatchCarrierRequestId) {
|
||||||
this.dispatchCarrierLoading = false;
|
this.dispatchCarrierLoading = false;
|
||||||
@@ -12731,9 +12795,19 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
handleDispatchCarrierChange(value) {
|
handleDispatchCarrierChange(value) {
|
||||||
const carrier = this.dispatchCarrierOptions.find(item => item.value === String(value || ''));
|
const carrier = this.dispatchCarrierOptions.find(item => {
|
||||||
|
const optionValue = this.dispatchIsCarrierMode ? item.carrierContractId : item.value;
|
||||||
|
return String(optionValue || '') === String(value || '');
|
||||||
|
});
|
||||||
|
if (this.dispatchIsCarrierMode) {
|
||||||
|
this.dispatchItemForm.carrierContractId = carrier?.carrierContractId || '';
|
||||||
|
this.dispatchItemForm.carrierId = '';
|
||||||
|
this.dispatchItemForm.carrierName = carrier?.carrierName || '';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.dispatchItemForm.carrierContractId = '';
|
||||||
this.dispatchItemForm.carrierId = carrier?.id || '';
|
this.dispatchItemForm.carrierId = carrier?.id || '';
|
||||||
this.dispatchItemForm.carrierName = value || '';
|
this.dispatchItemForm.carrierName = carrier?.carrierName || value || '';
|
||||||
},
|
},
|
||||||
loadDispatchDriverOptions() {
|
loadDispatchDriverOptions() {
|
||||||
if (this.taskDriverLoading) return Promise.resolve([]);
|
if (this.taskDriverLoading) return Promise.resolve([]);
|
||||||
@@ -12837,7 +12911,54 @@ export default {
|
|||||||
},
|
},
|
||||||
dispatchItemRemainingQuantity(row = {}) {
|
dispatchItemRemainingQuantity(row = {}) {
|
||||||
const unit = this.getDispatchQuantityUnit(row);
|
const unit = this.getDispatchQuantityUnit(row);
|
||||||
let remaining = this.getDispatchRemainingQuantity(unit);
|
const hasCargoIdentity = Boolean(
|
||||||
|
String(row.cargoName || row.goodsName || row.name || '').trim() ||
|
||||||
|
String(
|
||||||
|
row.cargoType || row.secondCargoTypeName || row.goodsType || row.type || ''
|
||||||
|
).trim()
|
||||||
|
);
|
||||||
|
const planGoodsRows = this.dispatchPlanGoodsRows;
|
||||||
|
const cargoKey = this.getDispatchCargoIdentity(row);
|
||||||
|
|
||||||
|
// 完整录入时按货物身份计算,不能把同单位的其他货物数量合并到当前行。
|
||||||
|
if (planGoodsRows.length && hasCargoIdentity) {
|
||||||
|
const matchedPlanRows = planGoodsRows.filter(
|
||||||
|
goods => this.getDispatchCargoIdentity(goods) === cargoKey
|
||||||
|
);
|
||||||
|
if (!matchedPlanRows.length) return 0;
|
||||||
|
const total = matchedPlanRows.reduce(
|
||||||
|
(sum, goods) =>
|
||||||
|
sum +
|
||||||
|
this.parseDispatchQuantity(
|
||||||
|
goods.quantity || goods.cargoQuantity || goods.goodsQuantity
|
||||||
|
),
|
||||||
|
0
|
||||||
|
);
|
||||||
|
const assigned = this.dispatchRows.reduce((sum, dispatchRow, index) => {
|
||||||
|
if (
|
||||||
|
index === this.dispatchItemIndex ||
|
||||||
|
!this.hasDispatchVehicleIdentifier(dispatchRow)
|
||||||
|
) {
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
sum +
|
||||||
|
this.getDispatchGoodsSourceRows(dispatchRow).reduce((goodsSum, goods) => {
|
||||||
|
if (this.getDispatchCargoIdentity(goods) !== cargoKey) return goodsSum;
|
||||||
|
return (
|
||||||
|
goodsSum +
|
||||||
|
this.parseDispatchQuantity(
|
||||||
|
goods.quantity || goods.cargoQuantity || goods.goodsQuantity
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}, 0)
|
||||||
|
);
|
||||||
|
}, 0);
|
||||||
|
return Math.max(total - assigned, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 兼容没有货物明细的旧数据,以及尚未选择货物的空白行。
|
||||||
|
const remaining = this.getDispatchRemainingQuantity(unit);
|
||||||
const editingRow = this.dispatchRows[this.dispatchItemIndex];
|
const editingRow = this.dispatchRows[this.dispatchItemIndex];
|
||||||
if (!editingRow || !this.hasDispatchVehicleIdentifier(editingRow)) return remaining;
|
if (!editingRow || !this.hasDispatchVehicleIdentifier(editingRow)) return remaining;
|
||||||
const editingGoodsRows = this.dispatchGoodsRows(editingRow.goodsJson);
|
const editingGoodsRows = this.dispatchGoodsRows(editingRow.goodsJson);
|
||||||
@@ -12943,6 +13064,9 @@ export default {
|
|||||||
if (this.isDispatchCarrierRequired(row.carrierType)) {
|
if (this.isDispatchCarrierRequired(row.carrierType)) {
|
||||||
requiredFields.push(['carrierName', row.carrierType === '网货平台' ? '承运方' : '承运商']);
|
requiredFields.push(['carrierName', row.carrierType === '网货平台' ? '承运方' : '承运商']);
|
||||||
}
|
}
|
||||||
|
if (row.carrierType === '承运商') {
|
||||||
|
requiredFields.push(['carrierContractId', '承运商合同']);
|
||||||
|
}
|
||||||
const fullEntry = row.taskEntryMode === 'full';
|
const fullEntry = row.taskEntryMode === 'full';
|
||||||
const roadTransport = this.resolveTransportMode(row.transportType) === 'road';
|
const roadTransport = this.resolveTransportMode(row.transportType) === 'road';
|
||||||
if (fullEntry) {
|
if (fullEntry) {
|
||||||
@@ -13056,16 +13180,25 @@ export default {
|
|||||||
? this.dispatchItemCargoRows
|
? this.dispatchItemCargoRows
|
||||||
: [this.dispatchItemForm];
|
: [this.dispatchItemForm];
|
||||||
if (!this.validateDispatchItemData(this.dispatchItemForm, goodsRows)) return false;
|
if (!this.validateDispatchItemData(this.dispatchItemForm, goodsRows)) return false;
|
||||||
const quantitiesByUnit = new Map();
|
const quantityGroups = new Map();
|
||||||
goodsRows.forEach(goods => {
|
goodsRows.forEach(goods => {
|
||||||
const unit = this.getDispatchQuantityUnit(goods);
|
const unit = this.getDispatchQuantityUnit(goods);
|
||||||
quantitiesByUnit.set(
|
const hasCargoIdentity = Boolean(
|
||||||
unit,
|
String(goods.cargoName || goods.goodsName || goods.name || '').trim() ||
|
||||||
(quantitiesByUnit.get(unit) || 0) + this.parseDispatchQuantity(goods.quantity)
|
String(
|
||||||
|
goods.cargoType || goods.secondCargoTypeName || goods.goodsType || goods.type || ''
|
||||||
|
).trim()
|
||||||
);
|
);
|
||||||
|
const key = hasCargoIdentity
|
||||||
|
? `cargo:${this.getDispatchCargoIdentity(goods)}`
|
||||||
|
: `unit:${unit}`;
|
||||||
|
const group = quantityGroups.get(key) || { row: goods, quantity: 0 };
|
||||||
|
group.quantity += this.parseDispatchQuantity(goods.quantity);
|
||||||
|
quantityGroups.set(key, group);
|
||||||
});
|
});
|
||||||
for (const [unit, quantity] of quantitiesByUnit.entries()) {
|
for (const { row: goods, quantity } of quantityGroups.values()) {
|
||||||
const remaining = this.dispatchItemRemainingQuantity({ quantityUnit: unit });
|
const unit = this.getDispatchQuantityUnit(goods);
|
||||||
|
const remaining = this.dispatchItemRemainingQuantity(goods);
|
||||||
if (quantity - remaining > 1e-8) {
|
if (quantity - remaining > 1e-8) {
|
||||||
this.$message.warning(
|
this.$message.warning(
|
||||||
`本次调度${unit}合计不能超过剩余数量${this.formatDispatchQuantity(remaining)}${unit}`
|
`本次调度${unit}合计不能超过剩余数量${this.formatDispatchQuantity(remaining)}${unit}`
|
||||||
|
|||||||
@@ -134,7 +134,6 @@
|
|||||||
<el-row v-if="route.freightItems.length" :gutter="16">
|
<el-row v-if="route.freightItems.length" :gutter="16">
|
||||||
<el-col :span="6"><el-form-item label="运费合计"><el-input :model-value="formatAmount(freightTotal(route))" readonly><template #suffix>{{ currencyLabel(route.currency) }}</template></el-input></el-form-item></el-col>
|
<el-col :span="6"><el-form-item label="运费合计"><el-input :model-value="formatAmount(freightTotal(route))" readonly><template #suffix>{{ currencyLabel(route.currency) }}</template></el-input></el-form-item></el-col>
|
||||||
<el-col :span="6"><el-form-item label="其他费用合计"><el-input :model-value="route.otherFeeTotal" inputmode="decimal" placeholder="请输入" @input="value => handleOtherFeeTotalInput(route, value)" /></el-form-item></el-col>
|
<el-col :span="6"><el-form-item label="其他费用合计"><el-input :model-value="route.otherFeeTotal" inputmode="decimal" placeholder="请输入" @input="value => handleOtherFeeTotalInput(route, value)" /></el-form-item></el-col>
|
||||||
<el-col :span="6"><el-form-item label="币种"><el-select v-model="route.currency"><el-option label="人民币" value="CNY" /><el-option label="美元" value="USD" /><el-option label="欧元" value="EUR" /></el-select></el-form-item></el-col>
|
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
@@ -143,16 +142,16 @@
|
|||||||
<el-form :model="route" label-position="right" label-width="auto" class="dispatch-form carrier-form">
|
<el-form :model="route" label-position="right" label-width="auto" class="dispatch-form carrier-form">
|
||||||
<el-row :gutter="16">
|
<el-row :gutter="16">
|
||||||
<template v-if="isRoad(route)">
|
<template v-if="isRoad(route)">
|
||||||
<el-col v-if="route.carrierType === '承运商'" :span="6"><el-form-item label="承运商" required><el-select v-model="route.carrierContractId" filterable clearable placeholder="请选择" :loading="carrierLoading" @change="value => handleCarrierContractChange(route, value)"><el-option v-for="item in carrierOptions" :key="item.contractId" :label="carrierOptionLabel(item)" :value="item.contractId" /></el-select></el-form-item></el-col>
|
<el-col :span="6"><el-form-item label="承运商" :required="route.carrierType === '承运商'"><el-select :model-value="route.carrierType === '承运商' ? route.carrierContractId : route.carrierName" filterable clearable placeholder="请选择" :loading="carrierLoading" @change="value => handleCarrierContractChange(route, value)"><el-option v-for="item in carrierOptions" :key="carrierOptionValue(item)" :label="carrierOptionLabel(item)" :value="route.carrierType === '承运商' ? carrierOptionValue(item) : item.carrierName" /></el-select></el-form-item></el-col>
|
||||||
<el-col :span="6"><el-form-item label="司机" :required="route.carrierType !== '承运商'"><el-autocomplete :ref="element => setDriverInput(route.segmentNo, element)" v-model="route.driverName" :debounce="300" :fetch-suggestions="fetchDriverSuggestions" clearable placeholder="请输入司机" :loading="driverLoading" @select="item => handleDriverSuggestionSelect(route, item)" /></el-form-item></el-col>
|
<el-col :span="6"><el-form-item label="司机" :required="route.carrierType !== '承运商'"><el-autocomplete :ref="element => setDriverInput(route.segmentNo, element)" v-model="route.driverName" :debounce="300" :fetch-suggestions="fetchDriverSuggestions" clearable placeholder="请输入司机" :loading="driverLoading" @select="item => handleDriverSuggestionSelect(route, item)" /></el-form-item></el-col>
|
||||||
<el-col :span="6"><el-form-item :label="route.carrierType === '承运商' ? '手机号' : '司机手机号'" :required="route.carrierType !== '承运商'"><el-input v-model="route.driverPhone" placeholder="请输入" /></el-form-item></el-col>
|
<el-col :span="6"><el-form-item :label="route.carrierType === '承运商' ? '手机号' : '司机手机号'" :required="route.carrierType !== '承运商'"><el-input v-model="route.driverPhone" placeholder="请输入" /></el-form-item></el-col>
|
||||||
<el-col :span="6"><el-form-item label="车牌号" required><el-input v-model="route.vehicleNo" placeholder="请输入" /></el-form-item></el-col>
|
<el-col :span="6"><el-form-item label="车牌号" required><el-input v-model="route.vehicleNo" placeholder="请输入" /></el-form-item></el-col>
|
||||||
<el-col v-if="route.carrierType !== '承运商'" :span="6"><el-form-item label="挂车车牌号" required><el-input v-model="route.trailerVehicleNo" placeholder="请输入" /></el-form-item></el-col>
|
<el-col v-if="route.carrierType !== '承运商'" :span="6"><el-form-item label="挂车车牌号"><el-input v-model="route.trailerVehicleNo" placeholder="请输入" /></el-form-item></el-col>
|
||||||
<el-col v-if="route.carrierType !== '承运商'" :span="6"><el-form-item label="押运人" required><el-input v-model="route.escortName" placeholder="请输入" /></el-form-item></el-col>
|
<el-col v-if="route.carrierType !== '承运商'" :span="6"><el-form-item label="押运人"><el-autocomplete v-model="route.escortName" :debounce="300" :fetch-suggestions="fetchEscortSuggestions" clearable placeholder="请输入" :loading="escortLoading" @select="item => handleEscortSuggestionSelect(route, item)" /></el-form-item></el-col>
|
||||||
<el-col v-if="route.carrierType !== '承运商'" :span="6"><el-form-item label="押运人手机号" required><el-input v-model="route.escortPhone" placeholder="请输入" /></el-form-item></el-col>
|
<el-col v-if="route.carrierType !== '承运商'" :span="6"><el-form-item label="押运人手机号"><el-input v-model="route.escortPhone" placeholder="请输入" /></el-form-item></el-col>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<el-col v-if="route.carrierType === '承运商'" :span="6"><el-form-item label="承运商" required><el-select v-model="route.carrierContractId" filterable clearable placeholder="请选择" :loading="carrierLoading" @change="value => handleCarrierContractChange(route, value)"><el-option v-for="item in carrierOptions" :key="item.contractId" :label="carrierOptionLabel(item)" :value="item.contractId" /></el-select></el-form-item></el-col>
|
<el-col :span="6"><el-form-item label="承运商" :required="route.carrierType === '承运商'"><el-select :model-value="route.carrierType === '承运商' ? route.carrierContractId : route.carrierName" filterable clearable placeholder="请选择" :loading="carrierLoading" @change="value => handleCarrierContractChange(route, value)"><el-option v-for="item in carrierOptions" :key="carrierOptionValue(item)" :label="carrierOptionLabel(item)" :value="route.carrierType === '承运商' ? carrierOptionValue(item) : item.carrierName" /></el-select></el-form-item></el-col>
|
||||||
<el-col :span="6"><el-form-item label="船/航/班列号" required><el-input v-model="route.vehicleNo" placeholder="请输入" /></el-form-item></el-col>
|
<el-col :span="6"><el-form-item label="船/航/班列号" required><el-input v-model="route.vehicleNo" placeholder="请输入" /></el-form-item></el-col>
|
||||||
<el-col :span="6"><el-form-item label="船长"><el-input v-model="route.captainName" placeholder="请输入" /></el-form-item></el-col>
|
<el-col :span="6"><el-form-item label="船长"><el-input v-model="route.captainName" placeholder="请输入" /></el-form-item></el-col>
|
||||||
<el-col :span="6"><el-form-item label="联系电话" required><el-input v-model="route.driverPhone" placeholder="请输入" /></el-form-item></el-col>
|
<el-col :span="6"><el-form-item label="联系电话" required><el-input v-model="route.driverPhone" placeholder="请输入" /></el-form-item></el-col>
|
||||||
@@ -208,7 +207,7 @@ export default {
|
|||||||
props: { id: [String, Number] },
|
props: { id: [String, Number] },
|
||||||
emits: ['back'],
|
emits: ['back'],
|
||||||
data() {
|
data() {
|
||||||
return { loading: false, submitting: false, master: null, routes: [], pending: [], pendingExpanded: false, editingId: null, driverInputs: {}, carrierOptions: [], driverOptions: [], carrierLoading: false, driverLoading: false, cargoTypeOptions: [], cargoTypeCascaderProps: { label: 'cargoName', value: 'id', children: 'children', emitPath: true }, quantityUnitOptions: ['吨', '千克', '立方米', '件', '车', '箱', '托盘'] };
|
return { loading: false, submitting: false, master: null, routes: [], pending: [], pendingExpanded: false, editingId: null, driverInputs: {}, carrierOptions: [], driverOptions: [], carrierLoading: false, driverLoading: false, escortLoading: false, cargoTypeOptions: [], cargoTypeCascaderProps: { label: 'cargoName', value: 'id', children: 'children', emitPath: true }, quantityUnitOptions: ['吨', '千克', '立方米', '件', '车', '箱', '托盘'] };
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
totalQuantity() { return (this.master?.goods || []).reduce((sum, item) => sum + Number(item.quantity || 0), 0); },
|
totalQuantity() { return (this.master?.goods || []).reduce((sum, item) => sum + Number(item.quantity || 0), 0); },
|
||||||
@@ -231,6 +230,7 @@ export default {
|
|||||||
},
|
},
|
||||||
async mounted() {
|
async mounted() {
|
||||||
await Promise.all([this.load(), this.loadCarrierOptions(), this.loadDriverOptions()]);
|
await Promise.all([this.load(), this.loadCarrierOptions(), this.loadDriverOptions()]);
|
||||||
|
this.applySelfOperatedCarrierDefaults();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async load() {
|
async load() {
|
||||||
@@ -238,10 +238,36 @@ export default {
|
|||||||
try {
|
try {
|
||||||
const res = await api.getDetail(this.id);
|
const res = await api.getDetail(this.id);
|
||||||
this.master = res.data?.data || res.data || res;
|
this.master = res.data?.data || res.data || res;
|
||||||
|
await this.loadContractCurrency();
|
||||||
this.cargoTypeOptions = this.buildMasterCargoTypeOptions(this.master.goods || []);
|
this.cargoTypeOptions = this.buildMasterCargoTypeOptions(this.master.goods || []);
|
||||||
this.routes = this.dispatchRouteNodes().map((node, index) => this.createRoute(node, index));
|
this.routes = this.dispatchRouteNodes().map((node, index) => this.createRoute(node, index));
|
||||||
} finally { this.loading = false; }
|
} finally { this.loading = false; }
|
||||||
},
|
},
|
||||||
|
normalizeCurrencyValue(value) {
|
||||||
|
const raw = typeof value === 'object'
|
||||||
|
? value.dictKey || value.value || value.code || value.dictValue || ''
|
||||||
|
: value;
|
||||||
|
const normalized = String(raw || 'RMB').trim().toUpperCase();
|
||||||
|
return normalized.includes(' - ') ? normalized.split(' - ')[0].trim() : normalized;
|
||||||
|
},
|
||||||
|
async loadContractCurrency() {
|
||||||
|
const directCurrency = this.master?.settlementCurrency || this.master?.settlementCurrencyCode || this.master?.currency;
|
||||||
|
if (!this.master?.projectId || !this.master?.contractId) {
|
||||||
|
this.master.settlementCurrency = this.normalizeCurrencyValue(directCurrency || 'RMB');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const response = await api.getProjectContracts(this.master.projectId);
|
||||||
|
const contract = unwrapRecords(response).find(item => String(item.id) === String(this.master.contractId));
|
||||||
|
this.master.customerContractPartyB = contract?.partyB || this.master.customerContractPartyB || '';
|
||||||
|
this.master.settlementCurrency = this.normalizeCurrencyValue(
|
||||||
|
directCurrency || contract?.settlementCurrency || contract?.settlementCurrencyCode || contract?.currency || 'RMB'
|
||||||
|
);
|
||||||
|
} catch {
|
||||||
|
this.master.customerContractPartyB = '';
|
||||||
|
this.master.settlementCurrency = 'RMB';
|
||||||
|
}
|
||||||
|
},
|
||||||
dispatchRouteNodes() {
|
dispatchRouteNodes() {
|
||||||
const routes = Array.isArray(this.master?.routes) ? this.master.routes : [];
|
const routes = Array.isArray(this.master?.routes) ? this.master.routes : [];
|
||||||
if (routes.length) return routes;
|
if (routes.length) return routes;
|
||||||
@@ -261,9 +287,9 @@ export default {
|
|||||||
...node,
|
...node,
|
||||||
selected: false,
|
selected: false,
|
||||||
documentType: '运单',
|
documentType: '运单',
|
||||||
carrierType: '承运商',
|
carrierType: node.carrierType || this.master?.carrierType || '承运商',
|
||||||
carrierContractId: '',
|
carrierContractId: '',
|
||||||
currency: 'CNY',
|
currency: this.normalizeCurrencyValue(this.master?.settlementCurrency || 'RMB'),
|
||||||
otherFeeTotal: '',
|
otherFeeTotal: '',
|
||||||
freightItems: [],
|
freightItems: [],
|
||||||
departureName: previous.departureName || '', departureAddress: previous.departureAddress || '', departureContact: previous.departureContact || '', departurePhone: previous.departurePhone || '',
|
departureName: previous.departureName || '', departureAddress: previous.departureAddress || '', departureContact: previous.departureContact || '', departurePhone: previous.departurePhone || '',
|
||||||
@@ -343,7 +369,7 @@ export default {
|
|||||||
},
|
},
|
||||||
buildFreightJson(route) {
|
buildFreightJson(route) {
|
||||||
return JSON.stringify({
|
return JSON.stringify({
|
||||||
currency: route.currency || 'CNY',
|
currency: route.currency || 'RMB',
|
||||||
totalFreightAmount: this.freightTotal(route),
|
totalFreightAmount: this.freightTotal(route),
|
||||||
otherFreightAmount: route.otherFeeTotal || '',
|
otherFreightAmount: route.otherFeeTotal || '',
|
||||||
freightItems: (route.freightItems || []).map(item => ({
|
freightItems: (route.freightItems || []).map(item => ({
|
||||||
@@ -352,7 +378,7 @@ export default {
|
|||||||
})),
|
})),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
currencyLabel(value) { return ({ CNY: '人民币', USD: '美元', EUR: '欧元' })[value] || value || '人民币'; },
|
currencyLabel(value) { return ({ CNY: '人民币', RMB: '人民币', USD: '美元', EUR: '欧元' })[value] || value || '人民币'; },
|
||||||
quantityNumber(value) { return Number(value || 0); },
|
quantityNumber(value) { return Number(value || 0); },
|
||||||
goodsKey(goods = {}, includeUnit = true) {
|
goodsKey(goods = {}, includeUnit = true) {
|
||||||
return [
|
return [
|
||||||
@@ -533,16 +559,23 @@ export default {
|
|||||||
}
|
}
|
||||||
if (value !== '承运商') {
|
if (value !== '承运商') {
|
||||||
route.carrierContractId = '';
|
route.carrierContractId = '';
|
||||||
route.carrierName = '';
|
if (value === '网货平台') route.carrierName = '';
|
||||||
|
if (value === '自运') this.applySelfOperatedCarrierDefaults(route);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleCarrierContractChange(route, contractId) {
|
handleCarrierContractChange(route, contractId) {
|
||||||
const contract = this.carrierOptions.find(
|
const contract = this.carrierOptions.find(
|
||||||
item => String(item.contractId) === String(contractId)
|
item =>
|
||||||
|
[item.contractId, item.carrierName, item.id].some(
|
||||||
|
value => String(value || '') === String(contractId || '')
|
||||||
|
)
|
||||||
);
|
);
|
||||||
route.carrierContractId = contract?.contractId || '';
|
route.carrierContractId = route.carrierType === '承运商' ? contract?.contractId || '' : '';
|
||||||
route.carrierName = contract?.carrierName || '';
|
route.carrierName = contract?.carrierName || '';
|
||||||
},
|
},
|
||||||
|
carrierOptionValue(item = {}) {
|
||||||
|
return item.contractId || item.id || item.value || item.carrierName || '';
|
||||||
|
},
|
||||||
carrierOptionLabel(item) {
|
carrierOptionLabel(item) {
|
||||||
const duplicateCount = this.carrierOptions.filter(option => option.carrierName === item.carrierName).length;
|
const duplicateCount = this.carrierOptions.filter(option => option.carrierName === item.carrierName).length;
|
||||||
return duplicateCount > 1
|
return duplicateCount > 1
|
||||||
@@ -568,10 +601,35 @@ export default {
|
|||||||
this.carrierLoading = false;
|
this.carrierLoading = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
applySelfOperatedCarrierDefaults(targetRoute) {
|
||||||
|
const routes = targetRoute ? [targetRoute] : this.routes;
|
||||||
|
if (!this.carrierOptions.length) {
|
||||||
|
const carrierName = String(this.master?.customerContractPartyB || '').trim();
|
||||||
|
if (carrierName) {
|
||||||
|
this.carrierOptions = [{
|
||||||
|
id: `customer-contract-${carrierName}`,
|
||||||
|
contractId: `customer-contract-${carrierName}`,
|
||||||
|
carrierName,
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
routes.forEach(route => {
|
||||||
|
if (route.carrierType !== '自运') return;
|
||||||
|
if (this.carrierOptions.length) {
|
||||||
|
const current = this.carrierOptions.find(
|
||||||
|
item => String(item.carrierName || '') === String(route.carrierName || '')
|
||||||
|
);
|
||||||
|
route.carrierName = current?.carrierName || this.carrierOptions[0].carrierName || '';
|
||||||
|
}
|
||||||
|
route.carrierContractId = '';
|
||||||
|
});
|
||||||
|
},
|
||||||
async loadDriverOptions(keyword = '') {
|
async loadDriverOptions(keyword = '') {
|
||||||
this.driverLoading = true;
|
this.driverLoading = true;
|
||||||
try {
|
try {
|
||||||
this.driverOptions = unwrapRecords(await getDriverList(1, 20, { driverName: keyword }));
|
this.driverOptions = unwrapRecords(
|
||||||
|
await getDriverList(1, 20, { driverName: keyword, posts: '司机' })
|
||||||
|
);
|
||||||
} finally {
|
} finally {
|
||||||
this.driverLoading = false;
|
this.driverLoading = false;
|
||||||
}
|
}
|
||||||
@@ -595,6 +653,28 @@ export default {
|
|||||||
const drivingVehicle = String(item.drivingVehicle || '').trim();
|
const drivingVehicle = String(item.drivingVehicle || '').trim();
|
||||||
if (drivingVehicle) route.vehicleNo = drivingVehicle;
|
if (drivingVehicle) route.vehicleNo = drivingVehicle;
|
||||||
},
|
},
|
||||||
|
fetchEscortSuggestions(queryString, callback) {
|
||||||
|
const keyword = String(queryString || '').trim();
|
||||||
|
this.escortLoading = true;
|
||||||
|
getDriverList(1, 20, { ...(keyword ? { driverName: keyword } : {}), posts: '押运员' })
|
||||||
|
.then(res => {
|
||||||
|
callback(
|
||||||
|
unwrapRecords(res).map(item => ({
|
||||||
|
...item,
|
||||||
|
value: this.driverOptionLabel(item),
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.catch(() => callback([]))
|
||||||
|
.finally(() => {
|
||||||
|
this.escortLoading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleEscortSuggestionSelect(route, item = {}) {
|
||||||
|
route.escortName = this.driverOptionLabel(item);
|
||||||
|
const phone = item.mobile || item.driverPhone || item.phone || '';
|
||||||
|
if (phone) route.escortPhone = phone;
|
||||||
|
},
|
||||||
setDriverInput(segmentNo, element) {
|
setDriverInput(segmentNo, element) {
|
||||||
if (element) this.driverInputs[segmentNo] = element;
|
if (element) this.driverInputs[segmentNo] = element;
|
||||||
else delete this.driverInputs[segmentNo];
|
else delete this.driverInputs[segmentNo];
|
||||||
@@ -622,7 +702,7 @@ export default {
|
|||||||
if (route.documentType === '运单') {
|
if (route.documentType === '运单') {
|
||||||
if (this.isRoad(route)) {
|
if (this.isRoad(route)) {
|
||||||
if (route.carrierType === '承运商' && (!route.carrierContractId || !route.carrierName || !route.vehicleNo)) return this.$message.warning('请选择承运商并填写车牌号');
|
if (route.carrierType === '承运商' && (!route.carrierContractId || !route.carrierName || !route.vehicleNo)) return this.$message.warning('请选择承运商并填写车牌号');
|
||||||
if (route.carrierType !== '承运商' && (!route.driverName || !route.driverPhone || !route.vehicleNo || !route.trailerVehicleNo || !route.escortName || !route.escortPhone)) return this.$message.warning('请补全自运或网货平台的车辆与人员信息');
|
if (route.carrierType !== '承运商' && (!route.driverName || !route.driverPhone || !route.vehicleNo)) return this.$message.warning('请补全自运或网货平台的车辆与人员信息');
|
||||||
} else if (!route.vehicleNo || !route.driverPhone || (route.carrierType === '承运商' && (!route.carrierContractId || !route.carrierName))) {
|
} else if (!route.vehicleNo || !route.driverPhone || (route.carrierType === '承运商' && (!route.carrierContractId || !route.carrierName))) {
|
||||||
return this.$message.warning('请补全非公路运输的承运信息');
|
return this.$message.warning('请补全非公路运输的承运信息');
|
||||||
}
|
}
|
||||||
@@ -632,7 +712,7 @@ export default {
|
|||||||
id: `${route.segmentNo}-${item.cargoName}-${Date.now()}-${Math.random()}`,
|
id: `${route.segmentNo}-${item.cargoName}-${Date.now()}-${Math.random()}`,
|
||||||
batchNo,
|
batchNo,
|
||||||
segmentNo: route.segmentNo, relationNo: route.segmentNo, documentType: route.documentType, transportType: route.transportType, carrierType: route.carrierType,
|
segmentNo: route.segmentNo, relationNo: route.segmentNo, documentType: route.documentType, transportType: route.transportType, carrierType: route.carrierType,
|
||||||
carrierContractId: route.carrierContractId, carrierName: route.carrierName, driverName: route.driverName, driverPhone: route.driverPhone, vehicleNo: route.vehicleNo, captainName: route.captainName, cabinNo: route.cabinNo, containerNo: route.containerNo, trailerVehicleNo: route.trailerVehicleNo, escortName: route.escortName, escortPhone: route.escortPhone, mileage: this.normalizeMileage(route.mileage), unitPrice: this.freightItemsForGoods(route, item).unitPrice || '', priceUnit: this.freightItemsForGoods(route, item).priceUnit || '', currency: route.currency || 'CNY', freightAmount: this.freightAmount(this.freightItemsForGoods(route, item)), freightTotal: this.freightTotal(route), otherFeeTotal: route.otherFeeTotal || '', freightJson: this.buildFreightJson(route), remark: route.remark,
|
carrierContractId: route.carrierContractId, carrierName: route.carrierName, driverName: route.driverName, driverPhone: route.driverPhone, vehicleNo: route.vehicleNo, captainName: route.captainName, cabinNo: route.cabinNo, containerNo: route.containerNo, trailerVehicleNo: route.trailerVehicleNo, escortName: route.escortName, escortPhone: route.escortPhone, mileage: this.normalizeMileage(route.mileage), unitPrice: this.freightItemsForGoods(route, item).unitPrice || '', priceUnit: this.freightItemsForGoods(route, item).priceUnit || '', currency: route.currency || 'RMB', freightAmount: this.freightAmount(this.freightItemsForGoods(route, item)), freightTotal: this.freightTotal(route), otherFeeTotal: route.otherFeeTotal || '', freightJson: this.buildFreightJson(route), remark: route.remark,
|
||||||
departureName: route.departureName, departureAddress: route.departureAddress, departureContact: route.departureContact, departurePhone: route.departurePhone,
|
departureName: route.departureName, departureAddress: route.departureAddress, departureContact: route.departureContact, departurePhone: route.departurePhone,
|
||||||
arrivalName: route.arrivalName, arrivalAddress: route.arrivalAddress, arrivalContact: route.arrivalContact, arrivalPhone: route.arrivalPhone,
|
arrivalName: route.arrivalName, arrivalAddress: route.arrivalAddress, arrivalContact: route.arrivalContact, arrivalPhone: route.arrivalPhone,
|
||||||
estimatedStartTime: route.estimatedStartTime, estimatedEndTime: route.estimatedEndTime,
|
estimatedStartTime: route.estimatedStartTime, estimatedEndTime: route.estimatedEndTime,
|
||||||
@@ -661,6 +741,9 @@ export default {
|
|||||||
}
|
}
|
||||||
if (goods) goods.dispatchQuantity = item.quantity;
|
if (goods) goods.dispatchQuantity = item.quantity;
|
||||||
Object.assign(route, item);
|
Object.assign(route, item);
|
||||||
|
route.currency = this.normalizeCurrencyValue(
|
||||||
|
this.master?.settlementCurrency || route.currency || 'RMB'
|
||||||
|
);
|
||||||
this.syncFreightItems(route);
|
this.syncFreightItems(route);
|
||||||
const freightItem = this.freightItemsForGoods(route, goods);
|
const freightItem = this.freightItemsForGoods(route, goods);
|
||||||
if (freightItem) { freightItem.unitPrice = item.unitPrice || ''; freightItem.priceUnit = item.priceUnit || freightItem.priceUnit; }
|
if (freightItem) { freightItem.unitPrice = item.unitPrice || ''; freightItem.priceUnit = item.priceUnit || freightItem.priceUnit; }
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -24,7 +24,7 @@
|
|||||||
<el-form-item label="结算方式"><el-input v-model="form.settlementMode" /></el-form-item>
|
<el-form-item label="结算方式"><el-input v-model="form.settlementMode" /></el-form-item>
|
||||||
<el-form-item label="是否需要加盖法人章"><el-select v-model="form.legalSealFlag"><el-option label="是" :value="1" /><el-option label="否" :value="0" /></el-select></el-form-item>
|
<el-form-item label="是否需要加盖法人章"><el-select v-model="form.legalSealFlag"><el-option label="是" :value="1" /><el-option label="否" :value="0" /></el-select></el-form-item>
|
||||||
<el-form-item label="一式(份)"><el-input v-model="form.copyCount" inputmode="numeric" maxlength="9" placeholder="请输入" @input="value => positiveIntegerInput('copyCount', value)" /></el-form-item>
|
<el-form-item label="一式(份)"><el-input v-model="form.copyCount" inputmode="numeric" maxlength="9" placeholder="请输入" @input="value => positiveIntegerInput('copyCount', value)" /></el-form-item>
|
||||||
<el-form-item label="回款账期(天)"><el-input v-model="form.paymentDays" inputmode="numeric" maxlength="9" placeholder="请输入" @input="value => positiveIntegerInput('paymentDays', value)" /></el-form-item>
|
<el-form-item label="回款账期"><el-input v-model="form.paymentDays" inputmode="numeric" maxlength="9" placeholder="请输入" @input="value => positiveIntegerInput('paymentDays', value)" /></el-form-item>
|
||||||
</div>
|
</div>
|
||||||
<el-form-item label="备注" class="contract-basic-section__remark"><el-input v-model="form.remark" type="textarea" :rows="2" maxlength="2000" show-word-limit placeholder="请输入备注" /></el-form-item>
|
<el-form-item label="备注" class="contract-basic-section__remark"><el-input v-model="form.remark" type="textarea" :rows="2" maxlength="2000" show-word-limit placeholder="请输入备注" /></el-form-item>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@@ -239,16 +239,6 @@
|
|||||||
placeholder="请选择签订日期"
|
placeholder="请选择签订日期"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="结算类型" prop="settlementMode">
|
|
||||||
<el-select v-model="form.settlementMode" placeholder="请选择结算类型">
|
|
||||||
<el-option
|
|
||||||
v-for="item in settlementModeOptions"
|
|
||||||
:key="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
:value="item.value"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="合同格式" prop="contractFormat">
|
<el-form-item label="合同格式" prop="contractFormat">
|
||||||
<el-select v-model="form.contractFormat" placeholder="请选择合同格式">
|
<el-select v-model="form.contractFormat" placeholder="请选择合同格式">
|
||||||
<el-option
|
<el-option
|
||||||
@@ -273,12 +263,39 @@
|
|||||||
><template #suffix>份</template></el-input
|
><template #suffix>份</template></el-input
|
||||||
>
|
>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="回款账期(天)">
|
<el-form-item label="结算币种" prop="settlementCurrency">
|
||||||
|
<el-select v-model="form.settlementCurrency" placeholder="请选择结算币种" clearable>
|
||||||
|
<el-option
|
||||||
|
v-for="item in settlementCurrencyOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="结算方式" prop="settlementMode">
|
||||||
|
<el-select v-model="form.settlementMode" placeholder="请选择结算方式" clearable>
|
||||||
|
<el-option
|
||||||
|
v-for="item in settlementModeOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="开票周期">
|
||||||
|
<el-input
|
||||||
|
v-model="form.invoiceCycle"
|
||||||
|
placeholder="请输入"
|
||||||
|
@input="value => positiveIntegerInput('invoiceCycle', value)"
|
||||||
|
><template #suffix>天</template></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="回款账期">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="form.paymentDays"
|
v-model="form.paymentDays"
|
||||||
placeholder="请输入"
|
placeholder="请输入"
|
||||||
@input="value => integerInput('paymentDays', value)"
|
@input="value => integerInput('paymentDays', value)"
|
||||||
/>
|
><template #suffix>天</template></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
<el-form-item label="备注" prop="remark" class="contract-manage-form__remark">
|
<el-form-item label="备注" prop="remark" class="contract-manage-form__remark">
|
||||||
@@ -605,9 +622,6 @@
|
|||||||
<el-descriptions-item label="签订日期">{{
|
<el-descriptions-item label="签订日期">{{
|
||||||
detailValue('signDate')
|
detailValue('signDate')
|
||||||
}}</el-descriptions-item>
|
}}</el-descriptions-item>
|
||||||
<el-descriptions-item label="结算类型">{{
|
|
||||||
detailValue('settlementMode')
|
|
||||||
}}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="合同格式">{{
|
<el-descriptions-item label="合同格式">{{
|
||||||
detailValue('contractFormat')
|
detailValue('contractFormat')
|
||||||
}}</el-descriptions-item>
|
}}</el-descriptions-item>
|
||||||
@@ -617,6 +631,15 @@
|
|||||||
<el-descriptions-item label="一式">{{
|
<el-descriptions-item label="一式">{{
|
||||||
detailUnitValue('copyCount', '份')
|
detailUnitValue('copyCount', '份')
|
||||||
}}</el-descriptions-item>
|
}}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="结算币种">{{
|
||||||
|
detailDictionaryValue('settlementCurrency', settlementCurrencyOptions)
|
||||||
|
}}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="结算方式">{{
|
||||||
|
detailDictionaryValue('settlementMode', settlementModeOptions)
|
||||||
|
}}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="开票周期">{{
|
||||||
|
detailUnitValue('invoiceCycle', '天')
|
||||||
|
}}</el-descriptions-item>
|
||||||
<el-descriptions-item label="回款账期">{{
|
<el-descriptions-item label="回款账期">{{
|
||||||
detailUnitValue('paymentDays', '天')
|
detailUnitValue('paymentDays', '天')
|
||||||
}}</el-descriptions-item>
|
}}</el-descriptions-item>
|
||||||
@@ -787,6 +810,8 @@ import * as api from '@/api/business/contract-manage';
|
|||||||
import { getList as getProjectList } from '@/api/business/project-apply';
|
import { getList as getProjectList } from '@/api/business/project-apply';
|
||||||
import { getList as getCustomerArchiveList } from '@/api/vehicle/customer-archive';
|
import { getList as getCustomerArchiveList } from '@/api/vehicle/customer-archive';
|
||||||
import { getDeptTree } from '@/api/system/dept';
|
import { getDeptTree } from '@/api/system/dept';
|
||||||
|
import { getDictionary as getSystemDictionary } from '@/api/system/dict';
|
||||||
|
import { getDictionary as getBizDictionary } from '@/api/system/dictbiz';
|
||||||
import { config, option } from '@/option/business/contract-manage';
|
import { config, option } from '@/option/business/contract-manage';
|
||||||
import { getToken } from '@/utils/auth';
|
import { getToken } from '@/utils/auth';
|
||||||
import { downloadFileByUrl, downloadXls } from '@/utils/util';
|
import { downloadFileByUrl, downloadXls } from '@/utils/util';
|
||||||
@@ -831,6 +856,8 @@ const defaultForm = () => ({
|
|||||||
contractFormat: '',
|
contractFormat: '',
|
||||||
legalSealFlag: 0,
|
legalSealFlag: 0,
|
||||||
copyCount: '',
|
copyCount: '',
|
||||||
|
settlementCurrency: '',
|
||||||
|
invoiceCycle: '',
|
||||||
paymentDays: '',
|
paymentDays: '',
|
||||||
startDate: '',
|
startDate: '',
|
||||||
endDate: '',
|
endDate: '',
|
||||||
@@ -1114,14 +1141,27 @@ export default {
|
|||||||
contractName: [{ required: true, message: '请输入合同名称', trigger: 'blur' }],
|
contractName: [{ required: true, message: '请输入合同名称', trigger: 'blur' }],
|
||||||
contractCategory: [{ required: true, message: '请选择合同类别', trigger: 'change' }],
|
contractCategory: [{ required: true, message: '请选择合同类别', trigger: 'change' }],
|
||||||
signType: [{ required: true, message: '请选择签约类型', trigger: 'change' }],
|
signType: [{ required: true, message: '请选择签约类型', trigger: 'change' }],
|
||||||
|
settlementCurrency: [{ required: true, message: '请选择结算币种', trigger: 'change' }],
|
||||||
projectName: [{ required: true, message: '请选择所属项目', trigger: 'change' }],
|
projectName: [{ required: true, message: '请选择所属项目', trigger: 'change' }],
|
||||||
organizationName: [{ required: true, message: '请选择所属组织', trigger: 'change' }],
|
organizationName: [{ required: true, message: '请选择所属组织', trigger: 'change' }],
|
||||||
partyA: [{ required: true, message: '请选择甲方', trigger: 'change' }],
|
partyA: [{ required: true, message: '请选择甲方', trigger: 'change' }],
|
||||||
partyB: [{ required: true, message: '请选择乙方', trigger: 'change' }],
|
partyB: [{ required: true, message: '请选择乙方', trigger: 'change' }],
|
||||||
signDate: [{ required: true, message: '请选择签订日期', trigger: 'change' }],
|
signDate: [{ required: true, message: '请选择签订日期', trigger: 'change' }],
|
||||||
settlementMode: [{ required: true, message: '请选择结算类型', trigger: 'change' }],
|
settlementMode: [{ required: true, message: '请选择结算方式', trigger: 'change' }],
|
||||||
contractFormat: [{ required: true, message: '请选择合同格式', trigger: 'change' }],
|
contractFormat: [{ required: true, message: '请选择合同格式', trigger: 'change' }],
|
||||||
legalSealFlag: [{ required: true, message: '请选择是否需要加盖法人章', trigger: 'change' }],
|
legalSealFlag: [{ required: true, message: '请选择是否需要加盖法人章', trigger: 'change' }],
|
||||||
|
invoiceCycle: [
|
||||||
|
{
|
||||||
|
validator: (rule, value, callback) => {
|
||||||
|
if (value === '' || value === undefined || value === null) return callback();
|
||||||
|
if (!/^\d+$/.test(String(value)) || Number(value) < 1) {
|
||||||
|
return callback(new Error('开票周期只能输入正整数'));
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
},
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
|
],
|
||||||
startDate: [{ required: true, message: '请选择开始日期', trigger: 'change' }],
|
startDate: [{ required: true, message: '请选择开始日期', trigger: 'change' }],
|
||||||
endDate: [{ required: true, message: '请选择结束日期', trigger: 'change' }],
|
endDate: [{ required: true, message: '请选择结束日期', trigger: 'change' }],
|
||||||
},
|
},
|
||||||
@@ -1129,6 +1169,8 @@ export default {
|
|||||||
projectOptions: [],
|
projectOptions: [],
|
||||||
projectLoading: false,
|
projectLoading: false,
|
||||||
selectedProjectId: '',
|
selectedProjectId: '',
|
||||||
|
settlementCurrencyOptions: [],
|
||||||
|
settlementModeDictOptions: [],
|
||||||
contractPartyAOptions: [],
|
contractPartyAOptions: [],
|
||||||
contractPartyBOptions: [],
|
contractPartyBOptions: [],
|
||||||
contractPartyLoading: false,
|
contractPartyLoading: false,
|
||||||
@@ -1223,7 +1265,9 @@ export default {
|
|||||||
return this.columnOptions('effectiveType');
|
return this.columnOptions('effectiveType');
|
||||||
},
|
},
|
||||||
settlementModeOptions() {
|
settlementModeOptions() {
|
||||||
return this.columnOptions('settlementMode');
|
return this.settlementModeDictOptions.length
|
||||||
|
? this.settlementModeDictOptions
|
||||||
|
: this.columnOptions('settlementMode');
|
||||||
},
|
},
|
||||||
contractFormatOptions() {
|
contractFormatOptions() {
|
||||||
return this.columnOptions('contractFormat');
|
return this.columnOptions('contractFormat');
|
||||||
@@ -1315,6 +1359,7 @@ export default {
|
|||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.loadProjectOptions();
|
this.loadProjectOptions();
|
||||||
|
this.loadSettlementDictionaries();
|
||||||
this.loadOrganizationOptions();
|
this.loadOrganizationOptions();
|
||||||
if (this.isFormPage) this.initFormPage();
|
if (this.isFormPage) this.initFormPage();
|
||||||
},
|
},
|
||||||
@@ -1504,6 +1549,7 @@ export default {
|
|||||||
...defaultForm(),
|
...defaultForm(),
|
||||||
...detail,
|
...detail,
|
||||||
copyCount: normalizeOptionalInteger(detail.copyCount, ''),
|
copyCount: normalizeOptionalInteger(detail.copyCount, ''),
|
||||||
|
invoiceCycle: normalizeOptionalInteger(detail.invoiceCycle, ''),
|
||||||
paymentDays: normalizeOptionalInteger(detail.paymentDays, ''),
|
paymentDays: normalizeOptionalInteger(detail.paymentDays, ''),
|
||||||
feeGenerationMode:
|
feeGenerationMode:
|
||||||
detail.feeGenerationMode || (Number(detail.billingEnabled) === 0 ? 'manual' : 'system'),
|
detail.feeGenerationMode || (Number(detail.billingEnabled) === 0 ? 'manual' : 'system'),
|
||||||
@@ -1548,6 +1594,10 @@ export default {
|
|||||||
this.$message.warning('请选择合同类别');
|
this.$message.warning('请选择合同类别');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (!this.form.settlementCurrency) {
|
||||||
|
this.$message.warning('请选择结算币种');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (['temporary', 'formal', 'edit'].includes(action) && !this.form.signType) {
|
if (['temporary', 'formal', 'edit'].includes(action) && !this.form.signType) {
|
||||||
this.$message.warning('请选择签约类型');
|
this.$message.warning('请选择签约类型');
|
||||||
return false;
|
return false;
|
||||||
@@ -1561,7 +1611,7 @@ export default {
|
|||||||
['startDate', '合同开始日期'],
|
['startDate', '合同开始日期'],
|
||||||
['endDate', '合同结束日期'],
|
['endDate', '合同结束日期'],
|
||||||
['signDate', '签订日期'],
|
['signDate', '签订日期'],
|
||||||
['settlementMode', '结算类型'],
|
['settlementMode', '结算方式'],
|
||||||
['contractFormat', '合同格式'],
|
['contractFormat', '合同格式'],
|
||||||
];
|
];
|
||||||
const empty = required.find(([prop]) => !this.form[prop]);
|
const empty = required.find(([prop]) => !this.form[prop]);
|
||||||
@@ -1580,6 +1630,7 @@ export default {
|
|||||||
return {
|
return {
|
||||||
...this.form,
|
...this.form,
|
||||||
copyCount: normalizeOptionalInteger(this.form.copyCount),
|
copyCount: normalizeOptionalInteger(this.form.copyCount),
|
||||||
|
invoiceCycle: normalizeOptionalInteger(this.form.invoiceCycle),
|
||||||
paymentDays: normalizeOptionalInteger(this.form.paymentDays),
|
paymentDays: normalizeOptionalInteger(this.form.paymentDays),
|
||||||
billingEnabled: this.form.feeGenerationMode === 'manual' ? 0 : 1,
|
billingEnabled: this.form.feeGenerationMode === 'manual' ? 0 : 1,
|
||||||
contractFileJson: JSON.stringify(this.contractFileRows),
|
contractFileJson: JSON.stringify(this.contractFileRows),
|
||||||
@@ -1656,6 +1707,29 @@ export default {
|
|||||||
this.projectLoading = false;
|
this.projectLoading = false;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
loadSettlementDictionaries() {
|
||||||
|
Promise.all([
|
||||||
|
getSystemDictionary({ code: 'currency_type' }),
|
||||||
|
getBizDictionary({ code: 'settle_method' }),
|
||||||
|
]).then(([currencyRes, methodRes]) => {
|
||||||
|
const records = response => {
|
||||||
|
const data = response?.data?.data || response?.data || [];
|
||||||
|
return Array.isArray(data) ? data : data.records || [];
|
||||||
|
};
|
||||||
|
this.settlementCurrencyOptions = records(currencyRes).map(item => ({
|
||||||
|
label: `${item.dictKey} - ${item.dictValue}`,
|
||||||
|
value: item.dictKey,
|
||||||
|
}));
|
||||||
|
this.settlementModeDictOptions = records(methodRes).map(item => ({
|
||||||
|
label: item.dictValue,
|
||||||
|
value: item.dictKey,
|
||||||
|
}));
|
||||||
|
['settlementMode'].forEach(prop => {
|
||||||
|
const column = this.findColumn(this.tableOption.column, prop);
|
||||||
|
if (column) column.dicData = this.settlementModeDictOptions;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
syncCurrentProjectOption() {
|
syncCurrentProjectOption() {
|
||||||
if (!this.form.projectId || !this.form.projectName) return;
|
if (!this.form.projectId || !this.form.projectName) return;
|
||||||
if (this.projectOptions.some(item => String(item.id) === String(this.form.projectId))) return;
|
if (this.projectOptions.some(item => String(item.id) === String(this.form.projectId))) return;
|
||||||
@@ -1664,12 +1738,13 @@ export default {
|
|||||||
handleProjectChange(projectId) {
|
handleProjectChange(projectId) {
|
||||||
const project = this.projectOptions.find(item => String(item.id) === String(projectId));
|
const project = this.projectOptions.find(item => String(item.id) === String(projectId));
|
||||||
if (!project) {
|
if (!project) {
|
||||||
Object.assign(this.form, { projectId: '', projectName: '' });
|
Object.assign(this.form, { projectId: '', projectName: '', settlementMode: '' });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Object.assign(this.form, {
|
Object.assign(this.form, {
|
||||||
projectId: project.id,
|
projectId: project.id,
|
||||||
projectName: project.projectName || '',
|
projectName: project.projectName || '',
|
||||||
|
settlementMode: project.settlementMode || this.form.settlementMode || '',
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
loadContractPartyOptions() {
|
loadContractPartyOptions() {
|
||||||
@@ -1806,6 +1881,10 @@ export default {
|
|||||||
integerInput(prop, value) {
|
integerInput(prop, value) {
|
||||||
this.form[prop] = String(value || '').replace(/\D/g, '');
|
this.form[prop] = String(value || '').replace(/\D/g, '');
|
||||||
},
|
},
|
||||||
|
positiveIntegerInput(prop, value) {
|
||||||
|
const normalized = String(value || '').replace(/\D/g, '').replace(/^0+/, '');
|
||||||
|
this.form[prop] = normalized;
|
||||||
|
},
|
||||||
previewAttachment(row, rows = []) {
|
previewAttachment(row, rows = []) {
|
||||||
const url = attachmentUrl(row);
|
const url = attachmentUrl(row);
|
||||||
if (!url) {
|
if (!url) {
|
||||||
@@ -1996,6 +2075,7 @@ export default {
|
|||||||
this.detailRow = {
|
this.detailRow = {
|
||||||
...detail,
|
...detail,
|
||||||
copyCount: normalizeOptionalInteger(detail.copyCount),
|
copyCount: normalizeOptionalInteger(detail.copyCount),
|
||||||
|
invoiceCycle: normalizeOptionalInteger(detail.invoiceCycle),
|
||||||
paymentDays: normalizeOptionalInteger(detail.paymentDays),
|
paymentDays: normalizeOptionalInteger(detail.paymentDays),
|
||||||
};
|
};
|
||||||
this.detailContractFileRows = parseArray(detail.contractFileJson);
|
this.detailContractFileRows = parseArray(detail.contractFileJson);
|
||||||
@@ -2054,6 +2134,11 @@ export default {
|
|||||||
if (prop === 'feeGenerationMode') return value === 'manual' ? '手动生成' : '系统生成';
|
if (prop === 'feeGenerationMode') return value === 'manual' ? '手动生成' : '系统生成';
|
||||||
return this.displayValue(value);
|
return this.displayValue(value);
|
||||||
},
|
},
|
||||||
|
detailDictionaryValue(prop, options = []) {
|
||||||
|
const value = this.detailRow[prop];
|
||||||
|
if (value === undefined || value === null || value === '') return '-';
|
||||||
|
return options.find(item => String(item.value) === String(value))?.label || value;
|
||||||
|
},
|
||||||
handleOperation(operation, row) {
|
handleOperation(operation, row) {
|
||||||
if (operation.action === 'startChange') {
|
if (operation.action === 'startChange') {
|
||||||
this.$router.push({ path: '/business/contract-manage/change', query: { id: row.id } });
|
this.$router.push({ path: '/business/contract-manage/change', query: { id: row.id } });
|
||||||
|
|||||||
@@ -823,12 +823,15 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="loading-manage-dialog__grid loading-manage-dialog__task-grid">
|
<div class="loading-manage-dialog__grid loading-manage-dialog__task-grid">
|
||||||
<el-form-item
|
<el-form-item
|
||||||
v-if="dialogForm.carrierType === '承运商'"
|
:required="dialogForm.carrierType === '承运商'"
|
||||||
label="承运商"
|
label="承运商"
|
||||||
required
|
|
||||||
>
|
>
|
||||||
<el-select
|
<el-select
|
||||||
v-model="dialogForm.carrierContractId"
|
:model-value="
|
||||||
|
dialogForm.carrierType === '承运商'
|
||||||
|
? dialogForm.carrierContractId
|
||||||
|
: dialogForm.carrierName
|
||||||
|
"
|
||||||
clearable
|
clearable
|
||||||
filterable
|
filterable
|
||||||
:disabled="dialogReadonly || !selectedWaybillRows.length"
|
:disabled="dialogReadonly || !selectedWaybillRows.length"
|
||||||
@@ -839,9 +842,13 @@
|
|||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in taskCarrierOptions"
|
v-for="item in taskCarrierOptions"
|
||||||
:key="item.id"
|
:key="item.id || item.carrierName"
|
||||||
:label="item.carrierName"
|
:label="item.carrierName || item.partyB"
|
||||||
:value="item.id"
|
:value="
|
||||||
|
dialogForm.carrierType === '承运商'
|
||||||
|
? item.id
|
||||||
|
: item.carrierName || item.partyB
|
||||||
|
"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -866,7 +873,15 @@
|
|||||||
<el-input v-model="dialogForm.trailerVehicleNo" clearable placeholder="请输入" />
|
<el-input v-model="dialogForm.trailerVehicleNo" clearable placeholder="请输入" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item v-if="dialogForm.carrierType !== '承运商'" label="押运人">
|
<el-form-item v-if="dialogForm.carrierType !== '承运商'" label="押运人">
|
||||||
<el-input v-model="dialogForm.escortName" clearable placeholder="请输入" />
|
<el-autocomplete
|
||||||
|
v-model="dialogForm.escortName"
|
||||||
|
clearable
|
||||||
|
:debounce="300"
|
||||||
|
:fetch-suggestions="fetchEscortSuggestions"
|
||||||
|
:loading="escortLoading"
|
||||||
|
placeholder="请输入"
|
||||||
|
@select="item => handleEscortSuggestionSelect('dialog', item)"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item v-if="dialogForm.carrierType !== '承运商'" label="押运人手机号">
|
<el-form-item v-if="dialogForm.carrierType !== '承运商'" label="押运人手机号">
|
||||||
<el-input v-model="dialogForm.escortPhone" clearable placeholder="请输入" />
|
<el-input v-model="dialogForm.escortPhone" clearable placeholder="请输入" />
|
||||||
@@ -982,6 +997,7 @@ import {
|
|||||||
getList as getWaybillList,
|
getList as getWaybillList,
|
||||||
getDetail as getWaybillDetail,
|
getDetail as getWaybillDetail,
|
||||||
} from '@/api/business/waybill-manage';
|
} from '@/api/business/waybill-manage';
|
||||||
|
import { getList as getContractList } from '@/api/business/contract-manage';
|
||||||
import { getParentOptions as getCargoTypeOptions } from '@/api/base/cargo-type';
|
import { getParentOptions as getCargoTypeOptions } from '@/api/base/cargo-type';
|
||||||
import { getList as getCustomerList } from '@/api/vehicle/customer-archive';
|
import { getList as getCustomerList } from '@/api/vehicle/customer-archive';
|
||||||
import { getList as getDriverList } from '@/api/transportCapacity/driver';
|
import { getList as getDriverList } from '@/api/transportCapacity/driver';
|
||||||
@@ -1188,6 +1204,7 @@ export default {
|
|||||||
customerLoading: false,
|
customerLoading: false,
|
||||||
cargoTypeLoading: false,
|
cargoTypeLoading: false,
|
||||||
driverLoading: false,
|
driverLoading: false,
|
||||||
|
escortLoading: false,
|
||||||
carrierLoading: false,
|
carrierLoading: false,
|
||||||
taskCarrierLoading: false,
|
taskCarrierLoading: false,
|
||||||
planLoading: false,
|
planLoading: false,
|
||||||
@@ -1606,10 +1623,6 @@ export default {
|
|||||||
this.dialogForm.waybillIdsJson,
|
this.dialogForm.waybillIdsJson,
|
||||||
this.dialogForm.loadingSubNos
|
this.dialogForm.loadingSubNos
|
||||||
);
|
);
|
||||||
if (this.dialogForm.carrierType !== '承运商') {
|
|
||||||
this.dialogForm.carrierContractId = '';
|
|
||||||
this.dialogForm.carrierName = '';
|
|
||||||
}
|
|
||||||
this.syncProcessProjectOptions();
|
this.syncProcessProjectOptions();
|
||||||
this.restoreRouteAndCargo();
|
this.restoreRouteAndCargo();
|
||||||
this.restoreRouteChangeRecords();
|
this.restoreRouteChangeRecords();
|
||||||
@@ -2131,7 +2144,7 @@ export default {
|
|||||||
normalizePayload() {
|
normalizePayload() {
|
||||||
this.syncRouteAddressFields();
|
this.syncRouteAddressFields();
|
||||||
this.rebuildSummaryFromWaybills(false);
|
this.rebuildSummaryFromWaybills(false);
|
||||||
if (this.dialogForm.carrierType !== '承运商') {
|
if (this.dialogForm.carrierType === '网货平台') {
|
||||||
this.dialogForm.carrierContractId = '';
|
this.dialogForm.carrierContractId = '';
|
||||||
this.dialogForm.carrierName = '';
|
this.dialogForm.carrierName = '';
|
||||||
}
|
}
|
||||||
@@ -2317,17 +2330,20 @@ export default {
|
|||||||
this.dialogForm.escortName = '';
|
this.dialogForm.escortName = '';
|
||||||
this.dialogForm.escortPhone = '';
|
this.dialogForm.escortPhone = '';
|
||||||
}
|
}
|
||||||
if (this.dialogForm.carrierType !== '承运商') {
|
if (this.dialogForm.carrierType === '网货平台') {
|
||||||
this.dialogForm.carrierContractId = '';
|
this.dialogForm.carrierContractId = '';
|
||||||
this.dialogForm.carrierName = '';
|
this.dialogForm.carrierName = '';
|
||||||
this.taskCarrierOptions = [];
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
this.loadTaskCarrierOptions();
|
this.loadTaskCarrierOptions();
|
||||||
},
|
},
|
||||||
handleTaskCarrierChange(contractId) {
|
handleTaskCarrierChange(contractId) {
|
||||||
const contract = this.taskCarrierOptions.find(item => String(item.id) === String(contractId));
|
const contract = this.taskCarrierOptions.find(item =>
|
||||||
this.dialogForm.carrierContractId = contract?.id || '';
|
[item.id, item.carrierName, item.partyB].some(
|
||||||
|
value => String(value || '') === String(contractId || '')
|
||||||
|
)
|
||||||
|
);
|
||||||
|
this.dialogForm.carrierContractId =
|
||||||
|
this.dialogForm.carrierType === '承运商' && contract?.id ? contract.id : '';
|
||||||
this.dialogForm.carrierName = contract?.carrierName || '';
|
this.dialogForm.carrierName = contract?.carrierName || '';
|
||||||
},
|
},
|
||||||
handleDriverChange(value) {
|
handleDriverChange(value) {
|
||||||
@@ -2361,6 +2377,29 @@ export default {
|
|||||||
if (drivingVehicle) this.dialogForm.vehicleNo = drivingVehicle;
|
if (drivingVehicle) this.dialogForm.vehicleNo = drivingVehicle;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
fetchEscortSuggestions(queryString, callback) {
|
||||||
|
const keyword = String(queryString || '').trim();
|
||||||
|
this.escortLoading = true;
|
||||||
|
getDriverList(1, 20, { ...(keyword ? { driverName: keyword } : {}), posts: '押运员' })
|
||||||
|
.then(res => {
|
||||||
|
callback(
|
||||||
|
unwrapRecords(res).map(item => ({
|
||||||
|
...item,
|
||||||
|
value: item.driverName || item.name || '',
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.catch(() => callback([]))
|
||||||
|
.finally(() => {
|
||||||
|
this.escortLoading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleEscortSuggestionSelect(target, item = {}) {
|
||||||
|
if (target !== 'dialog') return;
|
||||||
|
this.dialogForm.escortName = item.driverName || item.name || '';
|
||||||
|
const phone = item.mobile || item.driverPhone || item.phone || '';
|
||||||
|
if (phone) this.dialogForm.escortPhone = phone;
|
||||||
|
},
|
||||||
handleMileageInput(value) {
|
handleMileageInput(value) {
|
||||||
this.dialogForm.mileage = String(value || '').replace(/[^\d.]/g, '');
|
this.dialogForm.mileage = String(value || '').replace(/[^\d.]/g, '');
|
||||||
},
|
},
|
||||||
@@ -2410,7 +2449,9 @@ export default {
|
|||||||
async loadDriverOptions(keyword = '') {
|
async loadDriverOptions(keyword = '') {
|
||||||
this.driverLoading = true;
|
this.driverLoading = true;
|
||||||
try {
|
try {
|
||||||
this.driverOptions = unwrapRecords(await getDriverList(1, 20, { driverName: keyword }));
|
this.driverOptions = unwrapRecords(
|
||||||
|
await getDriverList(1, 20, { driverName: keyword, posts: '司机' })
|
||||||
|
);
|
||||||
} finally {
|
} finally {
|
||||||
this.driverLoading = false;
|
this.driverLoading = false;
|
||||||
}
|
}
|
||||||
@@ -2431,7 +2472,7 @@ export default {
|
|||||||
},
|
},
|
||||||
async loadTaskCarrierOptions() {
|
async loadTaskCarrierOptions() {
|
||||||
const requestId = ++this.taskCarrierRequestId;
|
const requestId = ++this.taskCarrierRequestId;
|
||||||
if (this.dialogForm.carrierType !== '承运商' || !this.selectedWaybillRows.length) {
|
if (!this.selectedWaybillRows.length) {
|
||||||
this.taskCarrierOptions = [];
|
this.taskCarrierOptions = [];
|
||||||
this.taskCarrierLoading = false;
|
this.taskCarrierLoading = false;
|
||||||
this.dialogForm.carrierContractId = '';
|
this.dialogForm.carrierContractId = '';
|
||||||
@@ -2446,14 +2487,11 @@ export default {
|
|||||||
const response = await loadingApi.getCarrierContracts(projectIds);
|
const response = await loadingApi.getCarrierContracts(projectIds);
|
||||||
if (requestId !== this.taskCarrierRequestId) return [];
|
if (requestId !== this.taskCarrierRequestId) return [];
|
||||||
const contracts = response.data?.data || response.data || [];
|
const contracts = response.data?.data || response.data || [];
|
||||||
|
if (this.dialogForm.carrierType === '承运商') {
|
||||||
this.taskCarrierOptions = contracts;
|
this.taskCarrierOptions = contracts;
|
||||||
const current =
|
const current =
|
||||||
contracts.find(
|
contracts.find(item => String(item.id) === String(this.dialogForm.carrierContractId)) ||
|
||||||
item => String(item.id) === String(this.dialogForm.carrierContractId)
|
contracts.find(item => item.carrierName === this.dialogForm.carrierName);
|
||||||
) ||
|
|
||||||
contracts.find(
|
|
||||||
item => item.carrierName === this.dialogForm.carrierName
|
|
||||||
);
|
|
||||||
if (current) {
|
if (current) {
|
||||||
this.dialogForm.carrierContractId = current.id;
|
this.dialogForm.carrierContractId = current.id;
|
||||||
this.dialogForm.carrierName = current.carrierName;
|
this.dialogForm.carrierName = current.carrierName;
|
||||||
@@ -2462,11 +2500,52 @@ export default {
|
|||||||
this.dialogForm.carrierName = '';
|
this.dialogForm.carrierName = '';
|
||||||
}
|
}
|
||||||
return contracts;
|
return contracts;
|
||||||
|
}
|
||||||
|
if (this.dialogForm.carrierType === '自运' && contracts.length) {
|
||||||
|
this.taskCarrierOptions = contracts;
|
||||||
|
const current = contracts.find(item => item.carrierName === this.dialogForm.carrierName);
|
||||||
|
this.dialogForm.carrierContractId = '';
|
||||||
|
this.dialogForm.carrierName = current?.carrierName || contracts[0].carrierName || '';
|
||||||
|
return contracts;
|
||||||
|
}
|
||||||
|
if (this.dialogForm.carrierType !== '自运') {
|
||||||
|
this.taskCarrierOptions = [];
|
||||||
|
this.dialogForm.carrierContractId = '';
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
const customerContracts = await Promise.all(
|
||||||
|
projectIds.map(projectId =>
|
||||||
|
getContractList(1, 9999, { projectId, contractCategory: '客户合同' })
|
||||||
|
.then(res => extractRecords(res))
|
||||||
|
.catch(() => [])
|
||||||
|
)
|
||||||
|
);
|
||||||
|
const partyBNames = [];
|
||||||
|
const customerContractMap = new Map(
|
||||||
|
projectIds.map((projectId, index) => [String(projectId), customerContracts[index] || []])
|
||||||
|
);
|
||||||
|
this.selectedWaybillRows.forEach(row => {
|
||||||
|
const direct = row.partyB || row.contractPartyB || row.customerContractPartyB;
|
||||||
|
const contractsForProject = customerContractMap.get(String(row.projectId)) || [];
|
||||||
|
const matched = contractsForProject.find(
|
||||||
|
item => String(item.id) === String(row.contractId)
|
||||||
|
);
|
||||||
|
const name = String(direct || matched?.partyB || '').trim();
|
||||||
|
if (name && !partyBNames.includes(name)) partyBNames.push(name);
|
||||||
|
});
|
||||||
|
this.taskCarrierOptions = partyBNames.map(name => ({
|
||||||
|
id: `customer-contract-${name}`,
|
||||||
|
carrierName: name,
|
||||||
|
partyB: name,
|
||||||
|
}));
|
||||||
|
this.dialogForm.carrierContractId = '';
|
||||||
|
this.dialogForm.carrierName = partyBNames[0] || '';
|
||||||
|
return this.taskCarrierOptions;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (requestId !== this.taskCarrierRequestId) return [];
|
if (requestId !== this.taskCarrierRequestId) return [];
|
||||||
this.taskCarrierOptions = [];
|
this.taskCarrierOptions = [];
|
||||||
this.dialogForm.carrierContractId = '';
|
this.dialogForm.carrierContractId = '';
|
||||||
this.dialogForm.carrierName = '';
|
if (this.dialogForm.carrierType !== '自运') this.dialogForm.carrierName = '';
|
||||||
return [];
|
return [];
|
||||||
} finally {
|
} finally {
|
||||||
if (requestId === this.taskCarrierRequestId) this.taskCarrierLoading = false;
|
if (requestId === this.taskCarrierRequestId) this.taskCarrierLoading = false;
|
||||||
|
|||||||
@@ -813,7 +813,6 @@ import {
|
|||||||
businessTypeOptions,
|
businessTypeOptions,
|
||||||
projectSourceOptions,
|
projectSourceOptions,
|
||||||
projectTypeOptions,
|
projectTypeOptions,
|
||||||
settlementModeOptions,
|
|
||||||
} from '@/option/business/common';
|
} from '@/option/business/common';
|
||||||
import { config, option } from '@/option/business/project-apply';
|
import { config, option } from '@/option/business/project-apply';
|
||||||
|
|
||||||
@@ -960,7 +959,7 @@ export default {
|
|||||||
projectSourceOptions,
|
projectSourceOptions,
|
||||||
transportTypeOptions: [],
|
transportTypeOptions: [],
|
||||||
businessTypeOptions,
|
businessTypeOptions,
|
||||||
settlementModeOptions,
|
settlementModeOptions: [],
|
||||||
changeTypeOptions,
|
changeTypeOptions,
|
||||||
tableForm: {},
|
tableForm: {},
|
||||||
tableOption: this.buildTableOption(),
|
tableOption: this.buildTableOption(),
|
||||||
@@ -1225,6 +1224,7 @@ export default {
|
|||||||
this.loadDeptOptions();
|
this.loadDeptOptions();
|
||||||
this.loadCargoTypeOptions();
|
this.loadCargoTypeOptions();
|
||||||
this.loadTransportTypeOptions();
|
this.loadTransportTypeOptions();
|
||||||
|
this.loadSettlementModeOptions();
|
||||||
if (this.isProjectFormPage) {
|
if (this.isProjectFormPage) {
|
||||||
this.openProjectFormPage();
|
this.openProjectFormPage();
|
||||||
}
|
}
|
||||||
@@ -1970,6 +1970,17 @@ export default {
|
|||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
loadSettlementModeOptions() {
|
||||||
|
getBizDictionary({ code: 'settle_method' }).then(res => {
|
||||||
|
const data = res.data?.data || [];
|
||||||
|
this.settlementModeOptions = data.map(item => ({
|
||||||
|
label: item.dictValue,
|
||||||
|
value: item.dictKey,
|
||||||
|
}));
|
||||||
|
const column = this.findColumn(this.tableOption.column, 'settlementMode');
|
||||||
|
if (column) column.dicData = this.settlementModeOptions;
|
||||||
|
});
|
||||||
|
},
|
||||||
loadCustomerOptions(type) {
|
loadCustomerOptions(type) {
|
||||||
const loadingKey = type === '客户' ? 'customerLoading' : 'carrierLoading';
|
const loadingKey = type === '客户' ? 'customerLoading' : 'carrierLoading';
|
||||||
const optionsKey = type === '客户' ? 'customerOptions' : 'carrierOptions';
|
const optionsKey = type === '客户' ? 'customerOptions' : 'carrierOptions';
|
||||||
|
|||||||
@@ -1,14 +1,20 @@
|
|||||||
<template>
|
<template>
|
||||||
<business-crud-page :api="api" :config="config" :crud-option="option" :menu-width="270" standalone-form-page />
|
<shipping-template-page
|
||||||
|
:api="api"
|
||||||
|
:config="config"
|
||||||
|
:crud-option="option"
|
||||||
|
:menu-width="270"
|
||||||
|
standalone-form-page
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import BusinessCrudPage from './components/business-crud-page.vue';
|
import ShippingTemplatePage from './components/shipping-template-page.vue';
|
||||||
import * as api from '@/api/business/shipping-template';
|
import * as api from '@/api/business/shipping-template';
|
||||||
import { config, option } from '@/option/business/shipping-template';
|
import { config, option } from '@/option/business/shipping-template';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { BusinessCrudPage },
|
components: { ShippingTemplatePage },
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
api,
|
api,
|
||||||
|
|||||||
@@ -1,14 +1,21 @@
|
|||||||
<template>
|
<template>
|
||||||
<business-crud-page :api="api" :config="config" :crud-option="option" :detail-id="$route.query.detailId" :menu-width="220" standalone-form-page />
|
<transport-plan-page
|
||||||
|
:api="api"
|
||||||
|
:config="config"
|
||||||
|
:crud-option="option"
|
||||||
|
:detail-id="$route.query.detailId"
|
||||||
|
:menu-width="220"
|
||||||
|
standalone-form-page
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import BusinessCrudPage from './components/business-crud-page.vue';
|
import TransportPlanPage from './components/transport-plan-page.vue';
|
||||||
import * as api from '@/api/business/transport-plan';
|
import * as api from '@/api/business/transport-plan';
|
||||||
import { config, option } from '@/option/business/transport-plan';
|
import { config, option } from '@/option/business/transport-plan';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { BusinessCrudPage },
|
components: { TransportPlanPage },
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
api,
|
api,
|
||||||
|
|||||||
@@ -1,14 +1,21 @@
|
|||||||
<template>
|
<template>
|
||||||
<business-crud-page :api="api" :config="config" :crud-option="option" :detail-id="$route.query.detailId" :menu-width="250" standalone-form-page />
|
<waybill-manage-page
|
||||||
|
:api="api"
|
||||||
|
:config="config"
|
||||||
|
:crud-option="option"
|
||||||
|
:detail-id="$route.query.detailId"
|
||||||
|
:menu-width="250"
|
||||||
|
standalone-form-page
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import BusinessCrudPage from './components/business-crud-page.vue';
|
import WaybillManagePage from './components/waybill-manage-page.vue';
|
||||||
import * as api from '@/api/business/waybill-manage';
|
import * as api from '@/api/business/waybill-manage';
|
||||||
import { config, option } from '@/option/business/waybill-manage';
|
import { config, option } from '@/option/business/waybill-manage';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { BusinessCrudPage },
|
components: { WaybillManagePage },
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
api,
|
api,
|
||||||
|
|||||||
@@ -1853,13 +1853,15 @@ export default {
|
|||||||
return typeText && normalizedName.includes(typeText);
|
return typeText && normalizedName.includes(typeText);
|
||||||
});
|
});
|
||||||
if (matchedType?.value) return matchedType.value;
|
if (matchedType?.value) return matchedType.value;
|
||||||
const otherType = this.attachmentTypeOptions.find(item =>
|
const otherType = this.attachmentTypeOptions.find(item => this.isOtherAttachmentType(item));
|
||||||
String(item.label || item.value || '').includes('其他')
|
|
||||||
);
|
|
||||||
if (otherType?.value) return otherType.value;
|
if (otherType?.value) return otherType.value;
|
||||||
this.attachmentTypeOptions.push({ label: '其他附件', value: '其他附件' });
|
this.attachmentTypeOptions.push({ label: '其他附件', value: '其他附件' });
|
||||||
return '其他附件';
|
return '其他附件';
|
||||||
},
|
},
|
||||||
|
isOtherAttachmentType(item) {
|
||||||
|
const typeText = String(item?.label || item?.value || '').trim();
|
||||||
|
return typeText === '其他' || typeText === '其他附件';
|
||||||
|
},
|
||||||
getAttachmentTypeOrder(type) {
|
getAttachmentTypeOrder(type) {
|
||||||
const normalizedType = String(type || '').trim();
|
const normalizedType = String(type || '').trim();
|
||||||
const index = this.attachmentTypeOptions.findIndex(
|
const index = this.attachmentTypeOptions.findIndex(
|
||||||
@@ -1887,7 +1889,7 @@ export default {
|
|||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
);
|
);
|
||||||
return this.attachmentTypeOptions
|
return this.attachmentTypeOptions
|
||||||
.filter(item => String(item.label || item.value || '').trim() !== '其他附件')
|
.filter(item => !this.isOtherAttachmentType(item))
|
||||||
.filter(item => !uploadedTypes.has(String(item.value || item.label || '').trim()))
|
.filter(item => !uploadedTypes.has(String(item.value || item.label || '').trim()))
|
||||||
.map(item => item.label || item.value);
|
.map(item => item.label || item.value);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1150,7 +1150,7 @@ export default {
|
|||||||
this.resetEditor();
|
this.resetEditor();
|
||||||
await this.loadFeeOptions();
|
await this.loadFeeOptions();
|
||||||
await this.loadFeeCategoryOptions();
|
await this.loadFeeCategoryOptions();
|
||||||
if (this.pageMode) await this.loadTransportTypeOptions();
|
await this.loadTransportTypeOptions();
|
||||||
if (this.recordId) await this.loadDetail();
|
if (this.recordId) await this.loadDetail();
|
||||||
else if (this.initialData) this.applyInitialData();
|
else if (this.initialData) this.applyInitialData();
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user