diff --git a/src/option/base/measurement-unit.js b/src/option/base/measurement-unit.js index 7c68b87..b85e579 100644 --- a/src/option/base/measurement-unit.js +++ b/src/option/base/measurement-unit.js @@ -2,6 +2,9 @@ const dimensionOptions = [ { label: '重量', value: '重量' }, { label: '体积', value: '体积' }, { label: '数量', value: '数量' }, + { label: '整车', value: '整车' }, + { label: '里程', value: '里程' }, + { label: '吨·公里', value: '吨·公里' }, ]; const statusOptions = [ diff --git a/src/option/business/transport-plan.js b/src/option/business/transport-plan.js index 152054f..f395e93 100644 --- a/src/option/business/transport-plan.js +++ b/src/option/business/transport-plan.js @@ -400,7 +400,6 @@ export const option = { span: 6, order: 350, minWidth: 150, - rules: [{ required: true, message: '请选择计划开始日期', trigger: 'change' }], }, { label: '计划结束日期', @@ -411,7 +410,6 @@ export const option = { span: 6, order: 340, minWidth: 150, - rules: [{ required: true, message: '请选择计划结束日期', trigger: 'change' }], }, { label: '数据来源', diff --git a/src/utils/measurement-unit.js b/src/utils/measurement-unit.js new file mode 100644 index 0000000..a238460 --- /dev/null +++ b/src/utils/measurement-unit.js @@ -0,0 +1,27 @@ +import { getList as getMeasurementUnitList } from '@/api/base/measurement-unit'; + +/** + * 加载启用状态的计量单位选项,展示/取值均为「计量单位」字段(unitName)。 + * @returns {Promise>} + */ +export const loadMeasurementUnitOptions = () => { + return getMeasurementUnitList(1, 9999, { status: 1 }).then(res => { + const data = res?.data?.data || res?.data || {}; + const records = Array.isArray(data) ? data : data.records || []; + const names = new Set(); + return records + .filter(item => item.status === undefined || item.status === null || Number(item.status) === 1) + .map(item => { + const name = String(item.unitName || '').trim(); + if (!name || names.has(name)) return null; + names.add(name); + return { + id: item.id, + label: name, + value: name, + dimension: String(item.dimension || '').trim(), + }; + }) + .filter(Boolean); + }); +}; diff --git a/src/views/business/components/billing-plan-editor.vue b/src/views/business/components/billing-plan-editor.vue index b13e2ab..115798f 100644 --- a/src/views/business/components/billing-plan-editor.vue +++ b/src/views/business/components/billing-plan-editor.vue @@ -386,12 +386,15 @@ const BILLING_ELEMENT_DIMENSION_MAP = { 按重量: '重量', 按体积: '体积', 按数量: '数量', + 按里程: '里程', + '按吨·公里': '吨·公里', + '固定金额(整单一口价)': '整车', }; const BILLING_UNIT_SELECTABLE_ELEMENTS = Object.keys(BILLING_ELEMENT_DIMENSION_MAP); -/** 固定计费单位(不可编辑) */ -const FIXED_BILLING_UNIT_MAP = { +/** 对应维度下无计量单位时的默认计费单位 */ +const DEFAULT_BILLING_UNIT_MAP = { 按里程: '公里', - '按吨·公里': '吨公里', + '按吨·公里': '吨·公里', '固定金额(整单一口价)': '单', }; const defaultRule = () => ({ @@ -652,58 +655,61 @@ export default { }), ]).finally(() => { this.unitLoading = false; + (this.draft.rules || []).forEach(row => this.syncBillingUnit(row)); }); }, measurementDimension(billingElement) { return BILLING_ELEMENT_DIMENSION_MAP[billingElement] || ''; }, - fixedBillingUnit(billingElement) { - return FIXED_BILLING_UNIT_MAP[String(billingElement || '').trim()] || ''; + defaultBillingUnit(billingElement) { + return DEFAULT_BILLING_UNIT_MAP[String(billingElement || '').trim()] || ''; }, canSelectBillingUnit(row) { return BILLING_UNIT_SELECTABLE_ELEMENTS.includes(String(row?.billingElement || '').trim()); }, billingUnitPlaceholder(row) { if (!row?.billingElement) return '请先选择计费要素'; - if (this.fixedBillingUnit(row.billingElement)) return this.fixedBillingUnit(row.billingElement); if (!this.canSelectBillingUnit(row)) return '当前计费要素无需选择'; return '请选择'; }, unitOptionsFor(row) { - const fixedUnit = this.fixedBillingUnit(row?.billingElement); - if (fixedUnit) { - return [{ id: fixedUnit, label: fixedUnit, value: fixedUnit }]; - } if (!this.canSelectBillingUnit(row)) { return []; } const dimension = this.measurementDimension(row?.billingElement); - if (dimension) { - return this.measurementUnits - .filter(item => String(item.dimension || '').trim() === dimension) - .map(item => ({ - id: item.id, - label: item.unitName, - value: item.unitName, - })) - .filter(item => item.value); + const defaultUnit = this.defaultBillingUnit(row?.billingElement); + const options = dimension + ? this.measurementUnits + .filter(item => String(item.dimension || '').trim() === dimension) + .map(item => ({ + id: item.id, + label: item.unitName, + value: item.unitName, + })) + .filter(item => item.value) + : []; + // 对应维度未配置计量单位时,下拉仅展示默认值 + if (!options.length && defaultUnit) { + return [{ id: `default-${defaultUnit}`, label: defaultUnit, value: defaultUnit }]; } - return []; + return options; }, syncBillingUnit(row) { - const fixedUnit = this.fixedBillingUnit(row?.billingElement); - if (fixedUnit) { - row.billingUnit = fixedUnit; - return; - } if (!this.canSelectBillingUnit(row)) { row.billingUnit = ''; return; } const options = this.unitOptionsFor(row); - if (!options.some(item => String(item.value) === String(row.billingUnit || ''))) { - row.billingUnit = ''; + const defaultUnit = this.defaultBillingUnit(row?.billingElement); + const current = String(row.billingUnit || '').trim(); + if (options.some(item => String(item.value) === current)) { + return; } + if (defaultUnit && options.some(item => String(item.value) === defaultUnit)) { + row.billingUnit = defaultUnit; + return; + } + row.billingUnit = options[0]?.value || defaultUnit || ''; }, feeTypeKey(row) { const option = this.feeCategories.find( diff --git a/src/views/business/components/business-crud-page.vue b/src/views/business/components/business-crud-page.vue index 74613ad..069a237 100644 --- a/src/views/business/components/business-crud-page.vue +++ b/src/views/business/components/business-crud-page.vue @@ -5244,6 +5244,7 @@ import { formatUpdateUserName } from '@/utils/audit'; import { getToken, isAdministrator } from '@/utils/auth'; import { openImportDialog } from '@/utils/import-excel'; import { normalizeMapSearchResults, searchAmapPlaceText } from '@/utils/map-search'; +import { loadMeasurementUnitOptions } from '@/utils/measurement-unit'; import { applyTableMenuWidth } from '@/utils/table-menu'; import { downloadFileByUrl, downloadXls } from '@/utils/util'; import { isMobile } from '@/utils/validate'; @@ -5822,7 +5823,7 @@ export default { billCycleTypeOptions: ['固定截单日', '自然月', '自定义多周期'], reconciliationModeOptions: ['明细逐行核对', '按账单汇总核对', '跳过自动核对'], packageOptions, - quantityUnitOptions: ['吨', '千克', '立方米', '件', '车', '箱', '托盘'], + quantityUnitOptions: [], attachmentFileTypes: [ 'pdf', 'bmp', @@ -5865,7 +5866,6 @@ export default { this.ensureBillingUnitOptions(); } if (this.config.enableTaskInfoForm) { - this.loadTaskQuantityUnitOptions(); this.loadTaskFeeUnitOptions(); this.ensureBillingCargoTypeOptions(); } @@ -5886,6 +5886,7 @@ export default { } else { this.consumeTemplateCreatePayload(); } + this.loadTaskQuantityUnitOptions(); }, computed: { ...mapGetters(['permission', 'userInfo']), @@ -7789,8 +7790,6 @@ export default { ['contractName', '客户合同'], ['planName', '计划名称'], ['transportType', '运输方式'], - ['planStartDate', '计划开始日期'], - ['planEndDate', '计划结束日期'], ['departureAddress', '发货地址'], ['arrivalAddress', '收货地址'], ]; @@ -9270,9 +9269,10 @@ export default { return Promise.resolve(this.taskQuantityUnitOptions); } this.taskQuantityUnitLoading = true; - return getDictionary({ code: 'quantity_unit' }) - .then(res => { - this.taskQuantityUnitOptions = this.normalizeDictOptions(res.data.data || []); + return loadMeasurementUnitOptions() + .then(options => { + this.taskQuantityUnitOptions = options; + this.quantityUnitOptions = options.map(item => item.value); return this.taskQuantityUnitOptions; }) .finally(() => { diff --git a/src/views/business/components/master-order-dispatch.vue b/src/views/business/components/master-order-dispatch.vue index c5efbd2..9f6ad5f 100644 --- a/src/views/business/components/master-order-dispatch.vue +++ b/src/views/business/components/master-order-dispatch.vue @@ -317,6 +317,7 @@