refactor(business): 优化 process-config 弹窗及多页面基本信息布局
- process-config 弹窗改为手写 el-dialog,统一与 credit-score-quantification 风格 - 弹窗内三张 section-card 堆叠,卡间间距12px,底部按钮新增保存草稿/保存并启用 - 删除原 Avue 内置 dialog 及相关表单插槽,移除无用样式,调整弹窗最大高度 - 多页面「基本信息」类分区由3列(span 8)改为4列(span 6),包含结算、合同、船舶等多处页面 - contract-manage-change.vue 手写表单列宽全部由8改6,保留备注与分区标题整行显示 - business-crud-page.vue contract配置中基本信息分区改为4列显示,调整表单 label 宽度为150px - temporary-credit-limit 详情弹窗加 align-center 实现上下居中,新增 computed 绑定配置开关 - temporary-credit-limit 弹窗宽度修改为96%,与其他业务页面保持一致 - ship.vue 标签宽度调整为最多6汉字宽,允许超长标签换行,改善显示效果 - common-route.vue 调整部分输入框宽度适配布局 - element-ui.scss 调整 process-config 相关弹窗样式,取消原 Avue 透明化样式,全局灰底内卡片间距统一 - 精简 process-config 相关 option 配置,去除 dialog 相关冗余属性 - 过程配置弹窗新增打开、保存、关闭等手写逻辑,支持查看、编辑不同状态,保持业务逻辑完整 - 删除 process-config 内部 avue-crud 相关操作,整体改用标准 el-dialog 和 el-form 实现 - 其他局部样式细节调整,保证表单布局和交互统一规范
This commit is contained in:
@@ -1,5 +1,21 @@
|
||||
# 2026-08-21
|
||||
|
||||
## temporary-credit-limit 详情弹窗上下居中(align-center)
|
||||
- 需求:`/business/temporary-credit-limit` 详情弹窗(detailBox,走 business-crud-page 自定义详情)上下居中。
|
||||
- 机制:Element Plus el-dialog 的 `align-center` prop —— use-dialog 源码确认:align-center 时 `.el-overlay-dialog` 设 `display:flex`,`.el-dialog.is-align-center { margin:auto }`,实现垂直+水平居中;此时 top prop 设置的 `--el-dialog-margin-top` 被更高特异性的 `margin:auto` 覆盖,不生效。
|
||||
- 改动(3 处,开关式不影响其他页):
|
||||
1. `src/views/business/components/business-crud-page.vue` 详情 el-dialog(2504 行)加 `:align-center="detailAlignCenter"`。
|
||||
2. 同文件新增 computed `detailAlignCenter()`:`this.config.detailAlignCenter === true`(默认 false,contract/waybill 等共用详情弹窗不受影响)。
|
||||
3. `src/option/business/temporary-credit-limit.js` config 加 `detailAlignCenter: true`。
|
||||
- 安全性:全局 `.el-dialog__body { max-height: calc(100vh - 200px); overflow-y:auto }`(element-ui.scss 182 行)保证内容超高时在 body 内滚动,dialog 总高 < 视口,flex 居中不会顶部裁切。
|
||||
- 注意:element-plus 实际版本是 2.14.2(package.json 声明 ^2.10.1,锁到 2.14.2)。el-dialog 的 class 经 $attrs 透传最终落在 `div.el-dialog` 根元素(ElDialogContent 未设 inheritAttrs:false);因此 scoped 里 `&__detail-dialog.is-transport-plan-detail { :deep(.el-dialog){...} }` 的 max-width/margin 规则实际选不到自身(仅 header/body 后代规则生效)——历史遗留,未处理。
|
||||
- 验证:`node --check` 通过;Vite 2889 编译两个改动文件均 HTTP 200。
|
||||
|
||||
## temporary-credit-limit 弹窗宽度 1400px → 96%
|
||||
- 需求:`/business/temporary-credit-limit` 新增/编辑弹窗加宽到 96%。
|
||||
- 改动(单文件 `src/option/business/temporary-credit-limit.js`):`dialogWidth: 1400` → `dialogWidth: '96%'`。
|
||||
- 先例:waybill-manage / transport-plan 均为 `dialogWidth: '96%'`,shipping-template 为 `'92%'`。business-crud-page 对 dialogWidth 无特殊处理(仅独立表单页强制 100%),百分比直接透传 avue-crud;element-ui.scss 的 `.temporary-credit-limit-dialog` 只覆 label 宽度、不覆盖 el-dialog 宽度,无冲突。
|
||||
|
||||
## process-config 弹窗卡片间隔(对齐 project-apply 风格)
|
||||
- 需求:process-config 新增/编辑弹窗内三张 `<section-card>`(基本信息 / 现行过程节点 / 节点设置)要像 project-apply 表单页一样独立成卡、卡间露出灰底(12px)。
|
||||
- 根因:全站规则 `.el-dialog .avue-form { background:#fff; padding:8px 16px 4px }`(element-ui.scss ~246 行)把 Avue 弹窗表单整体包成一张白卡,section-card 白卡叠在其上看不出间隔。
|
||||
@@ -113,3 +129,33 @@
|
||||
1. 新建 `src/views/settlement/components/transport-reconciliation-table-panel.vue`:工具栏(新增/导出+刷新)+`el-table`+分页抽成子组件;props 同 formal 面板,emits `create/export/refresh/page-change/update:selection/action`;列渲染差异:`.link` 列点击 emit view、`reconciliationStatusName` 走 `row.reconciliationStatus==='completed'?'success':'warning'` 的 el-tag;行操作 `rowActions(row)` 为 查看(常显)+编辑/删除/确认(均 `hasPermission && isEditable(row)`,isEditable=`reconciliationStatus==='unfinished'`),确认非 danger。
|
||||
2. `src/views/settlement/transport-reconciliation.vue`:删除原 toolbar+table+pagination 块与对应 scoped 样式(`__toolbar/__toolbar-right/__links/__pagination`),在两个 `el-tab-pane` 内各放一个面板;保留 `.reconciliation-page__settlement-tabs`(含 `:deep(.el-tabs__header){margin:0}`);新增 `handlePageChange`、`handleAction({type,row})`(view→openView/edit→openEdit/delete→handleDelete/complete→handleComplete);删除 `handleSizeChange`。导出按钮无权限守卫、仍 emit `export` 由父 `handleExport`(用 `this.settlementType`)处理。
|
||||
- 验证:Vite build 通过(EXIT=0)。待用户在 2889 刷新核对应付/应收 tab 各自带完整表格与工具栏、切换触发 reload。
|
||||
|
||||
## process-config 弹窗重写为手写 el-dialog(对齐 credit-score-quantification 风格)
|
||||
- 原因:用户参考 `/vehicle/credit-score-quantification` 的弹窗(手写 `el-dialog` + 多个 `<section-card>` 堆叠、卡间 12px、底部 #footer 按钮),要求 process-config 弹窗同样"白底卡片包住蓝标内容块、卡间距 12px、风格统一"。原实现用的是 Avue 内置 dialog + formslot,与参考页机制不一致(即使视觉接近)。
|
||||
- 改动(3 文件):
|
||||
1. `src/views/business/process-config.vue`:删除 Avue 内置 dialog 相关(`before-open`、`#basicInfo-form`/`#nodeConfigJson-form`/`#menu-form-before` 插槽、`rowSave/rowUpdate/submitRow/stopSubmitLoading/handleProcessConfigSave`、数据项 `submitStatus`);新增手写 `<el-dialog class="process-config-dialog" append-to-body width="96%" top="4vh" :close-on-click-modal="false">`,内部 `<div class="process-config-form">` 堆三张 `<section-card>`:基本信息 / 现行过程节点(timeline)/ 节点设置(node 表);`#footer` 放 取消 / 保存草稿(plain) / 保存并启用(primary),`submitting` 控制 loading。新增 `openConfig(row, readonly)`、`submitConfig(mode)`、`handleDialogClosed`,保留全部节点配置逻辑(NODE_TEMPLATES/cloneNode/parseNodeConfig/syncNodeFields/timelineDescriptions/validateRow/checkEnabledProjectBeforeSubmit/confirmDuplicateVoucher 等)。菜单 查看→`openConfig(row,true)`、编辑→`openConfig(row)`、新建→`openConfig()`。
|
||||
2. `src/option/business/process-config.js`:option 删除仅作表单容器的 `basicInfo`/`nodeConfigJson` 两列与 `saveBtn/updateBtn/dialogTop/dialogWidth/dialogCustomClass` 等 dialog 配置。
|
||||
3. `src/styles/element-ui.scss`:删除原先 `.process-config-dialog .avue-form / .avue-form__group / .avue-dialog__footer` 三处透明化/归零规则(已无用),改为 `.process-config-dialog .el-dialog__body { max-height: calc(100vh - 130px) }`。
|
||||
- 关键点:弹窗内容走 `append-to-body` 会被 teleport 出 `.process-config-page`,故所有弹窗内样式(timeline/node-table/require-*/finish-days)改用顶层 scoped 类 `.process-config-form__*`(不再嵌套在 `.process-config-page` 下),否则 scoped 选择器因缺祖先类而失效。12px 卡距由全局 `.section-card{margin-bottom:12px}` + 全局灰底 `.el-dialog__body{background:#f2f2f2;padding:12px}` 保证,与参考页一致。
|
||||
- 验证:Vite build 通过(EXIT=0),无编译错误;2889 HMR 生效。待用户刷新核对弹窗卡片风格。
|
||||
|
||||
## 多页面「基本信息」类分区统一改为 4 列(span 8→6)
|
||||
- 用户逐一要求把各结算/合同页的「基本信息」分区从 3 列改为 4 列。列数由 el-col `:span` 控制(24/8=3 → 24/6=4)。
|
||||
- 手写 el-col 循环页面(直接改 span):
|
||||
- `src/views/settlement/components/formal-settlement-editor.vue`:`:span="8"`→`:span="6"`(结算基本信息)。
|
||||
- `src/views/settlement/components/transport-reconciliation-editor.vue`:`:span="8"`→`:span="6"`(导入外部账单核对)。
|
||||
- `src/views/settlement/components/settlement-adjustment-editor.vue`:`:span="8"`→`:span="6"`(基本信息)。
|
||||
- `src/views/settlement/components/pre-settlement-editor.vue`:动态 `:span="field.span || 8"`→`|| 6`(仅备注显式 span:24 仍整行)。
|
||||
- `src/views/business/contract-manage-change.vue`:`基本信息` 区 `:span="8"`→`:span="6"`(变更类型/备注 `:span="24"` 保持整行)。
|
||||
- Avue 分组表单页面(合同新增/编辑 form 页):非手写循环,`option.span=8` 控制默认列数。
|
||||
- 改动 `src/views/business/components/business-crud-page.vue` 的 `buildFormGroupOption`:当 `this.isContractConfig` 时,对首组(基本信息,=groups[0] 顶层 column)每个非分区标题、非 `span===24` 的列设 `col.span = 6`;备注(span:24)与分区标题列保持原样。其余分组仍 3 列。
|
||||
- 验证:2889 HMR 生效。注意合同 form 页走 Avue group,不能用简单 span 替换,须改 buildFormGroupOption。
|
||||
|
||||
## 续:更多页面「基本信息」类分区改 4 列(span 8→6)
|
||||
- `src/option/business/temporary-credit-limit.js`:Avue 配置页,扁平 column 列表,8 个表单字段 `span:8`→`span:6`(备注/附件 span:24 保持整行)。注意 createCrudOption 不设默认 span,可见字段都有显式 span。
|
||||
- `src/views/transportCapacity/ship.vue`:「基础船舶信息」10 个 `:span="8"`→`:span="6"`;该页 12 空格缩进=基础船舶信息区、14 空格缩进=船舶证书信息区,**勿用全局 replace_all**(12 空格串是 14 空格的子串会误伤证书区),必须按行号区间 sed(146,253)或带 label 上下文逐个替换。
|
||||
- `src/views/business/project-apply.vue`:`.project-apply-form__grid` `repeat(3,...)`→`repeat(4,...)`;label 规则(作用域 `__grid` 内)`width:100px !important; min-width:0 !important; white-space:normal`——6 汉字宽超出换行,`!important` 压过 label-width="auto" 的行内 width 与全局 min-width:160px。
|
||||
|
||||
## ship 页 label 规则:最多 6 汉字宽、超出换行
|
||||
- `src/views/transportCapacity/ship.vue`:el-form `label-width`(原 HEAD 为 auto,工作区历史为 150)→ `100`(6 汉字≈84px+冒号≈98px,100px 恰容 6 字);`.ship-form` 内新增 `:deep(.el-form-item__label) { white-space: normal; line-height: 20px }` 允许换行。适用整个 ship 表单(含证书区)。
|
||||
- 注意:改该文件前先确认 git 暂存区状态,`git checkout -- <file>` 恢复的是 index 版本;本文件 index=HEAD=auto,工作区曾为 150(历史未提交改动),已被本次需求覆盖。
|
||||
|
||||
@@ -21,13 +21,6 @@ export const config = {
|
||||
|
||||
export const option = {
|
||||
...createCrudOption([
|
||||
{
|
||||
label: '',
|
||||
prop: 'basicInfo',
|
||||
formslot: true,
|
||||
span: 24,
|
||||
hide: true,
|
||||
},
|
||||
{
|
||||
label: '配置名称',
|
||||
prop: 'configName',
|
||||
@@ -167,22 +160,10 @@ export const option = {
|
||||
dicData: [],
|
||||
filterable: true,
|
||||
},
|
||||
{
|
||||
label: '',
|
||||
prop: 'nodeConfigJson',
|
||||
formslot: true,
|
||||
span: 24,
|
||||
hide: true,
|
||||
},
|
||||
]),
|
||||
saveBtn: false,
|
||||
updateBtn: false,
|
||||
addBtn: false,
|
||||
viewBtn: false,
|
||||
editBtn: false,
|
||||
delBtn: false,
|
||||
dialogTop: '4vh',
|
||||
dialogWidth: '96%',
|
||||
dialogCustomClass: 'process-config-dialog',
|
||||
menuWidth: 220,
|
||||
};
|
||||
|
||||
@@ -47,6 +47,7 @@ export const config = {
|
||||
ignoreReadonlyDeleteStatus: ['draft', '草稿'],
|
||||
detailButton: true,
|
||||
detailButtonIgnoreDraftStatus: true,
|
||||
detailAlignCenter: true,
|
||||
detailSections: [
|
||||
{
|
||||
title: '申请信息',
|
||||
@@ -142,7 +143,7 @@ export const option = {
|
||||
value: 'projectName',
|
||||
},
|
||||
filterable: true,
|
||||
span: 8,
|
||||
span: 6,
|
||||
minWidth: 180,
|
||||
rules: textRule('项目名称', 100, true),
|
||||
},
|
||||
@@ -157,7 +158,7 @@ export const option = {
|
||||
prop: 'projectCode',
|
||||
hide: true,
|
||||
disabled: true,
|
||||
span: 8,
|
||||
span: 6,
|
||||
minWidth: 150,
|
||||
rules: textRule('项目编号', 50),
|
||||
},
|
||||
@@ -166,7 +167,7 @@ export const option = {
|
||||
prop: 'undertakeDeptName',
|
||||
hide: true,
|
||||
disabled: true,
|
||||
span: 8,
|
||||
span: 6,
|
||||
minWidth: 150,
|
||||
rules: textRule('承办部门', 50, true),
|
||||
},
|
||||
@@ -175,7 +176,7 @@ export const option = {
|
||||
prop: 'projectFundLimit',
|
||||
hide: true,
|
||||
disabled: true,
|
||||
span: 8,
|
||||
span: 6,
|
||||
minWidth: 200,
|
||||
rules: [nonNegativeRule('项目资金使用额度')],
|
||||
},
|
||||
@@ -184,7 +185,7 @@ export const option = {
|
||||
prop: 'usedFundLimit',
|
||||
hide: true,
|
||||
disabled: true,
|
||||
span: 8,
|
||||
span: 6,
|
||||
minWidth: 220,
|
||||
value: 0,
|
||||
rules: [nonNegativeRule('已使用项目资金额度')],
|
||||
@@ -194,7 +195,7 @@ export const option = {
|
||||
prop: 'remainingFundLimit',
|
||||
hide: true,
|
||||
disabled: true,
|
||||
span: 8,
|
||||
span: 6,
|
||||
minWidth: 230,
|
||||
value: 0,
|
||||
rules: [nonNegativeRule('剩余项目资金使用额度')],
|
||||
@@ -203,7 +204,7 @@ export const option = {
|
||||
label: '申请临时额度(万元)',
|
||||
prop: 'applyLimit',
|
||||
formslot: true,
|
||||
span: 8,
|
||||
span: 6,
|
||||
minWidth: 180,
|
||||
rules: [
|
||||
{ required: true, message: '请输入申请临时额度', trigger: 'blur' },
|
||||
@@ -216,7 +217,7 @@ export const option = {
|
||||
type: 'date',
|
||||
format: 'YYYY-MM-DD',
|
||||
valueFormat: 'YYYY-MM-DD',
|
||||
span: 8,
|
||||
span: 6,
|
||||
minWidth: 140,
|
||||
rules: [{ required: true, message: '请选择申请有效期至', trigger: 'change' }],
|
||||
},
|
||||
@@ -303,7 +304,7 @@ export const option = {
|
||||
},
|
||||
...auditColumns.map(column => ({ ...column, hide: true })),
|
||||
]),
|
||||
dialogWidth: 1400,
|
||||
dialogWidth: '96%',
|
||||
menuFixed: 'right',
|
||||
menuWidth: 320,
|
||||
index: false,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
export const settlementAdjustmentFormFields = [
|
||||
{ label: '单据号', prop: 'adjustmentNo' },
|
||||
{ label: '* 关联结算单号', prop: 'formalSettlementId' },
|
||||
{ label: '关联结算单号', prop: 'formalSettlementId' },
|
||||
{ label: '客户/客商名称', prop: 'customerName' },
|
||||
{ label: '结算单类型', prop: 'settlementTypeName' },
|
||||
{ label: '关联合同名称', prop: 'contractName' },
|
||||
|
||||
@@ -607,26 +607,11 @@
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
// 过程配置新增/编辑弹窗:avue-form 整体白卡透明化,
|
||||
// 让 <section-card> 分组白卡(基本信息 / 现行过程节点 / 节点设置)独立成卡、卡间露出灰底,
|
||||
// 与 business/project-apply 表单页的分组卡片风格统一
|
||||
.process-config-dialog .avue-form {
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
// formslot 外层 el-form-item 默认 margin-bottom 与 section-card 自身 margin 叠加会拉大卡距,
|
||||
// 归零后卡间距统一为 section-card 自身的 12px(与 project-apply 一致)
|
||||
.process-config-dialog .avue-form__group > .el-col > .el-form-item {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
// 抵消全局 .avue-crud__dialog .avue-dialog__footer 的 -30px 上移
|
||||
// (avue-form 已透明化,footer 若上移会压住最后一张分组卡片)
|
||||
.process-config-dialog .avue-dialog__footer,
|
||||
.avue-crud__dialog .process-config-dialog .avue-dialog__footer {
|
||||
margin-top: 0 !important;
|
||||
// 过程配置新增/编辑/查看弹窗(手写 el-dialog,参照 vehicle/credit-score-quantification):
|
||||
// 灰底弹窗体(全站 .el-dialog__body 已统一)内堆叠 <section-card> 分组白卡,
|
||||
// 卡间 12px 间距由 section-card 自身 margin-bottom 保证,与项目其他弹窗风格统一
|
||||
.process-config-dialog .el-dialog__body {
|
||||
max-height: calc(100vh - 170px);
|
||||
}
|
||||
|
||||
// 统一表格线条颜色
|
||||
|
||||
@@ -1012,7 +1012,7 @@ export default {
|
||||
}
|
||||
|
||||
.el-input:first-child {
|
||||
flex: 0 0 34%;
|
||||
flex: 0 0 42.5%;
|
||||
}
|
||||
|
||||
.el-button {
|
||||
|
||||
@@ -694,7 +694,7 @@
|
||||
<el-form
|
||||
:model="form"
|
||||
label-position="right"
|
||||
label-width="auto"
|
||||
label-width="150"
|
||||
class="business-crud-page__task-form business-crud-page__task-form--full"
|
||||
>
|
||||
<div class="business-crud-page__task-row">
|
||||
@@ -2506,6 +2506,7 @@
|
||||
:title="isTransportPlanDetailLayout ? '' : `${config.title}详情`"
|
||||
append-to-body
|
||||
top="10px"
|
||||
:align-center="detailAlignCenter"
|
||||
:width="isTransportPlanDetailLayout ? 'calc(100% - 16px)' : '96%'"
|
||||
show-close
|
||||
:class="[
|
||||
@@ -6239,6 +6240,9 @@ export default {
|
||||
detailSections() {
|
||||
return this.config.detailSections || [];
|
||||
},
|
||||
detailAlignCenter() {
|
||||
return this.config.detailAlignCenter === true;
|
||||
},
|
||||
contractDetailSettlementRows() {
|
||||
if (!this.isContractConfig) return [];
|
||||
return [
|
||||
@@ -6976,6 +6980,14 @@ export default {
|
||||
});
|
||||
if (current.length) groups.push(current);
|
||||
if (groups.length <= 1) return option;
|
||||
// 合同「基本信息」分区改为 4 列显示(分区标题列与已设整行的字段保持原样)
|
||||
if (this.isContractConfig && groups[0].length) {
|
||||
groups[0].forEach(col => {
|
||||
if (sectionTitleProps.includes(col.prop)) return;
|
||||
if (col.span === 24) return;
|
||||
col.span = 6;
|
||||
});
|
||||
}
|
||||
return {
|
||||
...option,
|
||||
column: groups[0],
|
||||
|
||||
@@ -5,20 +5,20 @@
|
||||
<div class="dialog-section-title">基本信息</div>
|
||||
<el-row :gutter="28">
|
||||
<el-col :span="24"><el-form-item label="变更类型"><el-radio-group v-model="form.changeType"><el-radio label="合同信息变更" /><el-radio label="终止合同" /></el-radio-group></el-form-item></el-col>
|
||||
<el-col :span="8"><el-form-item label="合同编号"><el-input v-model="form.contractNo" disabled /></el-form-item></el-col>
|
||||
<el-col :span="8"><el-form-item label="合同名称" prop="contractName"><el-input v-model="form.contractName" /></el-form-item></el-col>
|
||||
<el-col :span="8"><el-form-item label="合同类型"><el-select v-model="form.contractCategory" disabled><el-option label="客户合同" value="客户合同" /><el-option label="承运商合同" value="承运商合同" /></el-select></el-form-item></el-col>
|
||||
<el-col :span="8"><el-form-item label="甲方"><el-input v-model="form.partyA" disabled /></el-form-item></el-col>
|
||||
<el-col :span="8"><el-form-item label="乙方"><el-input v-model="form.partyB" disabled /></el-form-item></el-col>
|
||||
<el-col :span="8"><el-form-item label="所属项目"><el-input v-model="form.projectName" disabled /></el-form-item></el-col>
|
||||
<el-col :span="8"><el-form-item label="合同期限"><el-date-picker v-model="period" type="daterange" value-format="YYYY-MM-DD" range-separator="至" /></el-form-item></el-col>
|
||||
<el-col :span="8"><el-form-item label="所属组织"><el-input v-model="form.organizationName" disabled /></el-form-item></el-col>
|
||||
<el-col :span="8"><el-form-item label="签订日期"><el-date-picker v-model="form.signDate" type="date" value-format="YYYY-MM-DD" disabled /></el-form-item></el-col>
|
||||
<el-col :span="8"><el-form-item label="合同格式"><el-select v-model="form.contractFormat"><el-option label="电子合同" value="电子合同" /><el-option label="纸质合同" value="纸质合同" /></el-select></el-form-item></el-col>
|
||||
<el-col :span="8"><el-form-item label="结算方式"><el-input v-model="form.settlementMode" /></el-form-item></el-col>
|
||||
<el-col :span="8"><el-form-item label="是否需要加盖法人章"><el-select v-model="form.legalSealFlag"><el-option label="是" :value="1" /><el-option label="否" :value="0" /></el-select></el-form-item></el-col>
|
||||
<el-col :span="8"><el-form-item label="一式"><div class="inline-field"><el-input-number v-model="form.copyCount" :min="1" controls-position="right" /><span>份</span></div></el-form-item></el-col>
|
||||
<el-col :span="8"><el-form-item label="回款账期"><el-input-number v-model="form.paymentDays" :min="0" controls-position="right" /><span class="unit">天</span></el-form-item></el-col>
|
||||
<el-col :span="6"><el-form-item label="合同编号"><el-input v-model="form.contractNo" disabled /></el-form-item></el-col>
|
||||
<el-col :span="6"><el-form-item label="合同名称" prop="contractName"><el-input v-model="form.contractName" /></el-form-item></el-col>
|
||||
<el-col :span="6"><el-form-item label="合同类型"><el-select v-model="form.contractCategory" disabled><el-option label="客户合同" value="客户合同" /><el-option label="承运商合同" value="承运商合同" /></el-select></el-form-item></el-col>
|
||||
<el-col :span="6"><el-form-item label="甲方"><el-input v-model="form.partyA" disabled /></el-form-item></el-col>
|
||||
<el-col :span="6"><el-form-item label="乙方"><el-input v-model="form.partyB" disabled /></el-form-item></el-col>
|
||||
<el-col :span="6"><el-form-item label="所属项目"><el-input v-model="form.projectName" disabled /></el-form-item></el-col>
|
||||
<el-col :span="6"><el-form-item label="合同期限"><el-date-picker v-model="period" type="daterange" value-format="YYYY-MM-DD" range-separator="至" /></el-form-item></el-col>
|
||||
<el-col :span="6"><el-form-item label="所属组织"><el-input v-model="form.organizationName" disabled /></el-form-item></el-col>
|
||||
<el-col :span="6"><el-form-item label="签订日期"><el-date-picker v-model="form.signDate" type="date" value-format="YYYY-MM-DD" disabled /></el-form-item></el-col>
|
||||
<el-col :span="6"><el-form-item label="合同格式"><el-select v-model="form.contractFormat"><el-option label="电子合同" value="电子合同" /><el-option label="纸质合同" value="纸质合同" /></el-select></el-form-item></el-col>
|
||||
<el-col :span="6"><el-form-item label="结算方式"><el-input v-model="form.settlementMode" /></el-form-item></el-col>
|
||||
<el-col :span="6"><el-form-item label="是否需要加盖法人章"><el-select v-model="form.legalSealFlag"><el-option label="是" :value="1" /><el-option label="否" :value="0" /></el-select></el-form-item></el-col>
|
||||
<el-col :span="6"><el-form-item label="一式"><div class="inline-field"><el-input-number v-model="form.copyCount" :min="1" controls-position="right" /><span>份</span></div></el-form-item></el-col>
|
||||
<el-col :span="6"><el-form-item label="回款账期"><el-input-number v-model="form.paymentDays" :min="0" controls-position="right" /><span class="unit">天</span></el-form-item></el-col>
|
||||
<el-col :span="24"><el-form-item label="备注"><el-input v-model="form.remark" type="textarea" maxlength="2000" show-word-limit /></el-form-item></el-col>
|
||||
</el-row>
|
||||
</section>
|
||||
|
||||
@@ -31,4 +31,7 @@ export default {
|
||||
white-space: normal;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.el-col {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -8,9 +8,6 @@
|
||||
v-model="form"
|
||||
ref="crud"
|
||||
:permission="permissionList"
|
||||
:before-open="beforeOpen"
|
||||
@row-save="rowSave"
|
||||
@row-update="rowUpdate"
|
||||
@row-del="rowDel"
|
||||
@search-change="searchChange"
|
||||
@search-reset="searchReset"
|
||||
@@ -25,7 +22,7 @@
|
||||
type="primary"
|
||||
icon="el-icon-plus"
|
||||
v-if="hasPermission('process_config_add')"
|
||||
@click="$refs.crud.rowAdd()"
|
||||
@click="openConfig()"
|
||||
>新建过程配置
|
||||
</el-button>
|
||||
<el-button
|
||||
@@ -46,27 +43,6 @@
|
||||
</el-button>
|
||||
</template>
|
||||
|
||||
<template #menu-form-before="{ disabled }">
|
||||
<template v-if="!dialogReadonly">
|
||||
<el-button
|
||||
plain
|
||||
:loading="disabled"
|
||||
:disabled="disabled"
|
||||
@click="handleProcessConfigSave('draft')"
|
||||
>
|
||||
保存草稿
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
:loading="disabled"
|
||||
:disabled="disabled"
|
||||
@click="handleProcessConfigSave('enabled')"
|
||||
>
|
||||
保存并启用
|
||||
</el-button>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<template #status="{ row }">
|
||||
<el-tag :type="statusTagType(row.status)">
|
||||
{{ row.statusName || displayStatus(row.status) }}
|
||||
@@ -79,300 +55,18 @@
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<template #basicInfo-form>
|
||||
<section-card title="基本信息">
|
||||
<el-form
|
||||
:model="form"
|
||||
label-position="right"
|
||||
label-width="calc(6em + 24px)"
|
||||
>
|
||||
<el-row :gutter="18">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="配置名称" required>
|
||||
<el-input
|
||||
v-model="form.configName"
|
||||
:disabled="dialogReadonly"
|
||||
maxlength="100"
|
||||
placeholder="请输入"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="项目" required>
|
||||
<el-select
|
||||
v-model="selectedProjectId"
|
||||
clearable
|
||||
filterable
|
||||
remote
|
||||
:remote-method="loadProjectOptions"
|
||||
:loading="projectLoading"
|
||||
:disabled="dialogReadonly"
|
||||
placeholder="请选择"
|
||||
style="width: 100%"
|
||||
@change="handleProjectChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in projectOptions"
|
||||
:key="item.id"
|
||||
:label="formatProjectLabel(item)"
|
||||
:value="String(item.id)"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="运输完成时限">
|
||||
<div class="process-config-page__finish-days">
|
||||
<span>默认</span>
|
||||
<el-input
|
||||
v-model="form.defaultFinishDays"
|
||||
:disabled="dialogReadonly"
|
||||
maxlength="3"
|
||||
placeholder="请输入"
|
||||
@input="handleFinishDaysInput"
|
||||
/>
|
||||
<span>天后完成运输</span>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="备注">
|
||||
<el-input
|
||||
v-model="form.remark"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
:disabled="dialogReadonly"
|
||||
maxlength="500"
|
||||
show-word-limit
|
||||
placeholder="请输入"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</section-card>
|
||||
</template>
|
||||
|
||||
<template #nodeConfigJson-form>
|
||||
<div class="process-config-page__custom-form">
|
||||
<section-card title="现行过程节点">
|
||||
<div class="process-config-page__timeline" v-if="enabledNodes.length">
|
||||
<div class="process-config-page__timeline-line"></div>
|
||||
<div
|
||||
v-for="node in enabledNodes"
|
||||
:key="node.key"
|
||||
class="process-config-page__timeline-item"
|
||||
>
|
||||
<span class="process-config-page__timeline-dot"></span>
|
||||
<div class="process-config-page__timeline-name">{{ node.name }}</div>
|
||||
<div class="process-config-page__timeline-desc">
|
||||
<div v-for="text in timelineDescriptions(node)" :key="text">{{ text }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-empty v-else description="请在节点设置中勾选过程节点" :image-size="72" />
|
||||
</section-card>
|
||||
|
||||
<section-card title="节点设置">
|
||||
<el-table
|
||||
class="process-config-page__node-table"
|
||||
border
|
||||
:data="nodeRows"
|
||||
:span-method="nodeSpanMethod"
|
||||
>
|
||||
<el-table-column label="节点设置" width="136">
|
||||
<template #default="{ row, $index }">
|
||||
<div class="process-config-page__node-cell">
|
||||
<el-checkbox
|
||||
v-model="row.enabled"
|
||||
:disabled="dialogReadonly"
|
||||
@change="syncNodeFields"
|
||||
/>
|
||||
<span class="process-config-page__node-name">{{ row.name }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作要求" min-width="660">
|
||||
<template #default="{ row }">
|
||||
<div class="process-config-page__requirements">
|
||||
<template v-if="row.key === 'accept'">
|
||||
<div class="process-config-page__require-line">
|
||||
<span class="process-config-page__require-label">是否确认</span>
|
||||
<el-radio-group
|
||||
v-model="row.confirmMode"
|
||||
:disabled="dialogReadonly || !row.enabled"
|
||||
@change="syncNodeFields"
|
||||
>
|
||||
<el-radio label="yes">是</el-radio>
|
||||
<el-radio label="no_confirm_accept">无需确认接单</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<div class="process-config-page__require-line">
|
||||
<span class="process-config-page__require-label">确认接单人</span>
|
||||
<el-checkbox
|
||||
v-model="row.confirmDriver"
|
||||
:disabled="dialogReadonly || !row.enabled || row.confirmMode !== 'yes'"
|
||||
@change="syncNodeFields"
|
||||
>司机</el-checkbox
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-else-if="row.key === 'return'">
|
||||
<div class="process-config-page__require-line">
|
||||
<span class="process-config-page__require-label">是否确认</span>
|
||||
<el-radio-group
|
||||
v-model="row.confirmMode"
|
||||
:disabled="dialogReadonly || !row.enabled"
|
||||
@change="handleReturnConfirmChange(row)"
|
||||
>
|
||||
<el-radio label="yes">是</el-radio>
|
||||
<el-radio label="no_confirm_complete">无需确认完成</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<div class="process-config-page__require-line">
|
||||
<span class="process-config-page__require-label">确认完成</span>
|
||||
<el-checkbox
|
||||
v-model="row.confirmInternal"
|
||||
:disabled="dialogReadonly || !row.enabled || row.confirmMode !== 'yes'"
|
||||
@change="syncNodeFields"
|
||||
>内部人员</el-checkbox
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<div class="process-config-page__require-grid">
|
||||
<div class="process-config-page__require-line">
|
||||
<span class="process-config-page__require-label">是否打卡</span>
|
||||
<el-radio-group
|
||||
v-model="row.punch"
|
||||
:disabled="dialogReadonly || !row.enabled"
|
||||
@change="syncNodeFields"
|
||||
>
|
||||
<el-radio :label="true">是</el-radio>
|
||||
<el-radio :label="false">否</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<div class="process-config-page__require-line" v-if="row.supportCargo">
|
||||
<span class="process-config-page__require-label">上传货量</span>
|
||||
<el-radio-group
|
||||
v-model="row.uploadCargo"
|
||||
:disabled="dialogReadonly || !row.enabled"
|
||||
@change="syncNodeFields"
|
||||
>
|
||||
<el-radio :label="true">是</el-radio>
|
||||
<el-radio :label="false">否</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<div
|
||||
class="process-config-page__require-line process-config-page__require-line--wide"
|
||||
v-if="row.key === 'transit'"
|
||||
>
|
||||
<span class="process-config-page__require-label">打卡频次,每</span>
|
||||
<el-input
|
||||
v-model="row.frequencyDays"
|
||||
:disabled="dialogReadonly || !row.enabled || !row.punch"
|
||||
maxlength="3"
|
||||
@input="value => handleFrequencyInput(row, value)"
|
||||
/>
|
||||
<span>天打卡1次</span>
|
||||
</div>
|
||||
<div class="process-config-page__require-line">
|
||||
<span class="process-config-page__require-label">打卡定位</span>
|
||||
<el-radio-group
|
||||
v-model="row.location"
|
||||
:disabled="dialogReadonly || !row.enabled || !row.punch"
|
||||
@change="syncNodeFields"
|
||||
>
|
||||
<el-radio :label="true">是</el-radio>
|
||||
<el-radio :label="false">否</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<div class="process-config-page__require-line" v-if="row.supportCargo">
|
||||
<span class="process-config-page__require-label">上传货量类型</span>
|
||||
<el-checkbox-group
|
||||
v-model="row.cargoTypes"
|
||||
:disabled="dialogReadonly || !row.enabled || !row.uploadCargo"
|
||||
@change="syncNodeFields"
|
||||
>
|
||||
<el-checkbox label="重量">重量</el-checkbox>
|
||||
<el-checkbox label="体积">体积</el-checkbox>
|
||||
<el-checkbox label="数量">数量</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</div>
|
||||
<div
|
||||
class="process-config-page__require-line process-config-page__require-line--wide"
|
||||
v-if="row.key === 'transit'"
|
||||
>
|
||||
<span class="process-config-page__require-label">打卡时段</span>
|
||||
<el-time-picker
|
||||
v-model="row.timeStart"
|
||||
:disabled="dialogReadonly || !row.enabled || !row.punch"
|
||||
format="HH:mm"
|
||||
value-format="HH:mm"
|
||||
placeholder="开始"
|
||||
/>
|
||||
<span>-</span>
|
||||
<el-time-picker
|
||||
v-model="row.timeEnd"
|
||||
:disabled="dialogReadonly || !row.enabled || !row.punch"
|
||||
format="HH:mm"
|
||||
value-format="HH:mm"
|
||||
placeholder="结束"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="附件要求" min-width="320">
|
||||
<template #default="{ row }">
|
||||
<div class="process-config-page__attachments" v-if="row.supportVoucher">
|
||||
<div class="process-config-page__require-line">
|
||||
<span class="process-config-page__require-label">上传凭证</span>
|
||||
<el-radio-group
|
||||
v-model="row.uploadVoucher"
|
||||
:disabled="dialogReadonly || !row.enabled"
|
||||
@change="syncNodeFields"
|
||||
>
|
||||
<el-radio :label="true">是</el-radio>
|
||||
<el-radio :label="false">否</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<div class="process-config-page__require-line">
|
||||
<span class="process-config-page__require-label">凭证类型</span>
|
||||
<el-checkbox-group
|
||||
v-model="row.voucherTypes"
|
||||
:disabled="dialogReadonly || !row.enabled || !row.uploadVoucher"
|
||||
@change="syncNodeFields"
|
||||
>
|
||||
<el-checkbox v-for="item in row.voucherOptions" :key="item" :label="item">
|
||||
{{ item }}
|
||||
</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</section-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #menu="{ row, index }">
|
||||
<el-link
|
||||
type="primary"
|
||||
v-if="hasPermission('process_config_view')"
|
||||
@click="$refs.crud.rowView(row, index)"
|
||||
@click="openConfig(row, true)"
|
||||
>
|
||||
查看
|
||||
</el-link>
|
||||
<el-link
|
||||
type="primary"
|
||||
v-if="canEdit(row)"
|
||||
@click="$refs.crud.rowEdit(row, index)"
|
||||
@click="openConfig(row)"
|
||||
>
|
||||
编辑
|
||||
</el-link>
|
||||
@@ -407,6 +101,311 @@
|
||||
</template>
|
||||
</avue-crud>
|
||||
|
||||
<el-dialog
|
||||
:title="dialogReadonly ? '查看过程配置' : form.id ? '编辑过程配置' : '新建过程配置'"
|
||||
append-to-body
|
||||
v-model="configBox"
|
||||
width="96%"
|
||||
top="4vh"
|
||||
class="process-config-dialog"
|
||||
:close-on-click-modal="false"
|
||||
@closed="handleDialogClosed"
|
||||
>
|
||||
<div class="process-config-form">
|
||||
<section-card title="基本信息">
|
||||
<el-form
|
||||
:model="form"
|
||||
label-position="right"
|
||||
label-width="calc(6em + 24px)"
|
||||
:disabled="dialogReadonly"
|
||||
>
|
||||
<el-row :gutter="18">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="配置名称" required>
|
||||
<el-input
|
||||
v-model="form.configName"
|
||||
maxlength="100"
|
||||
placeholder="请输入"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="项目" required>
|
||||
<el-select
|
||||
v-model="selectedProjectId"
|
||||
clearable
|
||||
filterable
|
||||
remote
|
||||
:remote-method="loadProjectOptions"
|
||||
:loading="projectLoading"
|
||||
placeholder="请选择"
|
||||
style="width: 100%"
|
||||
@change="handleProjectChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in projectOptions"
|
||||
:key="item.id"
|
||||
:label="formatProjectLabel(item)"
|
||||
:value="String(item.id)"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="运输完成时限">
|
||||
<div class="process-config-form__finish-days">
|
||||
<span>默认</span>
|
||||
<el-input
|
||||
v-model="form.defaultFinishDays"
|
||||
maxlength="3"
|
||||
placeholder="请输入"
|
||||
@input="handleFinishDaysInput"
|
||||
/>
|
||||
<span>天后完成运输</span>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="备注">
|
||||
<el-input
|
||||
v-model="form.remark"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
maxlength="500"
|
||||
show-word-limit
|
||||
placeholder="请输入"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</section-card>
|
||||
|
||||
<section-card title="现行过程节点">
|
||||
<div class="process-config-form__timeline" v-if="enabledNodes.length">
|
||||
<div class="process-config-form__timeline-line"></div>
|
||||
<div
|
||||
v-for="node in enabledNodes"
|
||||
:key="node.key"
|
||||
class="process-config-form__timeline-item"
|
||||
>
|
||||
<span class="process-config-form__timeline-dot"></span>
|
||||
<div class="process-config-form__timeline-name">{{ node.name }}</div>
|
||||
<div class="process-config-form__timeline-desc">
|
||||
<div v-for="text in timelineDescriptions(node)" :key="text">{{ text }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-empty v-else description="请在节点设置中勾选过程节点" :image-size="72" />
|
||||
</section-card>
|
||||
|
||||
<section-card title="节点设置">
|
||||
<el-table
|
||||
class="process-config-form__node-table"
|
||||
border
|
||||
:data="nodeRows"
|
||||
:span-method="nodeSpanMethod"
|
||||
>
|
||||
<el-table-column label="节点设置" width="136">
|
||||
<template #default="{ row }">
|
||||
<div class="process-config-form__node-cell">
|
||||
<el-checkbox
|
||||
v-model="row.enabled"
|
||||
:disabled="dialogReadonly"
|
||||
@change="syncNodeFields"
|
||||
/>
|
||||
<span class="process-config-form__node-name">{{ row.name }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作要求" min-width="660">
|
||||
<template #default="{ row }">
|
||||
<div class="process-config-form__requirements">
|
||||
<template v-if="row.key === 'accept'">
|
||||
<div class="process-config-form__require-line">
|
||||
<span class="process-config-form__require-label">是否确认</span>
|
||||
<el-radio-group
|
||||
v-model="row.confirmMode"
|
||||
:disabled="dialogReadonly || !row.enabled"
|
||||
@change="syncNodeFields"
|
||||
>
|
||||
<el-radio label="yes">是</el-radio>
|
||||
<el-radio label="no_confirm_accept">无需确认接单</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<div class="process-config-form__require-line">
|
||||
<span class="process-config-form__require-label">确认接单人</span>
|
||||
<el-checkbox
|
||||
v-model="row.confirmDriver"
|
||||
:disabled="dialogReadonly || !row.enabled || row.confirmMode !== 'yes'"
|
||||
@change="syncNodeFields"
|
||||
>司机</el-checkbox
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-else-if="row.key === 'return'">
|
||||
<div class="process-config-form__require-line">
|
||||
<span class="process-config-form__require-label">是否确认</span>
|
||||
<el-radio-group
|
||||
v-model="row.confirmMode"
|
||||
:disabled="dialogReadonly || !row.enabled"
|
||||
@change="handleReturnConfirmChange(row)"
|
||||
>
|
||||
<el-radio label="yes">是</el-radio>
|
||||
<el-radio label="no_confirm_complete">无需确认完成</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<div class="process-config-form__require-line">
|
||||
<span class="process-config-form__require-label">确认完成</span>
|
||||
<el-checkbox
|
||||
v-model="row.confirmInternal"
|
||||
:disabled="dialogReadonly || !row.enabled || row.confirmMode !== 'yes'"
|
||||
@change="syncNodeFields"
|
||||
>内部人员</el-checkbox
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<div class="process-config-form__require-grid">
|
||||
<div class="process-config-form__require-line">
|
||||
<span class="process-config-form__require-label">是否打卡</span>
|
||||
<el-radio-group
|
||||
v-model="row.punch"
|
||||
:disabled="dialogReadonly || !row.enabled"
|
||||
@change="syncNodeFields"
|
||||
>
|
||||
<el-radio :label="true">是</el-radio>
|
||||
<el-radio :label="false">否</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<div class="process-config-form__require-line" v-if="row.supportCargo">
|
||||
<span class="process-config-form__require-label">上传货量</span>
|
||||
<el-radio-group
|
||||
v-model="row.uploadCargo"
|
||||
:disabled="dialogReadonly || !row.enabled"
|
||||
@change="syncNodeFields"
|
||||
>
|
||||
<el-radio :label="true">是</el-radio>
|
||||
<el-radio :label="false">否</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<div
|
||||
class="process-config-form__require-line process-config-form__require-line--wide"
|
||||
v-if="row.key === 'transit'"
|
||||
>
|
||||
<span class="process-config-form__require-label">打卡频次,每</span>
|
||||
<el-input
|
||||
v-model="row.frequencyDays"
|
||||
:disabled="dialogReadonly || !row.enabled || !row.punch"
|
||||
maxlength="3"
|
||||
@input="value => handleFrequencyInput(row, value)"
|
||||
/>
|
||||
<span>天打卡1次</span>
|
||||
</div>
|
||||
<div class="process-config-form__require-line">
|
||||
<span class="process-config-form__require-label">打卡定位</span>
|
||||
<el-radio-group
|
||||
v-model="row.location"
|
||||
:disabled="dialogReadonly || !row.enabled || !row.punch"
|
||||
@change="syncNodeFields"
|
||||
>
|
||||
<el-radio :label="true">是</el-radio>
|
||||
<el-radio :label="false">否</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<div class="process-config-form__require-line" v-if="row.supportCargo">
|
||||
<span class="process-config-form__require-label">上传货量类型</span>
|
||||
<el-checkbox-group
|
||||
v-model="row.cargoTypes"
|
||||
:disabled="dialogReadonly || !row.enabled || !row.uploadCargo"
|
||||
@change="syncNodeFields"
|
||||
>
|
||||
<el-checkbox label="重量">重量</el-checkbox>
|
||||
<el-checkbox label="体积">体积</el-checkbox>
|
||||
<el-checkbox label="数量">数量</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</div>
|
||||
<div
|
||||
class="process-config-form__require-line process-config-form__require-line--wide"
|
||||
v-if="row.key === 'transit'"
|
||||
>
|
||||
<span class="process-config-form__require-label">打卡时段</span>
|
||||
<el-time-picker
|
||||
v-model="row.timeStart"
|
||||
:disabled="dialogReadonly || !row.enabled || !row.punch"
|
||||
format="HH:mm"
|
||||
value-format="HH:mm"
|
||||
placeholder="开始"
|
||||
/>
|
||||
<span>-</span>
|
||||
<el-time-picker
|
||||
v-model="row.timeEnd"
|
||||
:disabled="dialogReadonly || !row.enabled || !row.punch"
|
||||
format="HH:mm"
|
||||
value-format="HH:mm"
|
||||
placeholder="结束"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="附件要求" min-width="320">
|
||||
<template #default="{ row }">
|
||||
<div class="process-config-form__attachments" v-if="row.supportVoucher">
|
||||
<div class="process-config-form__require-line">
|
||||
<span class="process-config-form__require-label">上传凭证</span>
|
||||
<el-radio-group
|
||||
v-model="row.uploadVoucher"
|
||||
:disabled="dialogReadonly || !row.enabled"
|
||||
@change="syncNodeFields"
|
||||
>
|
||||
<el-radio :label="true">是</el-radio>
|
||||
<el-radio :label="false">否</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<div class="process-config-form__require-line">
|
||||
<span class="process-config-form__require-label">凭证类型</span>
|
||||
<el-checkbox-group
|
||||
v-model="row.voucherTypes"
|
||||
:disabled="dialogReadonly || !row.enabled || !row.uploadVoucher"
|
||||
@change="syncNodeFields"
|
||||
>
|
||||
<el-checkbox v-for="item in row.voucherOptions" :key="item" :label="item">
|
||||
{{ item }}
|
||||
</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</section-card>
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button @click="configBox = false">{{ dialogReadonly ? '关闭' : '取消' }}</el-button>
|
||||
<el-button
|
||||
plain
|
||||
:loading="submitting"
|
||||
v-if="!dialogReadonly"
|
||||
@click="submitConfig('draft')"
|
||||
>
|
||||
保存草稿
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
:loading="submitting"
|
||||
v-if="!dialogReadonly"
|
||||
@click="submitConfig('enabled')"
|
||||
>
|
||||
保存并启用
|
||||
</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<empty-pagination
|
||||
:page="page"
|
||||
@size-change="sizeChange"
|
||||
@@ -507,6 +506,8 @@ export default {
|
||||
loading: true,
|
||||
data: [],
|
||||
dialogReadonly: false,
|
||||
configBox: false,
|
||||
submitting: false,
|
||||
projectOptions: [],
|
||||
projectLoading: false,
|
||||
selectedProjectId: '',
|
||||
@@ -518,7 +519,6 @@ export default {
|
||||
total: 0,
|
||||
},
|
||||
selectionList: [],
|
||||
submitStatus: 1,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -880,11 +880,6 @@ export default {
|
||||
}
|
||||
return true;
|
||||
},
|
||||
stopSubmitLoading(loading) {
|
||||
if (typeof loading === 'function') {
|
||||
loading();
|
||||
}
|
||||
},
|
||||
needsDuplicateVoucherConfirm() {
|
||||
const signNode = this.nodeRows.find(item => item.key === 'sign');
|
||||
const returnNode = this.nodeRows.find(item => item.key === 'return');
|
||||
@@ -914,14 +909,45 @@ export default {
|
||||
}
|
||||
);
|
||||
},
|
||||
submitRow(row, done, loading, status = this.submitStatus) {
|
||||
this.submitStatus = 1;
|
||||
this.syncNodeFields();
|
||||
const submitRow = this.normalizeRow({ ...row, status });
|
||||
if (!this.validateRow(submitRow)) {
|
||||
this.stopSubmitLoading(loading);
|
||||
openConfig(row, readonly = false) {
|
||||
this.dialogReadonly = readonly;
|
||||
if (!row || !row.id) {
|
||||
this.form = {
|
||||
configName: '',
|
||||
projectIds: '',
|
||||
projectNames: '',
|
||||
defaultFinishDays: '',
|
||||
remark: '',
|
||||
status: 0,
|
||||
};
|
||||
this.selectedProjectId = '';
|
||||
this.resetNodeRows();
|
||||
this.configBox = true;
|
||||
return;
|
||||
}
|
||||
api.getDetail(row.id).then(res => {
|
||||
this.form = res.data.data || {};
|
||||
this.selectedProjectId = this.form.projectIds ? String(this.form.projectIds) : '';
|
||||
this.ensureSelectedProjectOption();
|
||||
this.parseNodeConfig(this.form);
|
||||
this.configBox = true;
|
||||
});
|
||||
},
|
||||
handleDialogClosed() {
|
||||
this.submitting = false;
|
||||
this.dialogReadonly = false;
|
||||
},
|
||||
submitConfig(mode) {
|
||||
if (this.submitting) return;
|
||||
this.syncNodeFields();
|
||||
const submitRow = this.normalizeRow({
|
||||
...this.form,
|
||||
status: mode === 'draft' ? 2 : 1,
|
||||
});
|
||||
if (!this.validateRow(submitRow)) {
|
||||
return;
|
||||
}
|
||||
this.submitting = true;
|
||||
this.checkEnabledProjectBeforeSubmit(submitRow)
|
||||
.then(exists => {
|
||||
if (exists) {
|
||||
@@ -932,9 +958,9 @@ export default {
|
||||
.then(() => this.confirmDuplicateVoucher())
|
||||
.then(() => api.submit(submitRow))
|
||||
.then(() => {
|
||||
this.configBox = false;
|
||||
this.onLoad(this.page);
|
||||
this.$message({ type: 'success', message: '操作成功!' });
|
||||
done();
|
||||
})
|
||||
.catch(error => {
|
||||
if (
|
||||
@@ -944,21 +970,11 @@ export default {
|
||||
) {
|
||||
window.console.log(error);
|
||||
}
|
||||
this.stopSubmitLoading(loading);
|
||||
})
|
||||
.finally(() => {
|
||||
this.submitting = false;
|
||||
});
|
||||
},
|
||||
rowSave(row, done, loading) {
|
||||
this.submitRow(row, done, loading);
|
||||
},
|
||||
rowUpdate(row, index, done, loading) {
|
||||
this.submitRow(row, done, loading);
|
||||
},
|
||||
handleProcessConfigSave(mode) {
|
||||
this.submitStatus = mode === 'draft' ? 2 : 1;
|
||||
if (this.$refs.crud && typeof this.$refs.crud.rowSave === 'function') {
|
||||
this.$refs.crud.rowSave();
|
||||
}
|
||||
},
|
||||
rowDel(row) {
|
||||
this.$confirm('确定将选择数据删除?', {
|
||||
confirmButtonText: '确定',
|
||||
@@ -1001,35 +1017,6 @@ export default {
|
||||
}
|
||||
this.selectionClear();
|
||||
},
|
||||
beforeOpen(done, type) {
|
||||
this.dialogReadonly = type === 'view';
|
||||
this.submitStatus = 1;
|
||||
if (type === 'add') {
|
||||
this.form = {
|
||||
configName: '',
|
||||
projectIds: '',
|
||||
projectNames: '',
|
||||
defaultFinishDays: '',
|
||||
remark: '',
|
||||
status: 0,
|
||||
};
|
||||
this.selectedProjectId = '';
|
||||
this.resetNodeRows();
|
||||
done();
|
||||
return;
|
||||
}
|
||||
if (['edit', 'view'].includes(type)) {
|
||||
api.getDetail(this.form.id).then(res => {
|
||||
this.form = res.data.data || {};
|
||||
this.selectedProjectId = this.form.projectIds ? String(this.form.projectIds) : '';
|
||||
this.ensureSelectedProjectOption();
|
||||
this.parseNodeConfig(this.form);
|
||||
done();
|
||||
});
|
||||
return;
|
||||
}
|
||||
done();
|
||||
},
|
||||
searchReset() {
|
||||
this.query = {};
|
||||
this.applyDefaultDeptSearch();
|
||||
@@ -1164,6 +1151,13 @@ export default {
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
:deep(.avue-crud__header) {
|
||||
margin-top: 12px;
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.process-config-form {
|
||||
&__finish-days {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -1174,10 +1168,6 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
&__custom-form {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&__timeline {
|
||||
position: relative;
|
||||
display: flex;
|
||||
@@ -1285,11 +1275,6 @@ export default {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
:deep(.avue-crud__header) {
|
||||
margin-top: 12px;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
:deep(.el-table) {
|
||||
--el-table-border-color: #eff1f7;
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@
|
||||
:model="form"
|
||||
:rules="formRules"
|
||||
label-position="right"
|
||||
label-width="auto"
|
||||
label-width="150"
|
||||
class="project-apply-form"
|
||||
:disabled="dialogReadonly"
|
||||
>
|
||||
@@ -1964,7 +1964,7 @@ export default {
|
||||
|
||||
&__grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
column-gap: 24px;
|
||||
row-gap: 0;
|
||||
margin-bottom: 12px;
|
||||
@@ -1972,6 +1972,13 @@ export default {
|
||||
border-radius: 0 0 6px 6px;
|
||||
padding: 14px 16px 4px;
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
|
||||
|
||||
// label 固定宽度:可容纳 6 个汉字,超出自动换行(覆盖全局 min-width:160px 与 auto 行内宽度)
|
||||
:deep(.el-form-item__label) {
|
||||
width: 108px !important;
|
||||
min-width: 0 !important;
|
||||
white-space: normal;
|
||||
}
|
||||
}
|
||||
|
||||
&__picker-icon {
|
||||
|
||||
@@ -364,7 +364,7 @@
|
||||
:before-close="beforeProgressDialogClose"
|
||||
@opened="loadProgress"
|
||||
>
|
||||
<section class="voucher-manage-page__progress-search">
|
||||
<section-card class="voucher-manage-page__progress-search">
|
||||
<el-form :model="progressQuery" label-position="right" label-width="160px"
|
||||
><div class="voucher-manage-page__search-grid">
|
||||
<el-form-item label="凭证批次号"
|
||||
@@ -391,7 +391,7 @@
|
||||
</div>
|
||||
</div></el-form
|
||||
>
|
||||
</section>
|
||||
</section-card>
|
||||
<el-table :data="progressRows" border class="voucher-manage-page__table"
|
||||
><el-table-column type="selection" width="52" /><el-table-column
|
||||
type="index"
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
class="pre-settlement-editor__form"
|
||||
>
|
||||
<el-row :gutter="24">
|
||||
<el-col v-for="field in formFields" :key="field.prop" :span="field.span || 8">
|
||||
<el-col v-for="field in formFields" :key="field.prop" :span="field.span || 6">
|
||||
<el-form-item :label="field.label" :prop="field.prop">
|
||||
<el-select
|
||||
v-if="field.type === 'contract'"
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
label-width="auto"
|
||||
>
|
||||
<el-row :gutter="24">
|
||||
<el-col v-for="field in fields" :key="field.prop" :span="8"
|
||||
<el-col v-for="field in fields" :key="field.prop" :span="6"
|
||||
><el-form-item :label="field.label" :prop="field.prop"
|
||||
><el-select
|
||||
v-if="field.prop === 'formalSettlementId' && editable"
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
label-width="auto"
|
||||
>
|
||||
<el-row :gutter="24">
|
||||
<el-col v-for="field in formFields" :key="field.prop" :span="8">
|
||||
<el-col v-for="field in formFields" :key="field.prop" :span="6">
|
||||
<el-form-item :label="field.label" :prop="field.prop">
|
||||
<el-input
|
||||
v-if="field.prop === 'formalSettlementNo' && editable"
|
||||
|
||||
@@ -137,13 +137,13 @@
|
||||
:model="shipForm"
|
||||
:rules="formRules"
|
||||
label-position="right"
|
||||
label-width="auto"
|
||||
label-width="100"
|
||||
:disabled="readonly"
|
||||
class="ship-form archive-form"
|
||||
>
|
||||
<section-card title="基础船舶信息">
|
||||
<el-row :gutter="18">
|
||||
<el-col :span="8">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="船舶所属组织" prop="organizationName">
|
||||
<el-select
|
||||
v-model="shipForm.organizationName"
|
||||
@@ -160,12 +160,12 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="船名" prop="shipName">
|
||||
<el-input v-model="shipForm.shipName" maxlength="20" show-word-limit />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="安放龙骨日期/建造完工日期" prop="keelLayingDate">
|
||||
<div class="date-range-inline">
|
||||
<el-date-picker
|
||||
@@ -186,7 +186,7 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="18">
|
||||
<el-col :span="8">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="总长" prop="totalLength">
|
||||
<el-input
|
||||
v-model="shipForm.totalLength"
|
||||
@@ -196,7 +196,7 @@
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="船宽" prop="shipWidth">
|
||||
<el-input
|
||||
v-model="shipForm.shipWidth"
|
||||
@@ -206,7 +206,7 @@
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="型深" prop="moldedDepth">
|
||||
<el-input
|
||||
v-model="shipForm.moldedDepth"
|
||||
@@ -218,7 +218,7 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="18">
|
||||
<el-col :span="8">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="最大船高" prop="maxShipHeight">
|
||||
<el-input
|
||||
v-model="shipForm.maxShipHeight"
|
||||
@@ -228,7 +228,7 @@
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="空载吃水" prop="lightDraft">
|
||||
<el-input
|
||||
v-model="shipForm.lightDraft"
|
||||
@@ -238,7 +238,7 @@
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="满载吃水" prop="fullLoadDraft">
|
||||
<el-input
|
||||
v-model="shipForm.fullLoadDraft"
|
||||
@@ -250,7 +250,7 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="18">
|
||||
<el-col :span="8">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="航区" prop="navigationArea">
|
||||
<div class="navigation-area-field">
|
||||
<el-select v-model="shipForm.navigationArea" placeholder="请选择">
|
||||
@@ -1226,6 +1226,12 @@ export default {
|
||||
:deep(.el-input-number) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
// label 固定宽度:可容纳 6 个汉字,超出自动换行
|
||||
:deep(.el-form-item__label) {
|
||||
white-space: normal;
|
||||
line-height: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.date-range-inline {
|
||||
|
||||
@@ -1079,7 +1079,7 @@
|
||||
ref="scoreForm"
|
||||
:model="currentScore"
|
||||
label-position="right"
|
||||
label-width="auto"
|
||||
label-width="150"
|
||||
:disabled="readonly"
|
||||
class="score-detail-form"
|
||||
>
|
||||
@@ -4416,8 +4416,8 @@ export default {
|
||||
flex-wrap: nowrap;
|
||||
|
||||
:deep(.el-date-editor) {
|
||||
flex: 0 0 150px;
|
||||
width: 150px;
|
||||
flex: 0 0 140px;
|
||||
width: 140px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user