diff --git a/src/api/business/common-cargo.js b/src/api/business/common-cargo.js new file mode 100644 index 0000000..4588c4e --- /dev/null +++ b/src/api/business/common-cargo.js @@ -0,0 +1,8 @@ +import { createCrudApi } from './common'; + +const api = createCrudApi('/blade-transport/common-cargo'); + +export const getList = api.getList; +export const getDetail = api.getDetail; +export const submit = api.submit; +export const remove = api.remove; diff --git a/src/api/business/common-route.js b/src/api/business/common-route.js new file mode 100644 index 0000000..4b69585 --- /dev/null +++ b/src/api/business/common-route.js @@ -0,0 +1,8 @@ +import { createCrudApi } from './common'; + +const api = createCrudApi('/blade-transport/common-route'); + +export const getList = api.getList; +export const getDetail = api.getDetail; +export const submit = api.submit; +export const remove = api.remove; diff --git a/src/api/business/common.js b/src/api/business/common.js new file mode 100644 index 0000000..b74ffe7 --- /dev/null +++ b/src/api/business/common.js @@ -0,0 +1,103 @@ +import request from '@/axios'; + +export const createCrudApi = baseUrl => ({ + getList(current, size, params) { + return request({ + url: `${baseUrl}/list`, + method: 'get', + params: { + ...params, + current, + size, + }, + }); + }, + getDetail(id) { + return request({ + url: `${baseUrl}/detail`, + method: 'get', + params: { + id, + }, + }); + }, + submit(row) { + return request({ + url: `${baseUrl}/submit`, + method: 'post', + data: row, + }); + }, + remove(ids) { + return request({ + url: `${baseUrl}/remove`, + method: 'post', + params: { + ids, + }, + }); + }, + copy(id) { + return request({ + url: `${baseUrl}/copy`, + method: 'post', + params: { + id, + }, + }); + }, + enable(id) { + return request({ + url: `${baseUrl}/enable`, + method: 'post', + params: { + id, + }, + }); + }, + disable(id) { + return request({ + url: `${baseUrl}/disable`, + method: 'post', + params: { + id, + }, + }); + }, + cancel(id) { + return request({ + url: `${baseUrl}/cancel`, + method: 'post', + params: { + id, + }, + }); + }, + complete(id) { + return request({ + url: `${baseUrl}/complete`, + method: 'post', + params: { + id, + }, + }); + }, + reassign(id) { + return request({ + url: `${baseUrl}/reassign`, + method: 'post', + params: { + id, + }, + }); + }, + batchComplete(ids) { + return request({ + url: `${baseUrl}/batch-complete`, + method: 'post', + params: { + ids, + }, + }); + }, +}); diff --git a/src/api/business/contract-manage.js b/src/api/business/contract-manage.js new file mode 100644 index 0000000..109b21c --- /dev/null +++ b/src/api/business/contract-manage.js @@ -0,0 +1,78 @@ +import { createCrudApi } from './common'; +import request from '@/axios'; + +const baseUrl = '/blade-transport/contract-manage'; +const api = createCrudApi(baseUrl); + +export const getList = api.getList; +export const getDetail = api.getDetail; +export const submit = api.submit; +export const remove = api.remove; +export const copy = api.copy; + +export const saveDraft = row => + request({ + url: `${baseUrl}/save-draft`, + method: 'post', + data: row, + }); + +export const toTemporary = id => + request({ + url: `${baseUrl}/to-temporary`, + method: 'post', + params: { id }, + }); + +export const submitFormal = id => + request({ + url: `${baseUrl}/submit-formal`, + method: 'post', + params: { id }, + }); + +export const approve = id => + request({ + url: `${baseUrl}/approve`, + method: 'post', + params: { id }, + }); + +export const reject = id => + request({ + url: `${baseUrl}/reject`, + method: 'post', + params: { id }, + }); + +export const withdraw = id => + request({ + url: `${baseUrl}/withdraw`, + method: 'post', + params: { id }, + }); + +export const startChange = (id, reason) => + request({ + url: `${baseUrl}/start-change`, + method: 'post', + params: { + id, + changeContent: reason, + changeReason: reason, + }, + }); + +export const terminate = (id, reason) => + request({ + url: `${baseUrl}/terminate`, + method: 'post', + params: { id, reason }, + }); + +export const expireStats = params => + request({ + url: `${baseUrl}/expire-stats`, + method: 'get', + params, + }); diff --git a/src/api/business/process-config.js b/src/api/business/process-config.js new file mode 100644 index 0000000..21a3bc4 --- /dev/null +++ b/src/api/business/process-config.js @@ -0,0 +1,11 @@ +import { createCrudApi } from './common'; + +const api = createCrudApi('/blade-transport/process-config'); + +export const getList = api.getList; +export const getDetail = api.getDetail; +export const submit = api.submit; +export const remove = api.remove; +export const copy = api.copy; +export const enable = api.enable; +export const disable = api.disable; diff --git a/src/api/business/project-apply.js b/src/api/business/project-apply.js new file mode 100644 index 0000000..6d8224c --- /dev/null +++ b/src/api/business/project-apply.js @@ -0,0 +1,63 @@ +import { createCrudApi } from './common'; +import request from '@/axios'; + +const baseUrl = '/blade-transport/project-apply'; +const api = createCrudApi(baseUrl); + +export const getList = api.getList; +export const getDetail = api.getDetail; +export const submit = api.submit; +export const remove = api.remove; + +export const saveDraft = row => + request({ + url: `${baseUrl}/save-draft`, + method: 'post', + data: row, + }); + +export const submitApproval = id => + request({ + url: `${baseUrl}/submit-approval`, + method: 'post', + params: { id }, + }); + +export const approve = id => + request({ + url: `${baseUrl}/approve`, + method: 'post', + params: { id }, + }); + +export const reject = id => + request({ + url: `${baseUrl}/reject`, + method: 'post', + params: { id }, + }); + +export const withdraw = id => + request({ + url: `${baseUrl}/withdraw`, + method: 'post', + params: { id }, + }); + +export const voidProject = (id, reason) => + request({ + url: `${baseUrl}/void`, + method: 'post', + params: { id, reason }, + }); + +export const startChange = (id, reason) => + request({ + url: `${baseUrl}/start-change`, + method: 'post', + params: { + id, + changeContent: reason, + changeReason: reason, + }, + }); diff --git a/src/api/business/shipping-template.js b/src/api/business/shipping-template.js new file mode 100644 index 0000000..7246a79 --- /dev/null +++ b/src/api/business/shipping-template.js @@ -0,0 +1,9 @@ +import { createCrudApi } from './common'; + +const api = createCrudApi('/blade-transport/shipping-template'); + +export const getList = api.getList; +export const getDetail = api.getDetail; +export const submit = api.submit; +export const remove = api.remove; +export const copy = api.copy; diff --git a/src/api/business/temporary-credit-limit.js b/src/api/business/temporary-credit-limit.js new file mode 100644 index 0000000..aff777d --- /dev/null +++ b/src/api/business/temporary-credit-limit.js @@ -0,0 +1,45 @@ +import { createCrudApi } from './common'; +import request from '@/axios'; + +const baseUrl = '/blade-transport/temporary-credit-limit'; +const api = createCrudApi(baseUrl); + +export const getList = api.getList; +export const getDetail = api.getDetail; +export const submit = api.submit; +export const remove = api.remove; + +export const saveDraft = row => + request({ + url: `${baseUrl}/save-draft`, + method: 'post', + data: row, + }); + +export const submitApproval = id => + request({ + url: `${baseUrl}/submit-approval`, + method: 'post', + params: { id }, + }); + +export const approve = id => + request({ + url: `${baseUrl}/approve`, + method: 'post', + params: { id }, + }); + +export const reject = id => + request({ + url: `${baseUrl}/reject`, + method: 'post', + params: { id }, + }); + +export const withdraw = id => + request({ + url: `${baseUrl}/withdraw`, + method: 'post', + params: { id }, + }); diff --git a/src/api/business/transport-plan.js b/src/api/business/transport-plan.js new file mode 100644 index 0000000..c6a46a5 --- /dev/null +++ b/src/api/business/transport-plan.js @@ -0,0 +1,11 @@ +import { createCrudApi } from './common'; + +const api = createCrudApi('/blade-transport/transport-plan'); + +export const getList = api.getList; +export const getDetail = api.getDetail; +export const submit = api.submit; +export const remove = api.remove; +export const copy = api.copy; +export const cancel = api.cancel; +export const complete = api.complete; diff --git a/src/api/business/waybill-manage.js b/src/api/business/waybill-manage.js new file mode 100644 index 0000000..64ed50e --- /dev/null +++ b/src/api/business/waybill-manage.js @@ -0,0 +1,13 @@ +import { createCrudApi } from './common'; + +const api = createCrudApi('/blade-transport/waybill-manage'); + +export const getList = api.getList; +export const getDetail = api.getDetail; +export const submit = api.submit; +export const remove = api.remove; +export const copy = api.copy; +export const cancel = api.cancel; +export const reassign = api.reassign; +export const complete = api.complete; +export const batchComplete = api.batchComplete; diff --git a/src/option/business/common-cargo.js b/src/option/business/common-cargo.js new file mode 100644 index 0000000..cc92f26 --- /dev/null +++ b/src/option/business/common-cargo.js @@ -0,0 +1,179 @@ +import { + auditColumns, + createCrudOption, + nonNegativeRule, + packageOptions, + priceUnitOptions, + selectRule, + textRule, +} from './common'; + +export const config = { + title: '常用货物', + permission: 'common_cargo', + exportUrl: '/blade-transport/common-cargo/export-common-cargo', + exportName: '常用货物', + importUrl: '/blade-transport/common-cargo/import-common-cargo', + templateUrl: '/blade-transport/common-cargo/export-template', + enableAllDept: true, +}; + +export const option = createCrudOption([ + { + label: '组织', + prop: 'deptName', + search: true, + minWidth: 150, + addDisplay: false, + editDisplay: false, + }, + { + label: '一级货物类型', + prop: 'firstCargoTypeName', + search: true, + minWidth: 150, + editDisabled: true, + rules: textRule('一级货物类型', 100, true), + }, + { + label: '一级货物类型编码', + prop: 'firstCargoTypeCode', + hide: true, + editDisabled: true, + }, + { + label: '二级货物类型', + prop: 'secondCargoTypeName', + search: true, + minWidth: 150, + editDisabled: true, + rules: textRule('二级货物类型', 100, true), + }, + { + label: '二级货物类型编码', + prop: 'secondCargoTypeCode', + search: true, + minWidth: 150, + editDisabled: true, + rules: textRule('二级货物类型编码', 20, true), + }, + { + label: '货物名称', + prop: 'cargoName', + search: true, + minWidth: 150, + rules: textRule('货物名称', 100, true), + }, + { + label: '货物编号', + prop: 'cargoCode', + search: true, + minWidth: 120, + editDisabled: true, + rules: textRule('货物编号', 20, true), + }, + { + label: '品牌', + prop: 'brand', + search: true, + minWidth: 120, + rules: textRule('品牌', 50), + }, + { + label: '包装', + prop: 'packageType', + type: 'select', + dicData: packageOptions, + minWidth: 100, + }, + { + label: '货值', + prop: 'cargoValue', + type: 'number', + precision: 2, + min: 0, + minWidth: 120, + rules: [nonNegativeRule('货值')], + }, + { + label: '规格', + prop: 'specification', + minWidth: 120, + rules: textRule('规格', 50), + }, + { + label: '计价单位', + prop: 'priceUnit', + type: 'select', + dicData: priceUnitOptions, + minWidth: 120, + }, + { + label: '型号', + prop: 'model', + minWidth: 120, + rules: textRule('型号', 50), + }, + { + label: '说明1', + prop: 'descriptionOne', + minWidth: 160, + rules: textRule('说明1', 100), + }, + { + label: '尺寸', + prop: 'sizeText', + minWidth: 120, + rules: textRule('尺寸', 50), + }, + { + label: '说明2', + prop: 'descriptionTwo', + minWidth: 160, + rules: textRule('说明2', 100), + }, + { + label: '数据来源', + prop: 'dataSource', + minWidth: 120, + addDisplay: false, + editDisplay: false, + }, + { + label: '备注', + prop: 'remark', + type: 'textarea', + minRows: 4, + span: 24, + hide: true, + maxlength: 200, + showWordLimit: true, + rules: textRule('备注', 200), + }, + ...auditColumns, +]); + +export const excelOption = { + submitBtn: false, + emptyBtn: false, + column: [ + { + label: '导入模板', + prop: 'excelTemplate', + formslot: true, + span: 24, + }, + { + label: 'Excel文件', + prop: 'excelFile', + type: 'upload', + drag: true, + loadText: '模板上传中,请稍等', + span: 24, + propsHttp: { + res: 'data', + }, + tip: '请上传 .xls,.xlsx 标准格式文件', + }, + ], +}; diff --git a/src/option/business/common-route.js b/src/option/business/common-route.js new file mode 100644 index 0000000..947a99f --- /dev/null +++ b/src/option/business/common-route.js @@ -0,0 +1,131 @@ +import { auditColumns, createCrudOption, phoneRule, textRule } from './common'; + +export const config = { + title: '常用线路', + permission: 'common_route', + exportUrl: '/blade-transport/common-route/export-common-route', + exportName: '常用线路', + enableAllDept: true, +}; + +export const option = createCrudOption([ + { + label: '组织', + prop: 'deptName', + search: true, + minWidth: 150, + addDisplay: false, + editDisplay: false, + }, + { + label: '线路编号', + prop: 'routeCode', + search: true, + minWidth: 120, + addDisplay: false, + editDisabled: true, + }, + { + label: '线路名称', + prop: 'routeName', + search: true, + minWidth: 150, + rules: textRule('线路名称', 100, true), + }, + { + label: '发货地', + prop: 'departureName', + search: true, + minWidth: 140, + rules: textRule('发货地', 100, true), + }, + { + label: '发货地址', + prop: 'departureAddress', + search: true, + minWidth: 220, + rules: textRule('发货地址', 255, true), + }, + { + label: '发货经度', + prop: 'departureLongitude', + type: 'number', + precision: 6, + minWidth: 120, + hide: true, + }, + { + label: '发货纬度', + prop: 'departureLatitude', + type: 'number', + precision: 6, + minWidth: 120, + hide: true, + }, + { + label: '发货联系人', + prop: 'departureContact', + minWidth: 120, + rules: textRule('发货联系人', 50), + }, + { + label: '发货联系方式', + prop: 'departurePhone', + minWidth: 140, + rules: [phoneRule('发货联系方式'), ...textRule('发货联系方式', 50)], + }, + { + label: '收货地', + prop: 'arrivalName', + search: true, + minWidth: 140, + rules: textRule('收货地', 100, true), + }, + { + label: '收货地址', + prop: 'arrivalAddress', + search: true, + minWidth: 220, + rules: textRule('收货地址', 255, true), + }, + { + label: '收货经度', + prop: 'arrivalLongitude', + type: 'number', + precision: 6, + minWidth: 120, + hide: true, + }, + { + label: '收货纬度', + prop: 'arrivalLatitude', + type: 'number', + precision: 6, + minWidth: 120, + hide: true, + }, + { + label: '收货联系人', + prop: 'arrivalContact', + minWidth: 120, + rules: textRule('收货联系人', 50), + }, + { + label: '收货联系方式', + prop: 'arrivalPhone', + minWidth: 140, + rules: [phoneRule('收货联系方式'), ...textRule('收货联系方式', 50)], + }, + { + label: '备注', + prop: 'remark', + type: 'textarea', + minRows: 4, + span: 24, + hide: true, + maxlength: 500, + showWordLimit: true, + rules: textRule('备注', 500), + }, + ...auditColumns, +]); diff --git a/src/option/business/common.js b/src/option/business/common.js new file mode 100644 index 0000000..f158f9f --- /dev/null +++ b/src/option/business/common.js @@ -0,0 +1,244 @@ +export const transportTypeOptions = [ + { label: '公路整车', value: '公路整车' }, + { label: '公路零担', value: '公路零担' }, + { label: '铁路运输', value: '铁路运输' }, + { label: '水路运输', value: '水路运输' }, + { label: '跨境海运', value: '跨境海运' }, + { label: '航空运输', value: '航空运输' }, +]; + +export const packageOptions = [ + { label: '袋装', value: '袋装' }, + { label: '散装', value: '散装' }, + { label: '桶装', value: '桶装' }, + { label: '箱装', value: '箱装' }, + { label: '托盘', value: '托盘' }, +]; + +export const priceUnitOptions = [ + { label: '元/吨', value: '元/吨' }, + { label: '元/立方米', value: '元/立方米' }, + { label: '元/件', value: '元/件' }, + { label: '元/车', value: '元/车' }, +]; + +export const templateTypeOptions = [ + { label: '运输计划', value: '运输计划' }, + { label: '常规运单', value: '常规运单' }, +]; + +export const processStatusOptions = [ + { label: '草稿', value: 0 }, + { label: '启用', value: 1 }, + { label: '停用', value: 2 }, +]; + +export const planStatusOptions = [ + { label: '草稿', value: 'draft' }, + { label: '待调度', value: 'waiting_dispatch' }, + { label: '调度中', value: 'dispatching' }, + { label: '已完成', value: 'completed' }, + { label: '已取消', value: 'cancelled' }, +]; + +export const waybillStatusOptions = [ + { label: '草稿', value: 'draft' }, + { label: '待执行', value: 'pending' }, + { label: '进行中', value: 'processing' }, + { label: '已完成', value: 'completed' }, + { label: '已取消', value: 'cancelled' }, +]; + +export const dataSourceOptions = [ + { label: '手工创建', value: '手工创建' }, + { label: '批量导入', value: '批量导入' }, + { label: '模板生成', value: '模板生成' }, + { label: '计划调度', value: '计划调度' }, +]; + +export const projectTypeOptions = [ + { label: '普通项目', value: '普通项目' }, + { label: '重大项目', value: '重大项目' }, +]; + +export const projectSourceOptions = [ + { label: '商务洽谈', value: '商务洽谈' }, + { label: '招投标', value: '招投标' }, + { label: '客户委托', value: '客户委托' }, + { label: '其它', value: '其它' }, +]; + +export const projectApprovalStatusOptions = [ + { label: '草稿', value: 'draft' }, + { label: '审批中', value: 'reviewing' }, + { label: '已撤回', value: 'withdrawn' }, + { label: '审批通过', value: 'approved' }, + { label: '已驳回', value: 'rejected' }, + { label: '变更审批中', value: 'change_reviewing' }, + { label: '变更驳回', value: 'change_rejected' }, + { label: '变更审批通过', value: 'change_approved' }, + { label: '已作废', value: 'voided' }, +]; + +export const approvalStatusOptions = [ + { label: '草稿', value: 'draft' }, + { label: '审批中', value: 'reviewing' }, + { label: '已撤回', value: 'withdrawn' }, + { label: '审批通过', value: 'approved' }, + { label: '已驳回', value: 'rejected' }, +]; + +export const effectiveTypeOptions = [ + { label: '临时', value: 'temporary' }, + { label: '正式', value: 'formal' }, +]; + +export const businessTypeOptions = [ + { label: '一类规模业务', value: '一类规模业务' }, + { label: '二类规模业务', value: '二类规模业务' }, + { label: '普通业务', value: '普通业务' }, +]; + +export const settlementModeOptions = [ + { label: '先票后款', value: '先票后款' }, + { label: '先款后票', value: '先款后票' }, + { label: '月结', value: '月结' }, +]; + +export const contractCategoryOptions = [ + { label: '客户合同', value: '客户合同' }, + { label: '承运商合同', value: '承运商合同' }, + { label: '补充协议', value: '补充协议' }, +]; + +export const signTypeOptions = [ + { label: '新签', value: '新签' }, + { label: '续签', value: '续签' }, +]; + +export const contractStageOptions = [ + { label: '草稿', value: 'draft' }, + { label: '临时合同', value: 'temporary' }, + { label: '正式合同', value: 'formal' }, + { label: '已终止', value: 'terminated' }, +]; + +export const contractApprovalStatusOptions = [ + { label: '草稿', value: 'draft' }, + { label: '审批中', value: 'reviewing' }, + { label: '已驳回', value: 'rejected' }, + { label: '审批通过', value: 'approved' }, + { label: '变更审批中', value: 'change_reviewing' }, + { label: '变更驳回', value: 'change_rejected' }, + { label: '变更审批通过', value: 'change_approved' }, +]; + +export const nodeOptions = [ + { label: '接单', value: '接单' }, + { label: '到场', value: '到场' }, + { label: '装货', value: '装货' }, + { label: '发货', value: '发货' }, + { label: '在途', value: '在途' }, + { label: '到货', value: '到货' }, + { label: '卸货', value: '卸货' }, + { label: '签收', value: '签收' }, + { label: '回单', value: '回单' }, +]; + +export const textRule = (label, max, required = false) => { + const rules = []; + if (required) { + rules.push({ required: true, message: `请输入${label}`, trigger: 'blur' }); + } + if (max) { + rules.push({ max, message: `${label}不能超过${max}个字符`, trigger: 'blur' }); + } + return rules; +}; + +export const selectRule = label => [{ required: true, message: `请选择${label}`, trigger: 'change' }]; + +export const nonNegativeRule = label => ({ + validator: (rule, value, callback) => { + if (value !== undefined && value !== null && value !== '' && Number(value) < 0) { + callback(new Error(`${label}不能小于0`)); + return; + } + callback(); + }, + trigger: 'blur', +}); + +export const phoneRule = label => ({ + pattern: /^(1\d{10}|0\d{2,3}-?\d{7,8})$/, + message: `${label}格式不正确`, + trigger: 'blur', +}); + +export const createCrudOption = columns => ({ + height: 'auto', + calcHeight: 32, + dialogWidth: 980, + labelPosition: 'right', + labelWidth: 'auto', + tip: false, + searchBtnText: '查询', + emptyBtnText: '重置', + saveBtnText: '提交', + updateBtnText: '提交', + searchShow: true, + searchMenuSpan: 24, + searchIcon: true, + searchIndex: 8, + searchMenuPosition: 'right', + border: true, + index: true, + indexLabel: '序号', + indexWidth: 70, + selection: true, + addBtn: false, + viewBtn: false, + editBtn: false, + delBtn: false, + dialogClickModal: false, + menuFixed: 'right', + menuWidth: 240, + column: columns, +}); + +export const auditColumns = [ + { + label: '创建人', + prop: 'createUserName', + minWidth: 120, + addDisplay: false, + editDisplay: false, + }, + { + label: '更新人', + prop: 'updateUserName', + minWidth: 120, + addDisplay: false, + editDisplay: false, + }, + { + label: '创建时间', + prop: 'createTime', + type: 'datetime', + format: 'YYYY-MM-DD HH:mm:ss', + valueFormat: 'YYYY-MM-DD HH:mm:ss', + minWidth: 160, + addDisplay: false, + editDisplay: false, + }, + { + label: '更新时间', + prop: 'updateTime', + type: 'datetime', + format: 'YYYY-MM-DD HH:mm:ss', + valueFormat: 'YYYY-MM-DD HH:mm:ss', + minWidth: 160, + addDisplay: false, + editDisplay: false, + }, +]; diff --git a/src/option/business/contract-manage.js b/src/option/business/contract-manage.js new file mode 100644 index 0000000..fa6676b --- /dev/null +++ b/src/option/business/contract-manage.js @@ -0,0 +1,333 @@ +import { + auditColumns, + contractApprovalStatusOptions, + contractCategoryOptions, + contractStageOptions, + createCrudOption, + selectRule, + settlementModeOptions, + signTypeOptions, + textRule, +} from './common'; + +export const config = { + title: '合同管理', + permission: 'contract_manage', + exportUrl: '/blade-transport/contract-manage/export-contract-manage', + exportName: '合同管理', + enableAllDept: true, + actions: ['copy'], + statusProp: 'approvalStatus', + statusTextProp: 'approvalStatusName', + deleteStatus: ['draft'], + editStatus: ['draft', 'rejected', 'change_rejected'], + operations: [ + { + action: 'toTemporary', + label: '转临时', + statusProp: 'approvalStatus', + status: ['draft'], + stage: ['draft'], + permission: 'contract_manage_temp', + }, + { + action: 'submitFormal', + label: '转正式', + statusProp: 'approvalStatus', + status: ['draft', 'rejected', 'approved'], + stage: ['temporary'], + permission: 'contract_manage_formal', + }, + { + action: 'withdraw', + label: '撤回', + icon: 'el-icon-refresh-left', + statusProp: 'approvalStatus', + status: ['reviewing', 'change_reviewing'], + permission: 'contract_manage_withdraw', + }, + { + action: 'approve', + label: '审批通过', + type: 'success', + icon: 'el-icon-check', + statusProp: 'approvalStatus', + status: ['reviewing', 'change_reviewing'], + permission: 'contract_manage_approve', + }, + { + action: 'reject', + label: '审批驳回', + type: 'warning', + icon: 'el-icon-close', + statusProp: 'approvalStatus', + status: ['reviewing', 'change_reviewing'], + permission: 'contract_manage_reject', + }, + { + action: 'startChange', + label: '发起变更', + icon: 'el-icon-edit-outline', + statusProp: 'approvalStatus', + status: ['approved', 'change_approved'], + stage: ['formal'], + permission: 'contract_manage_change', + prompt: '请输入变更内容与原因', + }, + { + action: 'terminate', + label: '终止', + type: 'danger', + icon: 'el-icon-close', + statusProp: 'approvalStatus', + status: ['approved', 'change_approved'], + stage: ['formal'], + permission: 'contract_manage_terminate', + prompt: '请输入终止原因', + }, + ], +}; + +export const option = createCrudOption([ + { + label: '合同编号', + prop: 'contractNo', + search: true, + minWidth: 160, + addDisplay: false, + editDisabled: true, + }, + { + label: '合同名称', + prop: 'contractName', + search: true, + minWidth: 180, + rules: textRule('合同名称', 100, true), + }, + { + label: '所属项目', + prop: 'projectName', + search: true, + minWidth: 160, + }, + { + label: '所属项目ID', + prop: 'projectId', + hide: true, + }, + { + label: '所属组织', + prop: 'organizationName', + search: true, + minWidth: 150, + addDisplay: false, + editDisabled: true, + }, + { + label: '合同类别', + prop: 'contractCategory', + type: 'select', + search: true, + dicData: contractCategoryOptions, + minWidth: 130, + rules: selectRule('合同类别'), + }, + { + label: '签约类型', + prop: 'signType', + type: 'select', + search: true, + dicData: signTypeOptions, + minWidth: 120, + }, + { + label: '甲方', + prop: 'partyA', + minWidth: 160, + }, + { + label: '乙方', + prop: 'partyB', + minWidth: 160, + }, + { + label: '开始日期', + prop: 'startDate', + type: 'date', + format: 'YYYY-MM-DD', + valueFormat: 'YYYY-MM-DD', + minWidth: 130, + }, + { + label: '结束日期', + prop: 'endDate', + type: 'date', + format: 'YYYY-MM-DD', + valueFormat: 'YYYY-MM-DD', + minWidth: 130, + }, + { + label: '临时效力起', + prop: 'temporaryStartDate', + type: 'date', + format: 'YYYY-MM-DD', + valueFormat: 'YYYY-MM-DD', + minWidth: 130, + }, + { + label: '临时效力止', + prop: 'temporaryEndDate', + type: 'date', + format: 'YYYY-MM-DD', + valueFormat: 'YYYY-MM-DD', + minWidth: 130, + }, + { + label: '经办人', + prop: 'handlerUserName', + minWidth: 120, + }, + { + label: '签订日期', + prop: 'signDate', + type: 'date', + format: 'YYYY-MM-DD', + valueFormat: 'YYYY-MM-DD', + minWidth: 130, + }, + { + label: '结算方式', + prop: 'settlementMode', + type: 'select', + dicData: settlementModeOptions, + minWidth: 120, + }, + { + label: '合同格式', + prop: 'contractFormat', + type: 'select', + dicData: [ + { label: '电子合同', value: '电子合同' }, + { label: '纸质合同', value: '纸质合同' }, + ], + minWidth: 120, + }, + { + label: '法人章', + prop: 'legalSealFlag', + type: 'switch', + dicData: [ + { label: '否', value: 0 }, + { label: '是', value: 1 }, + ], + value: 0, + minWidth: 100, + }, + { + label: '一式份数', + prop: 'copyCount', + type: 'number', + minWidth: 110, + }, + { + label: '回款账期(天)', + prop: 'paymentDays', + type: 'number', + minWidth: 130, + }, + { + label: '合同阶段', + prop: 'contractStage', + type: 'select', + search: true, + slot: true, + dicData: contractStageOptions, + minWidth: 120, + addDisplay: false, + editDisplay: false, + fixed: 'right', + }, + { + label: '审核状态', + prop: 'approvalStatus', + type: 'select', + search: true, + slot: true, + dicData: contractApprovalStatusOptions, + minWidth: 130, + addDisplay: false, + editDisplay: false, + fixed: 'right', + }, + { + label: '当前节点', + prop: 'currentNode', + minWidth: 140, + addDisplay: false, + editDisplay: false, + }, + { + label: '当前处理人', + prop: 'currentProcessor', + minWidth: 130, + addDisplay: false, + editDisplay: false, + }, + { + label: '计费信息', + prop: 'billingEnabled', + type: 'switch', + dicData: [ + { label: '关闭', value: 0 }, + { label: '开启', value: 1 }, + ], + value: 0, + minWidth: 110, + }, + { + label: '合同主文件JSON', + prop: 'contractFileJson', + type: 'textarea', + span: 24, + hide: true, + }, + { + label: '其它附件JSON', + prop: 'attachmentsJson', + type: 'textarea', + span: 24, + hide: true, + }, + { + label: '计费方案JSON', + prop: 'billingPlanJson', + type: 'textarea', + span: 24, + hide: true, + }, + { + label: '结算生成规则JSON', + prop: 'settlementRuleJson', + type: 'textarea', + span: 24, + hide: true, + }, + { + label: '对账配置JSON', + prop: 'reconciliationJson', + type: 'textarea', + span: 24, + hide: true, + }, + { + label: '备注', + prop: 'remark', + type: 'textarea', + span: 24, + hide: true, + maxlength: 2000, + showWordLimit: true, + rules: textRule('备注', 2000), + }, + ...auditColumns, +]); diff --git a/src/option/business/process-config.js b/src/option/business/process-config.js new file mode 100644 index 0000000..1a8c09a --- /dev/null +++ b/src/option/business/process-config.js @@ -0,0 +1,103 @@ +import { auditColumns, createCrudOption, nodeOptions, processStatusOptions, selectRule, textRule } from './common'; + +export const config = { + title: '过程配置', + permission: 'process_config', + exportUrl: '/blade-transport/process-config/export-process-config', + exportName: '过程配置', + enableAllDept: true, + actions: ['copy', 'enable', 'disable'], + statusProp: 'status', + statusTextProp: 'statusName', + deleteStatus: [0, 2], +}; + +export const option = createCrudOption([ + { + label: '配置编号', + prop: 'configCode', + search: true, + minWidth: 130, + addDisplay: false, + editDisabled: true, + }, + { + label: '配置名称', + prop: 'configName', + search: true, + minWidth: 150, + rules: textRule('配置名称', 100, true), + }, + { + label: '项目ID集合', + prop: 'projectIds', + hide: true, + rules: textRule('项目ID集合', 1000, true), + }, + { + label: '项目', + prop: 'projectNames', + search: true, + type: 'textarea', + minRows: 2, + minWidth: 180, + rules: textRule('项目', 1000, true), + }, + { + label: '包含过程节点', + prop: 'includedNodes', + search: true, + type: 'select', + multiple: true, + dicData: nodeOptions, + minWidth: 180, + rules: selectRule('包含过程节点'), + }, + { + label: '默认完成运输天数', + prop: 'defaultFinishDays', + type: 'number', + min: 1, + max: 999, + minWidth: 150, + }, + { + label: '状态', + prop: 'status', + type: 'select', + search: true, + dicData: processStatusOptions, + slot: true, + minWidth: 100, + addDisplay: false, + editDisplay: false, + }, + { + label: '所属组织', + prop: 'deptName', + search: true, + minWidth: 150, + addDisplay: false, + editDisplay: false, + }, + { + label: '节点配置JSON', + prop: 'nodeConfigJson', + type: 'textarea', + minRows: 6, + span: 24, + hide: true, + }, + { + label: '备注', + prop: 'remark', + type: 'textarea', + minRows: 4, + span: 24, + hide: true, + maxlength: 500, + showWordLimit: true, + rules: textRule('备注', 500), + }, + ...auditColumns, +]); diff --git a/src/option/business/project-apply.js b/src/option/business/project-apply.js new file mode 100644 index 0000000..14761b9 --- /dev/null +++ b/src/option/business/project-apply.js @@ -0,0 +1,359 @@ +import { + auditColumns, + businessTypeOptions, + createCrudOption, + effectiveTypeOptions, + nonNegativeRule, + projectApprovalStatusOptions, + projectSourceOptions, + projectTypeOptions, + selectRule, + settlementModeOptions, + textRule, + transportTypeOptions, +} from './common'; + +const amountRules = label => [ + { required: true, message: `请输入${label}`, trigger: 'blur' }, + nonNegativeRule(label), +]; + +export const config = { + title: '项目管理', + permission: 'project_apply', + exportUrl: '/blade-transport/project-apply/export-project-apply', + exportName: '项目立项', + enableAllDept: true, + statusProp: 'approvalStatus', + statusTextProp: 'approvalStatusName', + deleteStatus: ['draft', 'withdrawn', 'rejected'], + editStatus: ['draft', 'withdrawn', 'rejected', 'change_rejected'], + operations: [ + { + action: 'submitApproval', + label: '提交审批', + icon: 'el-icon-position', + statusProp: 'approvalStatus', + status: ['draft', 'withdrawn', 'rejected'], + permission: 'project_apply_submit', + }, + { + action: 'withdraw', + label: '撤回', + icon: 'el-icon-refresh-left', + statusProp: 'approvalStatus', + status: ['reviewing'], + permission: 'project_apply_withdraw', + }, + { + action: 'approve', + label: '审批通过', + type: 'success', + icon: 'el-icon-check', + statusProp: 'approvalStatus', + status: ['reviewing', 'change_reviewing'], + permission: 'project_apply_approve', + }, + { + action: 'reject', + label: '审批驳回', + type: 'warning', + icon: 'el-icon-close', + statusProp: 'approvalStatus', + status: ['reviewing', 'change_reviewing'], + permission: 'project_apply_reject', + }, + { + action: 'startChange', + label: '发起变更', + icon: 'el-icon-edit-outline', + statusProp: 'approvalStatus', + status: ['approved', 'change_approved'], + permission: 'project_apply_change', + prompt: '请输入变更内容与原因', + }, + { + action: 'voidProject', + label: '作废', + type: 'danger', + icon: 'el-icon-delete', + statusProp: 'approvalStatus', + status: ['approved', 'change_approved'], + permission: 'project_apply_void', + prompt: '请输入作废原因', + }, + ], +}; + +export const option = createCrudOption([ + { + label: '立项申请单号', + prop: 'applyNo', + search: true, + minWidth: 160, + addDisplay: false, + editDisabled: true, + }, + { + label: '项目编号', + prop: 'projectCode', + minWidth: 150, + addDisplay: false, + editDisabled: true, + }, + { + label: '项目名称', + prop: 'projectName', + search: true, + minWidth: 180, + maxlength: 50, + rules: textRule('项目名称', 50, true), + }, + { + label: '项目简称', + prop: 'projectShortName', + minWidth: 140, + maxlength: 20, + rules: textRule('项目简称', 20, true), + }, + { + label: '项目类型', + prop: 'projectType', + type: 'select', + search: true, + dicData: projectTypeOptions, + minWidth: 120, + rules: selectRule('项目类型'), + }, + { + label: '业务部门', + prop: 'businessDeptName', + minWidth: 150, + rules: textRule('业务部门', 50, true), + }, + { + label: '承办部门', + prop: 'undertakeDeptName', + search: true, + minWidth: 150, + rules: textRule('承办部门', 50, true), + }, + { + label: '承办部门ID', + prop: 'undertakeDeptId', + hide: true, + }, + { + label: '项目负责人', + prop: 'principalUserName', + search: true, + minWidth: 130, + rules: textRule('项目负责人', 50, true), + }, + { + label: '项目经办人', + prop: 'handlerUserName', + minWidth: 130, + rules: textRule('项目经办人', 50, true), + }, + { + label: '项目由来', + prop: 'projectSource', + type: 'select', + dicData: projectSourceOptions, + value: '商务洽谈', + minWidth: 120, + }, + { + label: '项目资金使用额度(万元)', + prop: 'fundLimit', + type: 'number', + precision: 2, + minWidth: 190, + rules: amountRules('项目资金使用额度'), + }, + { + label: '项目应收账款额度(万元)', + prop: 'receivableLimit', + type: 'number', + precision: 2, + minWidth: 200, + rules: amountRules('项目应收账款额度'), + }, + { + label: '应收账款回款期限(天)', + prop: 'receivableDays', + type: 'number', + minWidth: 190, + rules: [{ required: true, message: '请输入应收账款回款期限', trigger: 'blur' }], + }, + { + label: '回款账期(天)', + prop: 'paymentDays', + type: 'number', + minWidth: 140, + rules: [{ required: true, message: '请输入回款账期', trigger: 'blur' }], + }, + { + label: '客户名称', + prop: 'customerNames', + search: true, + minWidth: 180, + rules: textRule('客户名称', 255, true), + }, + { + label: '下游承运商', + prop: 'carrierNames', + minWidth: 180, + rules: textRule('下游承运商', 255, true), + }, + { + label: '货物类型', + prop: 'cargoType', + minWidth: 120, + }, + { + label: '预估货物数量', + prop: 'cargoQuantity', + minWidth: 150, + maxlength: 100, + }, + { + label: '业务周期开始', + prop: 'businessStartDate', + type: 'date', + format: 'YYYY-MM-DD', + valueFormat: 'YYYY-MM-DD', + minWidth: 130, + }, + { + label: '业务周期结束', + prop: 'businessEndDate', + type: 'date', + format: 'YYYY-MM-DD', + valueFormat: 'YYYY-MM-DD', + minWidth: 130, + }, + { + label: '运输线路', + prop: 'transportRoute', + minWidth: 180, + maxlength: 100, + }, + { + label: '运输类型', + prop: 'transportType', + type: 'select', + dicData: transportTypeOptions, + minWidth: 120, + }, + { + label: '业务类型', + prop: 'businessType', + type: 'select', + dicData: businessTypeOptions, + minWidth: 130, + }, + { + label: '项目规模(万元)', + prop: 'projectScale', + type: 'number', + precision: 2, + minWidth: 150, + rules: [nonNegativeRule('项目规模')], + }, + { + label: '预计利润(万元)', + prop: 'estimatedProfit', + type: 'number', + precision: 2, + minWidth: 150, + rules: [nonNegativeRule('预计利润')], + }, + { + label: '资金需求(万元)', + prop: 'fundDemand', + type: 'number', + precision: 2, + minWidth: 150, + rules: [nonNegativeRule('资金需求')], + }, + { + label: '结算方式', + prop: 'settlementMode', + type: 'select', + dicData: settlementModeOptions, + minWidth: 120, + }, + { + label: '审批状态', + prop: 'approvalStatus', + type: 'select', + search: true, + slot: true, + dicData: projectApprovalStatusOptions, + minWidth: 130, + addDisplay: false, + editDisplay: false, + fixed: 'right', + }, + { + label: '当前节点', + prop: 'currentNode', + minWidth: 140, + addDisplay: false, + editDisplay: false, + }, + { + label: '当前处理人', + prop: 'currentProcessor', + minWidth: 130, + addDisplay: false, + editDisplay: false, + }, + { + label: '生效类型', + prop: 'effectiveType', + type: 'select', + search: true, + dicData: effectiveTypeOptions, + value: 'temporary', + minWidth: 110, + }, + { + label: '审核通过时间', + prop: 'approvedTime', + type: 'datetime', + format: 'YYYY-MM-DD HH:mm:ss', + valueFormat: 'YYYY-MM-DD HH:mm:ss', + minWidth: 170, + addDisplay: false, + editDisplay: false, + }, + { + label: '项目由来说明', + prop: 'sourceRemark', + type: 'textarea', + span: 24, + hide: true, + maxlength: 300, + showWordLimit: true, + }, + { + label: '项目情况说明', + prop: 'situationRemark', + type: 'textarea', + span: 24, + hide: true, + maxlength: 1000, + showWordLimit: true, + }, + { + label: '项目附件JSON', + prop: 'attachmentsJson', + type: 'textarea', + span: 24, + hide: true, + }, + ...auditColumns, +]); diff --git a/src/option/business/shipping-template.js b/src/option/business/shipping-template.js new file mode 100644 index 0000000..60e812f --- /dev/null +++ b/src/option/business/shipping-template.js @@ -0,0 +1,167 @@ +import { + auditColumns, + createCrudOption, + templateTypeOptions, + transportTypeOptions, + selectRule, + textRule, +} from './common'; + +export const config = { + title: '发货模板', + permission: 'shipping_template', + exportUrl: '/blade-transport/shipping-template/export-shipping-template', + exportName: '发货模板', + enableAllDept: true, + actions: ['copy'], +}; + +export const option = createCrudOption([ + { + label: '模板编号', + prop: 'templateCode', + search: true, + minWidth: 150, + addDisplay: false, + editDisabled: true, + }, + { + label: '模板名称', + prop: 'templateName', + search: true, + minWidth: 150, + rules: textRule('模板名称', 50, true), + }, + { + label: '模板类型', + prop: 'templateType', + type: 'select', + search: true, + dicData: templateTypeOptions, + minWidth: 120, + value: '运输计划', + rules: selectRule('模板类型'), + }, + { + 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: 'transportType', + type: 'select', + dicData: transportTypeOptions, + minWidth: 130, + rules: selectRule('运输类型'), + }, + { + label: '发货地', + prop: 'departureName', + minWidth: 140, + rules: textRule('发货地', 100, true), + }, + { + label: '发货地址', + prop: 'departureAddress', + minWidth: 220, + rules: textRule('发货地址', 255, true), + }, + { + label: '发货联系人', + prop: 'departureContact', + minWidth: 120, + rules: textRule('发货联系人', 20), + }, + { + label: '发货联系方式', + prop: 'departurePhone', + minWidth: 140, + rules: textRule('发货联系方式', 20), + }, + { + label: '收货地', + prop: 'arrivalName', + minWidth: 140, + rules: textRule('收货地', 100, true), + }, + { + label: '收货地址', + prop: 'arrivalAddress', + minWidth: 220, + rules: textRule('收货地址', 255, true), + }, + { + label: '收货联系人', + prop: 'arrivalContact', + minWidth: 120, + rules: textRule('收货联系人', 20), + }, + { + label: '收货联系方式', + prop: 'arrivalPhone', + minWidth: 140, + rules: textRule('收货联系方式', 20), + }, + { + label: '货物信息JSON', + prop: 'goodsJson', + type: 'textarea', + minRows: 5, + 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: 200, + showWordLimit: true, + rules: textRule('备注', 200), + }, + ...auditColumns, +]); diff --git a/src/option/business/temporary-credit-limit.js b/src/option/business/temporary-credit-limit.js new file mode 100644 index 0000000..ed9ab50 --- /dev/null +++ b/src/option/business/temporary-credit-limit.js @@ -0,0 +1,191 @@ +import { approvalStatusOptions, auditColumns, createCrudOption, nonNegativeRule, textRule } from './common'; + +export const config = { + title: '临时额度管理', + permission: 'temporary_credit_limit', + exportUrl: '/blade-transport/temporary-credit-limit/export-temporary-credit-limit', + exportName: '临时额度申请', + enableAllDept: true, + statusProp: 'approvalStatus', + statusTextProp: 'approvalStatusName', + deleteStatus: ['draft', 'withdrawn', 'rejected'], + editStatus: ['draft', 'withdrawn', 'rejected'], + operations: [ + { + action: 'submitApproval', + label: '提交审批', + statusProp: 'approvalStatus', + status: ['draft', 'withdrawn', 'rejected'], + permission: 'temporary_credit_limit_submit', + }, + { + action: 'withdraw', + label: '撤回', + icon: 'el-icon-refresh-left', + statusProp: 'approvalStatus', + status: ['reviewing'], + permission: 'temporary_credit_limit_withdraw', + }, + { + action: 'approve', + label: '审批通过', + type: 'success', + icon: 'el-icon-check', + statusProp: 'approvalStatus', + status: ['reviewing'], + permission: 'temporary_credit_limit_approve', + }, + { + action: 'reject', + label: '审批驳回', + type: 'warning', + icon: 'el-icon-close', + statusProp: 'approvalStatus', + status: ['reviewing'], + permission: 'temporary_credit_limit_reject', + }, + ], +}; + +export const option = createCrudOption([ + { + label: '申请单号', + prop: 'applicationNo', + search: true, + minWidth: 160, + addDisplay: false, + editDisabled: true, + }, + { + label: '项目名称', + prop: 'projectName', + search: true, + minWidth: 180, + rules: textRule('项目名称', 100, true), + }, + { + label: '项目ID', + prop: 'projectId', + hide: true, + }, + { + label: '项目编号', + prop: 'projectCode', + minWidth: 150, + rules: textRule('项目编号', 50, true), + }, + { + label: '承办部门', + prop: 'undertakeDeptName', + minWidth: 150, + rules: textRule('承办部门', 50, true), + }, + { + label: '项目资金使用额度(万元)', + prop: 'projectFundLimit', + type: 'number', + precision: 2, + minWidth: 200, + editDisabled: true, + rules: [nonNegativeRule('项目资金使用额度')], + }, + { + label: '已使用项目资金额度(万元)', + prop: 'usedFundLimit', + type: 'number', + precision: 2, + minWidth: 220, + value: 0, + editDisabled: true, + rules: [nonNegativeRule('已使用项目资金额度')], + }, + { + label: '剩余项目资金使用额度(万元)', + prop: 'remainingFundLimit', + type: 'number', + precision: 2, + minWidth: 230, + editDisabled: true, + rules: [nonNegativeRule('剩余项目资金使用额度')], + }, + { + label: '申请临时额度(万元)', + prop: 'applyLimit', + type: 'number', + precision: 2, + minWidth: 180, + rules: [ + { required: true, message: '请输入申请临时额度', trigger: 'blur' }, + nonNegativeRule('申请临时额度'), + ], + }, + { + label: '申请有效期至', + prop: 'validUntil', + type: 'date', + format: 'YYYY-MM-DD', + valueFormat: 'YYYY-MM-DD', + minWidth: 140, + rules: [{ required: true, message: '请选择申请有效期至', trigger: 'change' }], + }, + { + label: '申请部门', + prop: 'applyDeptName', + search: true, + minWidth: 150, + addDisplay: false, + editDisabled: true, + }, + { + label: '申请人', + prop: 'applicantName', + search: true, + minWidth: 120, + addDisplay: false, + editDisabled: true, + }, + { + label: '审批状态', + prop: 'approvalStatus', + type: 'select', + search: true, + slot: true, + dicData: approvalStatusOptions, + minWidth: 130, + addDisplay: false, + editDisplay: false, + fixed: 'right', + }, + { + label: '当前节点', + prop: 'currentNode', + minWidth: 140, + addDisplay: false, + editDisplay: false, + }, + { + label: '当前处理人', + prop: 'currentProcessor', + minWidth: 130, + addDisplay: false, + editDisplay: false, + }, + { + label: '附件JSON', + prop: 'attachmentsJson', + type: 'textarea', + span: 24, + hide: true, + }, + { + label: '备注', + prop: 'remark', + type: 'textarea', + span: 24, + hide: true, + maxlength: 500, + showWordLimit: true, + rules: textRule('备注', 500), + }, + ...auditColumns, +]); diff --git a/src/option/business/transport-plan.js b/src/option/business/transport-plan.js new file mode 100644 index 0000000..7aa20d1 --- /dev/null +++ b/src/option/business/transport-plan.js @@ -0,0 +1,175 @@ +import { + auditColumns, + createCrudOption, + dataSourceOptions, + planStatusOptions, + selectRule, + textRule, + transportTypeOptions, +} from './common'; + +export const config = { + title: '运输计划', + permission: 'transport_plan', + exportUrl: '/blade-transport/transport-plan/export-transport-plan', + exportName: '运输计划', + enableAllDept: true, + actions: ['copy', 'cancel', 'complete'], + statusProp: 'businessStatus', + statusTextProp: 'businessStatusName', + deleteStatus: ['draft'], + editStatus: ['draft', 'waiting_dispatch'], +}; + +export const option = createCrudOption([ + { + label: '计划单号', + prop: 'planNo', + search: true, + minWidth: 150, + addDisplay: false, + editDisabled: true, + }, + { + label: '计划名称', + prop: 'planName', + search: true, + minWidth: 150, + rules: textRule('计划名称', 50, true), + }, + { + label: '项目', + prop: 'projectName', + 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: 'planStartDate', + type: 'date', + format: 'YYYY-MM-DD', + valueFormat: 'YYYY-MM-DD', + search: true, + minWidth: 130, + }, + { + label: '计划结束日期', + prop: 'planEndDate', + type: 'date', + format: 'YYYY-MM-DD', + valueFormat: 'YYYY-MM-DD', + search: true, + minWidth: 130, + }, + { + label: '发货地', + prop: 'departureName', + minWidth: 140, + rules: textRule('发货地', 100, true), + }, + { + label: '发货地址', + prop: 'departureAddress', + search: true, + minWidth: 220, + rules: textRule('发货地址', 255, true), + }, + { + label: '收货地', + prop: 'arrivalName', + minWidth: 140, + rules: textRule('收货地', 100, true), + }, + { + label: '收货地址', + prop: 'arrivalAddress', + search: true, + minWidth: 220, + rules: textRule('收货地址', 255, true), + }, + { + label: '货物信息JSON', + prop: 'goodsJson', + type: 'textarea', + minRows: 5, + span: 24, + hide: true, + }, + { + label: '附件JSON', + prop: 'attachmentsJson', + type: 'textarea', + minRows: 3, + span: 24, + hide: true, + }, + { + label: '数据来源', + prop: 'dataSource', + type: 'select', + search: true, + dicData: dataSourceOptions, + minWidth: 120, + }, + { + label: '业务状态', + prop: 'businessStatus', + type: 'select', + slot: true, + search: true, + dicData: planStatusOptions, + minWidth: 120, + addDisplay: false, + editDisplay: false, + }, + { + label: '所属组织', + prop: 'deptName', + minWidth: 150, + addDisplay: false, + editDisplay: false, + }, + { + label: '备注', + prop: 'remark', + type: 'textarea', + minRows: 4, + span: 24, + hide: true, + maxlength: 200, + showWordLimit: true, + rules: textRule('备注', 200), + }, + ...auditColumns, +]); diff --git a/src/option/business/waybill-manage.js b/src/option/business/waybill-manage.js new file mode 100644 index 0000000..7492149 --- /dev/null +++ b/src/option/business/waybill-manage.js @@ -0,0 +1,254 @@ +import { + auditColumns, + createCrudOption, + dataSourceOptions, + selectRule, + textRule, + transportTypeOptions, + waybillStatusOptions, +} from './common'; + +export const config = { + title: '运单管理', + permission: 'waybill_manage', + exportUrl: '/blade-transport/waybill-manage/export-waybill-manage', + exportName: '运单管理', + enableAllDept: true, + actions: ['copy', 'cancel', 'reassign', 'complete', 'batchComplete'], + statusProp: 'businessStatus', + statusTextProp: 'businessStatusName', + deleteStatus: ['draft'], + 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, +]); diff --git a/src/views/business/common-cargo.vue b/src/views/business/common-cargo.vue new file mode 100644 index 0000000..1519a96 --- /dev/null +++ b/src/views/business/common-cargo.vue @@ -0,0 +1,21 @@ + + + diff --git a/src/views/business/common-route.vue b/src/views/business/common-route.vue new file mode 100644 index 0000000..061ef72 --- /dev/null +++ b/src/views/business/common-route.vue @@ -0,0 +1,20 @@ + + + diff --git a/src/views/business/components/business-crud-page.vue b/src/views/business/components/business-crud-page.vue new file mode 100644 index 0000000..c401be5 --- /dev/null +++ b/src/views/business/components/business-crud-page.vue @@ -0,0 +1,673 @@ + + + + + diff --git a/src/views/business/contract-manage.vue b/src/views/business/contract-manage.vue new file mode 100644 index 0000000..738218c --- /dev/null +++ b/src/views/business/contract-manage.vue @@ -0,0 +1,20 @@ + + + diff --git a/src/views/business/process-config.vue b/src/views/business/process-config.vue new file mode 100644 index 0000000..0387f80 --- /dev/null +++ b/src/views/business/process-config.vue @@ -0,0 +1,20 @@ + + + diff --git a/src/views/business/project-apply.vue b/src/views/business/project-apply.vue new file mode 100644 index 0000000..55d2064 --- /dev/null +++ b/src/views/business/project-apply.vue @@ -0,0 +1,20 @@ + + + diff --git a/src/views/business/shipping-template.vue b/src/views/business/shipping-template.vue new file mode 100644 index 0000000..16442af --- /dev/null +++ b/src/views/business/shipping-template.vue @@ -0,0 +1,20 @@ + + + diff --git a/src/views/business/temporary-credit-limit.vue b/src/views/business/temporary-credit-limit.vue new file mode 100644 index 0000000..9242e5d --- /dev/null +++ b/src/views/business/temporary-credit-limit.vue @@ -0,0 +1,20 @@ + + + diff --git a/src/views/business/transport-plan.vue b/src/views/business/transport-plan.vue new file mode 100644 index 0000000..45fb67d --- /dev/null +++ b/src/views/business/transport-plan.vue @@ -0,0 +1,20 @@ + + + diff --git a/src/views/business/waybill-manage.vue b/src/views/business/waybill-manage.vue new file mode 100644 index 0000000..a9f7796 --- /dev/null +++ b/src/views/business/waybill-manage.vue @@ -0,0 +1,20 @@ + + + diff --git a/需求卡/临时额度管理需求卡.md b/需求卡/临时额度管理需求卡.md new file mode 100644 index 0000000..def7ec6 --- /dev/null +++ b/需求卡/临时额度管理需求卡.md @@ -0,0 +1,468 @@ +# 临时额度管理需求卡 + +## 目录 + +- [REQ-TEMPLIM-001 菜单入口](#req-templim-001-菜单入口) +- [REQ-TEMPLIM-002 列表与分页](#req-templim-002-列表与分页) +- [REQ-TEMPLIM-003 条件查询与重置](#req-templim-003-条件查询与重置) +- [REQ-TEMPLIM-004 列表状态与操作](#req-templim-004-列表状态与操作) +- [REQ-TEMPLIM-005 新增临时额度申请](#req-templim-005-新增临时额度申请) +- [REQ-TEMPLIM-006 项目选择与自动回填](#req-templim-006-项目选择与自动回填) +- [REQ-TEMPLIM-007 额度字段规则](#req-templim-007-额度字段规则) +- [REQ-TEMPLIM-008 有效期与备注规则](#req-templim-008-有效期与备注规则) +- [REQ-TEMPLIM-009 附件上传](#req-templim-009-附件上传) +- [REQ-TEMPLIM-010 保存草稿](#req-templim-010-保存草稿) +- [REQ-TEMPLIM-011 编辑临时额度申请](#req-templim-011-编辑临时额度申请) +- [REQ-TEMPLIM-012 提交审批](#req-templim-012-提交审批) +- [REQ-TEMPLIM-013 撤回审批](#req-templim-013-撤回审批) +- [REQ-TEMPLIM-014 审批通过](#req-templim-014-审批通过) +- [REQ-TEMPLIM-015 审批驳回](#req-templim-015-审批驳回) +- [REQ-TEMPLIM-016 临时额度生效与失效](#req-templim-016-临时额度生效与失效) +- [REQ-TEMPLIM-017 查看与流程](#req-templim-017-查看与流程) +- [REQ-TEMPLIM-018 删除草稿单据](#req-templim-018-删除草稿单据) +- [REQ-TEMPLIM-019 导出列表](#req-templim-019-导出列表) +- [REQ-TEMPLIM-020 权限与审计](#req-templim-020-权限与审计) +- [通用规则](#通用规则) + +--- + +### REQ-TEMPLIM-001 菜单入口 + +- 功能点: + - 临时额度管理模块归属于“项目管理”主菜单。 + - 在“项目管理”菜单下提供“临时额度管理”入口。 + - 用户进入临时额度管理页面后,可进行查询、新增、编辑、提交、查看、流程查看、撤回、删除、导出等操作。 + +- 异常与边界: + - 无菜单权限时不展示“临时额度管理”入口。 + - 有菜单权限但无按钮权限时,仅展示允许访问的页面和操作。 + - 菜单或页面加载失败时提示失败原因,不影响其他模块访问。 + +- 反例: + - 不允许把临时额度管理挂到非项目管理主菜单下。 + - 不允许无权限用户通过 URL 直接进入模块。 + - 不允许菜单入口存在但页面无法访问。 + +--- + +### REQ-TEMPLIM-002 列表与分页 + +- 功能点: + - 默认展示当前用户权限范围内的临时额度申请单。 + - 列表展示序号、申请单号、项目名称、申请额度、有效截至时间、申请部门、申请人、审批状态、当前节点、当前处理人、操作等字段。 + - 申请额度单位为万元,保留2位小数。 + - 有效截至时间展示到日期,格式为 yyyy-MM-dd。 + - 审批状态和操作列固定在右侧,不随横向滚动条滑动。 + - 默认按创建时间或申请时间降序展示。 + - 支持分页展示,默认10条/页,支持20/50/100条/页。 + +- 异常与边界: + - 查询无数据时展示空状态。 + - 当前页数据因保存、提交、撤回、审批、删除等操作发生变化后,应刷新列表并保持分页逻辑正确。 + - 列表加载失败时保留当前查询条件和分页条件,提示用户重新查询。 + +- 反例: + - 不允许审批状态或操作列被横向滚动隐藏。 + - 不允许列表展示申请人、当前处理人的用户 ID。 + - 不允许分页切换后丢失当前查询条件。 + +--- + +### REQ-TEMPLIM-003 条件查询与重置 + +- 功能点: + - 支持按申请单号、项目名称、申请人、申请部门、状态等条件组合查询。 + - 申请单号和项目名称使用输入框,支持模糊查询。 + - 申请人使用下拉选择或搜索选择控件,默认全部。 + - 申请部门使用下拉选择或部门选择控件,默认全部。 + - 状态使用下拉单选控件,默认全部。 + - 点击查询后按当前条件刷新列表。 + - 点击重置后清空查询条件,恢复默认列表。 + +- 异常与边界: + - 查询条件为空时点击查询,按默认规则展示全部权限范围内数据。 + - 查询结果为空时展示空状态,不清空用户已输入条件。 + - 重置后页码恢复第一页,并重新加载列表。 + +- 反例: + - 不允许重置后仍保留隐藏查询条件。 + - 不允许只按单个条件查询而忽略其他已选择条件。 + - 不允许查询后改变列表字段或操作范围。 + +--- + +### REQ-TEMPLIM-004 列表状态与操作 + +- 功能点: + - 审批状态包含草稿、审批中、已撤回、审批通过、审核不通过等状态。 + - 草稿状态展示编辑、提交、删除操作。 + - 审批中状态展示查看、流程操作。 + - 已撤回状态展示编辑、流程操作。 + - 审核不通过状态展示编辑、流程操作。 + - 审批通过状态展示查看、流程操作。 + - 操作按钮展示受单据状态和用户权限共同控制。 + +- 异常与边界: + - 操作执行前需重新校验单据最新状态,避免列表状态过期导致误操作。 + - 状态为空或未知时限制编辑、提交、删除等高风险操作。 + - 状态变更成功后刷新列表,展示最新状态和可执行操作。 + +- 反例: + - 不允许审批中单据继续编辑或删除。 + - 不允许审批通过单据再次提交审批。 + - 不允许仅根据前端状态跳过后端状态校验。 + +--- + +### REQ-TEMPLIM-005 新增临时额度申请 + +- 功能点: + - 点击列表顶部“新增”按钮后打开新增申请弹窗。 + - 新增弹窗展示临时额度申请信息和附件上传区域。 + - 新增字段包含项目名称、项目编号、承办部门、项目资金使用额度、已使用项目资金额度、剩余项目资金使用额度、申请临时额度、申请有效期至、备注等。 + - 项目名称、申请临时额度、申请有效期至为必填字段,并展示“*”标识。 + - 新增弹窗底部展示保存、提交、取消按钮。 + - 申请单号由系统保存后自动生成,全局唯一,只读不可编辑。 + +- 异常与边界: + - 新增弹窗打开失败时提示失败原因,不改变列表数据。 + - 必填字段为空时阻止提交审批并提示。 + - 保存或提交过程中重复点击按钮时应防止重复生成申请单。 + +- 反例: + - 不允许用户手工填写申请单号。 + - 不允许未选择项目直接提交临时额度申请。 + - 不允许缺少申请临时额度或有效期后提交审批。 + +--- + +### REQ-TEMPLIM-006 项目选择与自动回填 + +- 功能点: + - 项目名称使用弹窗搜索选择框,从项目管理中选择项目。 + - 可选项目范围为已审批通过且生效类型为正式的立项项目。 + - 选择项目后,系统自动带出项目编号、承办部门、项目资金使用额度、已使用项目资金额度、剩余项目资金使用额度。 + - 项目编号、承办部门、项目资金使用额度、已使用项目资金额度、剩余项目资金使用额度为只读字段,不允许手工修改。 + - 承办部门用于数据权限过滤和审批流程匹配。 + +- 异常与边界: + - 项目未审批通过、生效类型非正式或已作废时,不允许选择。 + - 项目额度信息加载失败时,阻止提交并提示重新选择项目。 + - 重新选择项目后,应清空并重新回填项目相关只读字段。 + +- 反例: + - 不允许手工输入项目名称代替项目管理选择。 + - 不允许选择草稿、临时生效或已作废项目。 + - 不允许修改自动回填的项目编号和额度字段。 + +--- + +### REQ-TEMPLIM-007 额度字段规则 + +- 功能点: + - 项目资金使用额度为只读数字字段,单位万元,来源于项目立项原始审批总资金额度。 + - 已使用项目资金额度为只读数字字段,单位万元,来源于系统实时计算的业务单据占用额度。 + - 剩余项目资金使用额度为只读数字字段,单位万元,由项目资金使用额度减去已使用额度自动计算回填。 + - 申请临时额度为必填数字字段,单位万元,表示本次申请追加的临时资金额度。 + - 申请临时额度必须大于0,并保留2位小数。 + +- 异常与边界: + - 申请临时额度为空、小于等于0或小数位超过2位时阻止提交并提示。 + - 项目资金使用额度、已使用额度、剩余额度出现负数或无法计算时,应提示数据异常并阻止提交。 + - 已使用额度需实时计算业务单据占用,不能仅取静态项目档案值。 + +- 反例: + - 不允许申请临时额度填写0、负数或非数字。 + - 不允许用户手动修改剩余项目资金使用额度。 + - 不允许额度数据异常时仍提交审批。 + +--- + +### REQ-TEMPLIM-008 有效期与备注规则 + +- 功能点: + - 申请有效期至为必填日期字段,用于表示临时额度失效截止日期。 + - 申请有效期至格式为 yyyy-MM-dd。 + - 申请有效期至必须晚于当前系统日期。 + - 备注使用大文本域,用于填写临时额度申请原因和业务补充说明。 + - 备注非必填,最多500字。 + +- 异常与边界: + - 申请有效期至为空时阻止提交并提示。 + - 申请有效期至早于或等于当前系统日期时阻止提交并提示。 + - 备注超过500字时阻止保存或提交并提示。 + +- 反例: + - 不允许选择今天或历史日期作为有效期截止日期。 + - 不允许备注超过500字后提交。 + - 不允许无有效期的临时额度审批通过。 + +--- + +### REQ-TEMPLIM-009 附件上传 + +- 功能点: + - 新增和编辑弹窗支持上传附件。 + - 附件列表展示序号、文件名、附件描述、文件大小、上传人、上传时间、操作等字段。 + - 附件上传成功后自动新增附件行,并展示完整文件信息。 + - 上传后需填写附件描述。 + - 支持删除未提交或允许编辑状态下的附件。 + - 支持批量下载已上传附件。 + - 单个附件大小限制50M。 + +- 异常与边界: + - 单个文件超过50M时阻止上传并提示。 + - 上传失败时保留当前附件列表,并提示失败原因。 + - 提交审批时如业务要求附件必传,应校验附件已上传且描述完整。 + - 删除附件前需二次确认,确认后同步删除附件记录和服务器文件。 + +- 反例: + - 不允许上传超过50M的附件。 + - 不允许上传成功后附件列表不展示文件信息。 + - 不允许只删除前端附件行而保留有效服务器引用。 + +--- + +### REQ-TEMPLIM-010 保存草稿 + +- 功能点: + - 新增或编辑弹窗底部支持点击保存。 + - 保存用于临时保存当前填写内容,单据状态标记为草稿,不触发审批流程。 + - 保存草稿无需完整填写全部必填项。 + - 保存成功后弹出成功提示,关闭弹窗后列表可重新编辑该草稿单据。 + +- 异常与边界: + - 保存草稿时至少需满足可生成单据的基本数据要求。 + - 保存失败时保留用户已填写内容,方便修正后重新保存。 + - 草稿已被删除或状态已变化时,不允许继续保存。 + +- 反例: + - 不允许保存草稿触发审批流程。 + - 不允许保存失败后清空用户已填写内容。 + - 不允许同一点击重复生成多条草稿。 + +--- + +### REQ-TEMPLIM-011 编辑临时额度申请 + +- 功能点: + - 草稿、审核不通过状态的临时额度申请单支持编辑。 + - 点击编辑后弹窗回显该单据全部历史填写内容。 + - 编辑时可修改项目名称、申请临时额度、申请有效期至、备注和附件等可编辑字段。 + - 项目相关只读字段仍由项目选择自动带出,不允许手工修改。 + - 编辑保存后单据保持草稿或原可编辑状态,提交后进入审批中。 + +- 异常与边界: + - 编辑前需校验当前单据状态仍允许编辑。 + - 编辑的数据已不存在时提示数据不存在,并刷新列表。 + - 修改项目后需重新回填额度信息,并重新校验申请临时额度。 + - 保存或提交失败时保留用户修改内容。 + +- 反例: + - 不允许审批中或审批通过单据继续编辑。 + - 不允许编辑时修改申请单号。 + - 不允许编辑后绕过项目选择和额度校验。 + +--- + +### REQ-TEMPLIM-012 提交审批 + +- 功能点: + - 草稿、已撤回、审核不通过状态的单据支持提交审批。 + - 提交审批前校验项目名称、申请临时额度、申请有效期至等必填字段。 + - 提交审批前校验有效期日期、额度格式和附件要求。 + - 提交成功后单据审批状态更新为审批中。 + - 提交成功后推送审批待办消息给当前审批人。 + +- 异常与边界: + - 必填字段缺失、日期不合法、额度不合法或附件不满足要求时阻止提交。 + - 审批流程发起失败时保持原状态,并保留用户输入内容。 + - 重复点击提交时应防止重复发起审批。 + +- 反例: + - 不允许资料不完整的申请单进入审批中。 + - 不允许提交失败后仍把状态改为审批中。 + - 不允许同一申请单重复发起多个审批流程。 + +--- + +### REQ-TEMPLIM-013 撤回审批 + +- 功能点: + - 申请人可对审批中单据执行撤回。 + - 撤回后单据退回草稿状态。 + - 撤回后清空审批流程待办节点。 + - 撤回成功后刷新列表,并展示最新单据状态。 + +- 异常与边界: + - 非申请人不允许撤回审批单据。 + - 单据已审批通过或已驳回时不允许撤回。 + - 撤回失败时保持原审批状态,并提示失败原因。 + +- 反例: + - 不允许审批通过后继续撤回。 + - 不允许非申请人撤回他人申请单。 + - 不允许撤回后审批待办仍停留在审批人列表。 + +--- + +### REQ-TEMPLIM-014 审批通过 + +- 功能点: + - 当前审批节点处理人可对审批中单据执行审批通过。 + - 审批通过后单据状态更新为审批通过。 + - 审批通过后临时额度立即生效,系统更新项目可用资金上限。 + - 审批通过后系统设置自动到期失效任务。 + - 审批通过成功后页面弹出成功提示,并刷新列表。 + +- 异常与边界: + - 非当前审批节点处理人不允许审批通过。 + - 审批通过时如项目已作废或非正式生效,应阻止通过并提示。 + - 更新项目可用资金上限失败时,应保证审批状态和额度生效状态一致。 + - 自动到期任务设置失败时需提示并保留可补偿处理记录。 + +- 反例: + - 不允许未审批通过的临时额度生效。 + - 不允许项目已作废时仍让临时额度生效。 + - 不允许审批状态成功但项目可用额度未同步且无补偿记录。 + +--- + +### REQ-TEMPLIM-015 审批驳回 + +- 功能点: + - 当前审批节点处理人可对审批中单据执行审批驳回。 + - 驳回后单据状态更新为审核不通过。 + - 驳回后将驳回意见反馈给申请人。 + - 审核不通过单据允许编辑后重新提交审批。 + +- 异常与边界: + - 非当前审批节点处理人不允许审批驳回。 + - 驳回失败时保持原审批状态,并提示失败原因。 + - 重新提交审批时需按最新内容重新校验字段和附件。 + +- 反例: + - 不允许驳回时丢失驳回意见。 + - 不允许审核不通过单据直接生效。 + - 不允许非审批处理人执行驳回。 + +--- + +### REQ-TEMPLIM-016 临时额度生效与失效 + +- 功能点: + - 审批通过后,申请临时额度叠加到项目可用资金上限。 + - 临时额度有效期截止日前,项目资金占用计算需包含有效临时额度。 + - 到达申请有效期至后,系统自动将该临时额度标记为失效。 + - 临时额度失效后,项目可用资金上限需扣减该笔临时额度。 + - 已失效临时额度不影响历史已产生业务单据。 + +- 异常与边界: + - 到期任务执行失败时,应支持后台补偿处理,避免额度长期错误生效。 + - 多笔临时额度同时生效时,应分别按有效期计算,不得互相覆盖。 + - 失效扣减后项目已使用额度超过新可用额度时,应保留历史占用并在后续额度校验中提示超额风险。 + +- 反例: + - 不允许临时额度过期后仍参与新业务额度校验。 + - 不允许多笔临时额度只保留最后一笔。 + - 不允许失效额度影响历史已完成业务数据。 + +--- + +### REQ-TEMPLIM-017 查看与流程 + +- 功能点: + - 支持通过列表行操作查看临时额度申请详情。 + - 查看详情时展示申请基础信息、项目额度信息、附件和审批信息。 + - 查看状态下所有字段只读。 + - 支持点击流程查看审批流程节点、处理人、处理时间和审批意见。 + +- 异常与边界: + - 数据已删除或无权限查看时提示无法查看。 + - 附件加载失败时不影响基础信息展示。 + - 流程信息加载失败时提示失败原因,不改变单据状态。 + +- 反例: + - 不允许在查看状态下保存修改。 + - 不允许查看流程时展示其他申请单的审批记录。 + - 不允许流程节点信息缺失却展示审批已完整流转。 + +--- + +### REQ-TEMPLIM-018 删除草稿单据 + +- 功能点: + - 草稿状态的临时额度申请单支持删除。 + - 点击删除后弹出二次确认弹窗。 + - 删除前校验该临时额度未审批通过、未生效且无业务单据占用。 + - 删除成功后刷新列表。 + +- 异常与边界: + - 非草稿状态不允许删除。 + - 存在业务占用临时额度时不允许删除,并提示无法删除。 + - 删除时状态已变化为审批中或审批通过时,应阻止删除并刷新列表。 + +- 反例: + - 不允许删除审批中或审批通过单据。 + - 不允许存在业务占用时删除临时额度申请。 + - 不允许跳过二次确认直接删除。 + +--- + +### REQ-TEMPLIM-019 导出列表 + +- 功能点: + - 列表顶部支持导出临时额度申请列表。 + - 点击导出后,导出当前筛选条件下所有申请单基础信息和附件清单至 Excel 文件。 + - 导出字段与列表和详情展示字段保持一致。 + - 数据量较大时页面展示加载或导出中提示。 + +- 异常与边界: + - 当前查询条件下无数据时允许导出空文件或提示无可导出数据。 + - 导出失败时提示失败原因,不改变当前列表状态。 + - 无导出权限时不展示导出按钮。 + +- 反例: + - 不允许无权限用户导出临时额度数据。 + - 不允许导出时忽略当前查询条件。 + - 不允许导出文件展示用户 ID 代替姓名。 + +--- + +### REQ-TEMPLIM-020 权限与审计 + +- 功能点: + - 根据用户权限控制查询、新增、编辑、提交、撤回、审批、查看、流程、删除、导出、附件上传和附件下载等操作入口。 + - 列表、详情、导出、审批流中用户可见字段优先展示姓名,不直接展示用户 ID。 + - 新增、编辑、保存、提交、撤回、审批通过、审批驳回、删除、额度生效、额度失效、导出等关键操作需记录操作日志。 + - 审计信息应包含操作人、操作时间、操作类型、申请单号、项目编号和关键额度变化。 + +- 异常与边界: + - 无按钮权限时不展示对应按钮,通过 URL 或接口绕过时也应拒绝。 + - 操作日志记录失败时不得影响用户已成功的业务操作,但需保留可排查信息。 + - 数据权限限制下,用户只能查看和操作授权范围内项目相关临时额度申请。 + +- 反例: + - 不允许无权限用户审批、删除或导出临时额度申请。 + - 不允许列表展示申请人、审批人等用户 ID。 + - 不允许额度生效或失效没有审计记录。 + +--- + +## 通用规则 + +- 临时额度管理用于对正式项目申请临时增加项目资金可用额度,归属于“项目管理”主菜单。 +- 项目名称必须从项目管理中选择,且仅允许选择审批通过、生效类型为正式、未作废的项目。 +- 选择项目后自动带出项目编号、承办部门、项目资金使用额度、已使用项目资金额度、剩余项目资金使用额度,自动带出字段只读不可编辑。 +- 申请单号由系统自动生成,全局唯一,只读不可编辑。 +- 申请临时额度必须大于0,单位万元,保留2位小数。 +- 申请有效期至必须晚于当前系统日期,格式为 yyyy-MM-dd。 +- 备注最多500字。 +- 单个附件大小限制50M,上传后需填写附件描述。 +- 草稿状态不触发审批流程,审批通过前临时额度不得生效。 +- 审批通过后临时额度立即生效,系统更新项目可用资金上限,并设置自动到期失效任务。 +- 临时额度到期失效后,应从项目可用资金上限中扣减,不影响历史已产生业务单据。 +- 草稿状态支持编辑、提交、删除;审批中仅支持查看和流程;审核不通过和已撤回支持编辑后重新提交;审批通过仅支持查看和流程。 +- 删除前需校验单据未生效且无业务单据占用临时额度。 +- 列表、详情、导出、审批等用户可见场景优先展示姓名字段,不直接展示用户 ID。 +- 新增、编辑、保存、提交、撤回、审批、删除、导出、额度生效、额度失效后均需刷新相关列表或详情状态。 diff --git a/需求卡/发货模板需求卡.md b/需求卡/发货模板需求卡.md new file mode 100644 index 0000000..bfdafb8 --- /dev/null +++ b/需求卡/发货模板需求卡.md @@ -0,0 +1,514 @@ +# 发货模板需求卡 + +## 目录 + +- [REQ-SHIPTPL-001 菜单入口](#req-shiptpl-001-菜单入口) +- [REQ-SHIPTPL-002 列表与分页](#req-shiptpl-002-列表与分页) +- [REQ-SHIPTPL-003 条件查询与重置](#req-shiptpl-003-条件查询与重置) +- [REQ-SHIPTPL-004 查看发货模板](#req-shiptpl-004-查看发货模板) +- [REQ-SHIPTPL-005 新增发货模板](#req-shiptpl-005-新增发货模板) +- [REQ-SHIPTPL-006 编辑发货模板](#req-shiptpl-006-编辑发货模板) +- [REQ-SHIPTPL-007 模板信息规则](#req-shiptpl-007-模板信息规则) +- [REQ-SHIPTPL-008 基本信息规则](#req-shiptpl-008-基本信息规则) +- [REQ-SHIPTPL-009 收发货信息规则](#req-shiptpl-009-收发货信息规则) +- [REQ-SHIPTPL-010 货物信息规则](#req-shiptpl-010-货物信息规则) +- [REQ-SHIPTPL-011 附件规则](#req-shiptpl-011-附件规则) +- [REQ-SHIPTPL-012 选择常用地址](#req-shiptpl-012-选择常用地址) +- [REQ-SHIPTPL-013 选择常用线路](#req-shiptpl-013-选择常用线路) +- [REQ-SHIPTPL-014 选择常用货物](#req-shiptpl-014-选择常用货物) +- [REQ-SHIPTPL-015 从模板新建](#req-shiptpl-015-从模板新建) +- [REQ-SHIPTPL-016 单条删除](#req-shiptpl-016-单条删除) +- [REQ-SHIPTPL-017 批量删除](#req-shiptpl-017-批量删除) +- [REQ-SHIPTPL-018 权限与审计](#req-shiptpl-018-权限与审计) +- [REQ-SHIPTPL-019 运单模板布局](#req-shiptpl-019-运单模板布局) +- [REQ-SHIPTPL-020 运费信息规则](#req-shiptpl-020-运费信息规则) +- [REQ-SHIPTPL-021 查看过程配置按钮](#req-shiptpl-021-查看过程配置按钮) +- [通用规则](#通用规则) + +--- + +### REQ-SHIPTPL-001 菜单入口 + +- 功能点: + - 新增主菜单“业务管理”。 + - 在“业务管理”菜单下提供“发货模板”模块入口。 + - 用户进入发货模板页面后,可进行查询、新建模板、编辑、删除、从模板新建等操作。 + +- 异常与边界: + - 无菜单权限时不展示“业务管理”或“发货模板”入口。 + - 有菜单权限但无按钮权限时,仅展示允许访问的页面和操作。 + - 菜单加载失败时提示失败原因,不影响其他菜单访问。 + +- 反例: + - 不允许把发货模板挂到非业务管理主菜单下。 + - 不允许无权限用户通过 URL 直接进入模块。 + - 不允许菜单入口存在但页面无法访问。 + +--- + +### REQ-SHIPTPL-002 列表与分页 + +- 功能点: + - 默认展示当前组织下的发货模板数据。 + - 列表展示字段与编辑表单字段保持一致,并额外展示更新人、创建时间、更新时间。 + - 列表至少展示模板编号、模板名称、模板类型、项目、客户合同、运输类型、发货地址、收货地址、货物信息、备注、更新人、创建时间、更新时间、操作等信息。 + - 操作按钮列固定在右侧,不随横向滚动条滑动。 + - 支持勾选多行数据进行批量删除。 + - 分页默认10条/页,支持20/50/100条/页。 + +- 异常与边界: + - 查询无数据时展示空状态。 + - 横向字段较多时允许表格横向滚动,但操作列必须保持固定。 + - 当前页删除后无数据时自动回退页码并刷新列表。 + - 列表加载失败时保留当前查询条件和分页条件。 + +- 反例: + - 不允许操作列被横向滚动隐藏。 + - 不允许列表字段与编辑表单长期不一致。 + - 不允许分页后丢失当前查询条件。 + +--- + +### REQ-SHIPTPL-003 条件查询与重置 + +- 功能点: + - 支持按模板编号、模板名称、模板类型查询。 + - 模板编号使用输入框,支持模糊查询。 + - 模板名称使用输入框,支持模糊查询。 + - 模板类型使用下拉单选控件。 + - 点击查询后,按模板编号、模板名称、模板类型组合条件筛选列表。 + - 点击重置后清空所有查询条件,恢复默认列表。 + +- 异常与边界: + - 查询条件为空时点击查询,按默认规则展示当前组织数据。 + - 查询结果为空时展示空状态,不清空用户已输入条件。 + - 重置后页码恢复第一页,并重新加载列表。 + +- 反例: + - 不允许重置后仍保留隐藏查询条件。 + - 不允许模板编号查询变成精确匹配。 + - 不允许查询后改变列表字段展示范围。 + +--- + +### REQ-SHIPTPL-004 查看发货模板 + +- 功能点: + - 支持通过行操作查看发货模板详情。 + - 详情展示模板信息、基本信息、收发货信息、货物信息、附件、更新人、创建时间、更新时间等内容。 + - 查看状态下所有字段置灰不可编辑。 + - 查看页面或弹窗底部仅显示关闭或返回按钮。 + +- 异常与边界: + - 数据已删除或不存在时提示数据不存在,并刷新列表。 + - 详情加载失败时提示失败原因,不改变列表数据。 + - 附件加载失败时不影响其他字段展示。 + +- 反例: + - 不允许查看状态下保存修改。 + - 不允许查看页面出现删除货物行、上传附件等编辑操作。 + - 不允许查看时自动切换为编辑状态。 + +--- + +### REQ-SHIPTPL-005 新增发货模板 + +- 功能点: + - 点击新建模板后进入新建模板页面,默认进入运输计划模板类型。 + - 新建页面包含模板信息、基本信息、收发货信息、货物信息、附件等区域。 + - 模板编号由系统自动生成,只读不可编辑。 + - 模板名称必填,使用输入框。 + - 模板类型默认显示运输计划,可切换至常规运单;切换后下方填写信息按对应模板类型展示。 + - 项目必填,使用模糊搜索选择框。 + - 客户合同必填,选择项目后自动带出;若项目下存在多个客户合同,则以下拉框供用户选择。 + - 运输类型必填,选择项目时自动带出,允许用户修改。 + - 发货地址、收货地址必填,控件类型随运输类型变化。 + - 货物信息中货物类型必填,支持新增、删除货物行。 + - 附件为非必填,支持上传多个 JPG、PNG、PDF 等文件。 + - 保存成功后刷新列表。 + +- 异常与边界: + - 模板名称为空时阻止提交并提示。 + - 项目、客户合同、运输类型为空时阻止提交并提示。 + - 发货地址或收货地址为空时阻止提交并提示。 + - 货物信息中任一货物行的货物类型为空时阻止提交。 + - 字段长度、数值、下拉枚举、附件格式不符合要求时阻止提交并提示。 + - 提交失败时保留用户已填写内容。 + +- 反例: + - 不允许用户手工填写模板编号。 + - 不允许缺少项目、合同或运输类型仍保存。 + - 不允许没有任何货物行时保存。 + - 不允许切换模板类型后继续提交旧模板类型的无效字段。 + +--- + +### REQ-SHIPTPL-006 编辑发货模板 + +- 功能点: + - 支持编辑已存在的发货模板。 + - 模板编号在编辑状态下只读不可编辑。 + - 模板名称、模板类型、备注、基本信息、收发货信息、货物信息、附件可按规则编辑。 + - 编辑页面回显模板全部信息。 + - 保存成功后刷新列表。 + +- 异常与边界: + - 编辑时修改模板类型,应按新模板类型刷新下方字段结构,并提示用户确认是否清空不适用字段。 + - 编辑的数据已不存在时提示数据不存在,并刷新列表。 + - 提交失败时保留用户修改内容。 + +- 反例: + - 不允许编辑时修改模板编号。 + - 不允许编辑后提交不符合当前模板类型的字段。 + - 不允许保存后列表仍展示旧数据。 + +--- + +### REQ-SHIPTPL-007 模板信息规则 + +- 功能点: + - 模板编号为模板唯一编码,由系统自动生成,只读展示。 + - 模板编号规则为 MBJH + 8位年月日 + 3位流水号,最长30字符。 + - 模板名称使用输入框,必填,最长50字符。 + - 模板类型为固定枚举,默认显示运输计划,可切换至常规运单。 + - 模板备注使用文本输入框,非必填,最长200字符。 + +- 异常与边界: + - 模板编号生成失败时阻止保存并提示。 + - 模板名称为空或超过50字符时阻止保存。 + - 模板类型为空或不在允许枚举内时阻止保存。 + - 模板备注超过200字符时阻止保存。 + +- 反例: + - 不允许手工编辑模板编号。 + - 不允许保存无模板名称的数据。 + - 不允许提交未知模板类型。 + +--- + +### REQ-SHIPTPL-008 基本信息规则 + +- 功能点: + - 项目使用模糊搜索选择框,必填,用于选择计划所属项目。 + - 客户合同使用选择框,必填,选择项目后自动带出,不允许单独修改;若项目下存在多个客户合同,则下拉供用户选择。 + - 运输类型使用下拉单选控件,必填,枚举包含公路整车、公路零担、空运、铁路、水运等,默认公路整车。 + - 基本信息备注使用文本输入框,非必填,最长200字符。 + +- 异常与边界: + - 项目为空时阻止提交。 + - 客户合同未能根据项目带出时阻止提交,并提示用户重新选择项目。 + - 运输类型为空或不在允许枚举内时阻止提交。 + - 基本信息备注超过200字符时阻止提交。 + +- 反例: + - 不允许未选项目时选择客户合同。 + - 不允许客户合同脱离项目单独维护。 + - 不允许使用非枚举运输类型。 + +--- + +### REQ-SHIPTPL-009 收发货信息规则 + +- 功能点: + - 公路运输时,发货地址和收货地址使用地址选择框或输入搜索选择框,可从常用地址库选择,也可按地址搜索选择。 + - 水运或海运时,发货地址和收货地址显示为港口选择,交互变为从基础数据选择港口。 + - 空运时,发货地址和收货地址显示为空港选择,交互变为从基础数据选择空港。 + - 铁运时,发货地址和收货地址显示为站点选择,交互变为从基础数据选择站点。 + - 非公路运输选择基础数据后,前侧展示名称或编码,后侧展示详细地址。 + - 发货联系人、收货联系人使用输入框,最长20字符。 + - 发货联系方式、收货联系方式使用输入框,最长20字符。 + - 计划发货日期、计划完成日期使用日期选择控件。 + - 支持通过选择常用线路自动回填发货地址、收货地址、联系人、联系方式等信息。 + +- 异常与边界: + - 发货地址或收货地址为空时阻止提交。 + - 非公路运输未选择对应基础数据时阻止提交。 + - 联系方式超过20字符或格式不合法时阻止提交。 + - 联系人超过20字符时阻止提交。 + - 计划完成日期早于计划发货日期时阻止提交。 + - 切换运输类型后,不适用的收发货地址字段应清空或重新选择。 + +- 反例: + - 不允许水运、空运、铁运继续使用公路地址选择逻辑。 + - 不允许运输类型切换后沿用旧类型地址数据。 + - 不允许保存缺失发货地址或收货地址的模板。 + +--- + +### REQ-SHIPTPL-010 货物信息规则 + +- 功能点: + - 货物信息以明细行方式维护,每行可独立新增或删除。 + - 货物名称使用输入框,最长50字符,非必填。 + - 货物类型使用下拉搜索单选控件,必填,来源于货物类型基础数据。 + - 包装使用下拉单选控件,非必填。 + - 数量使用数字输入框,非必填。 + - 数量单位使用下拉单选控件,非必填,枚举包含吨、件、立方米等。 + - 品牌、规格、型号使用输入框,最长50字符。 + - 物料编码、设备编码使用输入框,最长30字符。 + - 货物行备注使用输入框,最长50字符。 + - 支持导入货物。 + - 支持选择常用货物,将常用货物信息回填到货物明细行。 + - 每行支持删除;最后一行支持新增一行。 + +- 异常与边界: + - 货物类型为空时阻止提交。 + - 数量小于0或不是数值时阻止提交。 + - 数量单位不在枚举范围内时阻止提交。 + - 货物名称、品牌、规格、型号、行备注超过50字符时阻止提交。 + - 物料编码、设备编码超过30字符时阻止提交。 + - 删除最后一行货物明细时应保留一条空行或提示至少保留一行。 + +- 反例: + - 不允许无货物明细保存模板。 + - 不允许货物类型为空的明细行参与保存。 + - 不允许导入货物后覆盖用户已确认的不相关字段。 + +--- + +### REQ-SHIPTPL-011 附件规则 + +- 功能点: + - 支持上传模板相关附件。 + - 附件为非必填,支持多个文件。 + - 支持 JPG、PNG、PDF 等格式。 + - 编辑时支持查看、追加或删除附件。 + +- 异常与边界: + - 附件格式不支持时阻止上传并提示。 + - 附件上传失败时保留页面已填写内容。 + - 删除附件时需确认用户操作,避免误删。 + +- 反例: + - 不允许不支持格式的附件静默上传成功。 + - 不允许附件上传失败导致整页已填内容丢失。 + - 不允许查看状态下上传或删除附件。 + +--- + +### REQ-SHIPTPL-012 选择常用地址 + +- 功能点: + - 支持打开选择常用地址弹窗。 + - 弹窗支持按地址名称、地址类型、详细地址查询。 + - 列表展示序号、地址名称、地址编号、类型、站点编码、详细地址、操作等字段。 + - 常规地址的站点编码显示为“/”。 + - 点击选择后,将地址名称、地址编号、类型、站点编码、详细地址等信息回填到当前发货地址或收货地址。 + +- 异常与边界: + - 查询无数据时展示空状态。 + - 选择的数据已失效或不存在时提示重新选择。 + - 地址类型与当前运输类型不匹配时不允许选择。 + +- 反例: + - 不允许选择后只回填地址名称而丢失详细地址。 + - 不允许常规地址展示错误站点编码。 + - 不允许水运、空运、铁运选择不匹配的常用地址类型。 + +--- + +### REQ-SHIPTPL-013 选择常用线路 + +- 功能点: + - 支持打开选择常用线路弹窗。 + - 弹窗支持按线路名称、收发货地址查询。 + - 列表展示序号、线路名称、线路编号、发货地、发货地址、发货联系人、收货地、收货地址、收货联系人、操作等字段。 + - 点击选择后,自动回填发货地址、收货地址、发货联系人、发货联系方式、收货联系人、收货联系方式等信息。 + +- 异常与边界: + - 查询无数据时展示空状态。 + - 线路已删除或不可用时提示重新选择。 + - 常用线路的运输类型或地址类型与当前模板运输类型不匹配时不允许选择。 + +- 反例: + - 不允许选择线路后只回填发货地址而不回填收货地址。 + - 不允许选择与当前运输类型不匹配的线路。 + - 不允许选择失效线路。 + +--- + +### REQ-SHIPTPL-014 选择常用货物 + +- 功能点: + - 支持打开选择常用货物弹窗。 + - 弹窗支持按货物名称、货物编号、货物类型等条件查询。 + - 选择常用货物后,将货物名称、货物类型、包装、品牌、规格、型号、数量单位等信息回填到货物明细。 + - 支持选择一条或多条常用货物,回填为一行或多行货物明细。 + +- 异常与边界: + - 查询无数据时展示空状态。 + - 常用货物已删除或不可用时提示重新选择。 + - 回填多条货物时应避免覆盖已有明细。 + +- 反例: + - 不允许选择常用货物后丢失必填的货物类型。 + - 不允许多选回填时覆盖用户已有货物行。 + - 不允许选择已失效或不可用货物。 + +--- + +### REQ-SHIPTPL-015 从模板新建 + +- 功能点: + - 支持在列表行操作中点击从模板新建。 + - 系统根据当前发货模板的模板类型自动分流: + - 模板类型为运输计划时,跳转至“运输计划”模块的新建页面。 + - 模板类型为常规运单或运单时,跳转至“运单管理”模块的新建页面。 + - 跳转后目标页面自动回填当前模板可映射的数据,包含模板信息、基本信息、收发货信息、货物信息、附件等内容。 + - 回填后用户可继续补充或调整目标模块中允许编辑的字段。 + - 若模板包含目标模块特有字段,按目标模块规则进行回填,不适配字段不强制带入。 + +- 异常与边界: + - 模板数据已删除或不存在时提示数据不存在。 + - 模板缺少目标模块必填字段时,跳转后应明确提示用户补齐。 + - 模板类型无法识别时,不允许跳转,提示模板类型不支持。 + - 跳转失败时不影响原模板数据。 + +- 反例: + - 不允许从模板新建时修改原模板数据。 + - 不允许跳转错误目标模块。 + - 不允许跳转后不回填模板数据。 + - 不允许缺失模板数据时静默创建失败。 + +--- + +### REQ-SHIPTPL-016 单条删除 + +- 功能点: + - 支持通过行操作删除单条发货模板。 + - 点击删除弹出二次确认弹窗。 + - 确认后删除该模板,删除成功刷新列表,并提示“删除成功”。 + +- 异常与边界: + - 数据不存在时提示数据不存在,并刷新列表。 + - 删除失败时提示失败原因,不改变列表其他数据。 + - 用户取消二次确认时不执行删除。 + +- 反例: + - 不允许跳过二次确认直接删除。 + - 不允许删除失败后仍提示成功。 + - 不允许删除成功后列表不刷新。 + +--- + +### REQ-SHIPTPL-017 批量删除 + +- 功能点: + - 支持勾选多行发货模板后批量删除。 + - 点击批量删除弹出二次确认弹窗。 + - 确认后批量删除所选模板。 + - 删除成功后刷新列表,并提示“删除成功”。 + +- 异常与边界: + - 未勾选数据时点击批量删除,应提示先选择需要删除的数据。 + - 部分删除失败时应提示成功数量与失败数量。 + - 用户取消二次确认时不执行删除。 + +- 反例: + - 不允许未选择数据时执行批量删除。 + - 不允许因为部分失败而回滚已成功删除的数据,除非后端明确按事务处理。 + - 不允许删除后不刷新列表。 + +--- + +### REQ-SHIPTPL-018 权限与审计 + +- 功能点: + - 根据用户权限控制查询、新建模板、编辑、删除、从模板新建、批量删除等操作入口。 + - 创建人、创建时间、更新人、更新时间由系统自动记录。 + - 列表、详情、导出预览等用户可见场景优先展示用户姓名,不直接展示用户 ID。 + +- 异常与边界: + - 无权限访问时提示权限不足。 + - 无按钮权限时不展示对应按钮。 + - 操作失败时不记录为成功日志。 + +- 反例: + - 不允许无权限用户执行新增、编辑、删除、从模板新建等操作。 + - 不允许手动维护创建人、创建时间、更新人、更新时间。 + - 不允许删除或篡改审计信息。 + +--- + +### REQ-SHIPTPL-019 运单模板布局 + +- 功能点: + - 运单类型页面采用模板信息、基本信息、收发货信息、货物信息、运费信息、附件等分区布局。 + - 模板信息区包含模板编号、模板名称、模板类型、备注。 + - 基本信息区包含项目、客户合同、发货计划、运输类型、备注。 + - 收发货信息区包含发货地址、发货联系人、联系方式、收货地址、收货联系人、联系方式,以及计划发货日期、计划完成日期等字段。 + - 货物信息区以表格方式维护货物明细,支持新增、删除、导入货物、常用货物。 + - 底部固定展示保存模板、返回等操作按钮,操作区与内容区分离。 + +- 异常与边界: + - 切换到运单类型时,模板类型与下方布局必须联动切换。 + - 非运单模板不展示运费信息区。 + - 运单页面若从模板新建进入,应默认带入模板信息并维持运单布局。 + +- 反例: + - 不允许运单页面沿用发货模板的表单布局。 + - 不允许将运单类型与模板类型混为同一字段。 + - 不允许保存按钮被滚动内容遮挡。 + +--- + +### REQ-SHIPTPL-020 运费信息规则 + +- 功能点: + - 运输类型为铁、水、空时显示运费信息区。 + - 运费信息区包含运费、数量、其他运费合计、运费合计、币种等字段。 + - 运费合计为只读字段,由系统自动计算,规则为运费 + 其他运费合计。 + - 如果货物的数量与计量单位已填写,且单价已填写,则系统自动计算运费,运费允许用户修改。 + - 若数量、计量单位或单价缺少任一项,则不自动计算运费。 + - 运输类型为公路时不展示该运费信息区。 + - 币种默认显示 USD 或人民币等对应枚举值,支持下拉选择。 + +- 异常与边界: + - 运费、其他运费合计为数值输入,最多2位小数。 + - 运费合计不允许手工编辑。 + - 当数量、计量单位、单价完整但自动计算失败时应提示计算异常。 + - 运输类型切换后,运费信息区应按当前类型重新展示与计算。 + +- 反例: + - 不允许公路类型继续显示铁、水、空运费区。 + - 不允许运费合计被手工改写。 + - 不允许数量或单价缺失时仍强制自动计算运费。 + +--- + +### REQ-SHIPTPL-021 查看过程配置按钮 + +- 功能点: + - 底部提供查看过程配置按钮。 + - 点击后弹出过程配置弹窗,展示该项目配置的现行过程节点。 + - 若该项目未配置过程配置,则不展示该按钮。 + - 弹窗仅用于查看,不允许修改过程节点配置。 + +- 异常与边界: + - 项目无过程配置时不显示查看过程配置按钮。 + - 过程配置加载失败时提示失败原因。 + - 弹窗关闭后不影响当前表单内容。 + +- 反例: + - 不允许未配置项目强制展示查看过程配置按钮。 + - 不允许在查看弹窗中修改节点配置。 + - 不允许按钮点击后丢失当前运单表单数据。 + +--- + +## 通用规则 + +- 发货模板用于沉淀运输计划或常规运单的常用填写内容,提升创建运输计划和运单的效率。 +- 发货模板归属于新增主菜单“业务管理”。 +- 模板编号由系统自动生成,规则为 MBJH + 8位年月日 + 3位流水号,且不可编辑。 +- 模板名称必填,最长50字符。 +- 项目、客户合同、运输类型、发货地址、收货地址、货物类型为核心必填项。 +- 运输类型为公路时,收发货地址按地址选择逻辑处理;运输类型为水运或海运时选择港口,空运时选择空港,铁运时选择站点。 +- 收发货地址从基础数据、常用地址或常用线路选择后,必须同步回填名称、编码、详细地址等关联信息。 +- 货物信息至少保留一行,货物类型必填。 +- 运单类型页面需支持查看过程配置按钮和运费信息区。 +- 从模板新建时需按模板类型自动跳转到运输计划或运单管理模块,并回填模板可映射数据。 +- 运费合计自动计算为运费加其他运费合计,并只读展示。 +- 当数量、计量单位、单价完整时可自动计算运费,计算结果允许用户修改。 +- 附件非必填,支持多个 JPG、PNG、PDF 等格式文件。 +- 新增、编辑、删除、批量删除成功后均需刷新列表。 diff --git a/需求卡/合同管理需求卡.md b/需求卡/合同管理需求卡.md new file mode 100644 index 0000000..f564c5a --- /dev/null +++ b/需求卡/合同管理需求卡.md @@ -0,0 +1,774 @@ +# 合同管理需求卡 + +## 目录 + +- [REQ-CONTR-001 菜单入口](#req-contr-001-菜单入口) +- [REQ-CONTR-002 列表与分页](#req-contr-002-列表与分页) +- [REQ-CONTR-003 条件查询与重置](#req-contr-003-条件查询与重置) +- [REQ-CONTR-004 到期快捷筛选](#req-contr-004-到期快捷筛选) +- [REQ-CONTR-005 合同阶段与审核状态](#req-contr-005-合同阶段与审核状态) +- [REQ-CONTR-006 列表操作](#req-contr-006-列表操作) +- [REQ-CONTR-007 新增合同](#req-contr-007-新增合同) +- [REQ-CONTR-008 合同基本信息](#req-contr-008-合同基本信息) +- [REQ-CONTR-009 合同文件与附件](#req-contr-009-合同文件与附件) +- [REQ-CONTR-010 保存草稿](#req-contr-010-保存草稿) +- [REQ-CONTR-011 转临时合同](#req-contr-011-转临时合同) +- [REQ-CONTR-012 临时合同转正式合同](#req-contr-012-临时合同转正式合同) +- [REQ-CONTR-013 正式合同审批通过](#req-contr-013-正式合同审批通过) +- [REQ-CONTR-014 编辑合同](#req-contr-014-编辑合同) +- [REQ-CONTR-015 删除草稿合同](#req-contr-015-删除草稿合同) +- [REQ-CONTR-016 查看合同与流程](#req-contr-016-查看合同与流程) +- [REQ-CONTR-017 复制合同](#req-contr-017-复制合同) +- [REQ-CONTR-018 附件上传](#req-contr-018-附件上传) +- [REQ-CONTR-019 计费信息开关](#req-contr-019-计费信息开关) +- [REQ-CONTR-020 计费方案](#req-contr-020-计费方案) +- [REQ-CONTR-021 计费规则明细](#req-contr-021-计费规则明细) +- [REQ-CONTR-022 计费要素组合](#req-contr-022-计费要素组合) +- [REQ-CONTR-023 计费规则匹配条件](#req-contr-023-计费规则匹配条件) +- [REQ-CONTR-024 结算生成规则](#req-contr-024-结算生成规则) +- [REQ-CONTR-025 对账配置](#req-contr-025-对账配置) +- [REQ-CONTR-026 标准结算流程](#req-contr-026-标准结算流程) +- [REQ-CONTR-027 发起合同变更](#req-contr-027-发起合同变更) +- [REQ-CONTR-028 合同内容变更](#req-contr-028-合同内容变更) +- [REQ-CONTR-029 终止合同](#req-contr-029-终止合同) +- [REQ-CONTR-030 变更审批与生效](#req-contr-030-变更审批与生效) +- [REQ-CONTR-031 变更记录](#req-contr-031-变更记录) +- [REQ-CONTR-032 导出合同列表](#req-contr-032-导出合同列表) +- [REQ-CONTR-033 权限与审计](#req-contr-033-权限与审计) +- [通用规则](#通用规则) + +--- + +### REQ-CONTR-001 菜单入口 + +- 功能点: + - 合同管理模块归属于“合同管理”主菜单。 + - 在“合同管理”菜单下提供“合同管理”入口。 + - 用户进入合同管理页面后,可进行查询、新增合同、复制、编辑、删除、转临时合同、转正式合同、变更、终止、附件上传、流程查看、导出等操作。 + +- 异常与边界: + - 无菜单权限时不展示“合同管理”入口。 + - 有菜单权限但无按钮权限时,仅展示允许访问的页面和操作。 + - 菜单或页面加载失败时提示失败原因,不影响其他模块访问。 + +- 反例: + - 不允许把合同管理挂到非合同管理主菜单下。 + - 不允许无权限用户通过 URL 直接进入合同管理页面。 + - 不允许菜单入口存在但页面无法访问。 + +--- + +### REQ-CONTR-002 列表与分页 + +- 功能点: + - 默认展示当前用户权限范围内的合同数据。 + - 列表展示序号、合同编号、合同名称、所属项目、所属组织、合同类别、签约类型、甲方、乙方、开始日期、结束日期、临时效力起、临时效力止、经办人、创建时间、合同阶段、审核状态、当前节点、当前处理人、操作等字段。 + - 合同名称支持点击查看合同详情。 + - 合同阶段、审核状态和操作列固定在右侧,不随横向滚动条滑动。 + - 默认按创建时间降序展示。 + - 支持分页展示,默认10条/页,支持20/50/100条/页。 + +- 异常与边界: + - 查询无数据时展示空状态。 + - 当前页数据因新增、编辑、提交、撤回、审批、变更、删除等操作变化后,应刷新列表并保持分页逻辑正确。 + - 列表加载失败时保留当前查询条件和分页条件,提示用户重新查询。 + +- 反例: + - 不允许合同阶段、审核状态或操作列被横向滚动隐藏。 + - 不允许列表展示经办人、当前处理人的用户 ID。 + - 不允许分页后丢失当前查询条件。 + +--- + +### REQ-CONTR-003 条件查询与重置 + +- 功能点: + - 支持按合同类别、所属项目、合同名称、合同编号、生效类型、审核状态、所属组织、合同阶段、签约类型等条件组合查询。 + - 合同类别、生效类型、审核状态、合同阶段、签约类型使用下拉单选或多选控件。 + - 所属项目使用搜索选择控件。 + - 合同名称、合同编号、所属组织使用输入框,支持模糊查询。 + - 点击查询后按当前条件刷新列表。 + - 点击重置后清空所有查询条件,恢复默认列表。 + +- 异常与边界: + - 查询条件为空时点击查询,按默认规则展示全部权限范围内数据。 + - 查询结果为空时展示空状态,不清空用户已输入条件。 + - 重置后页码恢复第一页,并重新加载列表。 + +- 反例: + - 不允许重置后仍保留隐藏查询条件。 + - 不允许只按单个条件查询而忽略其他已选择条件。 + - 不允许查询后改变列表字段或操作范围。 + +--- + +### REQ-CONTR-004 到期快捷筛选 + +- 功能点: + - 列表支持按合同到期时间快捷筛选。 + - 快捷筛选项包含全部、30天内到期、90天内到期、90天以上、已到期。 + - 每个筛选项展示当前条件下的数量。 + - 点击快捷筛选项后,列表按对应到期范围刷新。 + +- 异常与边界: + - 合同结束日期为空时不计入到期筛选统计。 + - 选择快捷筛选后再点击查询,应与其他查询条件组合生效。 + - 重置查询条件后快捷筛选恢复全部。 + +- 反例: + - 不允许快捷筛选忽略用户已选择的其他查询条件。 + - 不允许已到期合同仍统计到30天内到期。 + - 不允许数量统计与列表结果不一致。 + +--- + +### REQ-CONTR-005 合同阶段与审核状态 + +- 功能点: + - 合同阶段包含草稿、临时合同、正式合同、已终止。 + - 审核状态包含草稿、审批中、已驳回、审批通过、变更审批中、变更驳回、变更审批通过。 + - 草稿表示新增合同草稿,尚未转临时合同,无业务生效。 + - 临时合同表示草稿转临时成功,临时有效期内可执行短期结算。 + - 正式合同表示临时合同或合同草稿经审批通过后正式生效。 + - 已终止表示正式合同经终止变更审批通过后生命周期结束。 + +- 异常与边界: + - 状态为空或未知时,列表应展示兜底文案,并限制高风险操作。 + - 状态变更后需刷新列表和详情,确保合同阶段、审核状态、操作按钮一致。 + - 审核状态与合同阶段不匹配时,应提示数据异常并限制提交、变更、结算等操作。 + +- 反例: + - 不允许草稿合同执行业务结算。 + - 不允许临时合同永久有效。 + - 不允许已终止合同继续新建运单或结算单。 + +--- + +### REQ-CONTR-006 列表操作 + +- 功能点: + - 草稿合同支持复制、编辑、删除。 + - 临时合同草稿状态支持复制、编辑。 + - 临时合同审批中支持复制、查看流程、撤回。 + - 临时合同已驳回支持复制、编辑、重新提交转正。 + - 正式合同审批通过支持复制、发起变更、附件上传、查看流程。 + - 正式合同变更审批中支持复制、查看流程、撤回变更。 + - 正式合同变更驳回支持复制、编辑变更内容、重新提交变更。 + - 正式合同变更审批通过支持复制、再次发起变更、附件上传、查看流程。 + - 已终止合同仅支持复制和查看流程。 + +- 异常与边界: + - 操作执行前需重新校验合同最新阶段和审核状态。 + - 用户无按钮权限时不展示对应操作入口。 + - 状态变更成功后刷新列表,展示最新可操作按钮。 + +- 反例: + - 不允许临时合同转正审批中继续编辑合同正文。 + - 不允许正式合同直接删除。 + - 不允许已终止合同发起新变更。 + +--- + +### REQ-CONTR-007 新增合同 + +- 功能点: + - 点击“新增合同”后进入新建合同页面。 + - 新建合同页面包含基本信息、计费信息、结算生成规则、对账配置、其它附件、变更记录等区域。 + - 新建合同支持保存、提交临时合同、提交正式合同、关闭。 + - 合同编号不填写时由系统自动生成,生成后只读不可编辑。 + - 草稿保存不触发审批流程。 + +- 异常与边界: + - 新建页面打开失败时提示失败原因,不改变列表数据。 + - 基础信息必填项为空时不允许保存为有效草稿。 + - 提交临时合同或正式合同时需按对应规则校验必填项和附件。 + - 重复点击保存或提交时应防止重复生成合同。 + +- 反例: + - 不允许用户重复提交生成多个相同合同。 + - 不允许没有合同名称和合同类型的合同草稿保存成功。 + - 不允许合同编号由用户随意修改。 + +--- + +### REQ-CONTR-008 合同基本信息 + +- 功能点: + - 基本信息包含签约类型、合同编号、合同名称、合同类型、甲方、乙方、所属项目、合同期限、所属组织、经办人、签订日期、结算方式、合同格式、是否需要加盖法人章、一式份数、回款账期、备注等字段。 + - 签约类型为必填字段,使用下拉单选控件,枚举包含新签、续签。 + - 合同编号为必填字段,可不填写,由系统自动生成。 + - 合同名称为必填字段,使用输入框。 + - 合同类型为必填字段,枚举包含客户合同、承运商合同等。 + - 甲方、乙方为必填字段,从客商或组织档案选择。 + - 所属项目从项目管理中选择。 + - 合同期限为必填日期范围字段。 + - 签订日期为必填日期字段。 + - 结算方式、合同格式、是否需要加盖法人章、一式份数、回款账期、备注按合同业务要求填写。 + - 备注最多2000字。 + +- 异常与边界: + - 转临时合同时,签约人、签约日期、合同期限可不填。 + - 提交正式合同时,所有必填字段必须完整,包含签约人、签约日期、合同期限。 + - 合同期限开始日期晚于结束日期时阻止提交。 + - 备注超过2000字时阻止保存或提交。 + +- 反例: + - 不允许正式合同缺少签订日期或合同期限。 + - 不允许合同期限结束日期早于开始日期。 + - 不允许甲方、乙方为空后提交正式合同。 + +--- + +### REQ-CONTR-009 合同文件与附件 + +- 功能点: + - 合同文件区域用于上传合同主文件。 + - 其它附件区域用于上传银行承兑汇票、补充材料等合同相关附件。 + - 附件列表展示序号、文件名、附件描述、文件大小、上传人、上传时间、操作等字段。 + - 支持批量下载附件。 + - 支持 pdf、bmp、jpeg、png、jpg、doc、docx、ppt、pptx、xlsx、xls、eml、msg、zip 等格式文件。 + - 单个文件大小限制500M。 + +- 异常与边界: + - 保存草稿或转临时合同时,附件可不上传。 + - 提交正式合同时,应校验所有必须附件已上传。 + - 文件格式不支持或大小超过500M时阻止上传并提示。 + - 删除附件前需二次确认。 + +- 反例: + - 不允许正式合同缺少必须合同文件仍提交审批。 + - 不允许上传超过500M的文件。 + - 不允许附件上传成功后列表不展示文件信息。 + +--- + +### REQ-CONTR-010 保存草稿 + +- 功能点: + - 新建或编辑页面点击保存后,临时保存当前填写内容。 + - 保存后合同阶段为草稿,审核状态为草稿。 + - 保存草稿只要求基础信息满足最小必填校验,附件可不上传。 + - 草稿合同无业务生效,不可创建运单和结算单。 + +- 异常与边界: + - 基础信息缺失导致无法识别合同主体时阻止保存并提示。 + - 保存失败时保留用户已填写内容。 + - 草稿数据已删除或状态已变化时,不允许继续保存。 + +- 反例: + - 不允许保存草稿触发审批流程。 + - 不允许草稿合同执行结算过程。 + - 不允许保存失败后清空用户输入。 + +--- + +### REQ-CONTR-011 转临时合同 + +- 功能点: + - 草稿合同支持提交临时合同。 + - 转临时合同时,签约人、签约日期、合同期限可不填。 + - 转临时合同只校验基础信息必填项,附件可不上传。 + - 转临时成功后合同阶段变为临时合同,审核状态保持草稿。 + - 临时合同有效期为30天。 + - 临时合同可执行结算过程。 + - 转临时合同后不可删除。 + +- 异常与边界: + - 基础信息缺失时不允许转临时合同。 + - 临时有效期计算失败时不允许转临时合同。 + - 转临时合同失败时保持草稿状态,并保留用户填写内容。 + +- 反例: + - 不允许草稿合同未转临时就执行结算。 + - 不允许转临时合同后继续删除。 + - 不允许临时合同有效期超过30天。 + +--- + +### REQ-CONTR-012 临时合同转正式合同 + +- 功能点: + - 临时合同支持补全信息后提交正式合同审批。 + - 转正式合同前需完成所有正式合同必填内容。 + - 转正式合同前需上传所有必须附件。 + - 转正式合同需走审批流程。 + - 提交成功后合同阶段保持临时合同,审核状态更新为审批中。 + - 审批通过后合同阶段转为正式合同。 + +- 异常与边界: + - 正式合同必填字段缺失时阻止提交审批并提示。 + - 必须附件缺失时阻止提交审批并提示缺失附件。 + - 临时合同已超过30天有效期时,应提示临时效力已过期,并按业务规则限制继续结算。 + - 审批流程发起失败时保持原状态,并保留用户输入内容。 + +- 反例: + - 不允许资料未补齐的临时合同转正式审批。 + - 不允许转正式合同绕过审批。 + - 不允许提交失败后仍把合同阶段改为正式合同。 + +--- + +### REQ-CONTR-013 正式合同审批通过 + +- 功能点: + - 当前审批节点处理人可对审批中合同执行审批通过。 + - 全部审批通过后,合同阶段更新为正式合同,审核状态更新为审批通过。 + - 正式合同永久正式生效,完整开放运单、结算、回款权限。 + - 正式合同审批通过后,临时效力不再作为业务有效期判断依据。 + +- 异常与边界: + - 非当前审批节点处理人不允许审批通过。 + - 审批通过时如合同已被终止或数据不存在,应阻止审批并提示。 + - 审批状态更新失败时需保持审批前状态。 + +- 反例: + - 不允许未审批通过的合同成为正式合同。 + - 不允许非审批处理人执行审批通过。 + - 不允许正式合同仍按30天临时效力限制结算。 + +--- + +### REQ-CONTR-014 编辑合同 + +- 功能点: + - 草稿合同支持编辑。 + - 临时合同草稿或已驳回状态支持编辑。 + - 正式合同仅可通过变更流程修改合同内容。 + - 编辑页面回显合同完整信息,合同编号只读不可编辑。 + - 编辑保存后按当前阶段和审核状态保持或更新。 + +- 异常与边界: + - 编辑前需校验当前合同状态仍允许编辑。 + - 合同已进入审批中时不允许直接编辑。 + - 修改所属项目或合同类型时,应重新校验计费、结算、对账配置适用性。 + - 编辑失败时保留用户修改内容。 + +- 反例: + - 不允许审批中合同直接编辑。 + - 不允许正式合同绕过变更流程直接修改。 + - 不允许编辑时修改系统生成的合同编号。 + +--- + +### REQ-CONTR-015 删除草稿合同 + +- 功能点: + - 未转临时的草稿合同支持删除。 + - 点击删除后弹出二次确认弹窗。 + - 删除前需校验合同未生效且未被业务数据引用。 + - 删除成功后刷新列表。 + +- 异常与边界: + - 临时合同、正式合同、已终止合同均不允许删除。 + - 存在运单、结算、应收应付、附件审批等业务引用时不允许删除。 + - 删除时状态已变化为临时合同或审批中时,应阻止删除并刷新列表。 + +- 反例: + - 不允许删除转临时后的合同。 + - 不允许删除正式合同。 + - 不允许跳过二次确认直接删除。 + +--- + +### REQ-CONTR-016 查看合同与流程 + +- 功能点: + - 支持点击合同名称或行操作查看合同详情。 + - 查看详情展示基本信息、计费信息、结算生成规则、对账配置、附件、变更记录等内容。 + - 查看状态下所有字段只读。 + - 支持查看审批流程节点、处理人、处理时间和审批意见。 + +- 异常与边界: + - 合同不存在或无权限查看时提示无法查看。 + - 附件加载失败时不影响基础信息展示。 + - 流程加载失败时提示失败原因,不改变合同状态。 + +- 反例: + - 不允许查看状态下保存修改。 + - 不允许流程查看展示其他合同的审批记录。 + - 不允许查看时自动切换为编辑状态。 + +--- + +### REQ-CONTR-017 复制合同 + +- 功能点: + - 支持通过列表行操作复制合同。 + - 复制后生成一条新合同草稿。 + - 新合同编号重新生成,合同阶段为草稿,审核状态为草稿。 + - 复制时可带出原合同基本信息、计费规则、结算规则、对账配置和附件清单。 + +- 异常与边界: + - 原合同已删除或无权限查看时不允许复制。 + - 复制后的合同名称应提示用户调整,避免与原合同混淆。 + - 复制失败时不影响原合同数据。 + +- 反例: + - 不允许复制后沿用原合同编号。 + - 不允许复制操作修改原合同。 + - 不允许复制后直接生成临时合同或正式合同。 + +--- + +### REQ-CONTR-018 附件上传 + +- 功能点: + - 正式合同审批通过后支持附件上传。 + - 合同变更过程中支持上传变更材料。 + - 附件上传成功后自动新增附件行,展示文件名、大小、上传人、上传时间。 + - 支持批量下载附件。 + - 附件删除按合同阶段、审核状态和权限控制。 + +- 异常与边界: + - 审批中合同不允许随意删除已提交审批附件。 + - 附件上传失败时保留当前附件列表并提示失败原因。 + - 变更材料与普通附件需按业务场景区分归档。 + +- 反例: + - 不允许附件上传后不归属任何合同或变更记录。 + - 不允许审批材料被无权限用户删除。 + - 不允许变更材料混入普通附件后无法追溯。 + +--- + +### REQ-CONTR-019 计费信息开关 + +- 功能点: + - 合同基本信息支持配置是否自动生成费用明细。 + - 开启自动生成费用明细时,系统展示计价配置页面,并按合同计费规则自动核算单票运单总费用,生成应收或应付。 + - 关闭自动生成费用明细时,不展示计价配置页面。 + - 关闭后费用入账依据导入结算账单或手动生成账单。 + - 自动生成费用明细适用于先做运单,再按合同运价自动核算的业务场景。 + +- 异常与边界: + - 开启自动生成费用明细但未配置计费方案时,提交正式合同需阻止并提示。 + - 关闭自动生成费用明细后,不得继续要求填写计费方案。 + - 合同已产生自动费用明细后,关闭开关需按变更流程处理。 + +- 反例: + - 不允许开关关闭时仍展示计价配置并强制填写。 + - 不允许开关开启但没有任何计费规则就提交正式合同。 + - 不允许已生效合同绕过变更直接修改费用生成方式。 + +--- + +### REQ-CONTR-020 计费方案 + +- 功能点: + - 计费信息区域支持新增、编辑、删除计费方案。 + - 计费方案包含方案名称、默认方案标识、备注和计费规则明细。 + - 方案名称为必填字段。 + - 同一合同内可维护多套计费方案。 + - 同一合同内只能设置一个默认方案。 + +- 异常与边界: + - 方案名称为空时阻止提交并提示。 + - 删除默认方案前需提示用户重新指定默认方案。 + - 已被费用明细引用的计费方案不允许直接删除。 + +- 反例: + - 不允许一个合同存在多个默认计费方案。 + - 不允许无方案名称的计费方案保存。 + - 不允许删除已被历史运单费用引用的计费方案。 + +--- + +### REQ-CONTR-021 计费规则明细 + +- 功能点: + - 计费方案内支持添加多条计费规则。 + - 计费规则字段包含费用类型、费用项、计费要素、计费类型、计费单位、单价、计费要素下限、计费要素上限、保底计费量、备注和操作。 + - 费用类型包含运输费、其它费用等。 + - 费用项包含运费、装卸车费、提货费、送货费、保险费等。 + - 计费类型包含固定单价、区间单价、阶梯单价、区间阶梯一口价、固定一口价等。 + - 同一套计费方案内,同一条计费要素可配置多行区间。 + - 同一条计费要素的区间上下限必须连续、不重叠、无间隙。 + - 前端保存时需自动校验区间冲突。 + +- 异常与边界: + - 费用类型、费用项、计费要素、计费类型、计费单位、单价等核心字段为空时阻止保存。 + - 计费要素上下限不连续、重叠或存在间隙时阻止保存并提示。 + - 单价或保底计费量为负数时阻止保存。 + - 已生效计费规则被历史费用引用时,修改需走合同变更流程。 + +- 反例: + - 不允许同一计费要素区间重叠。 + - 不允许单价填写负数。 + - 不允许计费规则被引用后直接删除导致历史费用无法追溯。 + +--- + +### REQ-CONTR-022 计费要素组合 + +- 功能点: + - 计费要素支持按重量、按体积、按车辆、按里程、按吨公里、固定金额整单一口价、按数量等类型。 + - 按重量支持固定单价、区间单价、阶梯单价、区间阶梯一口价,适用于整车散货按吨计价、分吨位阶梯调价、吨位区间一口价。 + - 按体积支持固定单价、区间单价、阶梯单价、区间阶梯一口价,适用于轻泡货按立方计费。 + - 按车辆支持固定单价,适用于包月固定车费、单次车辆包干费。 + - 按里程支持固定单价、区间单价、阶梯单价、区间阶梯一口价,适用于长途干线按公里计价。 + - 按吨公里支持固定单价、区间单价、阶梯单价、区间阶梯一口价,适用于水陆联运复合计量计费。 + - 固定金额整单一口价支持固定一口价,适用于同城配送、短途整车包干。 + - 按数量支持固定单价、区间单价、阶梯单价、区间阶梯一口价,适用于小件零担按件计费。 + +- 异常与边界: + - 计费要素与计费类型不匹配时阻止保存并提示。 + - 计费单位需与计费要素匹配,例如重量对应元/吨,里程对应元/公里。 + - 复合计量场景需明确计费要素来源,避免同一运单重复计费。 + +- 反例: + - 不允许按车辆计费配置阶梯单价。 + - 不允许按里程计费用元/吨作为计费单位。 + - 不允许一个费用项重复命中多个同优先级计费规则。 + +--- + +### REQ-CONTR-023 计费规则匹配条件 + +- 功能点: + - 计费规则支持设置匹配条件。 + - 匹配条件包含起运地、目的地、运输方式、货物类型等字段。 + - 起运地和目的地支持按省、市、区县配置。 + - 运输方式和货物类型使用下拉选择。 + - 保存匹配条件后,系统在执行运单计费时按条件匹配对应计费规则。 + - 支持新增多组匹配条件。 + +- 异常与边界: + - 匹配条件为空时视为通用规则或按业务默认规则处理。 + - 多组匹配条件冲突时,应提示用户调整。 + - 保存失败时保留用户已填写条件。 + +- 反例: + - 不允许同一费用项存在无法区分优先级的重复匹配条件。 + - 不允许保存后匹配条件与计费规则脱离。 + - 不允许匹配条件冲突时静默覆盖旧规则。 + +--- + +### REQ-CONTR-024 结算生成规则 + +- 功能点: + - 合同支持配置是否自动生成预结算单。 + - 开启自动生成预结算单时,到达预设账单日,系统汇总当期所有应收或应付,生成统一内部预结算单。 + - 关闭自动生成预结算单时,不自动生成预结算单,可手动选择应收应付转预结算单。 + - 账单起始日期、结算类型、账单周期类型、账单截单日、周期天数等字段按结算规则配置。 + - 结算时以合同截止时间产生的运单为有效单据,支持超合同有效期发起结算。 + +- 异常与边界: + - 开启自动生成预结算单时,账单起始日期、结算类型、账单周期类型等必填字段缺失应阻止提交。 + - 周期天数不合法时阻止保存。 + - 自动预结算任务失败时,应保留补偿处理记录。 + +- 反例: + - 不允许开启自动预结算但缺少账单周期配置。 + - 不允许合同截止前产生的有效运单因合同已过期而不能结算。 + - 不允许关闭自动预结算后仍自动生成预结算单。 + +--- + +### REQ-CONTR-025 对账配置 + +- 功能点: + - 合同支持配置是否跳过对账。 + - 开启跳过对账后,预结算单手动确认后直接生成正式结算单。 + - 关闭跳过对账后,预结算单需按对账模式完成对账后生成正式结算单。 + - 对账模式包含明细逐行核对和仅核对总额。 + - 明细逐行核对要求外部账单明细与内部账单明细一一匹配,所有明细匹配后才可完成对账。 + - 仅核对总额要求外部账单总条数、总金额、总货量一致后即可完成对账,不按明细逐行核对。 + +- 异常与边界: + - 未选择是否跳过对账时阻止提交正式合同。 + - 不跳过对账时,对账模式必填。 + - 明细逐行核对存在不匹配明细时,不允许完成对账。 + - 仅核对总额存在总条数、总金额或总货量不一致时,不允许完成对账。 + +- 反例: + - 不允许开启跳过对账后仍强制进入对账流程。 + - 不允许未选择对账模式就保存正式合同配置。 + - 不允许明细不匹配或总额不一致时完成对账。 + +--- + +### REQ-CONTR-026 标准结算流程 + +- 功能点: + - 合同标准结算流程为合同配置计费规则、执行运单、生成应收应付、账期自动生成预结算、对账、正式结算。 + - 自动生成费用明细开启时,运单执行后系统按合同计费规则生成应收应付。 + - 自动生成预结算单开启时,系统按账期汇总生成预结算。 + - 对账完成或配置跳过对账后,系统生成正式结算单。 + +- 异常与边界: + - 合同未生效、计费规则不完整或费用明细开关关闭时,不按合同计费规则自动生成应收应付。 + - 运单未完成或不满足结算条件时,不进入预结算。 + - 合同已终止后,不允许新建运单或新结算单,但历史单据可正常对账回款。 + +- 反例: + - 不允许草稿合同进入标准结算流程。 + - 不允许已终止合同新建业务单据。 + - 不允许跳过应收应付直接生成正式结算单,除非业务配置明确支持。 + +--- + +### REQ-CONTR-027 发起合同变更 + +- 功能点: + - 审批通过的正式合同支持发起变更。 + - 变更类型包含合同信息变更、终止合同。 + - 发起变更后打开变更页面,自动带入原合同完整信息。 + - 变更页面支持修改允许变更的合同字段、计费规则、附件和变更说明。 + - 变更需要走审核流程。 + +- 异常与边界: + - 非审批通过正式合同不允许发起变更。 + - 存在未完成变更审批时,不允许重复发起变更。 + - 已终止合同不允许发起变更。 + +- 反例: + - 不允许临时合同发起合同内容变更。 + - 不允许变更页面为空白而不带入原合同数据。 + - 不允许同一合同同时存在多个审批中的变更单。 + +--- + +### REQ-CONTR-028 合同内容变更 + +- 功能点: + - 合同内容变更用于调整正式合同的基础信息、计费规则、结算规则、对账配置和附件。 + - 变更内容需填写本次修改说明。 + - 变更原因需填写本次变更原因。 + - 变更内容和变更原因最多2000字。 + - 内容变更审批通过后更新合同计费和基础信息。 + +- 异常与边界: + - 变更内容或变更原因为空时阻止提交审批。 + - 文本超过2000字时阻止提交。 + - 变更审批通过前,原合同条款保持正常履约,变更内容暂不生效。 + +- 反例: + - 不允许变更说明为空后发起审批。 + - 不允许审批未通过的变更内容影响正式合同。 + - 不允许超过2000字的变更原因提交。 + +--- + +### REQ-CONTR-029 终止合同 + +- 功能点: + - 终止合同属于合同变更类型。 + - 终止合同需填写变更原因和上传变更材料。 + - 终止申请提交后进入变更审批中。 + - 终止审批通过后合同阶段更新为已终止。 + - 已终止合同彻底停用,禁止新建任何运单、结算单据。 + - 历史单据可正常对账回款。 + +- 异常与边界: + - 终止审批未通过前,合同仍按原状态处理。 + - 存在未完成变更审批时,不允许再次发起终止。 + - 终止失败时保持原合同状态,并提示失败原因。 + +- 反例: + - 不允许未审批通过就终止合同。 + - 不允许已终止合同继续新建运单或结算单。 + - 不允许终止合同影响历史应收应付对账回款。 + +--- + +### REQ-CONTR-030 变更审批与生效 + +- 功能点: + - 变更提交后审核状态更新为变更审批中。 + - 变更审批通过后审核状态更新为变更审批通过。 + - 合同内容变更审批通过后,新内容正式生效。 + - 终止合同审批通过后,合同阶段更新为已终止。 + - 变更驳回后审核状态更新为变更驳回,允许编辑后重新提交。 + +- 异常与边界: + - 变更审批未通过前,不得覆盖原正式合同信息。 + - 审批过程中合同已终止或数据不存在时,不允许继续审批。 + - 变更审批失败时保持原合同数据不变,并提示失败原因。 + +- 反例: + - 不允许变更草稿直接影响正式合同。 + - 不允许审批未通过却生成正式变更结果。 + - 不允许变更驳回后仍按变更内容计费。 + +--- + +### REQ-CONTR-031 变更记录 + +- 功能点: + - 合同详情和编辑页面展示变更记录。 + - 变更记录展示序号、变更日期、经办人、变更类型、变更原因、状态、操作等字段。 + - 支持查看变更审批流程。 + - 变更记录在变更提交后生成,并在详情页可查看。 + - 变更记录需保留变更前后关键字段。 + +- 异常与边界: + - 变更记录加载失败时提示失败原因,不影响合同基础信息查看。 + - 查看历史变更记录时全字段只读。 + - 变更记录与合同不匹配时不展示,并提示数据异常。 + +- 反例: + - 不允许删除已审批通过的变更记录。 + - 不允许变更记录只保存变更原因而无变更内容。 + - 不允许跨合同展示变更记录。 + +--- + +### REQ-CONTR-032 导出合同列表 + +- 功能点: + - 列表顶部支持导出合同列表。 + - 点击导出后,导出当前筛选条件下的合同基础信息、阶段状态、计费方案摘要、附件清单和变更记录到 Excel 文件。 + - 导出字段与列表和详情展示字段保持一致。 + - 数据量较大时页面展示导出中提示。 + +- 异常与边界: + - 当前查询条件下无数据时允许导出空文件或提示无可导出数据。 + - 导出失败时提示失败原因,不改变当前列表状态。 + - 无导出权限时不展示导出按钮。 + +- 反例: + - 不允许无权限用户导出合同数据。 + - 不允许导出时忽略当前查询条件。 + - 不允许导出文件展示用户 ID 代替姓名。 + +--- + +### REQ-CONTR-033 权限与审计 + +- 功能点: + - 根据用户权限控制查询、新增、复制、编辑、删除、转临时、转正式、审批、变更、终止、附件上传、流程查看、导出等操作入口。 + - 列表、详情、导出、审批流中用户可见字段优先展示姓名,不直接展示用户 ID。 + - 新增、保存、提交临时合同、提交正式合同、审批、撤回、复制、删除、变更、终止、附件上传、导出等关键操作需记录操作日志。 + - 审计信息应包含操作人、操作时间、操作类型、合同编号、合同阶段、审核状态和关键变更内容。 + +- 异常与边界: + - 无按钮权限时不展示对应按钮,通过 URL 或接口绕过时也应拒绝。 + - 操作日志记录失败时不得影响用户已成功的业务操作,但需保留可排查信息。 + - 数据权限限制下,用户只能查看和操作授权范围内合同。 + +- 反例: + - 不允许无权限用户审批、变更、终止或导出合同。 + - 不允许列表展示经办人、审批人等用户 ID。 + - 不允许关键状态变更没有审计记录。 + +--- + +## 通用规则 + +- 合同管理用于维护客户合同、承运商合同等合同全生命周期,归属于“合同管理”主菜单。 +- 合同阶段包含草稿、临时合同、正式合同、已终止;审核状态包含草稿、审批中、已驳回、审批通过、变更审批中、变更驳回、变更审批通过。 +- 合同编号由系统自动生成,全局唯一,只读不可编辑。 +- 暂存草稿无业务生效,不可执行结算流程。 +- 草稿可提交为临时合同,签约人、签约日期、合同期限可不填;临时合同有效期30天,可执行结算流程,且不可删除。 +- 临时合同转正式合同需补齐所有必填信息并上传所有必须附件,审批通过后转为正式合同。 +- 正式合同可执行完整结算流程,并支持发起合同信息变更或终止合同变更。 +- 标准结算流程为合同配置计费规则、执行运单、生成应收应付、账期自动生成预结算、对账、正式结算。 +- 自动生成费用明细开启时,需维护计价配置;关闭时不展示计价配置,费用依据导入结算账单或手工生成账单入账。 +- 自动生成预结算单开启时,系统按账期生成预结算;关闭时可手动选择应收应付转预结算。 +- 是否跳过对账开启时,预结算单手动确认后直接生成正式结算单;关闭时需按明细逐行核对或仅核对总额完成对账。 +- 同一套计费方案内,同一计费要素的多行区间必须连续、不重叠、无间隙。 +- 变更审批通过前,原正式合同内容继续生效;变更审批通过后新内容生效或合同终止。 +- 已终止合同禁止新建运单、结算单据,历史单据可正常对账回款。 +- 列表、详情、导出、审批等用户可见场景优先展示姓名字段,不直接展示用户 ID。 +- 新增、保存、提交、审批、撤回、复制、删除、变更、终止、附件上传、导出后均需刷新相关列表或详情状态。 diff --git a/需求卡/常用线路需求卡.md b/需求卡/常用线路需求卡.md new file mode 100644 index 0000000..2e5e83b --- /dev/null +++ b/需求卡/常用线路需求卡.md @@ -0,0 +1,249 @@ +# 常用线路需求卡 + +## 目录 + +- [REQ-CYXL-001 列表与分页](#req-cyxl-001-列表与分页) +- [REQ-CYXL-002 条件查询与重置](#req-cyxl-002-条件查询与重置) +- [REQ-CYXL-003 查看常用线路](#req-cyxl-003-查看常用线路) +- [REQ-CYXL-004 新增常用线路](#req-cyxl-004-新增常用线路) +- [REQ-CYXL-005 编辑常用线路](#req-cyxl-005-编辑常用线路) +- [REQ-CYXL-006 线路编号与地址联动规则](#req-cyxl-006-线路编号与地址联动规则) +- [REQ-CYXL-007 批量导出](#req-cyxl-007-批量导出) +- [REQ-CYXL-008 单条删除](#req-cyxl-008-单条删除) +- [REQ-CYXL-009 批量删除](#req-cyxl-009-批量删除) +- [REQ-CYXL-010 组织权限与审计](#req-cyxl-010-组织权限与审计) +- [通用规则](#通用规则) + +--- + +### REQ-CYXL-001 列表与分页 + +- 功能点: + - 默认展示当前组织全部常用线路数据,列表按更新时间降序排列。 + - 展示组织、线路编号、线路名称、发货地、发货地址、收货地、收货地址、创建人、更新时间、创建时间、操作等字段。 + - 常规类型站点编码在列表中显示为“/”,其他类型显示对应编码。 + - 支持勾选多行数据用于批量导出、批量删除。 + - 操作列固定展示查看、编辑、删除,具体显示受权限控制。 + - 普通用户默认仅看当前组织数据;具备权限时可切换查看全部组织数据,但切换后的全部组织视图仅作只读查看。 + - 分页默认10条/页,支持20/50/100条/页。 + +- 异常与边界: + - 查询无数据时展示空状态。 + - 当前页删除后无数据时自动回退页码并刷新列表。 + - 切换组织范围时保留当前查询条件,仅重载数据。 + - 列表加载失败时保留当前筛选与分页条件。 + +- 反例: + - 不允许默认按更新时间以外的字段覆盖排序规则。 + - 不允许普通用户在全部组织视图下执行编辑、删除等写操作。 + - 不允许分页后丢失当前查询条件。 + +--- + +### REQ-CYXL-002 条件查询与重置 + +- 功能点: + - 支持按线路名称、线路编号、发货地、发货地址、收货地、收货地址、组织等条件组合查询。 + - 线路名称、发货地、发货地址、收货地、收货地址支持模糊查询。 + - 线路编号支持精确匹配。 + - 组织默认带出当前用户所属组织。 + - 点击查询后按条件展示数据。 + - 点击重置后清空所有条件并恢复默认列表。 + +- 异常与边界: + - 查询条件为空时点击查询,按默认规则展示当前组织全部数据。 + - 查询结果为空时展示空状态,不清空用户已输入条件。 + - 重置后页码恢复第一页,并按更新时间降序重新加载。 + +- 反例: + - 不允许重置后仍保留隐藏条件。 + - 不允许只按单一条件查询而忽略组合条件。 + - 不允许查询后改变列表字段展示范围。 + +--- + +### REQ-CYXL-003 查看常用线路 + +- 功能点: + - 支持通过行操作查看常用线路详情。 + - 详情展示所有业务字段,字段全部置灰不可编辑。 + - 查看弹窗底部仅显示关闭按钮。 + +- 异常与边界: + - 数据已删除或不存在时提示数据不存在,并刷新列表。 + - 详情加载失败时提示失败原因,不影响列表现状。 + +- 反例: + - 不允许在查看状态下保存修改。 + - 不允许查看时切换组织范围并修改数据。 + - 不允许查看弹窗出现提交按钮。 + +--- + +### REQ-CYXL-004 新增常用线路 + +- 功能点: + - 支持新增常用线路,用于运单创建时发货地址与收货地址的快速选择来源。 + - 线路编号由系统自动生成,规则为 XL + 5位流水号自增,保存后全局唯一。 + - 线路名称使用文本输入框,必填,长度不超过100字符。 + - 发货地址使用地址选择器,必填,支持地图搜索选点或从常用地址库中选择。 + - 收货地址使用地址选择器,必填,支持地图搜索选点或从常用地址库中选择。 + - 选择地址后,系统自动带出地址名称、详细地址、经度、纬度,并回填到表单关联字段。 + - 发货联系人、发货联系方式、收货联系人、收货联系方式使用文本输入框,长度不超过50字符。 + - 备注使用文本输入框,长度不超过500字符。 + - 保存成功后刷新列表。 + +- 异常与边界: + - 线路名称为空时阻止提交并提示。 + - 同一组织内线路名称重复时阻止提交并提示“同一组织内线路名称不允许重复”。 + - 发货地址或收货地址为空时阻止提交并提示。 + - 发货地址和收货地址组合在同一组织内重复时阻止提交并提示。 + - 发货联系方式、收货联系方式不符合手机号或固定电话格式时阻止提交并提示。 + - 发货联系人、收货联系人超过50字符时阻止提交并提示。 + - 发货联系方式、收货联系方式超过50字符时阻止提交并提示。 + - 备注超过500字符时阻止提交并提示。 + - 选择地址后未能正确回填地址名称、详细地址、经纬度时阻止提交。 + - 提交失败时保留用户已填写内容,方便修正后重新提交。 + +- 反例: + - 不允许新增手工填写线路编号。 + - 不允许在未选择发货地址或收货地址时保存。 + - 不允许同一组织内存在同名线路。 + - 不允许同一组织内存在相同发货地址与收货地址组合的线路。 + +--- + +### REQ-CYXL-005 编辑常用线路 + +- 功能点: + - 支持编辑已存在的常用线路。 + - 线路编号在编辑状态下置灰不可编辑。 + - 线路名称可编辑,校验规则与新增一致。 + - 发货地址、收货地址可重新选择,校验规则与新增一致。 + - 发货联系人、发货联系方式、收货联系人、收货联系方式、备注可编辑。 + - 保存成功后刷新列表。 + +- 异常与边界: + - 同一组织内线路名称修改后仍需保持唯一。 + - 同一组织内发货地址与收货地址组合修改后仍需保持唯一。 + - 线路编号为空或被篡改时阻止提交。 + - 编辑的数据已不存在时提示数据不存在,并刷新列表。 + - 提交失败时保留用户修改内容。 + +- 反例: + - 不允许编辑时修改线路编号。 + - 不允许编辑后产生同名线路。 + - 不允许编辑后产生重复起讫点组合。 + +--- + +### REQ-CYXL-006 线路编号与地址联动规则 + +- 功能点: + - 线路编号由系统按 XL + 5位流水号自增自动生成。 + - 线路编号在系统中全局唯一。 + - 发货地址与收货地址支持地图搜索选点或常用地址库选择。 + - 选择地址后自动回填地址名称、详细地址、经度、纬度。 + - 切换发货地址或收货地址时,相关回填信息同步更新。 + +- 异常与边界: + - 编码生成失败时阻止保存并提示。 + - 已存在相同线路编号时阻止保存并提示。 + - 地址选择返回的信息不完整时阻止保存。 + - 发货地址与收货地址任一项变更后应重新校验重复组合。 + +- 反例: + - 不允许手动编辑线路编号。 + - 不允许地址未回填经纬度仍保存。 + - 不允许沿用旧地址信息而不重新校验。 + +--- + +### REQ-CYXL-007 批量导出 + +- 功能点: + - 支持勾选多行数据后批量导出 Excel 文件。 + - 未勾选数据时点击批量导出,默认导出当前查询条件下的全部数据。 + - 导出字段与列表显示字段一致。 + +- 异常与边界: + - 当前条件下无数据时允许导出空文件或提示无可导出数据。 + - 导出失败时提示失败原因,不改变当前勾选状态。 + +- 反例: + - 不允许只导出当前页数据。 + - 不允许未筛选时导出非当前查询条件数据。 + +--- + +### REQ-CYXL-008 单条删除 + +- 功能点: + - 支持通过行操作删除单条常用线路。 + - 点击删除弹出二次确认弹窗,提示删除后不可恢复。 + - 删除成功后刷新列表,并提示“删除成功”。 + +- 异常与边界: + - 删除前必须校验是否已被运单、合同等业务数据引用。 + - 已被引用时不允许删除,并提示“该线路已被业务引用,不可删除”。 + - 数据不存在时提示数据不存在,并刷新列表。 + +- 反例: + - 不允许跳过二次确认直接删除。 + - 不允许删除已被业务引用的常用线路。 + +--- + +### REQ-CYXL-009 批量删除 + +- 功能点: + - 支持勾选多行常用线路后批量删除。 + - 点击批量删除弹出二次确认弹窗。 + - 删除前逐一校验所选数据是否被业务引用。 + - 已引用记录从删除队列剔除并单独提示。 + - 删除成功后刷新列表,并提示“删除成功XX条,因引用跳过XX条”。 + +- 异常与边界: + - 未勾选数据时点击批量删除,应提示先选择需要删除的数据。 + - 所选数据全部被引用时不执行删除,并提示全部跳过原因。 + - 部分删除失败时应提示成功数量和跳过数量。 + +- 反例: + - 不允许批量删除已被业务引用的记录。 + - 不允许因为部分记录被引用而影响可删除记录的正常删除。 + - 不允许删除后不刷新列表。 + +--- + +### REQ-CYXL-010 组织权限与审计 + +- 功能点: + - 组织列作为数据权限字段,普通用户默认仅可查看当前组织数据。 + - 具备权限的用户可切换查看全部组织数据,但该视图仅允许只读查看。 + - 根据权限配置控制查看、编辑、删除、导出等操作入口。 + - 创建人、创建时间、更新时间由系统自动记录。 + +- 异常与边界: + - 无权限用户访问时提示权限不足。 + - 在全部组织只读视图中不开放新增、编辑、删除、导出等写操作。 + - 列表、详情、导出等用户可见场景优先展示创建人姓名,不直接展示用户 ID。 + +- 反例: + - 不允许普通用户在全部组织视图下修改数据。 + - 不允许手动维护创建人、创建时间、更新时间。 + - 不允许删除或篡改审计信息。 + +--- + +## 通用规则 + +- 常用线路用于记录企业内高频使用的运输线路,作为运单创建时发货地址与收货地址的快速选择来源。 +- 线路编号由系统自动生成,规则为 XL + 5位流水号自增,且全局唯一。 +- 同一组织内线路名称不允许重复。 +- 同一组织内相同的发货地址与收货地址组合不允许重复创建。 +- 发货地址与收货地址必须填写,且支持地图搜索选点或从常用地址库选择。 +- 选择地址后必须自动回填地址名称、详细地址、经度、纬度。 +- 发货联系方式、收货联系方式需校验手机号或固定电话格式。 +- 备注最多500字符。 +- 删除前必须校验业务引用,已引用线路不允许删除。 +- 新增、编辑、导出成功后均需刷新列表。 diff --git a/需求卡/常用货物需求卡.md b/需求卡/常用货物需求卡.md new file mode 100644 index 0000000..302e55c --- /dev/null +++ b/需求卡/常用货物需求卡.md @@ -0,0 +1,320 @@ +# 常用货物需求卡 + +## 目录 + +- [REQ-CYHW-001 列表与分页](#req-cyhw-001-列表与分页) +- [REQ-CYHW-002 条件查询与重置](#req-cyhw-002-条件查询与重置) +- [REQ-CYHW-003 查看常用货物](#req-cyhw-003-查看常用货物) +- [REQ-CYHW-004 新增常用货物](#req-cyhw-004-新增常用货物) +- [REQ-CYHW-005 编辑常用货物](#req-cyhw-005-编辑常用货物) +- [REQ-CYHW-006 编号与级联规则](#req-cyhw-006-编号与级联规则) +- [REQ-CYHW-007 下载导入模板](#req-cyhw-007-下载导入模板) +- [REQ-CYHW-008 批量导入](#req-cyhw-008-批量导入) +- [REQ-CYHW-009 批量导出](#req-cyhw-009-批量导出) +- [REQ-CYHW-010 单条删除](#req-cyhw-010-单条删除) +- [REQ-CYHW-011 批量删除](#req-cyhw-011-批量删除) +- [REQ-CYHW-012 组织权限与审计](#req-cyhw-012-组织权限与审计) +- [通用规则](#通用规则) + +--- + +### REQ-CYHW-001 列表与分页 + +- 功能点: + - 默认展示当前组织全部常用货物数据,列表按更新时间降序排列。 + - 展示组织、一级货物类型、二级货物类型、货物名称、货物编号、品牌、包装、货值、规格、计价单位、型号、说明1、尺寸、说明2、备注、创建人、更新时间、创建时间、操作等字段。 + - 支持勾选多行数据用于批量导出、批量删除。 + - 操作列固定展示查看、编辑、删除,具体显示受权限控制。 + - 普通用户默认仅看当前组织数据;具备权限时可切换查看全部组织数据,但切换后的全部组织视图仅作只读查看。 + - 分页默认10条/页,支持20/50/100条/页。 + +- 异常与边界: + - 查询无数据时展示空状态。 + - 当前页删除后无数据时自动回退页码并刷新列表。 + - 切换组织范围时保留当前查询条件,仅重载数据。 + - 列表加载失败时保留当前筛选与分页条件。 + +- 反例: + - 不允许默认按更新时间以外的字段覆盖排序规则。 + - 不允许普通用户在全部组织视图下执行编辑、删除等写操作。 + - 不允许分页后丢失当前查询条件。 + +--- + +### REQ-CYHW-002 条件查询与重置 + +- 功能点: + - 支持按一级货物类型、二级货物类型、货物名称、货物编号、品牌、组织等条件组合查询。 + - 点击查询后按条件展示数据。 + - 点击重置后清空所有条件并恢复默认列表。 + +- 异常与边界: + - 查询条件为空时点击查询,按默认规则展示当前组织全部数据。 + - 查询结果为空时展示空状态,不清空用户已输入条件。 + - 重置后页码恢复第一页,并按更新时间降序重新加载。 + +- 反例: + - 不允许重置后仍保留隐藏条件。 + - 不允许只按单一条件查询而忽略组合条件。 + - 不允许查询后改变列表字段展示范围。 + +--- + +### REQ-CYHW-003 查看常用货物 + +- 功能点: + - 支持通过行操作查看常用货物详情。 + - 详情展示所有业务字段,字段全部置灰不可编辑。 + - 查看弹窗底部仅显示关闭按钮。 + +- 异常与边界: + - 数据已删除或不存在时提示数据不存在,并刷新列表。 + - 详情加载失败时提示失败原因,不影响列表现状。 + +- 反例: + - 不允许在查看状态下保存修改。 + - 不允许查看时切换组织范围并修改数据。 + - 不允许查看弹窗出现提交按钮。 + +--- + +### REQ-CYHW-004 新增常用货物 + +- 功能点: + - 支持新增常用货物档案,货物所属类别通过一级货物类型与二级货物类型级联选择定义。 + - 一级货物类型使用下拉搜索选择。 + - 二级货物类型使用下拉搜索选择,未选一级货物类型时置灰不可操作;切换一级货物类型时二级选项自动清空并重新加载。 + - 一级货物类型、二级货物类型、货物名称、货物编号为必填字段,字段名称需展示“*”标识。 + - 选择二级货物类型后,其编码自动带出为货物编号前4位前缀。 + - 货物编号由二级货物类型编码前4位 + 用户输入2位数字后缀组成,共6位。 + - 货物名称使用文本输入框,必填,长度不超过100字符。 + - 货物编号后缀使用文本输入框,必填,仅允许输入2位数字。 + - 品牌使用文本输入框,选填,长度不超过50字符。 + - 货值使用数字输入框,选填,保留2位小数;计价单位使用下拉选择。 + - 规格使用文本输入框,选填,长度不超过50字符。 + - 型号使用文本输入框,选填,长度不超过50字符。 + - 说明1使用文本输入框,选填,长度不超过100字符。 + - 尺寸使用文本输入框,选填,长度不超过50字符。 + - 说明2使用文本输入框,选填,长度不超过100字符。 + - 备注使用文本域,选填,长度不超过200字符。 + - 包装为下拉选择,选项包含袋装、散装、桶装、箱装、托盘等。 + - 计价单位为下拉选择,选项包含元/吨、元/立方米、元/件、元/车。 + - 保存成功后刷新列表。 + +- 异常与边界: + - 一级货物类型为空时阻止提交并提示“请选择一级货物类型”。 + - 二级货物类型为空时阻止提交并提示“请选择二级货物类型”。 + - 货物名称为空、超长或格式不合法时阻止提交并提示“请输入货物名称”。 + - 货物编号后缀为空、不是2位数字或货物编号不满6位时阻止提交并提示“请输入2位数字”。 + - 选择二级货物类型后未带出前4位编码时阻止提交。 + - 二级货物类型不属于当前一级货物类型时阻止提交。 + - 货物编号重复时阻止提交并提示“该货物编号已存在”。 + - 货值小于0或小数位超过2位时阻止提交。 + - 包装或计价单位不在允许选项内时阻止提交。 + - 品牌、规格、型号、尺寸超过50字符时阻止提交。 + - 说明1、说明2超过100字符时阻止提交。 + - 备注超过200字符时阻止提交并提示。 + - 提交失败时保留用户已填写内容。 + +- 反例: + - 不允许在未选择一级货物类型时选择二级货物类型。 + - 不允许手工修改二级货物类型带出的前4位编号前缀。 + - 不允许保存重复货物编号。 + - 不允许新增启用/停用状态字段。 + +--- + +### REQ-CYHW-005 编辑常用货物 + +- 功能点: + - 支持编辑已存在的常用货物档案。 + - 一级货物类型、二级货物类型在编辑状态下置灰不可编辑。 + - 货物编号在编辑状态下置灰不可编辑。 + - 货物名称、品牌、包装、货值、规格、计价单位、型号、说明1、尺寸、说明2、备注等字段可编辑。 + - 可编辑字段的控件类型、长度限制和校验规则与新增一致。 + - 保存成功后刷新列表。 + +- 异常与边界: + - 货物名称、货值、包装、计价单位、备注等字段的校验规则与新增保持一致。 + - 编辑的数据已不存在时提示数据不存在,并刷新列表。 + - 提交失败时保留用户修改内容。 + +- 反例: + - 不允许编辑时修改一级货物类型、二级货物类型和货物编号。 + - 不允许编辑后产生重复货物编号。 + - 不允许编辑状态下绕过新增校验规则。 + +--- + +### REQ-CYHW-006 编号与级联规则 + +- 功能点: + - 常用货物所属类别由一级货物类型和二级货物类型级联定义。 + - 一级货物类型变更时,二级货物类型选项同步刷新。 + - 二级货物类型必须归属于当前选择的一级货物类型。 + - 二级货物类型编码作为货物编号前4位来源。 + - 货物编号全局唯一。 + +- 异常与边界: + - 一级货物类型未选择时二级货物类型下拉置灰不可操作。 + - 切换一级货物类型后已选二级货物类型自动清空。 + - 二级货物类型编码不存在时不允许继续保存。 + - 二级货物类型与一级货物类型不匹配时不允许继续保存。 + - 货物编号重复时阻止提交并提示“该货物编号已存在”。 + +- 反例: + - 不允许货物编号脱离二级货物类型单独维护。 + - 不允许一级、二级货物类型选错后仍沿用旧编号前缀。 + - 不允许出现同一货物编号多条记录。 + +--- + +### REQ-CYHW-007 下载导入模板 + +- 功能点: + - 支持下载 Excel 导入模板。 + - 模板字段包含一级货物类型、二级货物类型编码、货物名称、货物编号后缀、品牌、包装、单价、规格、计价单位、型号、说明1、尺寸、说明2、备注。 + - 模板中一级货物类型、二级货物类型编码、货物名称、货物编号后缀为必填字段,字段名称需增加“*”标识。 + - 模板中的字段顺序与导入校验顺序保持一致。 + - 模板字段说明需标明:货物名称不超过100字符;品牌、规格、型号、尺寸不超过50字符;说明1、说明2不超过100字符;备注不超过200字符。 + - 模板用于批量导入常用货物档案。 + +- 异常与边界: + - 模板下载失败时提示失败,允许重新下载。 + - 模板字段缺失或顺序错误时视为模板异常,应修正后再发布。 + - 模板应附带字段说明,明确货物编号后缀为2位数字,单价为数值且保留2位小数。 + +- 反例: + - 不允许模板缺少一级货物类型、二级货物类型编码、货物名称、货物编号后缀等关键字段。 + - 不允许模板包含与导入无关的状态字段。 + - 不允许模板字段与导入校验字段不一致。 + +--- + +### REQ-CYHW-008 批量导入 + +- 功能点: + - 支持上传 Excel 文件批量导入常用货物。 + - 导入时逐条校验必填项、长度、数字格式、货物编号唯一性、二级货物类型编码是否存在等规则。 + - 导入时根据二级货物类型编码自动取得4位货物编号前缀,并与货物编号后缀组成完整货物编号。 + - 导入成功的数据标记为“批量导入”。 + - 存在失败行时自动生成错误报告 Excel 并自动下载,失败文件字段顺序与原模板一致,并在最后一列追加“导入失败原因”。 + - 导入失败明细文件名包含“常用货物导入失败明细”和时间戳。 + - 导入完成后刷新列表,并在页面上方提示“导入数据成功”。 + +- 异常与边界: + - 文件格式错误时阻止导入并提示失败原因。 + - 一级货物类型为空时对应行导入失败并写入错误原因。 + - 二级货物类型编码不存在时对应行导入失败并写入错误原因。 + - 二级货物类型编码不属于填写的一级货物类型时对应行导入失败。 + - 货物名称为空或超过100字符时对应行导入失败。 + - 货物编号后缀为空或不是2位数字时对应行导入失败。 + - 货物编号重复时对应行导入失败并写入错误原因“该货物编号已存在”。 + - 品牌、规格、型号、尺寸超过50字符时对应行导入失败。 + - 说明1、说明2超过100字符时对应行导入失败。 + - 单价小于0或小数位超过2位时对应行导入失败。 + - 包装或计价单位不在允许选项内时对应行导入失败。 + - 备注超过200字符时对应行导入失败。 + - 单行错误不影响其他正确数据入库。 + - 全部失败时不入库,但仍生成错误报告。 + - 存在部分失败时下载失败明细,并提示“部分数据导入失败,已下载失败明细”。 + +- 反例: + - 不允许错误数据静默跳过。 + - 不允许错误数据入库。 + - 不允许只提示失败数量而不提供失败明细。 + +--- + +### REQ-CYHW-009 批量导出 + +- 功能点: + - 支持勾选多行数据后批量导出 Excel 文件。 + - 未勾选数据时点击批量导出,默认导出当前查询条件下的全部数据。 + - 导出字段与列表显示字段一致。 + +- 异常与边界: + - 当前条件下无数据时允许导出空文件或提示无可导出数据。 + - 导出失败时提示失败原因,不改变当前勾选状态。 + +- 反例: + - 不允许只导出当前页数据。 + - 不允许未筛选时导出非当前查询条件数据。 + +--- + +### REQ-CYHW-010 单条删除 + +- 功能点: + - 支持通过行操作删除单条常用货物。 + - 点击删除弹出二次确认弹窗,提示删除后不可恢复。 + - 删除成功后刷新列表,并提示“删除成功”。 + +- 异常与边界: + - 删除前必须校验是否已被运单、合同、报价单、库存记录等业务数据引用。 + - 已被引用时不允许删除,并 toast 提示“已被业务引用,不允许删除”。 + - 数据不存在时提示数据不存在,并刷新列表。 + +- 反例: + - 不允许跳过二次确认直接删除。 + - 不允许删除已被业务引用的常用货物。 + - 不允许用停用状态替代删除。 + +--- + +### REQ-CYHW-011 批量删除 + +- 功能点: + - 支持勾选多行常用货物后批量删除。 + - 点击批量删除弹出二次确认弹窗。 + - 删除前逐一校验所选数据是否被业务引用。 + - 已引用记录从删除队列剔除并单独提示。 + - 删除成功后刷新列表,并提示“删除成功XX条,因引用跳过XX条”。 + +- 异常与边界: + - 未勾选数据时点击批量删除,应提示先选择需要删除的数据。 + - 所选数据全部被引用时不执行删除,并提示全部跳过原因。 + - 部分删除失败时应提示成功数量和跳过数量。 + +- 反例: + - 不允许批量删除已被业务引用的记录。 + - 不允许因为部分记录被引用而影响可删除记录的正常删除。 + - 不允许删除后不刷新列表。 + +--- + +### REQ-CYHW-012 组织权限与审计 + +- 功能点: + - 组织列作为数据权限字段,普通用户默认仅可查看当前组织数据。 + - 具备权限的用户可切换查看全部组织数据,但该视图仅允许只读查看。 + - 根据权限配置控制查看、编辑、删除、导入、导出等操作入口。 + - 创建人、创建时间、更新时间由系统自动记录。 + +- 异常与边界: + - 无权限用户访问时提示权限不足。 + - 在全部组织只读视图中不开放新增、编辑、删除、导入等写操作。 + - 列表、详情、导出等用户可见场景优先展示创建人姓名,不直接展示用户 ID。 + +- 反例: + - 不允许普通用户在全部组织视图下修改数据。 + - 不允许手动维护创建人、创建时间、更新时间。 + - 不允许删除或篡改审计信息。 + +--- + +## 通用规则 + +- 常用货物是实际业务中高频使用的具体货物档案。 +- 货物所属类别必须通过一级货物类型与二级货物类型级联确定。 +- 货物编号由二级货物类型编码前4位与用户输入的2位数字后缀组成,共6位。 +- 货物编号在系统中全局唯一,新增、编辑、导入时均需校验重复;重复时提示“该货物编号已存在”。 +- 一级货物类型与二级货物类型为级联关系,一级变更时二级选项必须清空并重新加载。 +- 货物名称必填且长度不超过100字符。 +- 货值为数字,保留2位小数,不得小于0。 +- 品牌、规格、型号、尺寸最多50字符。 +- 说明1、说明2最多100字符。 +- 备注最多200字符。 +- 包装选项包含袋装、散装、桶装、箱装、托盘等;计价单位选项包含元/吨、元/立方米、元/件、元/车。 +- 新增、编辑、导入成功后均需刷新列表。 +- 删除前必须校验业务引用,已引用记录不允许删除。 diff --git a/需求卡/过程配置需求卡.md b/需求卡/过程配置需求卡.md new file mode 100644 index 0000000..c927fbf --- /dev/null +++ b/需求卡/过程配置需求卡.md @@ -0,0 +1,317 @@ +# 过程配置需求卡 + +## 目录 + +- [REQ-PROC-001 列表与分页](#req-proc-001-列表与分页) +- [REQ-PROC-002 条件查询与重置](#req-proc-002-条件查询与重置) +- [REQ-PROC-003 查看过程配置](#req-proc-003-查看过程配置) +- [REQ-PROC-004 新增过程配置](#req-proc-004-新增过程配置) +- [REQ-PROC-005 编辑过程配置](#req-proc-005-编辑过程配置) +- [REQ-PROC-006 复制过程配置](#req-proc-006-复制过程配置) +- [REQ-PROC-007 编号与唯一性规则](#req-proc-007-编号与唯一性规则) +- [REQ-PROC-008 过程节点配置与联动](#req-proc-008-过程节点配置与联动) +- [REQ-PROC-009 启用/停用](#req-proc-009-启用停用) +- [REQ-PROC-010 单条删除](#req-proc-010-单条删除) +- [REQ-PROC-011 批量删除](#req-proc-011-批量删除) +- [REQ-PROC-012 组织权限与审计](#req-proc-012-组织权限与审计) +- [通用规则](#通用规则) + +--- + +### REQ-PROC-001 列表与分页 + +- 功能点: + - 默认展示当前组织全部过程配置数据,列表按创建时间降序排列。 + - 展示配置名称、配置编号、项目、包含过程节点、状态、默认后台完成运输天数、备注、组织、创建人、创建时间、更新时间、操作等字段。 + - 支持勾选多行数据用于批量删除。 + - 操作列根据状态与权限展示查看、编辑、复制、删除、启用、停用等按钮。 + - 草稿状态显示查看、编辑、复制、删除。 + - 启用状态显示查看、编辑、复制、停用。 + - 停用状态显示查看、编辑、复制、删除、启用。 + - 分页默认10条/页,支持20/50/100条/页。 + +- 异常与边界: + - 查询无数据时展示空状态。 + - 当前页删除后无数据时自动回退页码并刷新列表。 + - 切换组织范围时保留当前查询条件,仅重载数据。 + - 列表加载失败时保留当前筛选与分页条件。 + +- 反例: + - 不允许默认按创建时间以外的字段覆盖排序规则。 + - 不允许在不满足状态条件时展示删除、启用或停用按钮。 + - 不允许分页后丢失当前查询条件。 + +--- + +### REQ-PROC-002 条件查询与重置 + +- 功能点: + - 支持按配置名称、项目、配置编号、包含过程节点、状态、组织等条件组合查询。 + - 配置名称支持模糊查询。 + - 项目支持下拉模糊搜索选择,默认范围为当前用户所属组织下的项目。 + - 配置编号支持精确匹配。 + - 包含过程节点支持多选,枚举值为接单、到场、装货、发货、在途、到货、卸货、签收、回单。 + - 状态支持全部、草稿、启用、停用,默认全部。 + - 组织默认带出当前用户所属组织。 + - 点击查询后按条件展示数据。 + - 点击重置后清空所有条件并恢复默认列表。 + +- 异常与边界: + - 查询条件为空时点击查询,按默认规则展示当前组织全部数据。 + - 查询结果为空时展示空状态,不清空用户已输入条件。 + - 重置后页码恢复第一页,并按创建时间降序重新加载。 + +- 反例: + - 不允许重置后仍保留隐藏条件。 + - 不允许只按单一条件查询而忽略组合条件。 + - 不允许查询后改变列表字段展示范围。 + +--- + +### REQ-PROC-003 查看过程配置 + +- 功能点: + - 支持通过行操作查看过程配置详情。 + - 详情展示基本信息、现行过程节点、节点启用状态、节点联动配置、默认后台完成运输天数、备注、组织、创建人、创建时间、更新时间等信息。 + - 查看状态下字段全部置灰不可编辑。 + - 查看弹窗底部仅显示关闭按钮。 + +- 异常与边界: + - 数据已删除或不存在时提示数据不存在,并刷新列表。 + - 详情加载失败时提示失败原因,不影响列表现状。 + - 仅展示已勾选启用的现行过程节点,未启用节点不展示在时间线中。 + +- 反例: + - 不允许在查看状态下保存修改。 + - 不允许查看时切换组织范围并修改数据。 + - 不允许查看弹窗出现提交按钮。 + +--- + +### REQ-PROC-004 新增过程配置 + +- 功能点: + - 支持新增过程配置,用于按项目维度配置运输过程各节点的司机打卡要求。 + - 配置编号由系统自动生成,规则为 GC + 5位流水号,保存后全局唯一。 + - 配置名称使用文本输入框,必填,长度1到100字符,同一组织内不允许重复。 + - 项目使用下拉多选控件,支持模糊搜索,必填,默认仅显示当前用户所属组织下的项目。 + - 默认后台完成运输天数使用数字输入框,非必填,最多3位整数,不设置默认值。 + - 备注使用文本输入框,非必填,长度不超过500字符。 + - 新建保存后默认状态为草稿。 + - 新建弹窗包含基本信息与过程节点配置两个区域。 + +- 异常与边界: + - 配置名称为空时阻止提交并提示“配置名称不能为空”。 + - 配置名称超过100字符时阻止提交。 + - 同一组织内配置名称重复时阻止提交并提示“配置名称已存在”。 + - 项目为空时阻止提交并提示“项目不能为空”。 + - 默认后台完成运输天数不是正整数或超过3位时阻止提交并提示“请输入正整数”。 + - 备注超过500字符时阻止提交并提示。 + - 提交失败时保留用户已填写内容。 + +- 反例: + - 不允许手工填写配置编号。 + - 不允许新增时跳过项目必填校验。 + - 不允许新增后默认直接进入启用状态。 + +--- + +### REQ-PROC-005 编辑过程配置 + +- 功能点: + - 支持编辑已存在的过程配置。 + - 配置编号在编辑状态下置灰不可编辑。 + - 配置名称可编辑,校验规则同新增。 + - 项目可重新选择,但若该配置已被运单引用,则项目不可变更。 + - 过程节点配置可调整,校验规则同新增。 + - 默认后台完成运输天数、备注可编辑。 + - 保存成功后刷新列表。 + +- 异常与边界: + - 配置名称修改后仍需满足同组织内唯一。 + - 项目被运单引用时禁止变更项目并提示。 + - 编辑的数据已不存在时提示数据不存在,并刷新列表。 + - 提交失败时保留用户修改内容。 + +- 反例: + - 不允许编辑时修改配置编号。 + - 不允许编辑后产生同组织重名配置。 + - 不允许绕过新增时的节点联动与校验规则。 + +--- + +### REQ-PROC-006 复制过程配置 + +- 功能点: + - 支持复制已有过程配置生成新配置。 + - 复制后配置名称自动追加“ - 副本”。 + - 节点设置内容全部复制。 + - 配置编号重新生成。 + - 新配置默认状态为草稿。 + - 复制后的配置可继续编辑后保存。 + +- 异常与边界: + - 复制后若配置名称仍触发同组织重复校验,则阻止保存并提示。 + - 原配置不存在时不允许复制。 + - 复制失败时不影响原配置数据。 + +- 反例: + - 不允许复制后沿用原配置编号。 + - 不允许复制后直接变为启用状态。 + - 不允许复制时丢失节点配置内容。 + +--- + +### REQ-PROC-007 编号与唯一性规则 + +- 功能点: + - 配置编号由系统自动生成,规则为 GC + 5位流水号。 + - 配置编号在系统中全局唯一。 + - 配置名称在同一组织内唯一。 + - 一个项目在同一时间只能关联一条启用状态的过程配置。 + +- 异常与边界: + - 编号生成冲突时阻止保存并重新生成。 + - 同一组织内配置名称重复时阻止保存。 + - 启用前若所选项目中存在其他启用配置时阻止启用,并提示“该项目已有关联的启用配置,请先停用原配置”。 + - 项目为多选时,需要逐个校验每个项目的启用唯一性。 + +- 反例: + - 不允许手工编辑配置编号。 + - 不允许同一组织内出现同名配置。 + - 不允许同一项目同时存在两条启用配置。 + +--- + +### REQ-PROC-008 过程节点配置与联动 + +- 功能点: + - 过程节点顺序固定,不可拖拽排序,依次为接单、到场、装货、发货、在途、到货、卸货、签收、回单。 + - 仅勾选启用的节点会展示在现行过程节点时间线中。 + - 节点配置区域以逐行方式展示,每行对应一个节点。 + - 各节点的是否打卡、上传货量、上传凭证相互独立,可单独选择或多选。 + - 节点是否确认项必须选择确认方式;接单节点可选“无需确认接单”,回单节点可选“无需确认完成”,其他节点必须选择是或否。 + - 是否打卡选否时,打卡定位、打卡频次、打卡时段置灰不可编辑。 + - 上传货量选否时,上传货量类型置灰不可编辑。 + - 上传凭证选否时,凭证类型全量置灰不可编辑。 + - 仅在途节点支持打卡频次和打卡时段,默认打卡频次为1次,默认打卡时段为00:00-24:00。 + - 接单节点的是否确认支持“无需确认接单”。 + - 回单节点的是否确认支持“无需确认完成”,且选择是时系统自动勾选内部人员。 + - 打卡定位、上传货量类型、凭证类型根据当前节点可配置项展示。 + +- 异常与边界: + - 节点是否确认项为空时阻止提交并提示“请选择确认方式”。 + - 节点是否打卡为空时阻止提交并提示“请选择是否打卡”。 + - 在途节点是否打卡为是但未配置打卡频次或打卡时段时阻止提交。 + - 在途节点打卡频次为空或小于1时阻止提交并提示“请输入打卡频次 / 打卡频次必须≥1”。 + - 在途节点打卡时段为空时阻止提交并提示“请选择打卡时段”。 + - 非在途节点出现打卡频次或打卡时段时应不展示。 + - 保存时若同时勾选签收和回单,且两者都配置上传凭证,则弹窗提示“签收与回单同时勾选了上传凭证,司机将需重复上传凭证,是否确认?”,按钮为确认、返回修改。 + - 节点启用状态与时间线展示不一致时阻止保存。 + - 选择为否后仍保留被置灰字段的旧值时,保存前应按禁用状态规则处理。 + +- 反例: + - 不允许拖拽调整节点顺序。 + - 不允许非在途节点配置打卡频次和打卡时段。 + - 不允许是否打卡为否时仍强制填写打卡定位或打卡时段。 + - 不允许上传凭证关闭后仍提交凭证类型。 + +--- + +### REQ-PROC-009 启用/停用 + +- 功能点: + - 配置状态分为草稿、启用、停用三种,新增或复制后默认进入草稿状态。 + - 草稿状态下编辑页面点击保存并启用后投入使用,状态变更为启用。 + - 启用状态下可停用,状态变更为停用。 + - 停用状态下可重新启用。 + - 停用的配置在运单创建等下游业务场景中不再展示,但历史已引用数据保留关联关系。 + +- 异常与边界: + - 草稿启用前若同一项目已有其他启用配置,则阻止启用并提示先停用原配置。 + - 启用状态停用前若存在关联的未完成运单,则阻止停用并提示“该条配置已被引用,不可停用”。 + - 停用状态重新启用时仍需重新校验同一项目启用唯一性。 + - 状态切换失败时保持原状态不变。 + +- 反例: + - 不允许启用状态直接删除。 + - 不允许绕过启用唯一性校验直接投入使用。 + - 不允许被引用的配置直接停用。 + +--- + +### REQ-PROC-010 单条删除 + +- 功能点: + - 支持通过行操作删除单条过程配置。 + - 点击删除时弹出二次确认弹窗。 + - 删除成功后刷新列表,并提示“删除成功”。 + +- 异常与边界: + - 草稿配置可直接删除。 + - 停用配置删除前需校验未被运单引用,已引用则提示“该条配置已被引用,不可删除”。 + - 启用配置不可删除,需先停用后再处理。 + - 数据不存在时提示数据不存在,并刷新列表。 + +- 反例: + - 不允许跳过二次确认直接删除。 + - 不允许删除启用状态配置。 + - 不允许删除已被引用的停用配置。 + +--- + +### REQ-PROC-011 批量删除 + +- 功能点: + - 支持勾选多行过程配置后批量删除。 + - 点击批量删除时弹出二次确认弹窗。 + - 删除时按单条规则逐一校验状态与业务引用。 + - 删除成功后刷新列表,并提示“删除成功XX条,因引用跳过XX条”。 + +- 异常与边界: + - 未勾选数据时点击批量删除,应提示先选择需要删除的数据。 + - 草稿配置可直接删除。 + - 停用配置逐条校验是否被运单引用,已引用记录剔除并单独提示。 + - 启用配置不进入删除队列,并提示需先停用。 + - 所选数据全部不满足删除条件时不执行删除。 + +- 反例: + - 不允许批量删除启用状态配置。 + - 不允许因为部分记录不可删而影响草稿记录删除。 + - 不允许删除后不刷新列表。 + +--- + +### REQ-PROC-012 组织权限与审计 + +- 功能点: + - 组织列作为数据权限字段,普通用户默认仅可查看当前组织数据。 + - 具备权限的用户可切换查看全部组织数据,但该视图仅允许只读查看。 + - 根据权限配置控制查看、编辑、复制、删除、启用、停用等操作入口。 + - 创建人、创建时间、更新时间由系统自动记录。 + +- 异常与边界: + - 无权限用户访问时提示权限不足。 + - 在全部组织只读视图中不开放新增、编辑、删除、启用、停用等写操作。 + - 列表、详情等用户可见场景优先展示创建人姓名,不直接展示用户 ID。 + +- 反例: + - 不允许普通用户在全部组织视图下修改数据。 + - 不允许手动维护创建人、创建时间、更新时间。 + - 不允许删除或篡改审计信息。 + +--- + +## 通用规则 + +- 过程配置用于按项目维度配置运输过程各节点的司机打卡要求,确保运输过程可追溯。 +- 配置编号由系统自动生成,规则为 GC + 5位流水号,且全局唯一。 +- 配置名称在同一组织内不允许重复。 +- 一个项目在同一时间只能关联一条启用状态的过程配置。 +- 过程节点顺序固定,不可拖拽排序,依次为接单、到场、装货、发货、在途、到货、卸货、签收、回单。 +- 仅勾选启用的节点才会展示在现行过程节点时间线中。 +- 是否打卡、上传货量、上传凭证为节点内相互独立的配置项,可单独配置或多选。 +- 仅在途节点支持打卡频次和打卡时段,默认打卡频次为1次,默认打卡时段为00:00-24:00。 +- 节点配置触发重复上传凭证提示时,应允许用户确认后继续或返回修改。 +- 新增、编辑、复制、启用、停用、删除成功后均需刷新列表。 +- 删除前必须校验状态与业务引用,已引用配置不允许直接删除或停用。 diff --git a/需求卡/运单管理需求卡.md b/需求卡/运单管理需求卡.md new file mode 100644 index 0000000..5a1ad05 --- /dev/null +++ b/需求卡/运单管理需求卡.md @@ -0,0 +1,1313 @@ +# 运单管理需求卡 + +## 目录 + +- [REQ-WAYB-001 菜单入口](#req-wayb-001-菜单入口) +- [REQ-WAYB-002 列表与分页](#req-wayb-002-列表与分页) +- [REQ-WAYB-003 条件查询与重置](#req-wayb-003-条件查询与重置) +- [REQ-WAYB-004 状态展示与操作列](#req-wayb-004-状态展示与操作列) +- [REQ-WAYB-005 新建运单](#req-wayb-005-新建运单) +- [REQ-WAYB-006 编辑运单](#req-wayb-006-编辑运单) +- [REQ-WAYB-007 查看运单](#req-wayb-007-查看运单) +- [REQ-WAYB-008 运单编号与关联字段规则](#req-wayb-008-运单编号与关联字段规则) +- [REQ-WAYB-009 基本信息规则](#req-wayb-009-基本信息规则) +- [REQ-WAYB-010 货物信息规则](#req-wayb-010-货物信息规则) +- [REQ-WAYB-011 承运信息规则](#req-wayb-011-承运信息规则) +- [REQ-WAYB-012 过程节点配置规则](#req-wayb-012-过程节点配置规则) +- [REQ-WAYB-013 当前过程节点规则](#req-wayb-013-当前过程节点规则) +- [REQ-WAYB-014 过程节点完成与记录](#req-wayb-014-过程节点完成与记录) +- [REQ-WAYB-015 运单状态流转](#req-wayb-015-运单状态流转) +- [REQ-WAYB-016 取消运单](#req-wayb-016-取消运单) +- [REQ-WAYB-017 重新派单](#req-wayb-017-重新派单) +- [REQ-WAYB-018 完成运单](#req-wayb-018-完成运单) +- [REQ-WAYB-019 批量完成](#req-wayb-019-批量完成) +- [REQ-WAYB-020 公路配载](#req-wayb-020-公路配载) +- [REQ-WAYB-021 导入运单](#req-wayb-021-导入运单) +- [REQ-WAYB-022 批量导出](#req-wayb-022-批量导出) +- [REQ-WAYB-023 单条删除](#req-wayb-023-单条删除) +- [REQ-WAYB-024 复制运单](#req-wayb-024-复制运单) +- [REQ-WAYB-025 权限与审计](#req-wayb-025-权限与审计) +- [REQ-WAYB-026 新增编辑页面布局](#req-wayb-026-新增编辑页面布局) +- [REQ-WAYB-027 精简录入与完整录入](#req-wayb-027-精简录入与完整录入) +- [REQ-WAYB-028 收发货信息规则](#req-wayb-028-收发货信息规则) +- [REQ-WAYB-029 公路运输任务信息](#req-wayb-029-公路运输任务信息) +- [REQ-WAYB-030 铁水空运输任务信息](#req-wayb-030-铁水空运输任务信息) +- [REQ-WAYB-031 运费信息与币种规则](#req-wayb-031-运费信息与币种规则) +- [REQ-WAYB-032 新增编辑底部按钮](#req-wayb-032-新增编辑底部按钮) +- [REQ-WAYB-033 导入批次列表与分页](#req-wayb-033-导入批次列表与分页) +- [REQ-WAYB-034 导入批次查询与重置](#req-wayb-034-导入批次查询与重置) +- [REQ-WAYB-035 导入批次状态与操作](#req-wayb-035-导入批次状态与操作) +- [REQ-WAYB-036 新建导入批次](#req-wayb-036-新建导入批次) +- [REQ-WAYB-037 导入批次详情](#req-wayb-037-导入批次详情) +- [REQ-WAYB-038 导入明细查询与列表](#req-wayb-038-导入明细查询与列表) +- [REQ-WAYB-039 编辑导入批次](#req-wayb-039-编辑导入批次) +- [REQ-WAYB-040 删除导入批次](#req-wayb-040-删除导入批次) +- [REQ-WAYB-041 新建导入页面布局](#req-wayb-041-新建导入页面布局) +- [REQ-WAYB-042 新建导入信息填写](#req-wayb-042-新建导入信息填写) +- [REQ-WAYB-043 导入模板字段](#req-wayb-043-导入模板字段) +- [REQ-WAYB-044 导入模板校验规则](#req-wayb-044-导入模板校验规则) +- [REQ-WAYB-045 导入失败报告](#req-wayb-045-导入失败报告) +- [REQ-WAYB-046 导入数据明细](#req-wayb-046-导入数据明细) +- [REQ-WAYB-047 疑似重复处理](#req-wayb-047-疑似重复处理) +- [REQ-WAYB-048 确认导入](#req-wayb-048-确认导入) +- [REQ-WAYB-049 配载与多货物导入](#req-wayb-049-配载与多货物导入) +- [REQ-WAYB-050 导入地址解析](#req-wayb-050-导入地址解析) +- [REQ-WAYB-051 新建导入操作](#req-wayb-051-新建导入操作) +- [通用规则](#通用规则) + +--- + +### REQ-WAYB-001 菜单入口 + +- 功能点: + - 运单管理模块归属于“业务管理”主菜单。 + - 在“业务管理”菜单下提供“运单管理”入口。 + - 用户进入运单管理页面后,可进行查询、新建运单、导入运单、导出、编辑、复制、取消、重新派单、完成、公路配载、删除等操作。 + +- 异常与边界: + - 无菜单权限时不展示“业务管理”或“运单管理”入口。 + - 有菜单权限但无按钮权限时,仅展示允许访问的页面和操作。 + - 菜单加载失败时提示失败原因,不影响其他菜单访问。 + +- 反例: + - 不允许把运单管理挂到非业务管理主菜单下。 + - 不允许无权限用户通过 URL 直接进入模块。 + - 不允许菜单入口存在但页面无法访问。 + +--- + +### REQ-WAYB-002 列表与分页 + +- 功能点: + - 默认展示当前组织全部运单数据,列表按创建时间降序排列。 + - 列表展示字段与编辑表单字段保持一致,并额外展示创建时间、更新时间。 + - 列表至少展示运单号、项目名称、客户名称、运输类型、货物名称、货物类型、发货地址、收货地址、承运商名称、司机姓名、车/船/航班/班列号、原始单号、状态、数据来源、开始日期、结束日期、计划名称、多联总单、配载单号、运单批次号、关联单号、当前过程节点、操作等信息。 + - 状态列和操作按钮列固定在右侧,不随横向滚动条滑动。 + - 支持勾选多行用于批量完成和批量导出。 + - 分页默认10条/页,支持20/50/100条/页。 + +- 异常与边界: + - 查询无数据时展示空状态。 + - 横向字段较多时允许表格横向滚动,但状态列和操作列必须保持固定。 + - 当前页数据因删除、取消、完成、导入等操作发生变化后,应刷新列表并保持分页逻辑正确。 + - 列表加载失败时保留当前查询条件和分页条件,提示用户重新查询。 + +- 反例: + - 不允许状态列或操作列被横向滚动隐藏。 + - 不允许列表字段与编辑表单长期不一致。 + - 不允许分页后丢失当前查询条件。 + +--- + +### REQ-WAYB-003 条件查询与重置 + +- 功能点: + - 支持按运单号、项目名称、客户名称、运输类型、货物名称、货物类型、发货地址、收货地址、承运商名称、司机姓名、车/船/航班/班列号、原始单号、状态、数据来源、开始日期、结束日期、计划名称、多联总单、配载单号、运单批次号、关联单号等条件组合查询。 + - 运单号、货物名称、发货地址、收货地址、原始单号、多联总单、配载单号、运单批次号、关联单号使用输入框。 + - 项目名称、客户名称、货物类型、承运商名称、司机姓名使用输入搜索下拉框。 + - 运输类型、状态、数据来源使用下拉单选控件。 + - 开始日期、结束日期使用日期选择器。 + - 点击查询后按当前条件筛选列表。 + - 点击重置后清空所有查询条件,恢复默认列表。 + - 查询条件过多时支持展开/收起,默认折叠展示。 + +- 异常与边界: + - 查询条件为空时点击查询,按默认规则展示全部数据。 + - 查询结果为空时展示空状态,不清空用户已输入条件。 + - 重置后页码恢复第一页,并重新加载列表。 + - 日期格式不合法或开始日期晚于结束日期时阻止查询并提示。 + +- 反例: + - 不允许重置后仍保留隐藏查询条件。 + - 不允许只按单个条件查询而忽略其他已选择条件。 + - 不允许日期范围错误时继续请求列表数据。 + +--- + +### REQ-WAYB-004 状态展示与操作列 + +- 功能点: + - 运单状态包含草稿、待执行、进行中、已完成、已取消。 + - 草稿状态可执行编辑、删除、复制。 + - 待执行状态在司机未接单时可执行详情、编辑、复制、取消。 + - 待执行状态在司机拒绝接单时可执行详情、重新派单、复制、取消。 + - 进行中状态可执行详情、复制、完成。 + - 已完成状态可执行详情、复制。 + - 已取消状态可执行详情、复制。 + - 操作按钮列固定在右侧,按钮展示受状态和权限共同控制。 + +- 异常与边界: + - 状态为空或状态值未知时,列表应展示兜底文案,并限制高风险操作。 + - 操作执行前需重新校验最新状态,避免列表状态过期导致误操作。 + - 状态变更成功后刷新列表,展示最新状态和可执行操作。 + +- 反例: + - 不允许草稿状态执行完成或取消。 + - 不允许已完成或已取消状态继续编辑、删除、完成。 + - 不允许仅根据前端显示状态跳过后端状态校验。 + +--- + +### REQ-WAYB-005 新建运单 + +- 功能点: + - 点击“新建运单”按钮后进入新建运单页面。 + - 新建页面包含基本信息、收发货信息、任务信息或货物信息、承运信息、费用信息、附件等区域。 + - 新建页面默认展示精简录入,支持切换完整录入。 + - 精简录入下货物信息以简写字段展示;完整录入下货物信息以列表方式维护。 + - 新建页面底部展示运费合计、查看过程配置、返回、暂存、确认等操作。 + - 新建页面支持暂存为草稿或提交创建。 + - 新建保存后按项目过程配置自动决定初始状态。 + - 保存成功后刷新列表。 + +- 异常与边界: + - 运单号生成失败时阻止保存并提示。 + - 项目、客户、客户合同、运输类型、货物信息、承运信息等必填项为空时阻止提交并提示。 + - 运单货物名称、数量、计量单位为空时阻止提交并提示。 + - 字段长度、日期、数值、枚举、附件格式不符合规则时阻止提交并提示。 + - 切换精简录入和完整录入时,应保留两种录入方式共用字段。 + - 提交失败时保留用户已填写内容,方便修正后重新提交。 + +- 反例: + - 不允许用户手工填写或修改运单号。 + - 不允许确认保存缺少项目、合同、运输类型、货物名称、数量、计量单位的运单。 + - 不允许保存后不刷新列表。 + +--- + +### REQ-WAYB-006 编辑运单 + +- 功能点: + - 草稿、待执行状态支持点击编辑,跳转至编辑页面。 + - 编辑页面回显运单完整信息。 + - 运单号在编辑状态下只读不可编辑。 + - 项目、客户、客户合同、发货计划、运输类型、收发货信息、货物信息、承运信息、费用信息、附件、备注等字段按规则编辑。 + - 编辑页面支持精简录入和完整录入切换,校验规则同新建。 + - 编辑保存成功后刷新列表,并展示最新更新时间。 + +- 异常与边界: + - 编辑前需校验当前运单状态,非草稿、非待执行状态不允许进入可编辑提交流程。 + - 修改项目时,客户和客户合同应按新项目重新带出或重新选择。 + - 修改运输类型时,车/船/航班/班列号字段、过程节点和校验规则应按新运输类型重新匹配。 + - 修改运输类型后,收发货地址、任务信息和费用币种应按新运输类型重新校验。 + - 编辑的数据已不存在时提示数据不存在,并刷新列表。 + - 提交失败时保留用户修改内容。 + +- 反例: + - 不允许编辑时修改运单号。 + - 不允许进行中、已完成、已取消状态继续提交编辑。 + - 不允许修改运输类型后继续沿用旧类型不适用的信息。 + +--- + +### REQ-WAYB-007 查看运单 + +- 功能点: + - 支持点击详情查看运单完整信息。 + - 详情页展示基本信息、货物信息、承运信息、过程节点、当前过程节点、附件、状态、创建时间、更新时间等内容。 + - 详情页字段仅供查看,不允许编辑。 + - 详情页可查看过程节点时间线和节点记录。 + +- 异常与边界: + - 数据已删除或不存在时提示数据不存在,并刷新列表。 + - 详情加载失败时提示失败原因,不改变列表数据。 + - 附件加载失败时不影响其他字段展示。 + +- 反例: + - 不允许在详情状态下保存修改。 + - 不允许详情页出现删除货物、上传附件等编辑操作。 + - 不允许查看时自动切换为编辑状态。 + +--- + +### REQ-WAYB-008 运单编号与关联字段规则 + +- 功能点: + - 运单号由系统自动生成,且全局唯一,只读不可编辑。 + - 原始单号用于承接业务侧自有单号,不要求与系统运单号一致。 + - 多联总单用于标记同一批次拆分成多条明细的总单。 + - 配载单号用于关联公路配载业务。 + - 运单批次号用于批量导入或批量生成场景的批次关联。 + - 关联单号用于把当前运单和其他业务单据建立追溯关系。 + +- 异常与边界: + - 运单号生成冲突时阻止保存并重新生成。 + - 关联字段为空时可按业务规则允许,但不影响运单号唯一性。 + - 同一业务标识字段被重复使用时应按业务规则提示重复风险。 + +- 反例: + - 不允许手工编辑系统运单号。 + - 不允许把原始单号当作系统运单号使用。 + - 不允许多联总单、配载单号、运单批次号混用后仍无法追溯。 + +--- + +### REQ-WAYB-009 基本信息规则 + +- 功能点: + - 基本信息包含项目、客户合同、发货计划、原始单号、运输类型、配载单号、多联总单号、关联单号、备注、数据来源等字段。 + - 项目使用模糊搜索选择框,必填。 + - 客户合同选择项目后联动带出;若项目下存在多个客户合同,则以下拉方式供用户选择。 + - 发货计划使用选择框,支持按发货计划搜索选择,非必填。 + - 原始单号使用输入框,非必填。 + - 运输类型使用下拉单选控件,枚举包含公路整车、公路配载/零担、铁路运输、水路运输、跨境海运、航空运输。 + - 配载单号、多联总单号、关联单号使用输入框,非必填,最多30个字符。 + - 备注使用输入框或文本域,非必填,最多500字。 + - 数据来源用于标记运单创建渠道,创建后只读展示。 + +- 异常与边界: + - 项目为空时阻止提交并提示。 + - 客户合同未能根据项目带出时阻止提交,并提示用户重新选择项目。 + - 运输类型为空或不在允许枚举内时阻止提交。 + - 配载单号、多联总单号、关联单号超过30个字符时阻止提交。 + - 备注超过500字时阻止提交。 + +- 反例: + - 不允许未选项目时选择客户合同。 + - 不允许客户合同脱离项目单独维护。 + - 不允许使用非枚举运输类型。 + +--- + +### REQ-WAYB-010 货物信息规则 + +- 功能点: + - 货物信息支持单行或多行维护。 + - 运单货物信息中货物名称、货物类型、数量、计量单位均为必填。 + - 包装、规格、型号、物料编码等字段可按业务需要填写。 + - 货物名称和货物类型可用于列表查询和详情展示。 + - 精简录入字段来源于完整录入,字段说明和校验规则与完整录入保持一致。 + - 完整录入下货物信息列表与发货模板的新建运单模板货物信息保持一致。 + - 支持导入货物和选择常用货物。 + - 多货物运单支持通过多联总单或同一运单批次号进行关联。 + +- 异常与边界: + - 货物名称为空时阻止提交并提示。 + - 货物类型为空或不属于系统维护货物类型时阻止提交并提示。 + - 数量为空、为0、为负数或格式错误时阻止提交。 + - 计量单位为空或不是系统枚举值时阻止提交并提示。 + - 删除最后一行货物明细时应保留一条空行或提示至少保留一行。 + - 从精简录入切换为完整录入时,应将已填写的货物名称、货物类型、数量、计量单位带入货物列表。 + - 从完整录入切换为精简录入时,如存在多行货物,需按系统规则提示用户确认是否保留完整录入方式。 + +- 反例: + - 不允许无货物明细的运单进入提交流程。 + - 不允许货物名称、数量、计量单位为空的明细行参与保存。 + - 不允许多货物运单不做关联标记而无法追溯。 + +--- + +### REQ-WAYB-011 承运信息规则 + +- 功能点: + - 承运信息根据运输类型和承运类型展示不同字段。 + - 运输类型为公路时,承运类型默认显示承运商模式,可切换为自运模式。 + - 承运类型为承运商时,承运商为必填,使用输入搜索选择框,从已维护的承运商档案中选择。 + - 承运类型为自运时,不展示承运商字段,也不要求填写承运商。 + - 运输类型为公路时,车牌号为必填,挂车车牌号、押运人、押运人手机号、里程、预计发货日期、预计完成日期、备注按规则填写。 + - 运输类型为铁路、水路、跨境海运、航空时,载具字段按船/航班/班列号展示并必填;船长、联系电话、箱号、舱位等字段按运输类型展示。 + - 司机姓名、船长等人员字段支持输入或搜索选择。 + - 承运商、司机信息可用于导入、批量赋值和重新派单。 + +- 异常与边界: + - 承运商模式下承运商为空时阻止提交并提示。 + - 自运模式下司机姓名、司机手机号、车牌号为空时阻止提交并提示。 + - 运输类型为公路整车或公路配载/零担时,车牌号需满足首位汉字、次位大写字母、总长度7位或8位。 + - 司机手机号有值时需校验11位数字格式。 + - 船/航班/班列号为空或超过30个字符时阻止提交。 + - 船长超过20个字符、舱位或箱号超过30个字符时阻止提交。 + - 里程有值时必须为正整数且最多10个字符。 + - 预计完成日期早于预计发货日期时阻止提交。 + +- 反例: + - 不允许公路运单缺失车牌号。 + - 不允许承运商模式下不填写承运商。 + - 不允许自运模式下仍要求填写承运商。 + - 不允许非公路运输继续沿用公路车牌号字段口径。 + +--- + +### REQ-WAYB-012 过程节点配置规则 + +- 功能点: + - 过程节点顺序固定,不可拖拽排序,依次为接单、到场、装货、发货、在途、到货、卸货、签收、回单。 + - 节点配置由项目对应的过程配置决定是否启用。 + - 接单节点支持“无需确认接单”。 + - 回单节点支持“无需确认完成”。 + - 仅启用的节点参与运单过程展示和状态流转。 + +- 异常与边界: + - 节点顺序被篡改时阻止保存。 + - 未启用节点不应参与当前过程节点展示。 + - 接单或回单节点的特殊确认项为空时应按默认规则处理或阻止提交。 + +- 反例: + - 不允许拖拽调整节点顺序。 + - 不允许把在途节点移到最后一个节点。 + - 不允许未启用节点仍进入过程展示。 + +--- + +### REQ-WAYB-013 当前过程节点规则 + +- 功能点: + - 当前过程节点用于展示运单当前所处的流程节点。 + - 未配置过程或当前还没有完成的节点时,当前过程节点显示“/”。 + - 已完成一个节点后,当前过程节点更新为最新完成节点。 + - 当前过程节点在列表、详情页中均可展示。 + +- 异常与边界: + - 运单未配置过程节点时显示“/”。 + - 运单尚未完成任何节点时显示“/”。 + - 当前过程节点与后台记录不一致时,以后台最新记录为准并刷新展示。 + +- 反例: + - 不允许未完成节点时显示错误节点名称。 + - 不允许将未配置过程的运单强行显示为某个节点。 + - 不允许前端缓存旧节点而不刷新。 + +--- + +### REQ-WAYB-014 过程节点完成与记录 + +- 功能点: + - 每完成一个节点,后台记录完成时间。 + - 节点完成后在过程节点上标记为“已XX”,在途节点除外。 + - 接单、到场、装货、发货、到货、卸货、签收、回单等节点按固定顺序逐步完成。 + - 过程节点记录可用于详情页展示和状态流转判断。 + +- 异常与边界: + - 节点未完成前不记录完成时间。 + - 已完成节点重复完成时应阻止或按幂等规则处理。 + - 节点完成时间写入失败时不应造成状态展示错误。 + +- 反例: + - 不允许节点未完成却先写入完成时间。 + - 不允许把在途节点标记成“已在途”。 + - 不允许过程节点完成后不刷新当前节点展示。 + +--- + +### REQ-WAYB-015 运单状态流转 + +- 功能点: + - 如果运单对应项目未配置过程节点、未配置接单节点或接单节点配置为无需确认接单,则运单创建后状态默认为进行中。 + - 如果运单对应项目配置了需司机确认接单,则运单创建后默认待执行,司机接单后变为进行中。 + - 如果项目配置了需司机确认接单,则运单创建后在待执行阶段等待司机接单或拒绝。 + - 当最后一个节点是到货、卸货、签收任意一个,且回单配置为无需确认完成时,司机打卡完成最后一个节点后,运单状态自动流转为已完成。 + - 非上述自动完成条件下,运单不会自动流转为已完成,需内部人员手工完成。 + +- 异常与边界: + - 状态流转前需重新校验过程配置和节点完成情况。 + - 状态已变化时,列表和详情应同步刷新。 + - 司机接单、司机拒绝、节点完成等事件应以后台最新状态为准。 + +- 反例: + - 不允许未配置接单却进入待执行。 + - 不允许未完成最后节点却自动变成已完成。 + - 不允许跳过过程节点完成状态直接完成运单。 + +--- + +### REQ-WAYB-016 取消运单 + +- 功能点: + - 草稿、待执行和进行中且未发货前的运单支持取消。 + - 点击取消后弹出确认弹窗。 + - 确认后运单状态变更为已取消。 + - 取消后刷新列表,当前过程节点按取消前状态保留追溯信息。 + +- 异常与边界: + - 已完成或已取消状态不允许取消。 + - 取消前如运单已发货,则阻止取消并提示。 + - 用户取消弹窗时不改变运单状态。 + +- 反例: + - 不允许已发货后的运单继续取消。 + - 不允许跳过二次确认直接取消。 + - 不允许取消成功后仍显示原状态。 + +--- + +### REQ-WAYB-017 重新派单 + +- 功能点: + - 当待执行状态下司机拒绝接单时,列表操作列展示重新派单。 + - 点击重新派单后跳转至编辑页面底部定位区域,允许重新修改司机和司机手机号等信息。 + - 重新派单后运单继续保持待执行状态,等待新的司机接单。 + +- 异常与边界: + - 仅司机拒绝接单场景展示重新派单。 + - 重新派单前需校验运单当前状态仍为待执行。 + - 司机和手机号修改后需重新校验必填与格式。 + +- 反例: + - 不允许普通待执行状态无拒绝记录时重新派单。 + - 不允许重新派单后直接进入进行中。 + - 不允许跳转编辑后不允许修改司机信息。 + +--- + +### REQ-WAYB-018 完成运单 + +- 功能点: + - 进行中状态支持内部人员手动点击完成。 + - 点击完成后,系统依据当前过程节点和业务完成情况将运单状态变更为已完成。 + - 当最后一个节点满足无需确认完成时,也可由司机打卡触发自动完成。 + - 完成后刷新列表和详情。 + +- 异常与边界: + - 待执行、已完成、已取消状态不允许手动完成。 + - 完成前需重新校验当前过程节点和最后节点状态。 + - 完成失败时提示失败原因,运单保持原状态。 + +- 反例: + - 不允许未进入进行中就完成运单。 + - 不允许已取消运单被手工完成。 + - 不允许完成后不刷新列表。 + +--- + +### REQ-WAYB-019 批量完成 + +- 功能点: + - 支持勾选多条运单后批量完成。 + - 系统逐条校验所选运单是否处于可完成状态。 + - 校验通过的运单批量完成,完成后刷新列表。 + +- 异常与边界: + - 未勾选数据时点击批量完成,应提示先选择运单。 + - 非进行中状态的记录不参与批量完成。 + - 部分记录不可完成时,应单独提示并保留可完成记录的处理结果。 + +- 反例: + - 不允许未选中任何运单直接批量完成。 + - 不允许已完成或已取消运单参与批量完成。 + - 不允许批量完成后不刷新列表。 + +--- + +### REQ-WAYB-020 公路配载 + +- 功能点: + - 列表顶部提供公路配载按钮。 + - 点击公路配载后跳转至“配载管理-新建编辑”页面。 + - 公路配载用于处理公路配载或零担场景的运单拆分与配载。 + +- 异常与边界: + - 非公路运输类型不应展示公路配载入口。 + - 运单状态不允许参与配载时,应提示并禁止跳转。 + - 跳转失败时不改变当前运单数据。 + +- 反例: + - 不允许水运、铁路、航空运单执行公路配载。 + - 不允许跳转到错误的业务页面。 + - 不允许配载失败后提示成功。 + +--- + +### REQ-WAYB-021 导入运单 + +- 功能点: + - 支持点击“导入运单”进入导入页面。 + - 导入运单入口进入导入批次管理页面,用户可新建导入批次、查询导入批次、查看导入详情、编辑草稿批次、删除草稿批次。 + - 支持下载导入模板并上传 Excel 文件。 + - 导入后系统自动校验字段格式、运单状态、过程节点、运单号、配载关系、承运信息、货物信息、时间和费用等规则。 + - 校验通过的数据进入待导入明细或直接生成运单,按页面导入规则处理。 + - 存在失败数据时自动生成错误报告并下载。 + +- 异常与边界: + - 上传文件格式不支持时阻止导入并提示。 + - 必填字段为空、枚举错误、日期错误、费用错误时对应行导入失败。 + - 校验失败行不应直接进入正式运单。 + - 导入完成后刷新列表。 + +- 反例: + - 不允许错误数据静默入库。 + - 不允许导入模板与导入校验字段不一致。 + - 不允许失败后不下载错误报告。 + +--- + +### REQ-WAYB-022 批量导出 + +- 功能点: + - 支持勾选多行后批量导出运单 Excel 文件。 + - 未勾选数据时点击批量导出,默认导出当前查询条件下的全部数据。 + - 导出字段与列表显示字段一致。 + +- 异常与边界: + - 当前查询条件下无数据时允许导出空文件或提示无可导出数据。 + - 导出失败时提示失败原因,不改变当前勾选状态。 + +- 反例: + - 不允许只导出当前页数据。 + - 不允许导出字段与列表字段不一致。 + - 不允许导出失败后提示成功。 + +--- + +### REQ-WAYB-023 单条删除 + +- 功能点: + - 草稿状态支持通过行操作删除单条运单。 + - 点击删除后弹出二次确认弹窗。 + - 确认后删除成功并刷新列表。 + +- 异常与边界: + - 非草稿状态不允许删除。 + - 删除前状态已变化为非草稿时阻止删除,并刷新列表。 + - 数据不存在时提示数据不存在,并刷新列表。 + +- 反例: + - 不允许跳过二次确认直接删除。 + - 不允许删除待执行、进行中、已完成、已取消运单。 + - 不允许删除失败后仍提示成功。 + +--- + +### REQ-WAYB-024 复制运单 + +- 功能点: + - 任意状态的运单均支持复制。 + - 复制后生成新的草稿运单,运单号重新生成。 + - 复制时保留运单基础信息、货物信息、承运信息和过程配置相关信息,状态与过程记录重新初始化。 + - 复制成功后跳转编辑页面。 + +- 异常与边界: + - 原运单不存在时提示数据不存在。 + - 复制后名称、编号或关联字段触发唯一性校验时应重新处理。 + - 复制失败时不影响原运单数据。 + +- 反例: + - 不允许复制后沿用原运单号。 + - 不允许复制后直接生成进行中或已完成状态。 + - 不允许复制后保留原过程节点完成记录。 + +--- + +### REQ-WAYB-025 权限与审计 + +- 功能点: + - 根据用户权限控制查询、新建运单、导入、导出、编辑、复制、删除、取消、重新派单、完成、公路配载等操作入口。 + - 创建时间、更新时间由系统自动记录。 + - 若列表或详情展示创建人、更新人等审计字段,应优先展示姓名,不直接展示用户 ID。 + +- 异常与边界: + - 无权限访问时提示权限不足。 + - 无按钮权限时不展示对应按钮,并阻止绕过页面发起操作。 + - 操作失败时不记录为成功日志。 + +- 反例: + - 不允许无权限用户执行新增、编辑、删除、取消、完成等操作。 + - 不允许用户手动维护创建时间、更新时间。 + - 不允许直接向用户展示 createUser、updateUser 等用户 ID 字段。 + +--- + +### REQ-WAYB-026 新增编辑页面布局 + +- 功能点: + - 新增和编辑页面采用分区布局,包含基本信息、收发货信息、任务信息或货物信息、承运信息、费用信息、附件等区域。 + - 基本信息区展示项目、客户合同、发货计划、原始单号、运输类型、配载单号、多联总单号、关联单号、备注等字段。 + - 收发货信息区展示发货地址、收货地址、发货联系人、发货联系方式、收货联系人、收货联系方式、计划发货日期、计划完成日期等字段。 + - 页面默认展示精简录入模式,用户可点击“精简录入/完整录入”切换。 + - 精简录入下任务信息将货物和承运关键字段集中展示。 + - 完整录入下拆分展示货物信息列表、承运信息、费用信息、附件等区域。 + - 页面底部固定展示运费合计、查看过程配置、返回、暂存、确认等操作。 + +- 异常与边界: + - 编辑页面加载失败时提示失败原因,不展示空白可编辑表单。 + - 从模板、计划、配载或导入入口带入的数据应按当前页面字段完整回填。 + - 字段因运输类型切换而不适用时,应清空或置灰不适用字段并重新校验。 + - 页面存在未保存内容时点击返回,应按系统统一规则提示用户确认。 + +- 反例: + - 不允许新增编辑页面缺少基本信息、收发货信息或货物信息区域。 + - 不允许从完整录入切回精简录入时静默丢失用户已填字段。 + - 不允许底部确认按钮被页面滚动内容遮挡。 + +--- + +### REQ-WAYB-027 精简录入与完整录入 + +- 功能点: + - 新增和编辑运单默认展示精简录入。 + - 精简录入用于快速填写单票运单核心字段,主要展示货物类型、货物名称、数量、计量单位、承运商或司机、车牌号或载具号、预计发货日期、预计完成日期、单价、备注等字段。 + - 完整录入用于填写完整运单信息,货物信息以列表方式展示,包含导入货物、常用货物、新增、删除等能力。 + - 精简录入字段来源于完整录入字段,字段说明和校验规则与完整录入保持一致。 + - 点击“精简录入/完整录入”可切换两种填写模式。 + - 完整录入表单与发货模板的新建运单模板保持一致。 + +- 异常与边界: + - 精简录入切换至完整录入时,应将精简录入已填的货物名称、货物类型、数量、计量单位、承运信息、费用信息等字段带入完整录入。 + - 完整录入存在多行货物时,切换回精简录入应提示用户确认或保留完整录入模式。 + - 两种模式切换后,应重新计算运费合计。 + - 切换模式不得绕过必填、格式、金额、日期等校验规则。 + +- 反例: + - 不允许精简录入与完整录入字段校验不一致。 + - 不允许切换录入模式后丢失已填写的货物数量或承运信息。 + - 不允许完整录入多货物被无提示压缩为单货物精简录入。 + +--- + +### REQ-WAYB-028 收发货信息规则 + +- 功能点: + - 收发货信息字段与发货模板的新建运单模板保持一致。 + - 发货地址、收货地址为必填。 + - 公路运输时,发货地址和收货地址可从常用地址选择、从常用线路回填,或按地址选择逻辑填写。 + - 运输类型为铁路、水路、跨境海运、航空等非公路类型时,收发地址只能从对应基础数据中选择。 + - 铁路运输选择站点,水路或跨境海运选择港口,航空运输选择空港。 + - 选择常用地址或常用线路后,系统自动回填地址名称、详细地址、联系人、联系方式等信息。 + - 非公路运输选择基础数据后,自动带出港口、空港或站点的名称和详细地址。 + +- 异常与边界: + - 发货地址或收货地址为空时阻止提交并提示。 + - 当运输类型为非公路时,如果常用地址或选择路线带出的地址不是对应运输类型的港口、空港或站点,则 toast 提示“请选择港口/空港/车站地址”。 + - 切换运输类型后,应清空不适用的收发货地址,并要求重新选择。 + - 联系方式有值时需校验手机号或固定电话格式。 + - 计划完成日期早于计划发货日期时阻止提交并提示。 + +- 反例: + - 不允许非公路运输使用公路地址自由输入逻辑。 + - 不允许水运选择空港、空运选择港口、铁路选择港口作为收发地址。 + - 不允许保存缺失发货地址或收货地址的运单。 + +--- + +### REQ-WAYB-029 公路运输任务信息 + +- 功能点: + - 运输类型为公路时,任务信息默认显示承运商模式。 + - 承运类型使用单选标签,选项为承运商、自运。 + - 承运商模式下,承运商为必填,使用输入搜索选择框,从承运商档案中选择。 + - 自运模式下,不展示承运商字段,承运商不需要填写。 + - 自运模式下,司机、司机手机号、车牌号为必填。 + - 司机支持输入或搜索选择;从司机档案选择时自动带出手机号,也支持手工录入非系统维护司机。 + - 公路任务字段包含车牌号、挂车车牌号、押运人、押运人手机号、里程、预计发货日期、预计完成日期、备注。 + - 车牌号最多30个字符,挂车车牌号最多30个字符,司机、押运人最多20个字符,手机号最多20个字符。 + - 里程为正整数,最多10个字符。 + +- 异常与边界: + - 承运商模式下未选择承运商时阻止提交。 + - 自运模式下司机、司机手机号或车牌号为空时阻止提交。 + - 车牌号格式不符合公路车辆规则时阻止提交。 + - 司机手机号、押运人手机号格式不合法时阻止提交。 + - 预计完成日期早于预计发货日期时阻止提交。 + - 备注超过500字时阻止提交。 + +- 反例: + - 不允许承运商模式下缺少承运商。 + - 不允许自运模式下仍强制填写承运商。 + - 不允许公路运单缺失车牌号。 + +--- + +### REQ-WAYB-030 铁水空运输任务信息 + +- 功能点: + - 运输类型为铁路、水路、跨境海运、航空时,任务信息展示非公路特殊字段,其余规则与公路运单一致。 + - 非公路运输的载具字段显示为船/航班/班列号,必填,最多30个字符。 + - 水路或跨境海运可填写船长、舱位、箱号等字段。 + - 船长最多20个字符,舱位最多30个字符,箱号最多30个字符。 + - 非公路运输可填写联系电话、预计发货日期、预计完成日期、备注等信息。 + - 运输类型切换为铁路、水路、跨境海运、航空后,应按对应类型刷新载具字段名称和收发地址选择规则。 + +- 异常与边界: + - 船/航班/班列号为空时阻止提交并提示。 + - 船/航班/班列号超过30个字符时阻止提交。 + - 船长、舱位、箱号超过长度限制时阻止提交。 + - 联系电话有值时需校验手机号或固定电话格式。 + - 非公路运输仍填写公路车牌号字段时,应按当前运输类型忽略或清空不适用字段。 + +- 反例: + - 不允许铁、水、空运单缺失船/航班/班列号。 + - 不允许非公路运输继续展示主车车牌号作为必填字段。 + - 不允许运输类型切换后沿用旧运输类型的载具字段名称。 + +--- + +### REQ-WAYB-031 运费信息与币种规则 + +- 功能点: + - 运费信息包含单价、计价单位、数量合计、运费、其他运费合计、运费合计、币种等字段。 + - 运费合计等于运费加其他运费合计,由系统自动计算并只读展示。 + - 运费由系统根据货物数量或货物列表中数量求和乘以单价自动计算。 + - 运费允许用户修改。 + - 数量合计由货物信息中的数量自动汇总。 + - 公路类型默认币种为 CNY。 + - 铁路、水路、跨境海运、航空类型支持选择币种 CNY 或 USD。 + - 完整录入下支持录入应收费用。 + +- 异常与边界: + - 货物数量、计量单位或单价缺少任一项时,不自动计算运费。 + - 不同计量单位的货物数量应按单位分别汇总或提示无法合并,不得无提示合并。 + - 单价、运费、其他运费合计不能小于0,金额最多保留2位小数。 + - 运费合计计算失败时提示计算异常,并阻止确认提交。 + - 币种不在 CNY、USD 等允许枚举内时阻止提交。 + +- 反例: + - 不允许运费合计被手工修改。 + - 不允许数量或单价缺失时强制自动计算运费。 + - 不允许公路运单默认币种展示为 USD。 + +--- + +### REQ-WAYB-032 新增编辑底部按钮 + +- 功能点: + - 新增和编辑页面底部操作按钮与发货模板的新建运单模板保持一致。 + - 底部左侧展示运费合计和查看过程配置入口。 + - 若当前项目未配置过程配置,则不展示查看过程配置入口。 + - 点击查看过程配置后弹出过程配置查看弹窗,只读展示当前项目的过程节点配置。 + - 底部右侧展示返回、暂存、确认按钮。 + - 点击返回时返回运单列表,不保存当前数据。 + - 点击暂存时保存草稿。 + - 点击确认时执行完整校验并按状态规则创建或更新运单。 + +- 异常与边界: + - 确认校验失败时停留在当前页面,并提示需要修改的字段。 + - 暂存失败时保留用户已填写内容。 + - 重复点击暂存或确认时应防止重复提交。 + - 查看过程配置加载失败时提示失败原因,不影响当前表单内容。 + +- 反例: + - 不允许点击返回后悄悄保存数据。 + - 不允许未配置过程配置时仍展示查看过程配置入口。 + - 不允许确认时绕过货物名称、数量、计量单位等运单必填校验。 + +--- + +### REQ-WAYB-033 导入批次列表与分页 + +- 功能点: + - 导入运单页面默认展示导入批次列表。 + - 页面顶部展示导入批次查询区域,查询区域下方展示操作按钮区和导入批次列表。 + - 操作按钮区固定展示“新建导入”“批量删除”按钮,按钮展示受权限控制。 + - 列表展示序号、运单批次号、项目名称、承运商、承运类型、运单数、导入方式、创建时间、更新时间、状态、操作等字段。 + - 列表首列支持复选框勾选,用于批量删除草稿导入批次。 + - 序号为列表行序号,按当前分页自增,从1开始。 + - 运单批次号为导入批次的唯一编号,示例格式为 PC202606010001,支持点击查看导入批次详情。 + - 项目名称取自项目档案。 + - 承运商在自运或承运商模式下按导入数据解析展示。 + - 承运类型枚举为承运商、自运。 + - 运单数展示本次导入批次包含的运单数量,为校验成功并导入的运单总数。 + - 导入方式枚举为 API 对接、手工导入。 + - 创建时间、更新时间精确到分钟,格式为 yyyy-MM-dd HH:mm。 + - 状态展示为标签样式,不同状态使用不同颜色区分。 + - 状态列和操作按钮列固定在右侧,不随横向滚动条滑动。 + - 支持分页展示,默认10条/页,支持20/50/100条/页。 + +- 异常与边界: + - 查询无数据时展示空状态。 + - 横向字段较多时允许列表横向滚动,但状态列和操作列必须保持固定。 + - 批次列表加载失败时保留当前查询条件和分页条件。 + - 运单批次号为空或重复时应阻止入库并提示。 + - 更新时间为空时展示“/”,不得展示空白或后端原始空值。 + +- 反例: + - 不允许状态列或操作列被横向滚动隐藏。 + - 不允许运单批次号重复。 + - 不允许把导入失败的数据计入运单数。 + - 不允许列表批量删除入口删除导入完成状态批次。 + +--- + +### REQ-WAYB-034 导入批次查询与重置 + +- 功能点: + - 支持按运单批次号、承运商、创建时间、创建人、状态等条件查询导入批次。 + - 运单批次号使用输入框,支持模糊查询。 + - 承运商使用输入搜索选择框。 + - 创建时间使用日期选择器或日期范围选择器。 + - 创建人使用输入框。 + - 状态使用下拉单选控件。 + - 状态查询枚举包含草稿、导入完成。 + - 点击查询后,根据查询条件刷新批次列表。 + - 点击重置后清空所有查询条件,恢复默认列表。 + +- 异常与边界: + - 查询条件为空时点击查询,按默认规则展示全部导入批次。 + - 查询结果为空时展示空状态,不清空用户已输入条件。 + - 创建时间格式不合法或开始时间晚于结束时间时阻止查询并提示。 + - 重置后页码恢复第一页。 + +- 反例: + - 不允许重置后仍保留隐藏查询条件。 + - 不允许创建时间范围错误时继续查询。 + - 不允许只按单个条件查询而忽略其他已选择条件。 + +--- + +### REQ-WAYB-035 导入批次状态与操作 + +- 功能点: + - 导入批次状态包含草稿、导入完成。 + - 草稿表示导入数据尚未最终确认导入。 + - 导入完成表示批次内所有运单已成功导入。 + - 草稿状态行操作展示编辑、删除。 + - 导入完成状态行操作仅展示查看。 + - 操作列根据批次状态和用户权限展示对应按钮。 + - 点击运单批次号默认进入导入批次详情,与点击查看入口保持一致。 + +- 异常与边界: + - 执行编辑、删除、查看前需重新校验批次最新状态。 + - 状态为空或未知时限制编辑和删除,仅允许按权限查看或提示异常。 + - 批次状态变更后刷新列表,展示最新操作按钮。 + - 用户无编辑、删除、查看按钮权限时,不展示对应操作入口。 + +- 反例: + - 不允许导入完成状态继续编辑或删除。 + - 不允许草稿状态展示查看完成结果而不允许编辑。 + - 不允许仅根据前端状态跳过后端校验。 + +--- + +### REQ-WAYB-036 新建导入批次 + +- 功能点: + - 点击“新建导入”按钮后跳转至新建导入运单页面,开始新的导入流程。 + - 新建导入用于上传或录入待导入运单数据,生成新的运单批次号。 + - 新建导入成功但未最终确认导入时,批次状态为草稿。 + - 新建导入最终确认成功后,批次状态变更为导入完成。 + +- 异常与边界: + - 新建导入页面打开失败时提示失败原因,不改变列表数据。 + - 运单批次号生成失败时阻止保存并提示。 + - 新建导入过程中校验失败的数据不得进入导入完成状态。 + - 用户离开新建导入页面前若存在未确认数据,应提示用户确认是否离开。 + - 重复点击新建或确认导入时应防止重复生成批次或运单。 + +- 反例: + - 不允许未确认导入的数据直接进入导入完成状态。 + - 不允许多个导入批次共用同一个运单批次号。 + - 不允许导入失败后仍提示导入完成。 + +--- + +### REQ-WAYB-037 导入批次详情 + +- 功能点: + - 支持点击运单批次号或导入完成状态行的查看按钮打开导入运单详情。 + - 导入运单详情标题展示为“导入运单详情”。 + - 导入运单详情以弹窗或详情页展示当前批次下的导入运单明细,默认只读。 + - 详情顶部支持按车牌号/船号和货物名称筛选明细。 + - 详情列表展示序号、运单批次号、原始单号、车牌号/航班号/船号/班列号、司机/船长、运输类型、货物名称、货物类型等字段。 + - 车牌号/航班号/船号/班列号按运输类型展示实际导入载具字段。 + - 司机/船长按运输类型展示司机姓名或船长姓名。 + - 运输类型展示导入数据解析后的系统枚举值。 + - 明细列表支持分页展示,默认10条/页。 + - 详情弹窗支持关闭。 + +- 异常与边界: + - 批次不存在或无权限查看时提示无法查看。 + - 详情列表加载失败时提示失败原因,不影响批次列表。 + - 查询条件为空时默认展示当前批次全部明细。 + - 明细字段较多时支持横向滚动。 + - 导入批次下无明细时展示空状态。 + +- 反例: + - 不允许导入详情展示其他批次的运单。 + - 不允许在导入完成详情中编辑运单明细。 + - 不允许关闭详情弹窗时改变批次状态。 + +--- + +### REQ-WAYB-038 导入明细查询与列表 + +- 功能点: + - 导入运单详情内支持按车牌号/船号、货物名称查询。 + - 车牌号/船号使用输入框,支持模糊查询。 + - 货物名称使用输入框,支持模糊查询。 + - 点击查询后刷新当前批次明细列表。 + - 点击重置后清空详情查询条件,恢复当前批次全部明细。 + - 明细列表的运输类型展示导入数据解析后的运输类型。 + - 明细列表分页切换、页容量切换时,应保留详情页当前查询条件。 + - 关闭详情后再次打开同一批次时,默认清空上一次详情内查询条件。 + +- 异常与边界: + - 查询无数据时展示空状态。 + - 重置后保留当前批次上下文,不返回批次列表。 + - 车牌号/船号或货物名称超长时阻止查询并提示。 + +- 反例: + - 不允许详情查询跨批次检索。 + - 不允许重置后丢失当前批次号。 + - 不允许查询后改变明细列表字段范围。 + +--- + +### REQ-WAYB-039 编辑导入批次 + +- 功能点: + - 草稿状态导入批次支持点击编辑。 + - 点击编辑后跳转至导入编辑页,允许修改未导入完成的批次数据。 + - 编辑保存后批次仍保持草稿状态,直到用户最终确认导入。 + - 编辑导入批次时应回显该批次已上传、已校验通过但未确认导入的数据。 + - 编辑页面的字段校验、重复校验、错误报告下载规则与新建导入保持一致。 + - 编辑完成后刷新导入批次列表。 + +- 异常与边界: + - 仅草稿状态允许编辑。 + - 编辑前需校验当前批次状态仍为草稿。 + - 编辑保存时需重新执行导入字段校验。 + - 导入完成状态点击编辑或通过地址绕过编辑时,应提示不可编辑。 + +- 反例: + - 不允许导入完成批次继续编辑。 + - 不允许编辑后绕过导入校验。 + - 不允许编辑失败后清空用户已修改内容。 + +--- + +### REQ-WAYB-040 删除导入批次 + +- 功能点: + - 草稿状态导入批次支持单条删除。 + - 点击删除后弹出二次确认弹窗。 + - 确认后删除当前草稿批次,删除成功刷新列表。 + - 支持勾选多条导入批次后批量删除。 + - 批量删除仅允许删除草稿状态记录。 + - 若选中非草稿状态记录,系统应给出不可删除提示并跳过执行。 + - 删除成功后提示删除成功;批量删除存在跳过记录时提示成功删除数量和跳过数量。 + +- 异常与边界: + - 未勾选数据时点击批量删除,应提示先选择数据。 + - 批量删除时应逐条校验批次状态,草稿可删除,导入完成不可删除。 + - 所选记录全部不可删除时,不执行删除并提示原因。 + - 部分删除成功时,应提示成功数量和跳过数量,并刷新列表。 + - 删除失败时提示失败原因,不改变其他数据。 + +- 反例: + - 不允许删除导入完成状态批次。 + - 不允许因为选中了导入完成记录而阻塞其他草稿记录删除。 + - 不允许跳过二次确认直接删除。 + +--- + +### REQ-WAYB-041 新建导入页面布局 + +- 功能点: + - 点击导入批次列表的“新建导入”后进入新建导入页面。 + - 页面上半部分为“新建导入”信息填写区域,下半部分为“导入数据明细”区域。 + - 信息填写区域展示项目、客户、客户合同、承运类型、承运商、导入状态、导入类型、发货计划、运单明细表等字段。 + - 运单明细表支持添加附件上传 Excel,旁边展示“请上传运单明细表,仅支持 excel 格式”提示文案。 + - 运单明细表区域支持下载模板。 + - 信息填写区域底部展示“提交”“返回”按钮。 + - 待导入数据明细区域展示批量删除按钮、运单数页签、疑似重复页签、明细表格和分页。 + - 页面底部固定展示已选数量、返回、确认导入按钮。 + +- 异常与边界: + - 页面初始化失败时提示失败原因,并允许返回导入批次列表。 + - 未上传 Excel 前,导入数据明细区域可为空状态或不展示明细数据。 + - 上传 Excel 校验未完成前,不允许点击确认导入。 + - 信息填写区域与导入数据明细区域的数据应归属于同一个运单批次号。 + +- 反例: + - 不允许未选择项目直接上传生成有效导入明细。 + - 不允许上传非 Excel 文件后进入导入明细。 + - 不允许一个页面混入多个导入批次的数据。 + +--- + +### REQ-WAYB-042 新建导入信息填写 + +- 功能点: + - 项目为必填字段,使用选择框或模糊查询选择框,选择项目档案。 + - 选择项目后系统自动带出客户;客户字段为只读文本,不允许手工编辑。 + - 选择项目后系统自动带出客户合同;客户合同字段为只读文本,若存在多个合同则支持下拉选择。 + - 承运类型为必填字段,使用下拉单选控件,枚举为承运商、自运,默认承运商。 + - 承运商根据承运类型和项目、合同关系自动带出;承运类型为承运商时,若存在多个承运商需支持多选选择。 + - 顶部承运商为批量赋值字段,选择后所有导入运单的承运商统一赋值为该值。 + - 承运类型为自运时,承运商可为空,导入数据按自运模式处理。 + - 导入状态为必填字段,使用下拉单选控件,枚举为完成、进行中,默认完成。 + - 导入类型为必填字段,使用下拉单选控件,枚举为运单、结算单,默认导入运单。 + - 发货计划为非必填字段,使用选择框,关联发货计划档案。 + +- 异常与边界: + - 项目为空时阻止提交并提示。 + - 项目变更后,应清空并重新带出客户、客户合同、承运商、发货计划和已解析导入上下文。 + - 客户或客户合同无法根据项目带出时,应提示用户检查项目档案配置。 + - 承运类型从承运商切换为自运时,应清空承运商批量赋值字段。 + - 导入状态为进行中时,实际发货时间和实际完成时间在模板中不强制必填。 + - 导入状态为完成时,导入成功后的运单状态为已完成;导入状态为进行中时,导入成功后的运单状态为进行中。 + +- 反例: + - 不允许客户字段由用户手工输入。 + - 不允许项目切换后继续沿用旧项目的客户、合同或发货计划。 + - 不允许导入状态不明确时生成正式运单。 + +--- + +### REQ-WAYB-043 导入模板字段 + +- 功能点: + - 点击“下载模板”下载 Excel 导入模板。 + - 模板字段包含序号、原始单号、配载标识号、车牌号/航班号/船号/班列号、运输类型、司机/船长姓名、司机/船长手机号、发货地址、发货联系人、发货联系人电话、到货地址、收货联系人、收货联系人电话、货物名称、货物类型、包装、数量、计量单位、规格、型号、里程(km)、单价、计价单位、运费、其他费用合计、运费合计、实际发货时间、实际完成时间、备注、同一运单标识号。 + - 模板中必填字段需使用“*”标识,包含车牌号/航班号/船号/班列号、运输类型、发货地址、到货地址、货物名称、数量、计量单位、单价、计价单位、运费。 + - 原始单号用于填写业务侧自有单号,无需与系统运单号一致。 + - 配载标识号适用于公路配载场景,推荐填写方式为“车牌后四位-发车日期”,例如 2345-20260601,要求在当前导入批次内唯一。 + - 发货地址和到货地址需精确到具体地址,否则轨迹回放可能受影响。 + - 货物类型用于指定系统内维护的一级或二级货物类型;为空时系统可按货物名称尝试匹配补全。 + - 计量单位需填写系统中的枚举值。 + - 计价单位枚举为元/吨、元/方、元/件、元/吨/公里。 + - 其他费用合计用于填写装卸费、过路费等费用总额。 + - 运费合计表示本运单的运输费用合计。 + - 实际发货时间、实际完成时间需填写日期时间格式。 + - 备注为文本,最多200字。 + - 同一运单标识号用于标记多行货物归属于同一运单,多货物运单需拆分多行并填写相同标识。 + +- 异常与边界: + - 模板字段顺序不得与系统校验规则不一致。 + - 必填字段在模板中必须明确标识,避免用户漏填。 + - 用户使用旧模板上传时,应按当前模板字段进行兼容校验;无法兼容时提示下载最新模板。 + +- 反例: + - 不允许导入模板缺少必填标识。 + - 不允许模板字段与错误报告字段顺序不一致。 + - 不允许把同一运单标识号当作系统运单号使用。 + +--- + +### REQ-WAYB-044 导入模板校验规则 + +- 功能点: + - 上传 Excel 后系统逐行校验字段必填、枚举、格式、数值、金额、日期、配载关系、多货物关系和重复数据。 + - 同一配载标识号下车牌号不一致时,行校验失败,错误文案为“配载单车牌号不一致”。 + - 运输类型为公路整车或公路配载/零担时,车牌号需满足首位汉字、次位大写字母、总长度7位或8位;不满足时错误文案为“车牌号校验不通过”。 + - 运输类型为铁路运输、水路运输、跨境海运、航空运输时,车牌号/航班号/船号/班列号不执行公路车牌格式校验。 + - 运输类型必须为系统枚举值之一,否则错误文案为“运输类型需系统枚举值”。 + - 司机/船长手机号、发货联系人电话、收货联系人电话有值时需校验11位数字格式;不满足时错误文案为“手机号格式校验不通过”。 + - 发货地址和到货地址未匹配到地址库时给出警告,文案为“地址未匹配到地址库,轨迹回放将受影响”,警告不阻止导入。 + - 货物名称为空时错误文案为“货物名称必填”。 + - 货物类型有值时需匹配系统内一级或二级货物类型;货物类型为空时,系统按货物名称尝试匹配补全,无法匹配时错误文案为“未匹配到货物类型”。 + - 包装、规格、型号为非必填字段。 + - 数量有值时必须为正数;数量为空时按必填字段校验失败。 + - 计量单位必须为系统枚举值,不存在时错误文案为“计量单位不存在”。 + - 里程(km)有值时必须为正数。 + - 单价为必填字段,且需为非负数。 + - 计价单位为必填字段,且必须为允许枚举值。 + - 运费为必填字段,且需为非负数。 + - 其他费用合计有值时需为非负数,空值按0处理。 + - 运费合计有值时,必须等于运费加其他费用合计;不一致时错误文案为“运费合计不等于运费与其他运费合计之和,请调整”。 + - 实际发货时间有值时必须为日期时间格式;若实际完成时间有值,则实际发货时间不能晚于实际完成时间,否则错误文案为“实际发货时间不能晚于实际完成时间”。 + - 实际完成时间有值时必须为日期时间格式;若实际发货时间有值,则实际完成时间不能早于实际发货时间,否则错误文案为“实际完成时间不能早于实际发货时间”。 + - 同一运单标识号下的多行数据需校验为同一个车牌号/航班号/船号/班列号,否则错误文案为“统一运单车牌不一致”。 + +- 异常与边界: + - 一行存在多个错误时,需收集全部错误文案,不得只返回第一条。 + - 警告类问题允许进入待导入数据明细,但需保留警告提示供用户识别。 + - 导入状态为进行中时,实际发货时间和实际完成时间不必填;有值时仍需执行日期格式和先后顺序校验。 + - 导入状态为完成时,实际发货时间和实际完成时间必填;导入状态为进行中时,实际发货时间和实际完成时间不必填。 + +- 反例: + - 不允许车牌格式错误的公路运单进入待导入明细。 + - 不允许费用合计错误的数据静默修正后导入。 + - 不允许日期先后错误的数据生成正式运单。 + +--- + +### REQ-WAYB-045 导入失败报告 + +- 功能点: + - 上传 Excel 后若存在校验失败数据,系统自动生成错误报告 Excel 并下载。 + - 错误报告字段顺序与原导入模板保持一致,并在最后一列追加错误原因。 + - 同一行存在多个错误或警告时,错误原因用分号分隔。 + - 校验失败时页面提示“提交失败,报错文件已下载,请根据提示修改内容”。 + - 校验失败的运单不展示在待导入数据明细中。 + +- 异常与边界: + - 错误报告下载失败时需提示用户重新下载或重新上传。 + - 仅存在警告且无错误时,可展示待导入数据明细,并在明细行标识警告。 + - 文件解析异常、空文件、模板格式错误时,应阻止继续导入并提示原因。 + +- 反例: + - 不允许校验失败数据混入待导入明细。 + - 不允许错误报告字段顺序与模板不一致。 + - 不允许有失败数据时只 toast 不下载错误报告。 + +--- + +### REQ-WAYB-046 导入数据明细 + +- 功能点: + - 当导入数据校验通过后,才展示在待导入数据明细中。 + - 系统对每一条上传的有效运单自动生成唯一运单号。 + - 待导入数据明细展示复选框、序号、运单批次号、原始单号、车牌号/航班号/船号/班列号、司机/船长、运输类型、货物名称、货物类型、重量、操作等字段。 + - 运单数页签展示总导入运单数量,格式为“运单数(4)”。 + - 明细列表支持分页展示,默认10条/页,支持20/50/100条/页。 + - 明细行支持编辑、保存、取消、删除。 + - 明细行点击编辑后,可编辑字段切换为输入框、下拉框等可编辑控件。 + - 点击保存后保存当前行编辑内容,并重新执行该行校验。 + - 点击取消后放弃当前行修改,恢复原始值。 + - 点击删除后移除当前行数据。 + - 支持勾选多行后批量删除待导入明细。 + +- 异常与边界: + - 行编辑时存在必填、枚举、格式、费用、日期等校验错误时阻止保存。 + - 删除明细后需重新统计运单数和疑似重复数量。 + - 所有明细被删除后,不允许确认导入。 + - 明细横向字段较多时支持横向滚动,操作列固定在右侧。 + +- 反例: + - 不允许未校验通过的数据展示在运单数页签中。 + - 不允许编辑行未保存时直接确认导入。 + - 不允许删除明细后统计数量不刷新。 + +--- + +### REQ-WAYB-047 疑似重复处理 + +- 功能点: + - 系统需校验导入数据重复性。 + - 同一运单批次号下,所有导入字段数据完全一致时,标记为疑似重复。 + - 疑似重复数据单独通过页签展示,页签格式为“疑似重复(2)”。 + - 疑似重复页签下支持用户在线编辑、保存、取消或删除重复条目。 + - 用户处理疑似重复数据后,系统需重新计算疑似重复数量。 + - 确认导入前,允许用户保留疑似重复数据,但需保证已通过字段校验。 + +- 异常与边界: + - 疑似重复只用于提示和辅助处理,不等同于校验失败。 + - 不同运单批次号之间的数据不参与本次疑似重复判断。 + - 编辑疑似重复数据后如不再完全一致,应从疑似重复页签中移出。 + +- 反例: + - 不允许把跨批次相同数据标记为当前批次疑似重复。 + - 不允许疑似重复数据绕过字段校验。 + - 不允许用户删除疑似重复数据后主运单数仍包含已删除记录。 + +--- + +### REQ-WAYB-048 确认导入 + +- 功能点: + - 点击底部“确认导入”后,系统校验当前待导入明细是否均通过校验。 + - 校验通过后生成正式运单,并将导入批次状态更新为导入完成。 + - 导入类型为运单时,确认导入后生成正式运单并跳转或返回运单列表。 + - 导入类型为结算单时,点击确认导入需弹出确认提示。 + - 结算单确认提示文案为“确认后将同时生成运单、应收应付明细、结算单,是否继续?”。 + - 结算单确认弹窗按钮为“确认”“取消”。 + - 点击确认后同时生成运单、应收应付明细、结算单。 + - 点击取消后关闭弹窗,保留当前导入页面数据。 + - 确认导入成功后提示成功,并刷新导入批次列表或运单列表。 + +- 异常与边界: + - 存在未保存编辑行时,不允许确认导入。 + - 存在校验失败数据时,不允许确认导入,并提示用户处理。 + - 导入类型为结算单时,任一结算相关数据生成失败应整体回滚或按后端事务规则保证数据一致。 + - 重复点击确认导入时应防止重复生成运单、应收应付明细或结算单。 + +- 反例: + - 不允许结算单导入绕过二次确认弹窗。 + - 不允许导入失败后仍把批次状态改为导入完成。 + - 不允许同一批次重复确认导入生成重复运单。 + +--- + +### REQ-WAYB-049 配载与多货物导入 + +- 功能点: + - 导入数据存在配载标识号时,系统按同一配载标识号自动生成一个配载单号。 + - 同一配载标识号下可包含多条运单,配载单号需回填到对应正式运单。 + - 若导入运单判断为配载单,导入运单状态为已完成或进行中时,配载单状态同步为已完成或进行中。 + - 导入数据存在同一运单标识号时,系统将相同标识下的货物相关字段写入同一运单的货物明细表。 + - 多货物明细字段包含货物类型、货物名称、数量、计量单位、规格、型号、包装等。 + - 多货物运单只生成一个运单号,多条货物明细关联该运单号。 + +- 异常与边界: + - 配载标识号相同但车牌号不一致时,整组配载数据校验失败。 + - 同一运单标识号下车牌号/航班号/船号/班列号不一致时,整组多货物数据校验失败。 + - 配载标识号和同一运单标识号同时存在时,应分别维护配载关系和多货物关系,不得互相覆盖。 + - 多货物运单中任一货物明细校验失败时,该运单不得确认导入。 + +- 反例: + - 不允许同一配载标识号生成多个配载单号。 + - 不允许多货物运单拆成多张正式运单。 + - 不允许配载关系和多货物关系混用后无法追溯。 + +--- + +### REQ-WAYB-050 导入地址解析 + +- 功能点: + - 系统支持对导入运单的发货地址和到货地址进行地址解析。 + - 用户上传或录入地址后,系统调用地图地址解析服务。 + - 地址解析成功后,系统自动获取并保存标准地址、省、市、区县、经度、纬度。 + - 地址解析后的经纬度用于轨迹回放和数据统计。 + - 地址解析失败时,系统保留原地址,并标记该地址不支持轨迹回放。 + - 地址未匹配到地址库时给出警告,不阻止导入。 + +- 异常与边界: + - 地图地址解析服务不可用时,应保留原地址并提示解析失败。 + - 地址为空时按模板必填规则处理,不进入解析流程。 + - 非公路运输地址仍需符合对应基础数据类型要求;不匹配时应提示用户修正。 + - 经纬度超过合法范围时视为解析失败。 + +- 反例: + - 不允许地址解析失败后清空用户原地址。 + - 不允许无经纬度地址仍展示为可轨迹回放。 + - 不允许把发货地址解析结果写入到货地址字段。 + +--- + +### REQ-WAYB-051 新建导入操作 + +- 功能点: + - 点击项目选择框后选择项目,系统联动带出客户、客户合同、承运商候选项和发货计划候选项。 + - 点击“添加附件”后选择 Excel 文件,上传后系统解析并校验。 + - 上传成功后展示解析进度或解析结果,并刷新导入数据明细。 + - 点击“下载模板”后下载 Excel 导入模板到本地。 + - 点击明细行“编辑”后,该行可编辑字段进入编辑状态。 + - 点击明细行“保存”后保存该行编辑内容,保存成功后恢复只读状态。 + - 点击明细行“取消”后放弃修改,行数据恢复原值。 + - 点击明细行“删除”后移除该行数据。 + - 点击底部“确认导入”后,校验通过的数据生成正式运单。 + - 点击底部“返回”后返回运单列表或导入批次列表,不执行导入。 + +- 异常与边界: + - 上传文件解析中时,不允许重复上传或确认导入。 + - 在线编辑保存失败时保留编辑状态和用户修改内容。 + - 返回前存在未保存数据时,应提示用户确认是否离开。 + - 导入成功后应清理当前导入页面的临时数据,避免再次进入误提交。 + +- 反例: + - 不允许上传成功但不展示解析或校验结果。 + - 不允许返回操作触发导入。 + - 不允许保存失败后行数据被错误还原为旧值。 + +--- + +## 通用规则 + +- 运单管理用于承接项目维度下的运输执行单据,归属于“业务管理”主菜单。 +- 运单状态包含草稿、待执行、进行中、已完成、已取消。 +- 运单号由系统自动生成,且全局唯一,生成后只读不可编辑。 +- 运输类型为公路整车、公路配载/零担、铁路运输、水路运输、跨境海运、航空运输等枚举值。 +- 新增和编辑页面默认展示精简录入,支持切换完整录入;两种录入方式的同名字段校验规则保持一致。 +- 运单货物信息中货物名称、货物类型、数量、计量单位均为必填。 +- 收发货信息字段与发货模板的新建运单模板保持一致。 +- 非公路运输的收发地址只能从对应基础数据中选择;地址类型不匹配时提示“请选择港口/空港/车站地址”。 +- 公路运输默认承运商模式,自运模式下承运商不需要填写。 +- 运费合计等于运费加其他运费合计,只读展示;运费由货物数量合计乘以单价自动计算且允许修改。 +- 公路类型默认币种为 CNY,铁路、水路、跨境海运、航空类型可选择 CNY 或 USD。 +- 列表、详情、导出、导入等用户可见场景应优先展示名称字段,不直接展示用户 ID。 +- 状态列和操作按钮列固定在右侧,不随横向滚动条滑动。 +- 过程节点顺序固定为接单、到场、装货、发货、在途、到货、卸货、签收、回单,不允许拖拽改序。 +- 未配置过程节点或未完成任何节点时,当前过程节点显示“/”。 +- 节点完成后应记录完成时间,并把当前过程节点更新为最新完成节点。 +- 草稿、待执行、进行中且未发货前的运单可按规则取消,已完成或已取消状态不允许取消。 +- 进行中状态支持内部人员手动完成,满足末节点无需确认完成时可自动完成。 +- 公路配载按钮仅用于公路配载或零担场景,不允许用于非公路运单。 +- 导入批次状态包含草稿、导入完成;仅草稿状态允许编辑和删除,导入完成仅允许查看。 +- 批量删除导入批次时仅删除草稿记录,非草稿记录需提示不可删除并跳过。 +- 导入运单详情只能展示当前导入批次下的明细,不能跨批次混合展示。 +- 新建导入流程为选择项目、上传 Excel 模板、系统自动校验、校验失败自动下载错误报告、校验通过展示运单列表、确认导入、生成正式运单。 +- 导入状态为完成时,确认导入后运单状态为已完成;导入状态为进行中时,确认导入后运单状态为进行中。 +- 导入类型为结算单时,确认导入需二次确认,并同步生成运单、应收应付明细和结算单。 +- 导入模板校验失败时,失败行不得进入待导入数据明细;错误报告需在原模板最后一列追加错误原因。 +- 同一导入批次内所有字段完全一致的数据标记为疑似重复,允许用户在线确认或删除。 +- 顶部承运商为批量赋值字段,选择后对所有导入运单统一赋值。 +- 导入地址解析失败时保留原地址,但不支持轨迹回放。 +- 新建、编辑、删除、取消、完成、导入、复制后均需刷新列表。 diff --git a/需求卡/运输计划需求卡.md b/需求卡/运输计划需求卡.md new file mode 100644 index 0000000..c534714 --- /dev/null +++ b/需求卡/运输计划需求卡.md @@ -0,0 +1,1173 @@ +# 运输计划需求卡 + +## 目录 + +- [REQ-PLAN-001 菜单入口](#req-plan-001-菜单入口) +- [REQ-PLAN-002 列表与分页](#req-plan-002-列表与分页) +- [REQ-PLAN-003 条件查询与重置](#req-plan-003-条件查询与重置) +- [REQ-PLAN-004 状态展示与操作列](#req-plan-004-状态展示与操作列) +- [REQ-PLAN-005 新增运输计划](#req-plan-005-新增运输计划) +- [REQ-PLAN-006 编辑运输计划](#req-plan-006-编辑运输计划) +- [REQ-PLAN-007 查看运输计划](#req-plan-007-查看运输计划) +- [REQ-PLAN-008 基本信息规则](#req-plan-008-基本信息规则) +- [REQ-PLAN-009 收发货信息规则](#req-plan-009-收发货信息规则) +- [REQ-PLAN-010 非公路地址规则](#req-plan-010-非公路地址规则) +- [REQ-PLAN-011 货物信息规则](#req-plan-011-货物信息规则) +- [REQ-PLAN-012 运输数量合计](#req-plan-012-运输数量合计) +- [REQ-PLAN-013 附件规则](#req-plan-013-附件规则) +- [REQ-PLAN-014 选择常用地址](#req-plan-014-选择常用地址) +- [REQ-PLAN-015 选择常用线路](#req-plan-015-选择常用线路) +- [REQ-PLAN-016 选择常用货物](#req-plan-016-选择常用货物) +- [REQ-PLAN-017 批量导入](#req-plan-017-批量导入) +- [REQ-PLAN-018 批量导出](#req-plan-018-批量导出) +- [REQ-PLAN-019 复制运输计划](#req-plan-019-复制运输计划) +- [REQ-PLAN-020 调度运输计划](#req-plan-020-调度运输计划) +- [REQ-PLAN-021 取消运输计划](#req-plan-021-取消运输计划) +- [REQ-PLAN-022 完成运输计划](#req-plan-022-完成运输计划) +- [REQ-PLAN-023 删除运输计划](#req-plan-023-删除运输计划) +- [REQ-PLAN-024 底部操作按钮](#req-plan-024-底部操作按钮) +- [REQ-PLAN-025 权限与审计](#req-plan-025-权限与审计) +- [REQ-PLAN-026 计划详情布局](#req-plan-026-计划详情布局) +- [REQ-PLAN-027 详情基本信息](#req-plan-027-详情基本信息) +- [REQ-PLAN-028 详情调度数据](#req-plan-028-详情调度数据) +- [REQ-PLAN-029 详情运单记录](#req-plan-029-详情运单记录) +- [REQ-PLAN-030 详情操作按钮](#req-plan-030-详情操作按钮) +- [REQ-PLAN-031 计划调度页布局](#req-plan-031-计划调度页布局) +- [REQ-PLAN-032 待调度列表](#req-plan-032-待调度列表) +- [REQ-PLAN-033 新增编辑调度弹窗](#req-plan-033-新增编辑调度弹窗) +- [REQ-PLAN-034 精简录入调度信息](#req-plan-034-精简录入调度信息) +- [REQ-PLAN-035 完整录入调度信息](#req-plan-035-完整录入调度信息) +- [REQ-PLAN-036 调度货量与费用规则](#req-plan-036-调度货量与费用规则) +- [REQ-PLAN-037 调度保存与生成运单](#req-plan-037-调度保存与生成运单) +- [REQ-PLAN-038 计划导入页布局](#req-plan-038-计划导入页布局) +- [REQ-PLAN-039 导入信息填写](#req-plan-039-导入信息填写) +- [REQ-PLAN-040 导入模板字段](#req-plan-040-导入模板字段) +- [REQ-PLAN-041 导入数据校验](#req-plan-041-导入数据校验) +- [REQ-PLAN-042 错误报告下载](#req-plan-042-错误报告下载) +- [REQ-PLAN-043 待导入数据明细](#req-plan-043-待导入数据明细) +- [REQ-PLAN-044 疑似重复处理](#req-plan-044-疑似重复处理) +- [REQ-PLAN-045 确认导入生成运单](#req-plan-045-确认导入生成运单) +- [通用规则](#通用规则) + +--- + +### REQ-PLAN-001 菜单入口 + +- 功能点: + - 运输计划模块归属于“业务管理”主菜单。 + - 在“业务管理”菜单下提供“运输计划”模块入口。 + - 用户进入运输计划页面后,可进行查询、新建计划、导入计划、导出、编辑、复制、调度、详情、取消、完成、删除等操作。 + +- 异常与边界: + - 无菜单权限时不展示“业务管理”或“运输计划”入口。 + - 有菜单权限但无按钮权限时,仅展示允许访问的页面和操作。 + - 菜单加载失败时提示失败原因,不影响其他已有菜单访问。 + +- 反例: + - 不允许把运输计划挂到非业务管理主菜单下。 + - 不允许无权限用户通过 URL 直接进入模块。 + - 不允许菜单入口存在但页面无法正常访问。 + +--- + +### REQ-PLAN-002 列表与分页 + +- 功能点: + - 默认展示当前组织下的运输计划数据。 + - 列表展示字段与编辑表单字段保持一致,并额外展示创建时间、更新时间。 + - 列表至少展示项目、客户合同、计划名称、计划单号、运输类型、计划开始日期、计划结束日期、收发货信息、货物信息、附件、备注、状态、创建时间、更新时间、操作等信息。 + - 状态列和操作按钮列固定在右侧,不随横向滚动条滑动。 + - 支持勾选多行数据用于批量导出。 + - 分页默认10条/页,支持20/50/100条/页。 + +- 异常与边界: + - 查询无数据时展示空状态。 + - 横向字段较多时允许表格横向滚动,但状态列和操作列必须保持固定。 + - 当前页数据因删除、取消、完成等操作发生变化后,应刷新列表并保持分页逻辑正确。 + - 列表加载失败时保留当前查询条件和分页条件,提示用户重新查询。 + +- 反例: + - 不允许状态列或操作列被横向滚动隐藏。 + - 不允许列表字段与编辑表单长期不一致。 + - 不允许分页后丢失当前查询条件。 + +--- + +### REQ-PLAN-003 条件查询与重置 + +- 功能点: + - 支持按计划单号、计划名称、客户名称、运输类型、货物名称、货物类型、发货地址、收货地址、计划开始时间、计划结束时间、状态、数据来源等条件组合查询。 + - 计划单号、货物名称、发货地址、收货地址使用输入框。 + - 计划名称、客户名称、货物类型使用输入搜索下拉框。 + - 运输类型、状态、数据来源使用下拉单选控件。 + - 计划开始时间、计划结束时间使用日期范围选择器。 + - 点击查询后,根据当前已输入或已选择条件筛选列表。 + - 点击重置后清空所有查询条件,恢复默认列表。 + +- 异常与边界: + - 查询条件为空时点击查询,按默认规则展示当前组织数据。 + - 查询结果为空时展示空状态,不清空用户已输入条件。 + - 重置后页码恢复第一页,并重新加载列表。 + - 日期范围格式不合法或开始时间晚于结束时间时阻止查询并提示。 + - 页面中出现重复业务字段时,应按同一查询含义处理,避免生成互相冲突的隐藏条件。 + +- 反例: + - 不允许重置后仍保留隐藏查询条件。 + - 不允许只按单个条件查询而忽略其他已选择条件。 + - 不允许日期范围错误时继续请求列表数据。 + +--- + +### REQ-PLAN-004 状态展示与操作列 + +- 功能点: + - 运输计划状态包含草稿、待调度、调度中、已完成、已取消。 + - 草稿状态可执行编辑、复制、删除;草稿来源于新建计划时点击暂存。 + - 待调度状态可执行调度、编辑、详情、复制、取消;待调度表示计划下未下挂任何运单。 + - 调度中状态可执行调度、详情、复制、完成;调度中表示计划下已下挂待执行、进行中或完成运单,已取消运单除外。 + - 已完成状态可执行详情、复制。 + - 已取消状态可执行详情、复制。 + - 操作按钮列固定在右侧,按钮展示受状态和权限共同控制。 + +- 异常与边界: + - 状态为空或状态值未知时,列表应展示兜底文案,并限制高风险操作。 + - 操作执行前需重新校验最新状态,避免列表状态过期导致误操作。 + - 状态变更成功后刷新列表,展示最新状态和可执行操作。 + +- 反例: + - 不允许草稿状态执行调度。 + - 不允许已完成或已取消状态继续编辑、删除、调度、完成。 + - 不允许仅根据前端显示状态跳过后端状态校验。 + +--- + +### REQ-PLAN-005 新增运输计划 + +- 功能点: + - 点击“新建计划”按钮后跳转至新建运输计划页面。 + - 新建页面包含基本信息、收发货信息、货物信息、附件等区域。 + - 基本信息区包含项目、客户合同、计划名称、计划单号、运输类型、计划开始日期、计划结束日期、备注。 + - 收发货信息、货物信息、附件按运输计划新建页面布局展示。 + - 支持通过选择常用地址、选择常用线路、选择常用货物快速回填表单信息。 + - 点击确认创建后校验必填字段并创建计划,创建成功提示并返回列表。 + - 点击暂存后保存为草稿,保存成功提示并返回列表。 + +- 异常与边界: + - 项目、客户合同、计划名称、计划单号、运输类型等必填项为空时,确认创建应阻止提交并提示。 + - 发货地址、收货地址、货物类型等核心业务字段缺失时,确认创建应阻止提交并提示。 + - 计划单号生成失败时阻止保存并提示。 + - 字段长度、日期、数值、枚举、附件格式不符合规则时阻止提交并提示。 + - 提交失败时保留用户已填写内容,方便修正后重新提交。 + +- 反例: + - 不允许用户手工填写或修改计划单号。 + - 不允许确认创建缺少项目、合同、运输类型、收发货地址或货物类型的计划。 + - 不允许选择常用数据后只回填部分关键字段导致数据不完整。 + +--- + +### REQ-PLAN-006 编辑运输计划 + +- 功能点: + - 草稿和待调度状态支持点击编辑,跳转至编辑页面。 + - 编辑页面回显运输计划完整信息。 + - 计划单号在编辑状态下只读不可编辑。 + - 项目、客户合同、计划名称、运输类型、计划开始日期、计划结束日期、收发货信息、货物信息、附件、备注等字段按规则编辑。 + - 编辑保存成功后刷新列表,并展示最新更新时间。 + +- 异常与边界: + - 编辑前需校验当前计划状态,非草稿、非待调度状态不允许进入可编辑提交流程。 + - 修改项目时,客户合同应按新项目重新带出或重新选择。 + - 修改运输类型时,收发货地址控件和校验规则应按新运输类型重新匹配。 + - 编辑的数据已不存在时提示数据不存在,并刷新列表。 + - 提交失败时保留用户修改内容。 + +- 反例: + - 不允许编辑时修改计划单号。 + - 不允许调度中、已完成、已取消状态继续提交编辑。 + - 不允许修改运输类型后继续沿用旧类型不适用的地址数据。 + +--- + +### REQ-PLAN-007 查看运输计划 + +- 功能点: + - 支持点击详情查看运输计划完整信息。 + - 详情页上方展示计划概要信息,下方展示当前计划关联的运单记录。 + - 详情页展示基本信息、收发货信息、货物信息、附件、调度数据、运单记录、状态、创建时间、更新时间等内容。 + - 详情页字段仅供查看,不允许编辑。 + - 草稿以外的可查看状态包含待调度、调度中、已完成、已取消。 + - 详情页支持通过运单记录查看对应运单详情。 + +- 异常与边界: + - 数据已删除或不存在时提示数据不存在,并刷新列表。 + - 详情加载失败时提示失败原因,不改变列表数据。 + - 附件加载失败时不影响其他字段展示。 + - 关联运单记录加载失败时保留计划概要信息,并提示运单记录加载失败。 + +- 反例: + - 不允许在详情状态下保存修改。 + - 不允许详情页出现删除货物行、上传附件等编辑操作。 + - 不允许查看时自动切换为编辑状态。 + - 不允许详情页修改关联运单数据。 + +--- + +### REQ-PLAN-008 基本信息规则 + +- 功能点: + - 项目使用模糊搜索选择框,必填,用于选择计划所属项目。 + - 客户合同选择项目后联动带出,必填,不允许脱离项目单独维护;若项目下存在多个客户合同,则以下拉方式供用户选择。 + - 计划名称使用输入框,必填,最长50字符。 + - 计划单号由系统自动生成,只读展示,规则为 JH + 8位年月日 + 3位流水号。 + - 运输类型选择项目时自动带出,必填,允许用户修改。 + - 计划开始日期和计划结束日期使用日期选择框,非必填。 + - 备注使用输入框或文本域,非必填,最长200字符。 + +- 异常与边界: + - 项目为空时阻止确认创建并提示。 + - 客户合同未能根据项目带出或用户未选择时阻止确认创建。 + - 计划名称为空或超过50字符时阻止提交并提示。 + - 计划单号为空、生成失败或重复时阻止保存并提示。 + - 计划开始日期晚于计划结束日期时阻止提交并提示。 + - 计划结束日期早于计划开始日期时阻止提交并提示。 + - 运输类型为空或不在枚举范围内时阻止提交。 + - 备注超过200字符时阻止提交并提示。 + +- 反例: + - 不允许未选择项目时选择客户合同。 + - 不允许客户合同脱离项目被单独修改。 + - 不允许计划结束日期早于计划开始日期。 + - 不允许手工改写系统生成的计划单号。 + +--- + +### REQ-PLAN-009 收发货信息规则 + +- 功能点: + - 收发货信息包含发货地址、收货地址、发货联系人、发货联系方式、收货联系人、收货联系方式、计划发货日期、计划完成日期等信息。 + - 发货地址、收货地址为必填。 + - 公路运输时,发货地址和收货地址可从常用地址选择、从常用线路回填,或按地址选择逻辑填写。 + - 选择地址后自动带出地址名称、详细地址、经度、纬度等关联信息,并回填当前表单。 + - 选择常用线路后自动回填发货地址、收货地址及对应联系人、联系方式。 + - 发货联系人、收货联系人使用输入框,最长20字符。 + - 发货联系方式、收货联系方式使用输入框,最长20字符。 + +- 异常与边界: + - 发货地址或收货地址为空时阻止确认创建并提示。 + - 地址选择返回信息不完整时阻止提交,并提示重新选择地址。 + - 联系人超过20字符时阻止提交。 + - 联系方式超过20字符或格式不合法时阻止提交。 + - 计划完成日期早于计划发货日期时阻止提交。 + +- 反例: + - 不允许保存缺失发货地址或收货地址的计划。 + - 不允许选择地址后只回填地址名称而丢失详细地址、经纬度等关联信息。 + - 不允许计划完成日期早于计划发货日期。 + +--- + +### REQ-PLAN-010 非公路地址规则 + +- 功能点: + - 当运输类型为水运或海运时,发货地址和收货地址显示为港口选择,并从基础数据中选择港口。 + - 当运输类型为空运时,发货地址和收货地址显示为空港选择,并从基础数据中选择空港。 + - 当运输类型为铁运时,发货地址和收货地址显示为站点选择,并从基础数据中选择站点。 + - 非公路运输的收发地址只能从对应基础数据中选择。 + - 通过常用地址或常用线路回填非公路地址时,也必须校验地址类型与当前运输类型匹配。 + +- 异常与边界: + - 非公路运输未选择对应基础数据时阻止提交。 + - 常用地址或常用线路中的地址不是当前运输类型对应的港口、空港、站点时,不允许选择并 toast 提示“请选择港口/空港/车站地址”。 + - 切换运输类型后,应清空不适用的收发地址并要求重新选择。 + - 基础数据已删除或不可用时提示重新选择。 + +- 反例: + - 不允许水运、空运、铁运继续使用公路地址自由输入逻辑。 + - 不允许非公路运输选择与运输类型不匹配的常用地址或常用线路。 + - 不允许运输类型切换后沿用旧类型地址数据。 + +--- + +### REQ-PLAN-011 货物信息规则 + +- 功能点: + - 货物信息以明细行方式维护,每行可独立新增或删除。 + - 货物名称使用输入框,最长50字符,非必填。 + - 货物类型使用下拉搜索单选控件,必填,来源于货物类型基础数据。 + - 数量使用数字输入框,非必填。 + - 数量单位使用下拉单选控件,非必填,枚举包含吨、件、立方米等。 + - 包装使用下拉单选控件,非必填。 + - 品牌、规格、型号使用输入框,最长50字符。 + - 物料编码、设备编码使用输入框,最长30字符。 + - 货物行备注使用输入框,最长50字符。 + - 支持导入货物。 + - 支持选择常用货物,将常用货物信息回填到货物明细行。 + - 每行支持删除,最后一行支持新增一行。 + +- 异常与边界: + - 货物类型为空时阻止确认创建并提示。 + - 数量小于0或不是数值时阻止提交。 + - 数量单位不在枚举范围内时阻止提交。 + - 货物名称、品牌、规格、型号、行备注超过50字符时阻止提交。 + - 物料编码、设备编码超过30字符时阻止提交。 + - 删除最后一行货物明细时应保留一条空行或提示至少保留一行。 + +- 反例: + - 不允许无货物明细确认创建计划。 + - 不允许货物类型为空的明细行参与保存。 + - 不允许导入货物后覆盖用户已确认的不相关字段。 + +--- + +### REQ-PLAN-012 运输数量合计 + +- 功能点: + - 货物信息下方展示运输数量合计。 + - 运输数量合计由系统根据货物明细中的数量自动计算。 + - 计划运输量为计划中填写的货物信息的货物数量求和。 + - 当货物明细数量变更、新增或删除时,运输数量合计同步刷新。 + - 若货物明细未填写数量,则该计划无可自动完成的计划运输量,后续完成需手动点击完成。 + +- 异常与边界: + - 货物明细存在不同数量单位时,应按系统业务口径分单位汇总或提示无法合并,不得错误合计为单一数值。 + - 货物数量为空时不参与自动求和。 + - 货物数量为负数或格式错误时阻止提交并提示。 + +- 反例: + - 不允许用户手工改写系统自动计算的运输数量合计。 + - 不允许把空数量当作0后误判计划已达到自动完成条件。 + - 不允许不同单位货物被无提示地合并成一个运输量。 + +--- + +### REQ-PLAN-013 附件规则 + +- 功能点: + - 支持上传运输计划相关附件。 + - 附件为非必填,支持多个文件。 + - 支持 JPG、PNG、PDF 等常用业务附件格式。 + - 编辑时支持查看、追加或删除附件。 + - 详情页支持查看或下载附件,不允许上传或删除。 + +- 异常与边界: + - 附件格式不支持时阻止上传并提示。 + - 附件上传失败时保留页面已填写内容。 + - 删除附件时需确认用户操作。 + - 附件已失效或下载失败时提示失败原因。 + +- 反例: + - 不允许不支持格式的附件静默上传成功。 + - 不允许附件上传失败导致整页已填内容丢失。 + - 不允许详情状态下上传或删除附件。 + +--- + +### REQ-PLAN-014 选择常用地址 + +- 功能点: + - 支持打开选择常用地址弹窗。 + - 弹窗支持按地址名称、地址类型、详细地址等条件查询。 + - 列表展示地址名称、地址编号、类型、站点编码、详细地址、操作等字段。 + - 常规地址的站点编码显示为“/”。 + - 点击选择后,将地址名称、地址编号、类型、站点编码、详细地址、经度、纬度等信息回填到当前发货地址或收货地址。 + +- 异常与边界: + - 查询无数据时展示空状态。 + - 选择的数据已删除、不可用或不存在时提示重新选择。 + - 非公路运输选择地址时,地址类型必须与当前运输类型匹配。 + - 地址类型不匹配时 toast 提示“请选择港口/空港/车站地址”。 + +- 反例: + - 不允许选择后只回填地址名称而丢失详细地址。 + - 不允许常规地址展示错误站点编码。 + - 不允许水运、空运、铁运选择不匹配的常用地址类型。 + +--- + +### REQ-PLAN-015 选择常用线路 + +- 功能点: + - 支持打开选择常用线路弹窗。 + - 弹窗支持按线路名称、发货地址、收货地址等条件查询。 + - 列表展示线路名称、线路编号、发货地、发货地址、发货联系人、收货地、收货地址、收货联系人、操作等字段。 + - 点击选择后,自动回填发货地址、收货地址、发货联系人、发货联系方式、收货联系人、收货联系方式等信息。 + +- 异常与边界: + - 查询无数据时展示空状态。 + - 线路已删除或不可用时提示重新选择。 + - 常用线路中的发货地址或收货地址与当前运输类型不匹配时不允许选择。 + - 非公路运输下选择不匹配线路时 toast 提示“请选择港口/空港/车站地址”。 + +- 反例: + - 不允许选择线路后只回填发货地址而不回填收货地址。 + - 不允许选择与当前运输类型不匹配的线路。 + - 不允许选择失效线路。 + +--- + +### REQ-PLAN-016 选择常用货物 + +- 功能点: + - 支持打开选择常用货物弹窗。 + - 弹窗支持按货物名称、货物编号、货物类型等条件查询。 + - 选择常用货物后,将货物名称、货物类型、包装、品牌、规格、型号、数量单位等信息回填到货物明细。 + - 支持选择一条或多条常用货物,回填为一行或多行货物明细。 + +- 异常与边界: + - 查询无数据时展示空状态。 + - 常用货物已删除或不可用时提示重新选择。 + - 回填多条货物时应避免覆盖已有明细。 + - 回填后货物类型为空或已失效时阻止提交。 + +- 反例: + - 不允许选择常用货物后丢失必填的货物类型。 + - 不允许多选回填时覆盖用户已有货物行。 + - 不允许选择已失效或不可用货物。 + +--- + +### REQ-PLAN-017 批量导入 + +- 功能点: + - 点击“批量导入”按钮后跳转至导入计划页面。 + - 导入计划页面支持选择项目、上传 Excel 计划明细表、下载导入模板、查看待导入数据明细。 + - 导入流程为选择项目、上传 Excel 模板、系统自动校验、校验不通过自动下载错误报告、校验通过展示运单列表、确认导入、生成正式运单。 + - 导入字段、模板说明、校验规则、疑似重复处理和确认导入规则按计划导入专项需求执行。 + - 导入完成后刷新列表,并跳转至运单列表或返回运输计划列表。 + +- 异常与边界: + - 文件格式错误时阻止导入并提示失败原因。 + - 项目、客户合同、计划名称、运输类型、发货地址、收货地址、货物类型等核心字段缺失时,对应行导入失败并写入失败原因。 + - 非公路运输地址不是对应港口、空港、站点时,对应行导入失败。 + - 日期格式错误或起止时间逻辑错误时,对应行导入失败。 + - 单行错误不影响其他校验通过的数据入库。 + - 全部失败时不入库,但仍生成错误报告。 + - 存在失败数据时下载错误报告,并提示“提交失败,报错文件已下载,请根据提示修改内容”。 + +- 反例: + - 不允许异常数据静默跳过。 + - 不允许错误数据入库。 + - 不允许导入校验与新增、编辑表单校验不一致。 + - 不允许只提示失败数量而不提供错误报告。 + +--- + +### REQ-PLAN-018 批量导出 + +- 功能点: + - 支持勾选多行数据后点击“批量导出”导出 Excel 文件。 + - 未勾选数据时点击批量导出,默认导出当前查询条件下的全部数据。 + - 导出字段与列表显示字段一致。 + - 导出成功后触发导出文件下载。 + +- 异常与边界: + - 当前查询条件下无数据时允许导出空文件或提示无可导出数据。 + - 导出数据量较大时提示用户等待或按系统策略异步处理。 + - 导出失败时提示失败原因,不改变列表勾选状态。 + +- 反例: + - 不允许未勾选时只导出当前页数据。 + - 不允许导出字段与列表字段不一致。 + - 不允许导出失败后提示成功。 + +--- + +### REQ-PLAN-019 复制运输计划 + +- 功能点: + - 任意状态的运输计划均支持点击复制。 + - 系统基于当前计划复制生成新的草稿计划。 + - 复制后的计划重新生成计划单号,状态默认为草稿。 + - 复制成功后跳转至编辑页面,允许用户继续调整计划信息。 + +- 异常与边界: + - 原计划已删除或不存在时提示数据不存在。 + - 复制时不得复制原计划的状态、调度记录、运单关联记录。 + - 计划单号生成失败时复制失败并提示。 + - 原计划附件是否复制应按系统文件规则处理,并在复制后保持可见范围一致。 + +- 反例: + - 不允许复制后沿用原计划单号。 + - 不允许复制后直接生成待调度、调度中、已完成或已取消状态。 + - 不允许复制原计划下挂运单。 + +--- + +### REQ-PLAN-020 调度运输计划 + +- 功能点: + - 待调度和调度中状态支持点击调度。 + - 点击调度后跳转至计划调度页面进行运单调度。 + - 计划调度页面展示计划概要信息和待调度列表。 + - 用户可在待调度列表新增、编辑、删除调度条目。 + - 调度完成后,若计划下挂待执行、进行中或完成状态运单,计划状态进入或保持调度中。 + - 已取消运单不计入调度中状态判断。 + +- 异常与边界: + - 草稿、已完成、已取消状态不允许进入调度流程。 + - 调度前需校验计划是否存在且状态允许调度。 + - 调度页面保存失败时不改变计划原状态。 + - 调度后实际运单数据变更时,应同步刷新计划状态和列表数据。 + +- 反例: + - 不允许草稿计划直接调度。 + - 不允许已完成或已取消计划继续调度。 + - 不允许将已取消运单计入调度中判断。 + +--- + +### REQ-PLAN-021 取消运输计划 + +- 功能点: + - 待调度状态支持点击取消。 + - 点击取消后弹出确认关闭提示。 + - 在关闭确认弹窗中点击确认后,执行计划关闭操作,计划状态变更为已取消。 + - 取消成功后记录关闭原因,并刷新列表。 + +- 异常与边界: + - 非待调度状态不允许取消。 + - 用户取消确认弹窗时不改变计划状态。 + - 取消前需校验计划是否已新增运单;若状态已变化为调度中,应阻止取消并刷新列表。 + - 取消失败时提示失败原因,计划保持原状态。 + +- 反例: + - 不允许草稿、调度中、已完成、已取消状态执行取消。 + - 不允许跳过二次确认直接取消计划。 + - 不允许取消失败后仍提示成功。 + +--- + +### REQ-PLAN-022 完成运输计划 + +- 功能点: + - 调度中状态支持点击完成,手动完成当前计划。 + - 当已调度运输量达到计划运输量,且关联运单全部完成时,系统自动将计划置为已完成。 + - 未满足自动完成条件时,支持用户手动完成计划。 + - 实际运输量为计划下所有完成状态运单货物数量求和。 + - 计划运输量为计划中填写的货物信息中的货物数量求和。 + - 如果计划运输量未填写,则均需手动点击完成。 + - 手动完成时,如计划运输量与实际运输量存在差异,弹窗提示“实际运输量与计划运输量不一致,是否确认完成?”。 + - 用户确认后计划状态变更为已完成,并刷新列表。 + +- 异常与边界: + - 非调度中状态不允许手动完成。 + - 存在未完成的关联运单时,自动完成条件不成立。 + - 手动完成前需重新计算实际运输量,避免使用过期数据。 + - 用户在差异确认弹窗中取消时,不改变计划状态。 + - 完成失败时提示失败原因,计划保持原状态。 + +- 反例: + - 不允许待执行、进行中运单仍存在时自动完成计划。 + - 不允许计划运输量和实际运输量不一致时跳过确认弹窗直接完成。 + - 不允许把已取消运单货物数量计入实际运输量。 + +--- + +### REQ-PLAN-023 删除运输计划 + +- 功能点: + - 草稿状态支持点击删除。 + - 点击删除后弹出二次确认弹窗。 + - 确认后校验计划仍为草稿状态,校验通过后删除该计划。 + - 删除成功后刷新列表,并提示“删除成功”。 + +- 异常与边界: + - 非草稿状态不允许删除。 + - 删除前状态已变化为非草稿时阻止删除,并刷新列表。 + - 数据不存在时提示数据不存在,并刷新列表。 + - 用户取消二次确认时不执行删除。 + - 删除失败时提示失败原因,不改变列表其他数据。 + +- 反例: + - 不允许跳过二次确认直接删除。 + - 不允许删除待调度、调度中、已完成、已取消计划。 + - 不允许删除失败后仍提示成功。 + +--- + +### REQ-PLAN-024 底部操作按钮 + +- 功能点: + - 新增或编辑页面底部展示确认创建、暂存、返回等操作按钮。 + - 点击确认创建时校验必填字段,创建或保存正式运输计划,成功提示并返回列表。 + - 点击暂存时直接保存草稿,成功提示并返回列表。 + - 点击返回时返回列表,不保存当前页面数据。 + - 底部操作区与页面内容区分离,便于用户在长表单中执行操作。 + +- 异常与边界: + - 确认创建校验失败时停留在当前页面,并定位或提示失败字段。 + - 暂存失败时保留用户已填写内容。 + - 返回前如存在未保存改动,可按系统统一规则提示用户确认。 + - 重复点击确认创建或暂存时应防止重复提交。 + +- 反例: + - 不允许确认创建时绕过必填校验。 + - 不允许点击返回后仍悄悄保存数据。 + - 不允许重复点击导致生成多条相同计划。 + +--- + +### REQ-PLAN-025 权限与审计 + +- 功能点: + - 根据用户权限控制查询、新建计划、批量导入、批量导出、编辑、复制、删除、调度、详情、取消、完成等操作入口。 + - 创建时间、更新时间由系统自动记录。 + - 若列表或详情展示创建人、更新人等审计字段,应优先展示用户姓名,不直接展示用户 ID。 + - 操作日志应记录新增、编辑、复制、删除、调度、取消、完成、导入、导出等关键动作。 + +- 异常与边界: + - 无权限访问时提示权限不足。 + - 无按钮权限时不展示对应按钮,并阻止绕过页面发起操作。 + - 操作失败时不记录为成功日志。 + - 审计字段缺失时不影响核心业务字段展示,但应按系统兜底规则展示。 + +- 反例: + - 不允许无权限用户执行新增、编辑、删除、调度、完成等操作。 + - 不允许用户手动维护创建时间、更新时间。 + - 不允许直接向用户展示 createUser、updateUser 等用户 ID 字段。 + +--- + +### REQ-PLAN-026 计划详情布局 + +- 功能点: + - 计划详情页顶部展示计划标题,标题由计划名称和计划单号组成。 + - 计划标题右侧展示计划状态标签和运输类型标签。 + - 详情顶部左侧展示客户、项目、合同编号、货物信息、计划执行时间、附件等只读信息。 + - 详情顶部右侧以起点到终点的线路形式展示发货地和收货地,包含省市区、详细地址、联系人、联系方式等信息。 + - 详情页下方展示运单记录区域,运单记录区域右上方展示计划总量、已调度量、剩余量,并提供新增调度入口。 + - 页面整体为只读详情布局,除允许的查看运单详情、新增调度等操作外,不提供表单编辑能力。 + +- 异常与边界: + - 计划名称、计划单号、状态或运输类型缺失时,应展示兜底文案,避免页面标题空白。 + - 发货地或收货地信息不完整时,应按已有字段展示,不得拼接错误地址。 + - 附件为空时展示无附件状态或不展示附件链接区域。 + - 运单记录为空时展示空状态,仍保留计划概要信息。 + +- 反例: + - 不允许详情页顶部缺少计划名称或计划单号。 + - 不允许起点、终点展示位置反向。 + - 不允许详情页布局中出现可编辑输入框。 + +--- + +### REQ-PLAN-027 详情基本信息 + +- 功能点: + - 详情基本信息全部为只读展示。 + - 计划名称展示运输计划名称,最长100字符,作为页面标题核心内容展示。 + - 计划单号展示系统生成的计划编号,最长20字符,不可编辑。 + - 计划状态以状态标签展示,枚举包含草稿、待调度、调度中、已完成、已取消。 + - 运输类型以标签展示计划运输方式。 + - 客户展示委托客户名称,最长100字符。 + - 项目展示关联项目名称,最长100字符。 + - 合同编号展示关联合同编号,最长50字符。 + - 货物信息固定展示首条货物和总数量,总数量从计划货物信息表中求和。 + - 计划执行时间展示计划开始时间至计划结束时间,日期格式为 yyyy/MM/dd。 + - 附件以文件链接展示,支持点击下载或预览。 + - 发货地和收货地分别展示省市区、详细地址、联系人、电话。 + +- 异常与边界: + - 计划状态或运输类型不在枚举范围内时展示兜底文案并限制相关操作。 + - 货物信息为空时展示“/”或无货物信息,不得展示错误合计。 + - 计划开始时间或计划结束时间缺失时,仅展示已有日期或展示“/”。 + - 附件下载或预览失败时提示失败原因,不影响详情其他内容。 + - 收发货地址超长时应换行或省略展示,鼠标悬停可查看完整内容。 + +- 反例: + - 不允许详情页编辑计划名称、计划单号、状态、运输类型等字段。 + - 不允许把计划单号展示为空白或展示内部数据库 ID。 + - 不允许货物总数量脱离计划货物明细自行录入。 + +--- + +### REQ-PLAN-028 详情调度数据 + +- 功能点: + - 详情页运单记录区域右侧展示调度统计数据。 + - “共X{计量单位}”统计当前计划下所有运单货物数量合计,运单范围包含草稿、待执行、进行中、已完成、已取消。 + - “已调度X{计量单位}”统计待执行、进行中、已完成状态运单的货物数量合计,用于反映已分配运力的货量。 + - “已完成X{计量单位}”统计已完成状态运单的货物数量合计,用于反映已运输完成的货量。 + - “剩余X{计量单位}”根据计划总量与已调度量计算展示。 + - 统计数值随运单新增、取消、完成等状态变化同步刷新。 + +- 异常与边界: + - 运单存在不同计量单位时,应按计量单位分别统计或提示无法合并,不得强行合并为单一单位。 + - 运单货物数量为空时不参与统计。 + - 已取消运单计入“共X”总量展示,但不计入“已调度”和“已完成”统计。 + - 已调度量大于计划总量时,剩余量可展示为0或负差异,但不得影响实际数据追溯。 + - 统计加载失败时展示兜底状态,并提示用户刷新页面。 + +- 反例: + - 不允许把已取消运单计入已调度量。 + - 不允许把待执行或进行中运单计入已完成量。 + - 不允许不同计量单位货量无提示合并。 + +--- + +### REQ-PLAN-029 详情运单记录 + +- 功能点: + - 运单记录列表展示当前计划下的所有运单。 + - 运单记录列表字段同“运单管理”的运单字段口径。 + - 列表至少展示序号、运单号、车牌号或航班号或船号或班列号、司机、承运商、运输类型、承运类型、货物信息、发货地址、状态、操作等字段。 + - 运单记录展示运单状态,状态示例包含草稿、待执行、进行中、已完成、已取消。 + - 运单号支持点击或通过操作列进入对应运单详情。 + - 操作按钮仅提供查看运单详情。 + - 运单记录支持分页展示,分页信息展示总条数和页码。 + +- 异常与边界: + - 当前计划未关联运单时展示空状态。 + - 运单详情已删除或无权限访问时提示无法查看。 + - 运单记录字段较多时允许横向滚动,操作列应保持可见。 + - 运单状态变化后返回计划详情,应刷新运单记录和调度统计。 + +- 反例: + - 不允许在计划详情的运单记录中直接编辑或删除运单。 + - 不允许展示非当前计划下的运单。 + - 不允许操作列出现除详情以外的运单操作。 + +--- + +### REQ-PLAN-030 详情操作按钮 + +- 功能点: + - 计划详情页运单记录右侧提供“新增调度”按钮。 + - 当当前计划状态为待调度或调度中时,展示“新增调度”按钮。 + - 点击“新增调度”后跳转至计划调度页面。 + - 运单记录操作列提供“详情”按钮,点击后跳转对应运单详情。 + +- 异常与边界: + - 草稿、已完成、已取消状态不展示新增调度按钮。 + - 用户无调度权限时不展示新增调度按钮。 + - 点击新增调度前需校验计划最新状态,若状态已不允许调度则阻止跳转并刷新详情。 + - 点击运单详情时若运单不存在、已删除或无权限访问,应提示无法查看。 + +- 反例: + - 不允许草稿、已完成、已取消计划在详情页新增调度。 + - 不允许无权限用户通过详情页发起调度。 + - 不允许运单记录操作列提供编辑、删除、取消等操作。 + +--- + +### REQ-PLAN-031 计划调度页布局 + +- 功能点: + - 计划调度页顶部展示运输计划概要信息,布局与计划详情页保持一致。 + - 顶部标题展示计划名称、计划单号、计划状态标签和运输类型标签。 + - 顶部左侧展示客户、项目、合同编号、货物信息、计划执行时间、附件等只读信息。 + - 顶部右侧以起点到终点线路形式展示发货地、收货地、详细地址、联系人、联系方式。 + - 页面下方展示待调度列表,列表标题右侧展示计划总量、已调度量、剩余量。 + - 待调度列表标题区提供“新增”按钮,用于新增调度条目。 + +- 异常与边界: + - 计划不存在、已删除或状态不允许调度时,阻止进入计划调度页并提示。 + - 计划概要信息加载失败时不展示待调度操作,避免在未知计划上调度。 + - 附件为空时展示无附件状态或不展示附件链接区域。 + - 计划总量、已调度量、剩余量加载失败时,应提示统计加载失败,并限制生成运单。 + +- 反例: + - 不允许在计划调度页编辑计划基本信息。 + - 不允许草稿、已完成、已取消计划进入可调度页面。 + - 不允许调度页顶部展示与当前计划不一致的概要数据。 + +--- + +### REQ-PLAN-032 待调度列表 + +- 功能点: + - 待调度列表展示当前计划下已保存但尚未最终生成运单的调度条目。 + - 列表展示序号、运输类型、承运商、司机、车牌号或航班号或船号或班列号、货物信息、发货地址、到货地址、操作等字段。 + - 列表操作列提供编辑、删除。 + - 点击编辑后弹出新增或编辑调度弹窗,并回显该条调度数据。 + - 点击删除后删除当前调度条目,并同步刷新待调度列表、已调度量和剩余量。 + - 待调度列表字段较多时支持横向滚动,操作列保持可见。 + +- 异常与边界: + - 待调度列表为空时展示空状态,不影响新增调度。 + - 删除调度条目前应二次确认,用户取消时不删除。 + - 已生成运单的调度条目不允许在待调度列表继续编辑或删除。 + - 编辑或删除后统计数据应重新计算。 + +- 反例: + - 不允许待调度列表展示其他计划的调度条目。 + - 不允许删除已生成运单的调度条目。 + - 不允许编辑或删除后仍显示旧的已调度量和剩余量。 + +--- + +### REQ-PLAN-033 新增编辑调度弹窗 + +- 功能点: + - 点击待调度列表“新增”按钮,弹出新增或编辑调度弹窗。 + - 调度弹窗默认带出当前计划对应的收发货信息、货物信息、计划时间等内容,用户无需重复填写。 + - 调度弹窗支持精简录入和完整录入两种模式,用户可点击切换填写字段。 + - 编辑已保存调度条目时,仍通过弹窗编辑并回显原调度信息。 + - 弹窗底部展示重置、保存按钮。 + - 关闭弹窗时不自动保存未提交内容。 + +- 异常与边界: + - 当前计划状态不是待调度或调度中时,不允许打开新增调度弹窗。 + - 带出的计划收发货信息缺失时,阻止保存调度并提示计划数据不完整。 + - 切换精简录入和完整录入时,应保留已填写且两个模式共用的字段。 + - 用户关闭弹窗或点击取消时,如存在未保存改动,可按系统统一规则提示确认。 + +- 反例: + - 不允许新增调度时要求用户重复填写计划已有的收发货地址。 + - 不允许切换录入模式后丢失已填写的承运商、司机、车牌号、货物数量等共用字段。 + - 不允许关闭弹窗后静默保存数据。 + +--- + +### REQ-PLAN-034 精简录入调度信息 + +- 功能点: + - 精简录入用于快速生成单条调度任务。 + - 精简录入展示收发货信息和任务信息两个区域。 + - 收发货信息由计划自动带出,包含发货地址、收货地址、发货联系人、发货联系方式、收货联系人、收货联系方式。 + - 承运类型使用切换按钮,选项为承运商、自运。 + - 承运类型为承运商时,承运商为必填,使用搜索选择框。 + - 司机使用搜索选择框,手机号根据司机信息带出或手工录入。 + - 车牌号为必填;运输类型为非公路时,字段名称按航班号、船号、班列号等运输方式展示。 + - 货物类型、货物名称、数量为必填,数量单位随数量一起填写。 + - 规格、型号、里程、预计发货日期、预计完成日期、单价、备注为可填写字段。 + - 备注最多500字。 + +- 异常与边界: + - 承运类型为承运商且承运商为空时阻止保存。 + - 货物类型、货物名称、数量、数量单位为空时阻止保存。 + - 车牌号或对应运输载具编号为空时阻止保存。 + - 数量小于0、等于0或超过计划剩余量时阻止保存。 + - 预计完成日期早于预计发货日期时阻止保存。 + - 手机号格式不合法、里程或单价小于0时阻止保存。 + +- 反例: + - 不允许承运商模式下不选择承运商。 + - 不允许保存无货物数量或数量超过剩余量的调度条目。 + - 不允许非公路运输仍固定展示车牌号字段。 + +--- + +### REQ-PLAN-035 完整录入调度信息 + +- 功能点: + - 完整录入用于填写更完整的运单信息。 + - 完整录入包含收发货信息、货物信息、承运信息、费用信息、附件等区域。 + - 收发货信息由计划自动带出,允许按业务规则调整联系人和联系方式。 + - 货物信息以明细表格维护,支持新增、删除、导入货物、选择货物。 + - 货物明细展示货物名称、货物类型、剩余数量、本次数量、数量单位、包装、品牌、规格、型号、物料编码、操作等字段。 + - 货物名称、货物类型、本次数量、数量单位为必填。 + - 承运信息包含承运类型、承运商、司机、手机号、车牌号或航班号或船号或班列号、里程、预计发货日期、预计完成日期、备注。 + - 费用信息包含单价、数量合计、运费、其他运费合计、运费合计。 + - 附件支持上传调度或运单相关附件。 + +- 异常与边界: + - 货物明细为空时阻止保存。 + - 任一货物行本次数量为空、小于等于0或超过该货物剩余数量时阻止保存。 + - 删除最后一行货物明细时应保留一条空行或提示至少保留一行。 + - 导入货物或选择货物后,需重新计算数量合计和剩余数量。 + - 承运信息、费用信息、附件校验规则应与运单新增或编辑保持一致。 + - 附件格式不支持或上传失败时阻止保存或提示用户重新上传。 + +- 反例: + - 不允许完整录入保存没有货物明细的调度条目。 + - 不允许本次数量超过计划该货物剩余数量。 + - 不允许导入货物后绕过货物类型、数量单位等必填校验。 + +--- + +### REQ-PLAN-036 调度货量与费用规则 + +- 功能点: + - 待调度列表标题区展示共X、已调度X、剩余X等调度统计。 + - 新增或编辑调度时,本次数量占用计划剩余数量。 + - 完整录入中的剩余数量展示该货物在当前计划中扣减已调度数量后的剩余可调度数量。 + - 数量合计由当前调度货物明细的本次数量自动汇总。 + - 若填写数量、数量单位和单价,则系统自动计算运费。 + - 运费允许用户修改。 + - 运费合计由运费加其他运费合计自动计算,只读展示。 + +- 异常与边界: + - 不同计量单位的货物数量应按单位分别汇总或提示无法合并,不得无提示合并。 + - 编辑调度条目时,剩余数量应包含当前条目原占用数量后再重新校验。 + - 本次数量超过剩余数量时阻止保存。 + - 单价、运费、其他运费合计不能小于0,金额最多保留2位小数。 + - 数量、数量单位或单价缺少任一项时,无需自动计算运费。 + - 运费合计计算失败时提示计算异常,并阻止生成运单。 + +- 反例: + - 不允许本次数量保存为0或负数。 + - 不允许调度数量超过计划剩余数量。 + - 不允许运费合计被手工修改。 + - 不允许数量或单价缺失时仍强制自动计算运费。 + +--- + +### REQ-PLAN-037 调度保存与生成运单 + +- 功能点: + - 点击调度弹窗保存后,待调度列表新增或更新一条调度记录。 + - 对已保存的待调度条目,可继续编辑或删除。 + - 计划调度页右下角提供确认生成运单入口,点击后弹出确认弹窗。 + - 点击“生成运单草稿”后,跳转运单列表页,列表新增对应运单草稿。 + - 点击“确认生成运单”后,根据运单管理新增或编辑页面的状态规则生成正式运单。 + - 生成运单成功后,计划状态按调度结果变更为调度中或保持调度中,并刷新计划列表、计划详情和调度统计。 + +- 异常与边界: + - 待调度列表为空时,不允许确认生成运单。 + - 生成运单前需校验所有待调度条目的必填项、货量、承运信息、费用和附件规则。 + - 生成运单时如存在校验失败条目,应阻止生成并定位到对应条目。 + - 用户在确认弹窗中取消时,不生成运单且保留待调度列表。 + - 生成运单失败时保留待调度列表,提示失败原因,便于用户修正后重试。 + - 部分运单生成失败时,应按系统事务策略整体失败或明确提示成功与失败结果,不得静默丢失条目。 + +- 反例: + - 不允许待调度列表为空时生成运单。 + - 不允许生成运单时跳过运单新增或编辑状态规则。 + - 不允许生成失败后清空用户已保存的待调度条目。 + - 不允许重复点击导致重复生成运单。 + +--- + +### REQ-PLAN-038 计划导入页布局 + +- 功能点: + - 点击运输计划列表的批量导入后,进入导入发货计划页面。 + - 页面上方展示导入信息填写区,包含项目、客户、客户合同、计划明细表上传、下载模板、提交、返回等内容。 + - 页面下方展示数据明细区,包含批量删除、运单数页签、疑似重复页签、待导入数据列表、分页、底部返回和导入按钮。 + - 待导入数据列表字段至少包含勾选框、序号、计划单号、计划名称、运输类型、货物名称、货物类型、数量、计量单位、发货地址、操作等字段。 + - 操作列支持编辑、保存、取消、删除。 + - 底部展示当前已选或可导入数据数量。 + +- 异常与边界: + - 未上传文件时,数据明细区展示空状态或不展示待导入数据。 + - 校验失败数据不进入待导入数据明细,只通过错误报告反馈。 + - 数据明细字段较多时支持横向滚动,操作列应保持可见。 + - 页面刷新或返回前如存在已解析但未导入数据,应按系统统一规则提示用户确认。 + +- 反例: + - 不允许校验失败数据混入待导入数据明细。 + - 不允许未选择项目时直接上传并确认导入。 + - 不允许操作列被横向滚动隐藏。 + +--- + +### REQ-PLAN-039 导入信息填写 + +- 功能点: + - 项目为必填,使用选择框,支持模糊查询后选择项目档案。 + - 客户为必填,选择项目后自动带出,不可编辑;若项目下存在多个客户,则支持下拉选择。 + - 客户合同为必填,选择项目后自动带出,不可编辑;若项目下存在多个客户合同,则支持下拉选择。 + - 顶部承运商为批量赋值字段,选择后所有导入运单的承运商统一赋值为该值。 + - 计划明细表为必填,点击添加附件上传 Excel 文件。 + - 页面提示仅支持 Excel 格式。 + - 点击下载模板可下载 Excel 导入模板。 + - 点击提交后上传文件并解析校验。 + - 点击返回时返回计划列表,不执行导入。 + +- 异常与边界: + - 项目为空时阻止提交并提示。 + - 客户或客户合同未成功带出时阻止提交,并提示重新选择项目。 + - 上传文件为空时阻止提交并提示。 + - 上传文件不是 Excel 格式时阻止提交并提示。 + - 顶部承运商为空时不影响上传校验,但不进行批量赋值。 + - 项目切换后,应清空已上传文件和已解析数据,避免跨项目导入。 + +- 反例: + - 不允许客户或客户合同脱离项目单独编辑。 + - 不允许上传非 Excel 文件作为计划明细表。 + - 不允许项目切换后沿用上一个项目的待导入数据。 + +--- + +### REQ-PLAN-040 导入模板字段 + +- 功能点: + - 导入模板字段包含序号、原始单号、配载标识号、车牌号或航班号或船号或班列号、运输类型、司机或船长姓名、司机或船长手机号、发货地址、发货联系人、发货联系人电话、到货地址、收货联系人、收货联系人电话、货物名称、货物类型、包装、数量、计量单位、规格、型号、里程、单价、计价单位、运费、其他费用合计、运费合计、实际发货时间、实际完成时间、预计发货时间、预计完成时间、备注、同一运单标识号。 + - 必填字段标题需增加“*”标识,包含车牌号或航班号或船号或班列号、运输类型、发货地址、到货地址、货物名称、货物类型、数量、计量单位、实际发货时间、实际完成时间。 + - 原始单号用于填写业务侧自己的单号,无需与系统编号相同。 + - 配载标识号适用于公路配载场景,填写方式为配载组加配载顺序,例如001-1。 + - 运输类型枚举包含公路整车、公路配载或零担、铁路运输、水路运输、跨境海运、航空运输。 + - 发货地址和到货地址需精确到具体地址,用于轨迹回放。 + - 货物类型必须为系统内维护的货物类型;无法按货物名称匹配到货物类型时,归为其他类。 + - 计量单位必须填写系统中的枚举值。 + - 计价单位枚举包含元/吨、元/方、元/件、元/吨/公里。 + - 备注为文本,最多200字。 + - 当同一运单包含多个货物时,需拆分多行,并填写同一运单标识号标记多行为同一运单。 + +- 异常与边界: + - 模板字段缺失、字段名称被修改或字段顺序不符合模板时,应阻止解析并提示重新下载模板。 + - 必填字段为空时,对应行校验失败并写入错误原因。 + - 枚举字段不属于系统枚举值时,对应行校验失败。 + - 同一运单标识号为空时,默认按单行独立运单处理。 + +- 反例: + - 不允许导入模板缺少车牌号或运输类型等关键字段。 + - 不允许把非系统枚举的运输类型、计量单位、计价单位导入成功。 + - 不允许多货物运单不填写同一运单标识号却被强行合并。 + +--- + +### REQ-PLAN-041 导入数据校验 + +- 功能点: + - 上传 Excel 后系统逐行校验字段格式、必填、枚举、金额、日期、配载关系、多货物关系和重复性。 + - 同一配载标识号下车牌号必须一致;配载标识号不可重复。 + - 当运输类型为公路整车或公路配载或零担时,车牌号需满足首位汉字、次位大写字母、总长度7位或8位。 + - 当运输类型为非公路时,车牌号或航班号或船号或班列号不执行车牌格式校验。 + - 司机或船长手机号、发货联系人电话、收货联系人电话有值时,需校验11位数字格式。 + - 发货地址和到货地址未匹配到地址库时给出警告,允许继续导入,但提示轨迹回放将受影响。 + - 数量有值时必须为正数。 + - 里程有值时必须为正数。 + - 运费合计有值时,必须等于运费加其他费用合计。 + - 导入状态选择进行中时,实际发货时间和实际完成时间不必填。 + - 实际发货时间、实际完成时间、预计发货时间、预计完成时间有值时,必须为日期时间格式。 + - 实际发货时间不能晚于实际完成时间。 + - 实际完成时间不能早于实际发货时间。 + - 预计发货时间不能晚于预计完成时间。 + - 预计完成时间不能早于预计发货时间。 + - 同一运单标识号下需校验同一个车牌号或同一运输载具编号。 + +- 异常与边界: + - 运输类型不是系统枚举值时,对应行报错“运输类型需系统枚举值”。 + - 公路车牌号格式不通过时,对应行报错“车牌号校验不通过”。 + - 配载单车牌号不一致或配载标识号重复时,对应行报错“配载单车牌号不一致;配载标识号重复”。 + - 手机号格式不通过时,对应行报错“手机号格式校验不通过”。 + - 货物名称为空时,对应行报错“货物名称必填”。 + - 计量单位不存在时,对应行报错“计量单位不存在”。 + - 运费合计不等于运费与其他费用合计之和时,对应行报错“运费合计不等于运费与其他运费合计之和,请调整”。 + - 同一运单车牌不一致时,对应行报错“统一运单车牌不一致”。 + +- 反例: + - 不允许枚举、金额、日期明显错误的数据进入待导入明细。 + - 不允许同一配载单使用不同车牌号。 + - 不允许同一运单标识号下出现不同车牌号仍合并为一个运单。 + - 不允许运费合计与分项费用不一致仍校验通过。 + +--- + +### REQ-PLAN-042 错误报告下载 + +- 功能点: + - 若上传文件存在校验不通过数据,则 toast 提示“提交失败,报错文件已下载,请根据提示修改内容”。 + - 系统自动下载错误报告 Excel。 + - 错误报告在上传文档原字段最后一列追加报错文案。 + - 同一行存在多个错误时,多个报错文案以分号隔开。 + - 校验失败的运单不展示在待导入数据明细中。 + - 错误报告文件名应包含运输计划或发货计划、报错文件或导入失败明细、时间戳。 + +- 异常与边界: + - 错误报告生成失败时仍需提示提交失败,并提示用户重新上传或联系管理员。 + - 文件中仅存在警告且无报错时,允许进入待导入数据明细,并在行内展示警告信息。 + - 全部数据校验失败时,不展示待导入列表,仅下载错误报告。 + - 部分数据失败时,失败行下载错误报告,通过行进入待导入数据明细。 + +- 反例: + - 不允许只提示失败但不下载错误报告。 + - 不允许错误报告丢失原始导入字段。 + - 不允许多个错误只保留最后一个错误原因。 + +--- + +### REQ-PLAN-043 待导入数据明细 + +- 功能点: + - 当导入数据校验通过后,展示在待导入数据明细中。 + - 系统对每一条上传的条目自动生成唯一计划号。 + - 数据明细页签展示运单数,格式如“运单数(4)”。 + - 待导入列表支持勾选多行并批量删除。 + - 单行支持在线编辑、保存、取消、删除。 + - 点击编辑后,该行可编辑字段变为输入状态。 + - 点击保存后保存该行编辑内容,行恢复只读。 + - 点击取消后放弃修改,恢复原始值。 + - 点击删除后移除该行数据。 + - 列表支持分页,默认10条/页。 + +- 异常与边界: + - 在线编辑保存时需重新执行该行字段校验。 + - 批量删除未勾选数据时提示先选择数据。 + - 删除全部待导入数据后,导入按钮不可用或点击时提示无可导入数据。 + - 行编辑过程中切换页签或分页时,应按系统统一规则提示保存或放弃修改。 + +- 反例: + - 不允许编辑后绕过导入校验。 + - 不允许删除行后仍参与最终导入。 + - 不允许未通过校验的数据出现在运单数页签中。 + +--- + +### REQ-PLAN-044 疑似重复处理 + +- 功能点: + - 系统需校验导入数据重复性。 + - 疑似重复判断规则为同一运单批次号下,所有导入字段数据一致。 + - 检测到疑似重复运单时,单独通过疑似重复页签展示,格式如“疑似重复(2)”。 + - 疑似重复数据允许用户在线确认、编辑或删除。 + - 用户确认保留后,该数据可参与最终导入。 + - 用户删除后,该数据不参与最终导入。 + +- 异常与边界: + - 疑似重复数据未经确认时,确认导入应提示用户先处理疑似重复。 + - 编辑疑似重复数据后需重新校验重复性和字段合法性。 + - 疑似重复页签数量应随确认、编辑、删除动作实时更新。 + - 不同运单批次号下的相同字段数据不按疑似重复处理,除非系统另有全局重复规则。 + +- 反例: + - 不允许疑似重复数据未经处理直接生成正式运单。 + - 不允许把仅部分字段相同的数据误判为完全重复。 + - 不允许删除疑似重复数据后仍参与导入。 + +--- + +### REQ-PLAN-045 确认导入生成运单 + +- 功能点: + - 点击底部导入按钮后,对待导入明细再次执行最终校验。 + - 校验通过后生成正式运单。 + - 导入成功后跳转至运单列表。 + - 返回按钮返回计划列表,不执行导入。 + - 导入成功的数据应与所选项目、客户、客户合同建立关联。 + - 顶部承运商有值时,应批量赋值到所有导入运单。 + +- 异常与边界: + - 待导入明细为空时不允许导入。 + - 存在未保存编辑行时不允许导入,并提示先保存或取消编辑。 + - 存在未处理疑似重复数据时不允许导入,并提示先处理疑似重复。 + - 导入生成运单失败时保留待导入明细,提示失败原因。 + - 重复点击导入按钮时应防止重复生成运单。 + - 部分生成失败时,应按系统事务策略整体失败或明确展示成功与失败结果。 + +- 反例: + - 不允许未确认导入就生成正式运单。 + - 不允许导入失败后清空待导入数据。 + - 不允许承运商批量赋值覆盖用户已明确单独编辑的不同承运商,除非用户再次确认。 + +--- + +## 通用规则 + +- 运输计划用于记录项目维度下的计划运输任务,归属于“业务管理”主菜单。 +- 运输计划状态包含草稿、待调度、调度中、已完成、已取消。 +- 计划单号由系统自动生成,规则为 JH + 8位年月日 + 3位流水号,生成后只读不可编辑。 +- 项目、客户合同、计划名称、计划单号、运输类型为基本信息核心字段;确认创建时必须校验必填。 +- 发货地址、收货地址为收发货信息核心字段;货物类型为货物信息核心字段。 +- 运输类型为公路时,收发货地址按地址选择逻辑处理;运输类型为水运或海运时选择港口,空运时选择空港,铁运时选择站点。 +- 非公路运输通过常用地址或常用线路回填地址时,必须校验地址是否为当前运输类型对应的港口、空港、车站地址,不匹配时 toast 提示“请选择港口/空港/车站地址”。 +- 货物信息至少保留一行;数量为非负数,数量单位必须来自系统枚举。 +- 运输数量合计由系统根据货物明细数量自动计算,不允许手工修改。 +- 计划运输量为计划中货物信息的货物数量求和;实际运输量为计划下所有完成状态运单货物数量求和。 +- 已调度运输量达到计划运输量且关联运单全部完成时,计划自动变更为已完成。 +- 未填写计划运输量或自动完成条件不满足时,只能通过手动完成完成计划。 +- 计划详情页整体只读展示,详情页运单记录仅允许查看运单详情,不允许直接编辑或删除运单。 +- 计划详情页调度统计需区分计划总量、已调度量、已完成量、剩余量,并随运单状态变化刷新。 +- 计划调度页仅允许待调度和调度中状态进入,草稿、已完成、已取消状态不允许新增调度。 +- 计划调度弹窗支持精简录入和完整录入,两个模式切换时应保留共用字段。 +- 调度本次数量不得超过计划剩余数量,编辑时剩余数量需考虑当前条目原占用数量。 +- 调度生成运单前必须按运单新增或编辑规则完成校验,生成后刷新计划状态和调度统计。 +- 计划导入流程为选择项目、上传 Excel、系统校验、下载错误报告或展示待导入明细、处理疑似重复、确认导入、生成正式运单。 +- 计划导入模板必填字段必须使用“*”标识,导入校验失败报告必须在原字段最后追加错误原因列。 +- 计划导入中的疑似重复数据必须由用户确认、编辑或删除后才允许最终导入。 +- 新增、编辑、删除、取消、完成、导入等操作成功后均需刷新列表。 +- 批量导入失败明细应在原模板字段后追加“导入失败原因”,并自动下载。 +- 列表、详情、导出预览等用户可见场景如展示审计人员,应展示姓名字段,避免直接展示用户 ID。 diff --git a/需求卡/项目管理需求卡.md b/需求卡/项目管理需求卡.md new file mode 100644 index 0000000..d17baf8 --- /dev/null +++ b/需求卡/项目管理需求卡.md @@ -0,0 +1,713 @@ +# 项目管理需求卡 + +## 目录 + +- [REQ-PROJ-001 菜单入口](#req-proj-001-菜单入口) +- [REQ-PROJ-002 列表与分页](#req-proj-002-列表与分页) +- [REQ-PROJ-003 条件查询与重置](#req-proj-003-条件查询与重置) +- [REQ-PROJ-004 列表状态与操作](#req-proj-004-列表状态与操作) +- [REQ-PROJ-005 新建立项](#req-proj-005-新建立项) +- [REQ-PROJ-006 项目基础字段](#req-proj-006-项目基础字段) +- [REQ-PROJ-007 项目主要内容](#req-proj-007-项目主要内容) +- [REQ-PROJ-008 客户信息选择](#req-proj-008-客户信息选择) +- [REQ-PROJ-009 下游承运商选择](#req-proj-009-下游承运商选择) +- [REQ-PROJ-010 项目情况说明](#req-proj-010-项目情况说明) +- [REQ-PROJ-011 项目附件](#req-proj-011-项目附件) +- [REQ-PROJ-012 附件材料要求](#req-proj-012-附件材料要求) +- [REQ-PROJ-013 保存草稿与临时生效](#req-proj-013-保存草稿与临时生效) +- [REQ-PROJ-014 提交审批](#req-proj-014-提交审批) +- [REQ-PROJ-015 审批通过](#req-proj-015-审批通过) +- [REQ-PROJ-016 审批驳回与撤回](#req-proj-016-审批驳回与撤回) +- [REQ-PROJ-017 重大项目补录](#req-proj-017-重大项目补录) +- [REQ-PROJ-018 客户额度校验](#req-proj-018-客户额度校验) +- [REQ-PROJ-019 编辑立项](#req-proj-019-编辑立项) +- [REQ-PROJ-020 查看立项](#req-proj-020-查看立项) +- [REQ-PROJ-021 删除草稿立项](#req-proj-021-删除草稿立项) +- [REQ-PROJ-022 作废立项](#req-proj-022-作废立项) +- [REQ-PROJ-023 发起变更立项](#req-proj-023-发起变更立项) +- [REQ-PROJ-024 变更项目信息](#req-proj-024-变更项目信息) +- [REQ-PROJ-025 变更内容与原因](#req-proj-025-变更内容与原因) +- [REQ-PROJ-026 变更审批与生效](#req-proj-026-变更审批与生效) +- [REQ-PROJ-027 变更记录](#req-proj-027-变更记录) +- [REQ-PROJ-028 选择关联项目](#req-proj-028-选择关联项目) +- [REQ-PROJ-029 导出立项列表](#req-proj-029-导出立项列表) +- [REQ-PROJ-030 权限与审计](#req-proj-030-权限与审计) +- [通用规则](#通用规则) + +--- + +### REQ-PROJ-001 菜单入口 + +- 功能点: + - 项目管理模块归属于“项目管理”主菜单。 + - 在“项目管理”菜单下提供“项目管理”入口。 + - 用户进入项目管理页面后,可进行查询、新建立项、重大项目补录、编辑、提交、查看、删除、变更、作废、导出等操作。 + +- 异常与边界: + - 无菜单权限时不展示“项目管理”入口。 + - 有菜单权限但无按钮权限时,仅展示允许访问的页面和操作。 + - 菜单或列表加载失败时提示失败原因,不影响其他模块访问。 + +- 反例: + - 不允许把项目管理挂到非项目管理主菜单下。 + - 不允许无权限用户通过 URL 直接进入项目管理页面。 + - 不允许菜单入口存在但页面无法加载。 + +--- + +### REQ-PROJ-002 列表与分页 + +- 功能点: + - 默认展示当前用户权限范围内的项目立项数据。 + - 列表展示序号、立项申请单号、项目编号、项目名称、项目类型、客户名称、下游承运商、承办部门、项目负责人、审批状态、当前节点、当前处理人、生效类型、审核通过时间、操作等字段。 + - 审批状态和操作列固定在右侧,不随横向滚动条滑动。 + - 默认按创建时间或立项申请时间降序展示。 + - 支持分页展示,默认10条/页,支持20/50/100条/页。 + +- 异常与边界: + - 查询无数据时展示空状态。 + - 当前页数据因删除、提交、撤回、审批、变更等操作发生变化后,应刷新列表并保持分页逻辑正确。 + - 列表加载失败时保留当前查询条件和分页条件,提示用户重新查询。 + +- 反例: + - 不允许审批状态或操作列被横向滚动隐藏。 + - 不允许列表字段展示用户 ID 代替用户姓名。 + - 不允许分页后丢失当前查询条件。 + +--- + +### REQ-PROJ-003 条件查询与重置 + +- 功能点: + - 支持按立项申请单号、项目名称、承办部门、项目负责人、项目类型、审批状态、生效类型等条件组合查询。 + - 立项申请单号、项目名称使用输入框,支持模糊查询。 + - 承办部门、项目负责人使用输入或搜索选择控件。 + - 项目类型、审批状态、生效类型使用下拉单选控件。 + - 点击查询后按当前条件刷新列表。 + - 点击重置后清空所有查询条件,恢复默认列表。 + - 查询条件较多时支持展开和收起。 + +- 异常与边界: + - 查询条件为空时点击查询,按默认规则展示全部权限范围内数据。 + - 查询结果为空时展示空状态,不清空用户已输入条件。 + - 重置后页码恢复第一页,并重新加载列表。 + +- 反例: + - 不允许重置后仍保留隐藏查询条件。 + - 不允许只按单个条件查询而忽略其他已选择条件。 + - 不允许查询后改变列表字段或操作范围。 + +--- + +### REQ-PROJ-004 列表状态与操作 + +- 功能点: + - 审批状态包含草稿、审批中、已撤回、审批通过、已驳回、变更审批中、变更驳回、变更审批通过等状态。 + - 生效类型包含临时、正式。 + - 草稿状态展示编辑、提交、删除操作。 + - 审批中状态展示查看操作。 + - 已撤回状态展示编辑、查看、删除操作。 + - 已驳回状态展示编辑、查看、删除操作。 + - 审批通过且正式生效的项目展示查看、变更等操作。 + - 变更审批中状态展示查看操作。 + - 变更驳回状态展示编辑、查看操作。 + - 操作按钮展示受项目状态和用户权限共同控制。 + +- 异常与边界: + - 操作执行前需重新校验项目最新状态,避免列表状态过期导致误操作。 + - 状态为空或未知时限制编辑、提交、删除、变更等高风险操作。 + - 状态变更成功后刷新列表,展示最新状态和可执行操作。 + +- 反例: + - 不允许审批中项目继续删除。 + - 不允许已审批通过项目按草稿规则编辑基础信息。 + - 不允许仅根据前端展示状态跳过后端状态校验。 + +--- + +### REQ-PROJ-005 新建立项 + +- 功能点: + - 点击列表顶部“新建”按钮后打开新建立项页面或弹窗。 + - 新建立项页面包含项目基本信息、项目主要内容、客户信息、承运商信息、项目情况说明、项目材料等区域。 + - 立项申请单号和项目编号由系统保存草稿后自动生成,只读不可编辑。 + - 新建立项支持保存草稿、提交审批、关闭。 + - 普通项目和重大项目按项目类型区分审批流程。 + - 重大项目如果金额超过8000万,需走物流领导审批流程。 + +- 异常与边界: + - 新建页面打开失败时提示失败原因,不改变列表数据。 + - 项目类型、项目名称、项目简称、业务部门、承办部门、客户名称、下游承运商、资金和回款相关必填字段为空时阻止提交审批。 + - 保存草稿时仅校验基本信息必填项,不强制上传附件。 + - 重复点击保存或提交时应防止重复生成项目单据。 + +- 反例: + - 不允许用户手工填写或修改立项申请单号、项目编号。 + - 不允许缺少项目类型时保存有效项目。 + - 不允许金额超过8000万的重大项目走普通审批流程。 + +--- + +### REQ-PROJ-006 项目基础字段 + +- 功能点: + - 项目类型为必填字段,使用下拉单选控件,枚举包含普通项目、重大项目。 + - 立项申请单号为只读文本,由系统保存单据后自动生成,用于追踪立项申请流程。 + - 项目编号为只读文本,由系统自动生成,全局唯一,示例格式为 LX-2026-000001。 + - 项目名称为必填字段,使用单行输入框,最多50个汉字,且不可重复。 + - 项目简称为必填字段,使用单行输入框,最多20个汉字。 + - 业务部门为必填字段,使用下拉单选控件,关联用户所属部门。 + - 承办部门为必填字段,使用下拉单选控件,来源为组织部门树。 + - 项目由来使用下拉单选控件,默认商务洽谈。 + - 项目由来说明使用大文本域,最多300字。 + +- 异常与边界: + - 项目名称为空、超过50字或重复时阻止提交并提示。 + - 项目简称为空或超过20字时阻止提交并提示。 + - 业务部门或承办部门为空时阻止提交并提示。 + - 立项申请单号或项目编号生成失败时阻止保存并提示。 + +- 反例: + - 不允许两个项目使用完全相同的项目名称。 + - 不允许把立项申请单号或项目编号作为可编辑输入项。 + - 不允许承办部门脱离组织部门树随意录入。 + +--- + +### REQ-PROJ-007 项目主要内容 + +- 功能点: + - 项目资金使用额度为必填数字字段,单位万元,表示实际业务回款周期内付款额度,需大于等于0并保留2位小数。 + - 项目应收账款额度为必填数字字段,单位万元,表示回款周期内最大应收账款额度,需大于等于0并保留2位小数。 + - 应收账款回款期限为必填数字字段,单位天,范围为0到999的整数。 + - 回款账期为必填数字字段,单位天,范围为0到999的整数。 + - 货物类型使用弹窗选择控件,来源为数据字典或货物类型档案,非必填。 + - 预估货物数量使用文本输入框,最多100字。 + - 业务周期使用日期范围控件,格式为 yyyy-MM-dd 到 yyyy-MM-dd。 + - 运输线路使用单行输入框,最多100字。 + - 运输类型使用下拉单选控件,枚举包含汽运、铁路、海运等运输方式。 + - 业务类型使用下拉单选控件,枚举包含一类规模业务、二类规模业务等。 + - 项目规模、预计利润、资金需求均为数字字段,单位万元,需大于等于0并保留2位小数。 + - 结算方式使用下拉单选控件,枚举包含先票后款、先款后票等。 + - 项目经办人和项目负责人为必填字段,使用人员搜索选择控件,默认当前用户,可重新选择。 + +- 异常与边界: + - 项目应收账款额度大于项目资金使用额度时阻止提交并提示。 + - 天数字段不是0到999整数时阻止提交并提示。 + - 金额类字段小于0或小数位超过2位时阻止提交并提示。 + - 业务周期开始日期晚于结束日期时阻止提交并提示。 + +- 反例: + - 不允许项目应收账款额度超过项目资金使用额度。 + - 不允许回款账期填写负数或1000天。 + - 不允许项目经办人、项目负责人为空后提交审批。 + +--- + +### REQ-PROJ-008 客户信息选择 + +- 功能点: + - 客户名称为必填字段,使用弹窗搜索选择控件,从客商档案选择上游合作客户。 + - 支持多选客户,至少选择1家客户。 + - 选择客户后,系统自动在客户信息表格生成客户行。 + - 客户信息表格展示客户、客户信用额度、企业性质、法定代表人、联系地址、联系人、联系方式等字段。 + - 删除客户行时需保证至少保留1条客户记录。 + +- 异常与边界: + - 未选择客户时阻止提交审批并提示。 + - 客商档案中客户已停用或不存在时阻止选择。 + - 仅剩1条客户记录时,删除按钮置灰或隐藏。 + - 多选客户确认后应实时刷新客户信息表格。 + +- 反例: + - 不允许手工输入客户名称代替客商档案选择。 + - 不允许删除所有客户记录后提交。 + - 不允许选择非客户类型的客商作为客户。 + +--- + +### REQ-PROJ-009 下游承运商选择 + +- 功能点: + - 下游承运商为必填字段,使用弹窗搜索选择控件,从客商档案选择物流承运商。 + - 支持多选承运商,至少选择1家承运商。 + - 选择承运商后,系统自动在承运商信息表格生成承运商行。 + - 承运商信息表格展示承运商、企业性质、法定代表人、联系地址、联系人、联系方式等字段。 + - 删除承运商行时需保证至少保留1条承运商记录。 + +- 异常与边界: + - 未选择下游承运商时阻止提交审批并提示。 + - 客商档案中承运商已停用或不存在时阻止选择。 + - 仅剩1条承运商记录时,删除按钮置灰或隐藏。 + - 多选承运商确认后应实时刷新承运商信息表格。 + +- 反例: + - 不允许手工输入承运商名称代替客商档案选择。 + - 不允许删除所有承运商记录后提交。 + - 不允许选择非承运商类型的客商作为下游承运商。 + +--- + +### REQ-PROJ-010 项目情况说明 + +- 功能点: + - 项目情况说明区域包含项目简介、盈利模式及利润测算情况说明、项目风险点、风险防范措施及应急预案等大文本字段。 + - 各说明字段用于补充项目背景、利润来源、风险识别和风控预案。 + - 大文本字段支持多行录入,保存草稿时可不完整,提交审批时按项目类型和流程要求校验。 + +- 异常与边界: + - 大文本字段超过系统限制时阻止提交并提示。 + - 提交审批时若流程要求必填但未填写,应阻止提交并提示用户补齐。 + - 用户关闭页面前存在未保存说明内容时,应提示确认离开。 + +- 反例: + - 不允许超长文本绕过前端限制提交。 + - 不允许提交审批时丢失已填写说明内容。 + - 不允许查看状态下修改项目情况说明。 + +--- + +### REQ-PROJ-011 项目附件 + +- 功能点: + - 项目材料区域支持上传附件。 + - 附件列表展示序号、附件类型、文件名、附件描述、文件大小、上传人、上传时间、操作等字段。 + - 附件类型使用下拉选择控件。 + - 附件描述支持录入和编辑。 + - 支持上传 pdf、bmp、jpeg、png、jpg、doc、docx、ppt、pptx、xlsx、xls、eml、msg、zip 等格式文件。 + - 单个文件大小限制500M。 + - 上传成功后自动新增附件表格行,展示文件名、大小、上传人、上传时间。 + - 支持删除未提交或允许编辑状态下的附件。 + - 支持按项目材料要求批量下载附件。 + +- 异常与边界: + - 文件格式不支持或大小超过500M时阻止上传并提示。 + - 上传失败时保留当前附件列表并提示失败原因。 + - 已提交审批的单据附件删除按钮按权限和状态隐藏或置灰。 + - 删除附件前需二次确认,确认后同步删除附件记录和服务器文件。 + +- 反例: + - 不允许上传无附件类型的有效附件。 + - 不允许上传超过500M的文件。 + - 不允许删除附件后仅移除前端行而服务器文件仍保留有效引用。 + +--- + +### REQ-PROJ-012 附件材料要求 + +- 功能点: + - 普通项目或中小项目提交审批前需上传利润测算表、单一来源供应商申请表或三方比价表、合同模板、项目操作说明、项目分析报告、项目考察报告。 + - 重大项目提交审批前需上传会议纪要、评审表决票、利润测算表、单一来源供应商申请表或三方比价表、项目操作说明、项目分析报告、项目考察报告、合同模板、上游尽职调查报告、下游尽职调查报告、业务承诺函。 + - 页面应根据项目类型展示对应附件材料清单,并标识未上传材料。 + - 保存草稿时附件可不上传。 + - 提交审批时按项目类型校验附件是否齐全。 + +- 异常与边界: + - 附件材料缺失时阻止提交审批,并提示缺失的附件类型。 + - 用户切换项目类型后,附件材料清单需同步切换,已上传且仍适用的附件保留。 + - 同一附件类型支持上传多个文件时,应按业务规则合并校验是否满足要求。 + +- 反例: + - 不允许重大项目按普通项目附件清单提交审批。 + - 不允许保存草稿时强制上传全部附件。 + - 不允许缺少合同模板仍提交审批。 + +--- + +### REQ-PROJ-013 保存草稿与临时生效 + +- 功能点: + - 新增或变更页面点击保存后,临时保存当前页面填写内容。 + - 新建立项保存草稿后,审批状态保持草稿,生效类型默认为临时。 + - 临时生效项目允许合同选择该项目。 + - 临时生效项目不能执行结算流程。 + - 保存草稿只要求基本信息满足最小必填校验,附件可不上传。 + +- 异常与边界: + - 基本信息必填项缺失时阻止保存草稿并提示。 + - 保存失败时保留用户已填写内容,方便修正后重新保存。 + - 草稿项目被删除或无权限编辑时,不允许继续保存。 + +- 反例: + - 不允许草稿临时项目执行结算。 + - 不允许保存草稿后丢失已上传附件或表格信息。 + - 不允许保存草稿触发审批流程。 + +--- + +### REQ-PROJ-014 提交审批 + +- 功能点: + - 草稿、已撤回、已驳回状态的立项单据支持提交审批。 + - 提交审批前校验全部必填字段、客户信息、承运商信息、项目材料和业务规则。 + - 不同项目类型、项目金额和变更类型走不同审批流程。 + - 提交成功后审批状态更新为审批中。 + - 提交审批后应实时推送待办消息给当前审批人。 + +- 异常与边界: + - 必填字段、客户或承运商信息、附件材料缺失时阻止提交并提示。 + - 审批流程发起失败时保持原状态,并保留用户输入内容。 + - 项目金额或项目类型变更导致审批流不匹配时,应按最新数据重新匹配审批流。 + - 重复点击提交时应防止重复发起审批。 + +- 反例: + - 不允许资料未完善的项目进入审批中。 + - 不允许不同金额重大项目使用错误审批流。 + - 不允许提交失败后仍把状态改为审批中。 + +--- + +### REQ-PROJ-015 审批通过 + +- 功能点: + - 当前审批节点处理人可对审批中单据执行审批通过。 + - 审批全部通过后,立项审批状态更新为审批通过。 + - 首次审批通过后,项目生效类型自动由临时变为正式。 + - 正式项目可在合同、运单、结算等下游业务中按权限选择和使用。 + - 审批通过时间记录最终审批通过时间。 + +- 异常与边界: + - 非当前审批节点处理人不允许审批通过。 + - 审批过程中项目数据被删除或作废时,不允许继续审批。 + - 审批通过状态更新失败时需提示原因,并保持审批前状态。 + +- 反例: + - 不允许未走完审批流程的项目变为正式项目。 + - 不允许临时项目执行结算流程。 + - 不允许非审批人代替当前处理人审批通过。 + +--- + +### REQ-PROJ-016 审批驳回与撤回 + +- 功能点: + - 当前审批节点处理人可对审批中单据执行审批驳回。 + - 驳回后审批状态更新为已驳回,并将驳回意见反馈给立项发起人。 + - 申请人可对审批中单据执行撤回。 + - 撤回后审批状态更新为已撤回,并清空流程待办节点。 + - 已驳回或已撤回的单据允许编辑后重新提交审批。 + +- 异常与边界: + - 非申请人不允许撤回审批单据。 + - 非当前审批节点处理人不允许驳回。 + - 撤回或驳回失败时保持原审批状态,并提示失败原因。 + - 重新提交审批时需按最新内容重新校验必填和附件。 + +- 反例: + - 不允许审批通过后的立项单据继续撤回。 + - 不允许驳回时丢失驳回意见。 + - 不允许撤回后审批待办仍停留在审批人列表。 + +--- + +### REQ-PROJ-017 重大项目补录 + +- 功能点: + - 列表顶部支持“重大项目补录”入口。 + - 补录用于录入历史或线下已完成审批的重大项目。 + - 补录重大项目无需走系统审批流程。 + - 只要完善全部项目信息并满足附件材料要求,补录提交后立即生效。 + - 补录生效后的项目审批状态展示为审批通过或补录生效口径,生效类型为正式。 + - 补录生效后的项目可执行合同、运单、结算等正式项目流程。 + +- 异常与边界: + - 补录时若必填字段或重大项目附件材料缺失,应阻止提交。 + - 补录项目名称重复时阻止提交并提示。 + - 无重大项目补录权限时不展示入口。 + +- 反例: + - 不允许补录重大项目资料不完整却直接生效。 + - 不允许普通项目从重大项目补录入口提交。 + - 不允许无权限用户补录重大项目。 + +--- + +### REQ-PROJ-018 客户额度校验 + +- 功能点: + - 客户存在多个项目时,系统需校验当前客户关联项目是否超过客户信用额度或授信额度。 + - 校验范围包含当前客户已生效项目、临时生效草稿项目以及本次新建或变更项目的项目资金使用额度。 + - 若超过客户额度,系统进行提示,提醒用户确认风险。 + - 客户额度提示不替代审批校验,提交审批时仍需按流程判断是否允许继续。 + +- 异常与边界: + - 客户额度为空或无法获取时,应提示额度信息缺失,并允许按权限继续保存草稿。 + - 多客户项目应分别校验每个客户额度。 + - 客户额度校验服务失败时,应提示用户稍后重试或联系管理员。 + +- 反例: + - 不允许只校验当前项目金额而忽略同一客户其他项目占用额度。 + - 不允许多客户项目只校验第一家客户。 + - 不允许超过额度时无任何提示。 + +--- + +### REQ-PROJ-019 编辑立项 + +- 功能点: + - 草稿、已撤回、已驳回状态的立项单据支持编辑。 + - 编辑页面回显项目完整信息,项目编号只读不可编辑。 + - 编辑后可保存草稿或重新提交审批。 + - 已提交审批的单据在审批中状态不允许直接编辑。 + +- 异常与边界: + - 编辑前需校验当前单据状态仍允许编辑。 + - 编辑的数据已不存在时提示数据不存在,并刷新列表。 + - 修改项目类型后,应重新匹配附件材料要求和审批流程。 + - 保存或提交失败时保留用户修改内容。 + +- 反例: + - 不允许审批中单据绕过撤回直接编辑。 + - 不允许编辑时修改项目编号。 + - 不允许编辑后产生重复项目名称。 + +--- + +### REQ-PROJ-020 查看立项 + +- 功能点: + - 支持通过列表行操作查看项目详情。 + - 查看页面展示项目基本信息、项目主要内容、客户信息、承运商信息、项目情况说明、项目附件、审批信息和变更记录。 + - 查看状态下所有字段只读。 + - 支持查看附件和审批流转信息。 + +- 异常与边界: + - 数据已删除、作废或无权限查看时提示无法查看。 + - 附件加载失败时不影响其他项目字段展示。 + - 历史变更记录加载失败时提示失败原因,不影响当前项目信息展示。 + +- 反例: + - 不允许在查看状态下保存修改。 + - 不允许查看时自动切换到编辑状态。 + - 不允许隐藏已生效变更记录。 + +--- + +### REQ-PROJ-021 删除草稿立项 + +- 功能点: + - 草稿、已撤回、已驳回且未被业务引用的立项单据支持删除。 + - 点击删除后弹出二次确认弹窗。 + - 删除前需校验是否存在关联合同、运单、结算单据和历史变更记录。 + - 删除成功后刷新列表。 + +- 异常与边界: + - 存在业务关联单据时不允许删除,并提示无法删除原因。 + - 存在历史变更记录时不允许删除,并提示无法删除。 + - 删除时状态已变化为审批中或审批通过时,应阻止删除并刷新列表。 + +- 反例: + - 不允许删除审批中或审批通过项目。 + - 不允许存在合同、运单、结算单据时删除项目。 + - 不允许跳过二次确认直接删除。 + +--- + +### REQ-PROJ-022 作废立项 + +- 功能点: + - 审批通过的正式项目支持按权限执行作废。 + - 作废前需弹出二次确认提示。 + - 作废后禁止基于该项目新建合同、运单、结算单据。 + - 作废不影响历史已生成业务单据。 + - 作废操作需永久保留审计日志。 + +- 异常与边界: + - 非审批通过项目不允许作废。 + - 作废失败时保持原项目状态并提示失败原因。 + - 作废后如已有页面缓存该项目,应在选择时提示项目已作废不可使用。 + +- 反例: + - 不允许作废后继续新建合同、运单或结算单。 + - 不允许作废操作影响历史业务数据。 + - 不允许作废记录不留审计日志。 + +--- + +### REQ-PROJ-023 发起变更立项 + +- 功能点: + - 审批通过的正式项目支持发起变更立项。 + - 点击变更后打开变更项目页面,自动带入原立项全部历史填写数据。 + - 变更页面新增变更内容、变更原因和变更记录相关区域。 + - 原立项数据作为变更基础数据展示,允许按变更规则修改。 + - 变更类型包含项目变更、项目调整备案,并根据变更类型走不同审批流程。 + +- 异常与边界: + - 非正式生效项目不允许发起变更。 + - 存在未完成变更审批时,不允许重复发起新的变更。 + - 原项目已作废或无权限变更时不允许发起变更。 + +- 反例: + - 不允许草稿或临时项目发起变更立项。 + - 不允许变更页面为空白而不带入原项目数据。 + - 不允许同一项目同时存在多个审批中的变更单。 + +--- + +### REQ-PROJ-024 变更项目信息 + +- 功能点: + - 变更项目页面包含项目基本信息、项目主要内容、客户信息、承运商信息、项目情况说明、项目材料、变更内容、变更原因等区域。 + - 变更类型为必填字段,使用下拉单选控件。 + - 项目编号只读不可编辑。 + - 项目类型、项目名称、项目简称、业务部门、承办部门、客户信息、承运商信息、资金和回款相关字段按变更规则回显并允许修改。 + - 变更页面支持保存、提交、关闭。 + +- 异常与边界: + - 变更类型为空时阻止保存或提交并提示。 + - 变更时如修改项目类型或金额,应重新匹配审批流程和附件材料要求。 + - 变更保存失败时保留用户修改内容。 + - 关闭前存在未保存内容时,应提示确认是否放弃填写。 + +- 反例: + - 不允许变更时修改项目编号。 + - 不允许变更类型为空后提交审批。 + - 不允许变更保存失败后清空用户已填写内容。 + +--- + +### REQ-PROJ-025 变更内容与原因 + +- 功能点: + - 变更内容为必填大文本字段,用于填写本次调整前后的全部修改内容,最多2000字。 + - 变更原因为必填大文本字段,用于填写本次变更原因,最多2000字。 + - 文本框实时统计输入字数,超过上限时禁止继续输入或提交。 + - 草稿和驳回状态下可编辑变更内容与变更原因。 + +- 异常与边界: + - 提交审批时变更内容或变更原因为空,应阻止提交并提示。 + - 文本超过2000字时阻止提交并提示。 + - 查看历史变更记录时,变更内容和变更原因只读展示。 + +- 反例: + - 不允许变更内容为空后发起变更审批。 + - 不允许超过2000字的变更说明提交。 + - 不允许查看历史记录时修改变更原因。 + +--- + +### REQ-PROJ-026 变更审批与生效 + +- 功能点: + - 变更单提交后,项目审批状态更新为变更审批中。 + - 变更审批通过后,变更内容正式覆盖原项目信息,并新增一条变更记录。 + - 变更审批驳回后,项目状态更新为变更驳回,允许编辑后重新提交。 + - 项目调整备案和项目变更按不同流程审批。 + - 变更不改变项目原有生效类型,正式项目变更后仍为正式。 + +- 异常与边界: + - 变更审批未通过前,不得覆盖原正式项目信息。 + - 审批过程中项目被作废时,不允许继续完成变更审批。 + - 变更审批失败时保持原项目数据不变,并提示失败原因。 + +- 反例: + - 不允许变更草稿内容直接影响正式项目。 + - 不允许审批未通过却生成正式变更记录。 + - 不允许变更后把正式项目退回临时生效。 + +--- + +### REQ-PROJ-027 变更记录 + +- 功能点: + - 项目详情和变更页面展示变更记录列表。 + - 变更记录展示序号、变更日期、变更类型、经办人、变更内容、变更原因、状态、操作等字段。 + - 草稿或驳回状态的变更记录支持编辑。 + - 审批中或已通过状态的变更记录支持查看流程或查看详情。 + - 变更记录需归集客户、承运商等全部变更内容,保留变更前后字段。 + +- 异常与边界: + - 变更记录加载失败时提示失败原因,不影响查看项目基础信息。 + - 查看历史变更记录时全字段只读。 + - 变更记录与项目不匹配时不展示,并提示数据异常。 + +- 反例: + - 不允许删除已审批通过的变更记录。 + - 不允许变更记录只保存部分字段导致无法追溯。 + - 不允许跨项目展示变更记录。 + +--- + +### REQ-PROJ-028 选择关联项目 + +- 功能点: + - 支持打开“选择关联项目”弹窗。 + - 弹窗支持按项目编号、项目名称进行模糊查询。 + - 弹窗列表展示选择、序号、项目编号、项目名称、关联项目、所属部门等字段。 + - 支持分页展示关联项目候选数据。 + - 用户勾选项目后点击确定,关联项目回填到当前立项或变更单。 + - 点击取消或关闭弹窗时不回填数据。 + +- 异常与边界: + - 查询无数据时展示空状态。 + - 已作废项目不可作为有效关联项目选择。 + - 无权限查看的项目不出现在候选列表中。 + - 重复选择同一项目时应自动去重。 + +- 反例: + - 不允许选择已作废项目作为关联项目。 + - 不允许取消弹窗后仍回填关联项目。 + - 不允许关联项目重复展示或重复保存。 + +--- + +### REQ-PROJ-029 导出立项列表 + +- 功能点: + - 列表顶部支持导出立项列表。 + - 点击导出后,导出当前查询条件下的项目基础信息、客户、承运商、变更记录和附件清单等数据到 Excel 文件。 + - 导出文件字段与列表和详情展示字段保持一致。 + - 数据量较大时页面展示加载或导出中提示。 + +- 异常与边界: + - 当前查询条件下无数据时允许导出空文件或提示无可导出数据。 + - 导出失败时提示失败原因,不改变当前列表状态。 + - 无导出权限时不展示导出按钮。 + +- 反例: + - 不允许无权限用户导出项目数据。 + - 不允许导出时忽略当前查询条件。 + - 不允许导出文件展示用户 ID 代替姓名。 + +--- + +### REQ-PROJ-030 权限与审计 + +- 功能点: + - 根据用户权限控制查询、新建、重大项目补录、编辑、提交、查看、删除、变更、作废、导出、审批等操作入口。 + - 列表、详情、导出、审批流中用户可见字段优先展示姓名,不直接展示用户 ID。 + - 新增、编辑、提交、审批、撤回、驳回、删除、作废、变更、导出等关键操作需记录操作日志。 + - 审计信息应包含操作人、操作时间、操作类型和关键业务对象。 + +- 异常与边界: + - 无按钮权限时不展示对应按钮,通过 URL 或接口绕过时也应拒绝。 + - 操作日志记录失败时不得影响用户已成功的业务操作,但需保留可排查信息。 + - 数据权限限制下,用户只能查看和操作授权范围内项目。 + +- 反例: + - 不允许无权限用户执行项目审批或作废。 + - 不允许列表展示创建人、更新人等用户 ID。 + - 不允许关键状态变更没有审计记录。 + +--- + +## 通用规则 + +- 项目管理用于维护企业运输业务项目立项、审批、生效、变更和作废全过程,归属于“项目管理”主菜单。 +- 项目类型包含普通项目、重大项目;重大项目金额超过8000万时需走物流领导审批流程。 +- 立项申请单号和项目编号由系统自动生成,全局唯一,只读不可编辑。 +- 项目名称必填且不可重复,项目简称必填。 +- 保存草稿后项目审批状态为草稿,生效类型为临时;临时项目可被合同选择,但不可执行结算流程。 +- 完善全部项目信息并审批通过后,项目生效类型转为正式;正式项目可执行结算流程。 +- 重大项目补录无需走系统审批,完善全部信息并提交后即正式生效。 +- 客户名称和下游承运商均需从客商档案选择,至少各选择1条。 +- 客户存在多个项目时,应校验客户额度占用,超过额度需提示风险。 +- 普通项目或中小项目、重大项目按各自附件材料清单校验提交审批所需附件;保存草稿时附件可不上传。 +- 金额字段需大于等于0并保留2位小数,天数字段需为0到999的整数。 +- 项目应收账款额度不得大于项目资金使用额度。 +- 变更项目需按变更类型走对应审批流程,审批通过后才覆盖原正式项目信息并生成变更记录。 +- 删除项目前需校验无关联合同、运单、结算单据和历史变更记录。 +- 作废项目禁止新建合同、运单、结算单据,历史已产生业务数据不受影响。 +- 列表、详情、导出、审批等用户可见场景优先展示姓名字段,不直接展示用户 ID。 +- 新增、编辑、提交、审批、撤回、驳回、删除、作废、变更、导出后均需刷新相关列表或详情状态。