1、完善项目

2、完善合同
3、完善费用项
4、司机管理对接OCR
5、完善运输计划
6、完善临时额度
This commit is contained in:
2026-08-04 12:17:49 +08:00
parent 81c98f6ad8
commit f9f8221870
34 changed files with 7887 additions and 983 deletions

View File

@@ -4,16 +4,108 @@ import {
dataSourceOptions,
selectRule,
textRule,
transportTypeOptions,
waybillStatusOptions,
} from './common';
const transportTypeDict = {
dicUrl: '/blade-system/dict-biz/dictionary?code=transport_type',
props: {
label: 'dictValue',
value: 'dictKey',
},
};
const isEmpty = value => value === undefined || value === null || value === '';
const parseJsonArray = value => {
if (Array.isArray(value)) return value;
if (typeof value !== 'string' || !value.trim()) return [];
try {
const result = JSON.parse(value);
if (Array.isArray(result)) return result;
if (Array.isArray(result.records)) return result.records;
if (Array.isArray(result.rows)) return result.rows;
return [];
} catch (error) {
return [];
}
};
const getFirstValue = (row, props) => {
const prop = props.find(item => !isEmpty(row[item]));
return prop ? row[prop] : '';
};
const getGoodsRows = row => parseJsonArray(row.goodsList || row.goodsRows || row.goodsJson);
const getBillingRows = row => {
const freightRows = parseJsonArray(row.freightList || row.freightRows || row.freightJson);
if (freightRows.length) return freightRows;
return parseJsonArray(row.billingPlanJson).flatMap(item =>
Array.isArray(item.rules) ? item.rules : []
);
};
const joinText = list => list.filter(item => !isEmpty(item)).join('/');
const formatGoodsInfo = row => {
const text = getFirstValue(row, ['goodsInfo', 'cargoInfo']);
if (text) return text;
return getGoodsRows(row)
.map(item => {
const name = getFirstValue(item, ['cargoName', 'goodsName', 'name']);
const type = getFirstValue(item, ['cargoType', 'goodsType', 'typeName']);
const quantity = joinText([
getFirstValue(item, ['quantity', 'cargoQuantity', 'goodsQuantity']),
getFirstValue(item, ['quantityUnit', 'cargoUnit', 'unit']),
]);
return joinText([name, type, quantity]);
})
.filter(Boolean)
.join('; ');
};
const formatGoodsField = (row, props) => {
const value = getFirstValue(row, props);
if (value) return value;
const goods = getGoodsRows(row).find(item => getFirstValue(item, props));
return goods ? getFirstValue(goods, props) : '';
};
const formatTransportMode = row =>
getFirstValue(row, ['transportModeName', 'transportMode', 'transportWayName', 'transportWay']);
const formatUnitPrice = row => {
const value = getFirstValue(row, ['unitPrice', 'price']);
const unit = getFirstValue(row, ['priceUnit', 'billingUnit', 'unit']);
if (!isEmpty(value)) return unit ? `${value}(${unit})` : value;
const billing = getBillingRows(row).find(item => !isEmpty(item.unitPrice));
if (!billing) return '';
const billingUnit = getFirstValue(billing, ['priceUnit', 'billingUnit', 'unit']);
return billingUnit ? `${billing.unitPrice}(${billingUnit})` : billing.unitPrice;
};
const formatAmount = (row, props) => getFirstValue(row, props);
const auditColumn = prop => ({ ...auditColumns.find(item => item.prop === prop) });
export const config = {
title: '运单管理',
permission: 'waybill_manage',
exportUrl: '/blade-transport/waybill-manage/export-waybill-manage',
exportName: '运单管理',
enableAllDept: true,
importUrl: '/blade-transport/waybill-manage/import-waybill-manage',
enableAllDept: false,
batchDelete: false,
createText: '新建运单',
importText: '导入运单',
roadLoading: true,
roadLoadingText: '公路配载',
searchRangeMap: {
startDateRange: ['startDateStart', 'startDateEnd'],
endDateRange: ['endDateStart', 'endDateEnd'],
createTimeRange: ['createTimeStart', 'createTimeEnd'],
},
actions: ['copy', 'cancel', 'reassign', 'complete', 'batchComplete'],
statusProp: 'businessStatus',
statusTextProp: 'businessStatusName',
@@ -21,234 +113,437 @@ export const config = {
editStatus: ['draft', 'pending'],
};
export const option = createCrudOption([
{
label: '运单号',
prop: 'waybillNo',
search: true,
minWidth: 150,
addDisplay: false,
editDisabled: true,
},
{
label: '项目',
prop: 'projectName',
search: true,
minWidth: 150,
rules: textRule('项目', 100, true),
},
{
label: '项目ID',
prop: 'projectId',
hide: true,
},
{
label: '客户合同',
prop: 'contractName',
minWidth: 160,
rules: textRule('客户合同', 100, true),
},
{
label: '客户合同ID',
prop: 'contractId',
hide: true,
},
{
label: '客户名称',
prop: 'customerName',
search: true,
minWidth: 150,
},
{
label: '运输类型',
prop: 'transportType',
type: 'select',
search: true,
dicData: transportTypeOptions,
minWidth: 130,
rules: selectRule('运输类型'),
},
{
label: '货物名称',
prop: 'cargoName',
search: true,
minWidth: 150,
rules: textRule('货物名称', 100, true),
},
{
label: '货物类型',
prop: 'cargoType',
search: true,
minWidth: 130,
rules: textRule('货物类型', 100, true),
},
{
label: '发货地址',
prop: 'departureAddress',
search: true,
minWidth: 220,
rules: textRule('发货地址', 255, true),
},
{
label: '收货地址',
prop: 'arrivalAddress',
search: true,
minWidth: 220,
rules: textRule('收货地址', 255, true),
},
{
label: '承运商名称',
prop: 'carrierName',
search: true,
minWidth: 150,
},
{
label: '司机姓名',
prop: 'driverName',
search: true,
minWidth: 120,
},
{
label: '车/船/航班/班列号',
prop: 'vehicleNo',
search: true,
minWidth: 170,
},
{
label: '原始单号',
prop: 'originalNo',
search: true,
minWidth: 140,
},
{
label: '业务状态',
prop: 'businessStatus',
type: 'select',
slot: true,
search: true,
dicData: waybillStatusOptions,
minWidth: 120,
addDisplay: false,
editDisplay: false,
},
{
label: '数据来源',
prop: 'dataSource',
type: 'select',
search: true,
dicData: dataSourceOptions,
minWidth: 120,
},
{
label: '开始日期',
prop: 'startDate',
type: 'date',
format: 'YYYY-MM-DD',
valueFormat: 'YYYY-MM-DD',
search: true,
minWidth: 130,
},
{
label: '结束日期',
prop: 'endDate',
type: 'date',
format: 'YYYY-MM-DD',
valueFormat: 'YYYY-MM-DD',
search: true,
minWidth: 130,
},
{
label: '计划名称',
prop: 'planName',
search: true,
minWidth: 150,
},
{
label: '多联总单',
prop: 'masterNo',
search: true,
minWidth: 140,
},
{
label: '配载单号',
prop: 'loadingNo',
search: true,
minWidth: 140,
},
{
label: '运单批次号',
prop: 'batchNo',
search: true,
minWidth: 140,
},
{
label: '关联单号',
prop: 'relationNo',
search: true,
minWidth: 140,
},
{
label: '当前过程节点',
prop: 'currentProcessNode',
minWidth: 140,
},
{
label: '货物信息JSON',
prop: 'goodsJson',
type: 'textarea',
minRows: 5,
span: 24,
hide: true,
},
{
label: '承运信息JSON',
prop: 'carrierJson',
type: 'textarea',
minRows: 4,
span: 24,
hide: true,
},
{
label: '过程配置JSON',
prop: 'processJson',
type: 'textarea',
minRows: 4,
span: 24,
hide: true,
},
{
label: '运费信息JSON',
prop: 'freightJson',
type: 'textarea',
minRows: 4,
span: 24,
hide: true,
},
{
label: '附件JSON',
prop: 'attachmentsJson',
type: 'textarea',
minRows: 3,
span: 24,
hide: true,
},
{
label: '所属组织',
prop: 'deptName',
minWidth: 150,
addDisplay: false,
editDisplay: false,
},
{
label: '备注',
prop: 'remark',
type: 'textarea',
minRows: 4,
span: 24,
hide: true,
maxlength: 500,
showWordLimit: true,
rules: textRule('备注', 500),
},
...auditColumns,
]);
export const option = {
...createCrudOption([
{
label: '运单号',
prop: 'waybillNo',
search: true,
searchOrder: 23,
minWidth: 150,
addDisplay: false,
editDisabled: true,
},
{
label: '配载单号',
prop: 'loadingNo',
search: true,
searchOrder: 5,
minWidth: 140,
},
{
label: '总单号',
prop: 'masterNo',
search: true,
searchLabel: '多联总单',
searchOrder: 6,
minWidth: 140,
},
{
label: '项目名称',
prop: 'projectName',
search: true,
searchOrder: 22,
minWidth: 150,
rules: textRule('项目', 100, true),
},
{
label: '客户',
prop: 'customerName',
search: true,
searchLabel: '客户名称',
searchOrder: 21,
minWidth: 150,
},
{
label: '车牌号/航班号/船号/班列号',
prop: 'vehicleNo',
search: true,
searchLabel: '车/船/航班/班列',
searchOrder: 13,
minWidth: 210,
},
{
label: '司机',
prop: 'driverName',
search: true,
searchLabel: '司机名称',
searchOrder: 14,
minWidth: 120,
},
{
label: '联系方式',
prop: 'driverPhone',
formatter: row => getFirstValue(row, ['driverPhone', 'driverMobile', 'driverTel']),
minWidth: 140,
addDisplay: false,
editDisplay: false,
viewDisplay: false,
},
{
label: '运输方式',
prop: 'transportMode',
type: 'select',
search: true,
searchOrder: 1,
formatter: row => formatTransportMode(row),
...transportTypeDict,
minWidth: 130,
addDisplay: false,
editDisplay: false,
viewDisplay: false,
},
{
label: '运输类型',
prop: 'transportType',
type: 'select',
search: true,
searchOrder: 20,
...transportTypeDict,
minWidth: 130,
rules: selectRule('运输类型'),
},
{
label: '过程节点',
prop: 'currentProcessNode',
minWidth: 140,
},
{
label: '承运类型',
prop: 'carrierType',
formatter: row => getFirstValue(row, ['carrierTypeName', 'carrierType']),
minWidth: 120,
addDisplay: false,
editDisplay: false,
viewDisplay: false,
},
{
label: '承运商',
prop: 'carrierName',
search: true,
searchLabel: '承运商名称',
searchOrder: 15,
minWidth: 150,
},
{
label: '货物信息',
prop: 'goodsInfo',
formatter: row => formatGoodsInfo(row),
minWidth: 260,
overHidden: true,
addDisplay: false,
editDisplay: false,
viewDisplay: false,
},
{
label: '发货地址',
prop: 'departureAddress',
search: true,
searchOrder: 17,
minWidth: 220,
rules: textRule('发货地址', 255, true),
},
{
label: '到货地址',
prop: 'arrivalAddress',
search: true,
searchLabel: '收货地址',
searchOrder: 16,
minWidth: 220,
rules: textRule('收货地址', 255, true),
},
{
label: '发货联系人',
prop: 'departureContact',
minWidth: 120,
addDisplay: false,
editDisplay: false,
viewDisplay: false,
},
{
label: '收货联系人',
prop: 'arrivalContact',
minWidth: 120,
addDisplay: false,
editDisplay: false,
viewDisplay: false,
},
{
label: '单价(计价单位)',
prop: 'unitPrice',
formatter: row => formatUnitPrice(row),
minWidth: 140,
addDisplay: false,
editDisplay: false,
viewDisplay: false,
},
{
label: '运费',
prop: 'freight',
formatter: row => formatAmount(row, ['freight', 'freightAmount', 'transportFee']),
minWidth: 120,
addDisplay: false,
editDisplay: false,
viewDisplay: false,
},
{
label: '其他费用合计',
prop: 'otherFeeTotal',
formatter: row => formatAmount(row, ['otherFeeTotal', 'otherAmount', 'otherFeeAmount']),
minWidth: 140,
addDisplay: false,
editDisplay: false,
viewDisplay: false,
},
{
label: '运费合计',
prop: 'freightTotal',
formatter: row => formatAmount(row, ['freightTotal', 'totalFreight', 'totalAmount']),
minWidth: 120,
addDisplay: false,
editDisplay: false,
viewDisplay: false,
},
{
label: '客户合同',
prop: 'contractName',
minWidth: 160,
rules: textRule('客户合同', 100, true),
},
{
label: '计划名称',
prop: 'planName',
search: true,
searchOrder: 7,
minWidth: 150,
},
{
label: '货物类型',
prop: 'cargoType',
search: true,
searchOrder: 18,
formatter: row => formatGoodsField(row, ['cargoType', 'goodsType', 'typeName']),
minWidth: 130,
rules: textRule('货物类型', 100, true),
},
{
label: '货物名称',
prop: 'cargoName',
search: true,
searchOrder: 19,
formatter: row => formatGoodsField(row, ['cargoName', 'goodsName', 'name']),
minWidth: 150,
rules: textRule('货物名称', 100, true),
},
{
label: '实际发货时间',
prop: 'startDate',
type: 'datetime',
format: 'YYYY-MM-DD HH:mm:ss',
valueFormat: 'YYYY-MM-DD HH:mm:ss',
minWidth: 170,
},
{
label: '实际完成时间',
prop: 'endDate',
type: 'datetime',
format: 'YYYY-MM-DD HH:mm:ss',
valueFormat: 'YYYY-MM-DD HH:mm:ss',
minWidth: 170,
},
{
label: '原始单号',
prop: 'originalNo',
search: true,
searchOrder: 12,
minWidth: 140,
},
{
label: '运单批次号',
prop: 'batchNo',
search: true,
searchLabel: '运输批次',
searchOrder: 3,
minWidth: 140,
},
{
label: '预计发货时间',
prop: 'estimatedStartTime',
type: 'datetime',
format: 'YYYY-MM-DD HH:mm:ss',
valueFormat: 'YYYY-MM-DD HH:mm:ss',
formatter: row => getFirstValue(row, ['estimatedStartTime', 'planStartDate']),
minWidth: 170,
addDisplay: false,
editDisplay: false,
viewDisplay: false,
},
{
label: '预计完成时间',
prop: 'estimatedEndTime',
type: 'datetime',
format: 'YYYY-MM-DD HH:mm:ss',
valueFormat: 'YYYY-MM-DD HH:mm:ss',
formatter: row => getFirstValue(row, ['estimatedEndTime', 'planEndDate']),
minWidth: 170,
addDisplay: false,
editDisplay: false,
viewDisplay: false,
},
{
label: '备注',
prop: 'remark',
type: 'textarea',
minRows: 4,
span: 24,
minWidth: 180,
overHidden: true,
maxlength: 500,
showWordLimit: true,
rules: textRule('备注', 500),
},
{
label: '数据来源',
prop: 'dataSource',
type: 'select',
search: true,
searchOrder: 10,
dicData: dataSourceOptions,
minWidth: 120,
},
{
...auditColumn('createTime'),
},
{
...auditColumn('updateTime'),
},
{
label: '状态',
prop: 'businessStatus',
type: 'select',
slot: true,
search: true,
searchLabel: '状态',
searchOrder: 11,
dicData: waybillStatusOptions,
minWidth: 120,
fixed: 'right',
addDisplay: false,
editDisplay: false,
},
{
label: '实际发货时间',
prop: 'startDateRange',
type: 'datetime',
format: 'YYYY-MM-DD HH:mm:ss',
valueFormat: 'YYYY-MM-DD HH:mm:ss',
search: true,
searchRange: true,
searchOrder: 9,
hide: true,
addDisplay: false,
editDisplay: false,
viewDisplay: false,
},
{
label: '实际完成时间',
prop: 'endDateRange',
type: 'datetime',
format: 'YYYY-MM-DD HH:mm:ss',
valueFormat: 'YYYY-MM-DD HH:mm:ss',
search: true,
searchRange: true,
searchOrder: 8,
hide: true,
addDisplay: false,
editDisplay: false,
viewDisplay: false,
},
{
label: '创建时间',
prop: 'createTimeRange',
type: 'datetime',
format: 'YYYY-MM-DD HH:mm:ss',
valueFormat: 'YYYY-MM-DD HH:mm:ss',
search: true,
searchRange: true,
searchOrder: 4,
hide: true,
addDisplay: false,
editDisplay: false,
viewDisplay: false,
},
{
label: '关联单号',
prop: 'relationNo',
search: true,
searchOrder: 2,
minWidth: 140,
hide: true,
addDisplay: false,
editDisplay: false,
viewDisplay: false,
},
{
label: '货物信息JSON',
prop: 'goodsJson',
type: 'textarea',
minRows: 5,
span: 24,
hide: true,
},
{
label: '承运信息JSON',
prop: 'carrierJson',
type: 'textarea',
minRows: 4,
span: 24,
hide: true,
},
{
label: '过程配置JSON',
prop: 'processJson',
type: 'textarea',
minRows: 4,
span: 24,
hide: true,
},
{
label: '运费信息JSON',
prop: 'freightJson',
type: 'textarea',
minRows: 4,
span: 24,
hide: true,
},
{
label: '附件JSON',
prop: 'attachmentsJson',
type: 'textarea',
minRows: 3,
span: 24,
hide: true,
},
{
label: '所属组织',
prop: 'deptName',
hide: true,
minWidth: 150,
addDisplay: false,
editDisplay: false,
},
{
label: '项目ID',
prop: 'projectId',
hide: true,
display: false,
},
{
label: '客户合同ID',
prop: 'contractId',
hide: true,
display: false,
},
]),
menuWidth: 320,
};