import { auditColumns, createCrudOption, dataSourceOptions, phoneRule, planStatusOptions, selectRule, textRule, } from './common'; const listDicFormatter = res => { const data = res?.data || res; if (Array.isArray(data)) return data; if (Array.isArray(data?.records)) return data.records; if (Array.isArray(data?.data)) return data.data; if (Array.isArray(data?.data?.records)) return data.data.records; return []; }; const parseGoodsRows = value => { if (!value) return []; if (Array.isArray(value)) return value; if (typeof value === 'object') return [value]; try { const data = JSON.parse(value); return Array.isArray(data) ? data : [data]; } catch (error) { return []; } }; const formatGoodsField = (row, propList) => { const values = propList.map(prop => row[prop]).filter(Boolean); if (values.length) return values.join('、'); return parseGoodsRows(row.goodsJson) .map(item => propList.map(prop => item?.[prop]).find(Boolean)) .filter(Boolean) .join('、'); }; const getGoodsQuantity = item => { const value = item?.quantity ?? item?.cargoQuantity ?? item?.goodsQuantity ?? 0; const number = Number(String(value).replace(/,/g, '')); return Number.isFinite(number) ? number : 0; }; const formatGoodsQuantity = value => { const number = Math.round((value + Number.EPSILON) * 1000) / 1000; return Number.isInteger(number) ? String(number) : String(number).replace(/\.?0+$/, ''); }; const getSecondCargoTypeName = item => item?.cargoType || item?.secondCargoTypeName || item?.secondCargoType || item?.goodsType || item?.type || item?.cargoTypeName || item?.firstCargoTypeName || '货物'; const formatGoodsInfo = row => { const rows = parseGoodsRows(row.goodsJson); if (!rows.length) return row.goodsInfo || ''; const groups = rows.reduce((result, item = {}) => { const hasGoodsInfo = [ item.cargoName, item.goodsName, item.name, item.cargoType, item.secondCargoTypeName, item.goodsType, item.type, item.quantity, item.cargoQuantity, item.goodsQuantity, item.quantityUnit, item.goodsQuantityUnit, item.unit, ].some(Boolean); if (!hasGoodsInfo) return result; const unit = item.quantityUnit || item.goodsQuantityUnit || item.unit || ''; if (!result[unit]) { result[unit] = { typeName: getSecondCargoTypeName(item), count: 0, quantity: 0, }; } result[unit].count += 1; result[unit].quantity += getGoodsQuantity(item); return result; }, {}); const text = Object.entries(groups) .map(([unit, group]) => { const quantity = `${formatGoodsQuantity(group.quantity)}${unit}`; return `${group.typeName}等${group.count}中货物 | ${quantity}`; }) .join('; '); return text || row.goodsInfo || ''; }; const formatDispatchProgress = row => row.dispatchProgressName || row.dispatchProgress || row.progress || ''; const auditColumn = prop => ({ ...auditColumns.find(item => item.prop === prop) }); export const config = { title: '运输计划', permission: 'transport_plan', exportUrl: '/blade-transport/transport-plan/export-transport-plan', exportName: '运输计划', enableAllDept: false, enableProjectSelect: true, enableAttachmentTable: true, enableTransportPlanForm: true, enableTransportPlanCreateActions: true, attachmentTitle: '附件', searchRangeMap: { planStartDateRange: ['planStartDateStart', 'planStartDateEnd'], planEndDateRange: ['planEndDateStart', 'planEndDateEnd'], }, actions: ['copy', 'cancel', 'complete'], statusProp: 'businessStatus', statusTextProp: 'businessStatusName', deleteStatus: ['draft'], editStatus: ['draft', 'waiting_dispatch'], }; export const option = { ...createCrudOption([ { label: '', prop: 'basicInfoTitle', formslot: true, span: 24, order: 400, hide: true, labelWidth: 0, }, { label: '计划单号', prop: 'planNo', search: true, searchOrder: 13, span: 6, order: 370, minWidth: 150, disabled: true, placeholder: '系统自动生成', }, { label: '计划名称', prop: 'planName', search: true, searchOrder: 12, span: 6, order: 380, minWidth: 150, rules: textRule('计划名称', 50, true), }, { label: '运输方式', prop: 'transportType', type: 'select', search: true, searchOrder: 10, span: 6, order: 360, dicUrl: '/blade-system/dict-biz/dictionary?code=transport_type', props: { label: 'dictValue', value: 'dictKey', }, minWidth: 130, rules: selectRule('运输类型'), }, { label: '货物信息', prop: 'goodsInfo', formatter: row => formatGoodsInfo(row), minWidth: 320, className: 'business-crud-page__goods-info-cell', overHidden: false, showOverflowTooltip: false, addDisplay: false, editDisplay: false, viewDisplay: false, }, { label: '调度进度', prop: 'dispatchProgress', formatter: row => formatDispatchProgress(row), minWidth: 120, addDisplay: false, editDisplay: false, viewDisplay: false, }, { label: '发货地址', prop: 'departureAddress', formslot: true, search: true, searchOrder: 7, span: 24, order: 310, minWidth: 220, rules: textRule('发货地址', 255, true), }, { label: '到货地址', prop: 'arrivalAddress', formslot: true, search: true, searchOrder: 6, span: 24, order: 300, minWidth: 220, rules: textRule('收货地址', 255, true), }, { label: '项目名称', prop: 'projectName', formslot: true, search: true, searchOrder: 11, searchType: 'select', span: 6, order: 400, dicUrl: '/blade-transport/project-apply/list?current=1&size=9999', dicFormatter: listDicFormatter, props: { label: 'projectName', value: 'projectName', }, filterable: true, minWidth: 150, rules: textRule('项目', 100, true), }, { label: '客户名称', prop: 'customerName', search: true, searchOrder: 5, minWidth: 150, addDisplay: false, editDisplay: false, }, { label: '计划开始日期', prop: 'planStartDate', type: 'date', format: 'YYYY-MM-DD', valueFormat: 'YYYY-MM-DD', span: 6, order: 350, minWidth: 130, }, { label: '计划结束日期', prop: 'planEndDate', type: 'date', format: 'YYYY-MM-DD', valueFormat: 'YYYY-MM-DD', span: 6, order: 340, minWidth: 130, }, { label: '数据来源', prop: 'dataSource', type: 'select', search: true, searchOrder: 1, dicData: dataSourceOptions, minWidth: 120, addDisplay: false, editDisplay: false, }, { label: '货物类型', prop: 'cargoType', search: true, searchOrder: 8, formatter: row => formatGoodsField(row, ['cargoType', 'goodsType']), minWidth: 130, addDisplay: false, editDisplay: false, viewDisplay: false, }, { label: '货物名称', prop: 'cargoName', search: true, searchOrder: 9, formatter: row => formatGoodsField(row, ['cargoName', 'goodsName']), minWidth: 150, addDisplay: false, editDisplay: false, viewDisplay: false, }, { label: '备注', prop: 'remark', type: 'textarea', minRows: 4, span: 24, order: 330, minWidth: 180, maxlength: 200, showWordLimit: true, rules: textRule('备注', 200), }, { ...auditColumn('updateUserName'), }, { ...auditColumn('createTime'), }, { ...auditColumn('updateTime'), }, { label: '调度状态', prop: 'businessStatus', type: 'select', slot: true, search: true, searchLabel: '状态', searchOrder: 2, dicData: planStatusOptions, minWidth: 120, fixed: 'right', addDisplay: false, editDisplay: false, }, { label: '', prop: 'shippingInfoTitle', formslot: true, span: 24, order: 320, hide: true, labelWidth: 0, }, { label: '项目ID', prop: 'projectId', hide: true, display: false, }, { label: '客户合同', prop: 'contractName', formslot: true, hide: true, span: 6, order: 390, minWidth: 160, rules: textRule('客户合同', 100, true), }, { label: '客户合同ID', prop: 'contractId', hide: true, display: false, }, { label: '发货地', prop: 'departureName', hide: true, display: false, minWidth: 140, rules: textRule('发货地', 100, true), }, { label: '收货地', prop: 'arrivalName', hide: true, display: false, minWidth: 140, rules: textRule('收货地', 100, true), }, { label: '发货联系人', prop: 'departureContact', hide: true, display: false, rules: textRule('发货联系人', 50), }, { label: '发货联系方式', prop: 'departurePhone', hide: true, display: false, rules: [phoneRule('发货联系方式'), ...textRule('发货联系方式', 50)], }, { label: '收货联系人', prop: 'arrivalContact', hide: true, display: false, rules: textRule('收货联系人', 50), }, { label: '收货联系方式', prop: 'arrivalPhone', hide: true, display: false, rules: [phoneRule('收货联系方式'), ...textRule('收货联系方式', 50)], }, { label: '', prop: 'goodsInfoTitle', formslot: true, span: 24, order: 280, hide: true, labelWidth: 0, }, { label: '计划开始日期', prop: 'planStartDateRange', type: 'date', format: 'YYYY-MM-DD', valueFormat: 'YYYY-MM-DD', search: true, searchRange: true, searchOrder: 4, hide: true, addDisplay: false, editDisplay: false, viewDisplay: false, }, { label: '计划结束日期', prop: 'planEndDateRange', type: 'date', format: 'YYYY-MM-DD', valueFormat: 'YYYY-MM-DD', search: true, searchRange: true, searchOrder: 3, hide: true, addDisplay: false, editDisplay: false, viewDisplay: false, }, { label: '所属组织', prop: 'deptName', hide: true, minWidth: 150, addDisplay: false, editDisplay: false, }, { label: '', prop: 'goodsJson', type: 'textarea', formslot: true, minRows: 5, span: 24, order: 270, hide: true, labelWidth: '0px', className: 'business-crud-page__full-form-item', }, { label: '', prop: 'attachmentTitle', formslot: true, span: 24, order: 265, hide: true, labelWidth: 0, }, { label: '', prop: 'attachmentsJson', type: 'textarea', formslot: true, minRows: 3, span: 24, order: 260, hide: true, labelWidth: '0px', className: 'business-crud-page__full-form-item', }, ]), dialogWidth: '96%', };