4edaa8486d
- payable-detail 单据号列新增固定左侧配置,保障滚动时可见 - receivable-payable-detail 组件表格动态列透传 fixed 属性 - project-apply 列表所有列单元格及表头居中显示,审批状态列改为纯文字 - 全站表格列(含操作列按钮)全局居中,样式统一覆盖 el-table 组件 - 修复 AVUE 依赖表单 label 冒号默认显示,pnpm patch 修改 es 与 lib 版本同步 - 解决 Vite optimizeDeps 缓存问题,patch 依赖后需删除 vite 缓存并重启 dev server - railway-station 弹窗表单全局 labelSuffix 设为空,去除 label 后冒号
247 lines
37 KiB
Markdown
247 lines
37 KiB
Markdown
# 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 白卡叠在其上看不出间隔。
|
||
- 改动(仅 2 文件):
|
||
1. `src/option/business/process-config.js`:option 顶层加 `dialogCustomClass: 'process-config-dialog'`。
|
||
2. `src/styles/element-ui.scss`(contract-manage-dialog 规则块后新增):
|
||
- `.process-config-dialog .avue-form { background:transparent; box-shadow:none; padding:0 }` —— 白卡透明化,灰底(.el-dialog__body 全局 #f2f2f2)露出,section-card 自带 margin-bottom:12px 形成卡距。
|
||
- `.process-config-dialog .avue-form__group > .el-col > .el-form-item { margin-bottom:0 }` —— formslot 外层 form-item margin 与卡片 margin 叠加会拉大卡距,归零统一 12px。
|
||
- `.process-config-dialog .avue-dialog__footer` + `.avue-crud__dialog .process-config-dialog .avue-dialog__footer { margin-top:0 !important }` —— 抵消全局 947 行 `.avue-crud__dialog .avue-dialog__footer { margin-top:-30px !important }`(form 透明化后会上移压卡)。双选择器兼顾 dialog 未 teleport / teleport 两种挂载。
|
||
- 已验证:Vite 2889 编译通过、HMR 生效。
|
||
- 备注:`menu-form-before` 插槽(保存草稿/保存并启用按钮)渲染在 `.avue-dialog__footer` 内(avue 源码 dialog-form3.mjs 确认),不受 form 透明化影响,仍处白底底栏。
|
||
|
||
## 合同管理表单页:多分组卡片风格(对齐 project-apply 风格)
|
||
- 需求:合同管理新增/编辑表单页(`/business/contract-manage/form?mode=add|edit`)的 7 个业务分组(基本信息 / 合同文件 / 计费信息 / 结算单规则 / 付款比例设置 / 其它附件 / 变更记录)要像 project-apply 一样独立成白底卡、卡间 12px 间距、标题 4px 主色蓝条。
|
||
- 关键事实(容易踩坑):
|
||
- 合同表单走 `PageAvueForm` 组件(`src/views/business/components/business-crud-page.vue:5577`),render 函数 `h('div', { class: option.dialogCustomClass }, [h('avue-form', ...)])`,**不包 el-dialog**(所以底部按钮天然不浮动贴底,会随内容滚动——这点与 project-apply 的 el-dialog #footer 浮动有差异)。
|
||
- `option` 顶层在 `isStandaloneFormPage` 时已设 `dialogCustomClass: 'contract-manage-form-dialog'`、`dialogAppendToBody: false`、`dialogModal: false`、`dialogTop: '0'`、`dialogWidth: '100%'`(5897-5914 行)。
|
||
- 7 个分区标题列在 option.column 里以 `order` 升序分块(`basicInfoTitle=200` → `contractFileTitle=30` → `billingInfoTitle=10` → `settlementRuleTitle=-10` → `paymentRatioTitle=-30` → `attachmentTitle=-50` → `changeRecordTitle=-70`),其余字段 order 在每对标题列之间。
|
||
- 实施方案(已提交 63256a9):
|
||
1. `buildContractFormGroupOption(option)`(business-crud-page.vue 新增方法):按 order 降序遍历 option.column,遇到 7 个 `*Title` 列就切片分组;`groups.length<=1` 时回退原 option(不影响其他业务弹窗)。返回 `{ ...option, column: groups[0], group: groups.slice(1).map(g=>({ label:'', arrow:false, column:g })) }`。
|
||
2. `pageFormOption`(6205 行)`isContractFormPage` 时调用上述方法。
|
||
3. CSS(business-crud-page.vue scoped 末尾):
|
||
- `.contract-manage-form-dialog` 设 `padding:20px 24px 96px; background:#f5f6fa; box-sizing:border-box;`(外层灰底)
|
||
- `.business-crud-page--contract-form .avue-form { background:transparent; padding:0 }`(表单白卡透明化)
|
||
- `.business-crud-page--contract-form .avue-form > .el-form > .avue-form__group` 和 `.avue-group` 都设白底 + 6px 圆角 + 0 1px 2px 阴影 + 12px margin-bottom + 14px 16px 4px padding(两张选择器分别覆盖第 1 组 column 与第 2-7 组 group 渲染)
|
||
- 验证(agent-browser + 系统 Chrome,已登录后截图核对):
|
||
- 合同表单 7 张白底卡清晰分隔,每张卡左侧 4px 主色蓝条 + 标题(基本信息 / 合同文件 / 计费信息 / 结算单规则 / 付款比例设置 / 其它附件 / 变更记录),卡间约 12px 灰底露白。
|
||
- 底部 5 个按钮(提交 / 关闭 / 保存 / 提交临时合同 / 提交正式合同)随内容滚动(非浮动贴底)。
|
||
- 与 project-apply 滚动后的"客户信息 / 承运商信息"卡风格完全一致。
|
||
- 与 project-apply 的已知差异(用户本次未要求改):
|
||
- 合同表单底部按钮非浮动贴底(PageAvueForm 不包 el-dialog,avue-form 的 form_menu 渲染在内部)
|
||
- 合同表单无"返回"按钮(用"关闭"代替)
|
||
- 合同表单无独立页面标题(page-header 区域在 breadcrumb 处,不在 main 标题区)
|
||
- 行为验证码:登录页拼图/旋转求解基础设施已搭好——`/tmp/captcha_solve.py`(CORS 修复后支持 puzzle+rotate 双模式)、`/tmp/ab-install/node_modules/.bin/agent-browser --browser-channel chrome`。登录流程:访问 → 切"账号密码登录" → 点登录 → 检测 `.puzzle-stage`/`.rotate-image` → POST 至 http://127.0.0.1:8765 → 取 xDisp/angle → JS PointerEvent 模拟拖动 .track-handle 即可。
|
||
- 提交:63256a9 feat(business-crud-page): 合同管理表单页改为多分组卡片风格(1 file, +86/-2)。未提交改动(process-config.js、element-ui.scss、master-order-editor.vue、loading-manage.vue、project-apply.vue、formal-settlement.vue、customer-archive.vue)与本任务无关,未纳入。
|
||
|
||
## shipping-template 独立表单页加 archive-page-form__title(参考 customer-archive)
|
||
- 需求:独立表单页 `/business/shipping-template/form?mode=add&name=新运费发货模板` 顶部缺页面标题,参考 customer-archive 的 `.archive-page-form__title` 加标题。
|
||
- 改动(单文件 `src/views/business/components/business-crud-page.vue`):
|
||
1. `PageAvueForm`(5578 行)声明 `props.formPageTitle`,render 时若非空则先 push `<div class="archive-page-form__title">{{ title }}</div>` 再渲染 avue-form(title 在表单容器 `shipping-template-dialog` 内、avue-form 之前)。
|
||
2. 模板 `<component :is="crudContainer">` 新增 `:form-page-title="isStandaloneFormPage ? formPageTitle : undefined"`。
|
||
3. 新增 computed `formPageTitle()`:`isStandaloneFormPage && isShippingTemplatePage` 时返回 `this.$route.query.name || '新增'/'编辑' + config.title`,否则 ''。
|
||
4. 样式(scoped 末尾,用 `:global` 因为 title div 由 PageAvueForm 函数式组件渲染、无 scoped 属性):`:global(.business-crud-page--form-page .archive-page-form__title)` 复制 customer-archive 的 18px/600/#303133 + margin-bottom:20px(::before 为空,与参考一致,仅纯文字标题)。
|
||
- 仅作用于 shipping-template 独立表单页;其他独立表单页(waybill/transport-plan/contract)`formPageTitle` 返回 '',不受影响。
|
||
|
||
## transport-plan 独立表单页也加 archive-page-form__title
|
||
- 需求:`/business/transport-plan/form?mode=add&name=新运费运输计划` 也要同样的页面标题。
|
||
- 改动:`formPageTitle()` 条件由 `isStandaloneFormPage && isShippingTemplatePage` 改为 `isStandaloneFormPage && (isShippingTemplatePage || isTransportPlanPage)`(复用已有 `isTransportPlanPage` computed:`config.permission==='transport_plan'`)。标题文案取 `this.$route.query.name`(「新运费运输计划」)或回退「新增/编辑运输计划」。
|
||
- 验证:Vite 2889 编译通过(HTTP 200,无错误)。
|
||
- 验证:Vite 2889 编译通过(HTTP 200,无 transform/syntax 错误),HMR 生效。如需扩展到其他独立表单页,去掉 `isShippingTemplatePage` 限定即可。
|
||
|
||
## 将 .archive-page-form__title 全局化,并再加 waybill / loading-manage / master-order 三页
|
||
- 需求:把页面标题扩展到 `/business/waybill-manage/form`、`/business/loading-manage/form`、`/business/master-order?mode=editor` 三页,并与 customer-archive / shipping-template / transport-plan 视觉统一。
|
||
- **全局化样式**:`.archive-page-form__title` 原本分散在 `customer-archive.vue`(scoped)与 `business-crud-page.vue`(`:global`,::before 为空纯文字)。现统一提取到 `src/styles/element-ui.scss`(5b 段):18px/600/#303133 + margin-bottom:20px + `::before` 4px 主色竖条 + 8px 间距(补全竖条,与 section-card 卡头风格一致)。并删除上述两处本地重复定义。
|
||
- **waybill-manage/form**:在 `business-crud-page.vue` 的 `formPageTitle()` 条件再并入 `isWaybillDetailLayout`(`config.permission==='waybill_manage'`),复用既有 computed。标题取 `query.name || '新增/编辑运单管理'`。
|
||
- **loading-manage/form**:该路由直接映射到 `loading-manage.vue`(非 business-crud-page)。新增 computed `formPageTitle()`(`query.name || '新增/编辑配载管理'`),并在独立表单页的 `<component>` 内、body 之前加 `<div v-if="isStandaloneFormPage" class="archive-page-form__title">{{ formPageTitle }}</div>`。
|
||
- **master-order?mode=editor**:`master-order.vue` 渲染 `master-order-editor.vue`。将 `<master-order-editor>` 包进 `<template v-else-if="mode==='editor'">`,前置 `<div class="archive-page-form__title">{{ masterEditorTitle }}</div>`;新增 computed `masterEditorTitle`(`routeId ? '编辑总单' : '新增总单'`)。
|
||
- 验证:4 个 SFC + element-ui.scss 经 Vite 2889 编译均 HTTP 200、无 transform/syntax 错误。
|
||
|
||
## 综合台账弹窗 & 临时额度查看弹窗 布局调整
|
||
- vehicle-ledger / ship-ledger(/transportCapacity 车辆·船舶综合台账弹窗):把 `<el-table>`+分页从 `el-tabs` 外移入每个 `<el-tab-pane>` 内(切换 tab 表格跟着切换);ship-ledger 同步把三个蓝标内容块(船舶基本信息/船舶证书信息/证书附件)由 `<section>`+`.dialog-section-title` 改为全局 `<section-card :title>`,卡片间距 12px。两文件均加 `:deep(.el-tabs__content){padding:0}` 去 border-card 默认内边距。
|
||
- 临时额度查看弹窗改两列(/business/temporary-credit-limit):
|
||
- 原"查看"调 Avue 内置 `rowView`(列数复用 column.span,呈 3 列)。改用 business-crud-page 内置自定义详情弹窗。
|
||
- `src/option/business/temporary-credit-limit.js` config 加 `detailButton:true`、`detailButtonIgnoreDraftStatus:true`、`detailSections:[申请信息(申请单号/备注 span:2 整行,其余两列)、额度信息]`。
|
||
- `business-crud-page.vue` 的 `showDetailButton` 加 `if(this.config.detailButtonIgnoreDraftStatus) return true`(仅放开草稿态也走自定义详情,不动其他页面)。
|
||
|
||
## contract-manage/form 独立表单页也加 archive-page-form__title
|
||
- 需求:`/business/contract-manage/form?mode=add&name=新运费合同管理` 也要同样顶部页面标题。
|
||
- 改动:`business-crud-page.vue` 的 `formPageTitle()` 条件再并入 `isContractConfig`(`config.permission==='contract_manage'`,contract-manage 已用 `contract-form-page` prop 走 `PageAvueForm`)。标题取 `query.name`(「新运费合同管理」)或回退「新增/编辑合同管理」。
|
||
- 验证:Vite 2889 编译通过(HTTP 200,无错误),HMR 生效。至此 business-crud-page 系列(shipping-template / transport-plan / waybill-manage / contract-manage)独立表单页均已带统一标题。
|
||
- 渲染走 `detailSections` 分支(`section-card` + `el-descriptions(:column=2)`),值经 `formatDetailValue` 转字典 label。
|
||
- 验证:`temporary-credit-limit.js` 经 `node --check` 语法通过;business-crud-page.vue 仅 template 表达式改动。待用户在 2889 刷新核对两列效果。
|
||
|
||
## 合同管理详情弹窗 label 对齐修复
|
||
- 需求:`/business/contract-manage` 详情弹窗里两列 `el-descriptions` 的 label(尤其右边列 label)对齐不一致,长 label(如"是否需要加盖法人章")换行后行高/垂直位置错乱。
|
||
- 根因:`business-crud-page.vue` 的 `&__detail-content .section-card` 中对 `.el-descriptions__label` 只写了 `width: 140px` 与 `text-align: right`,缺 `min/max-width`、`vertical-align`、`line-height`、`box-sizing`;对 `.el-descriptions__content` 也缺垂直对齐,导致跨列/跨行 label 视觉上不齐。另外 `contract-manage.vue` 底部的 `<style>`(未加 `scoped`)把 `.el-dialog .el-form-item__label` 与 `.el-col` 全局覆盖,会污染全站弹窗。
|
||
- 改动:
|
||
1. `src/views/business/components/business-crud-page.vue`(15440 行附近):
|
||
- label 与 content 统一加 `box-sizing:border-box`、`vertical-align:middle`、`line-height:1.4`、一致 padding;label 加 `min-width:140px; max-width:140px` 防止被内容撑开或压缩,content 保持 `min-height:42px`。
|
||
- **新增 `:deep(.el-descriptions__table) { width:100%; table-layout:fixed }`**:强制表格按固定列宽渲染,label 占 140px 后,左右两个 content 列均分剩余宽度,解决用户截图里"合同期限"卡片左右内容区宽度不一致的问题。
|
||
2. `src/views/business/contract-manage.vue`:把底部无 scoped 的全局样式改为 `<style scoped>`,并把选择器限定到 `.contract-manage-dialog`;删除污染性更强的 `.el-col { margin-bottom:0 !important }` 全局覆盖。
|
||
- 验证:Vite 2889 编译通过(HTTP 200),HMR 生效。待用户在 2889 刷新核对详情弹窗两列 label 是否左右/上下对齐、左右内容区宽度是否均等。
|
||
|
||
## 应付明细调整弹窗:控件撑满单元格 + 表头居中
|
||
- 需求:`/settlement/payable-detail`(即 `receivable-payable-detail.vue`)"调整费用"弹窗中,里程 / 杂项 / 装卸费等列的 `el-input-number` 默认宽度 180px,超出窄列后被截断(见截图);同时要求所有表头居中。
|
||
- 改动(单文件 `src/views/settlement/receivable-payable-detail.vue`):
|
||
1. 给调整弹窗 `<el-table>` 加 `class="settlement-detail-page__adjust-table"`。
|
||
2. 页面级表格样式 `.settlement-detail-page__table, .settlement-detail-page :deep(.el-table)` 的 `th.el-table__cell` 增加 `text-align: center !important;`,统一所有表头居中(覆盖金额列 `align: right` 导致的表头右偏)。
|
||
3. 新增 `.settlement-detail-page__adjust-table` 样式块:`.el-input-number`、`.el-input`、`.el-select` 全部 `width: 100% !important;`,使控件撑满单元格不被截断;`el-input-number` 内部输入保持右对齐。
|
||
- 验证:Vite 2889 编译通过(HTTP 200),HMR 生效。待用户在 2889 刷新核对调整弹窗输入框是否完整显示、表头是否全部居中。
|
||
|
||
## formal-settlement:把表格放进 tabs
|
||
- 需求:`/settlement/formal-settlement` 原本 `el-tabs`(应付/应收) 是空的 type 切换器,表格+工具栏在 tabs 外面;要求把表格放进 tabs 内。
|
||
- 改动:
|
||
1. 新建 `src/views/settlement/components/formal-settlement-table-panel.vue`:把工具栏(新增/付款申请/同步金蝶/打印结算单/导出 + 刷新) + `el-table` + 分页整体抽成子组件;props 收 `rows/columns/loading/page/hasPermission`,emits `create/payment/sync/export/refresh/page-change/update:selection/action`;行操作(查看/编辑/删除/提交/通过/驳回/作废)经 `rowActions(row)` 计算可见项后 emit `action {type,row}`;工具栏"打印"经 `emitSingle('print')` 取选中单行后 emit action(与父 `selectedOne` 行为一致)。
|
||
2. `src/views/settlement/formal-settlement.vue`:删除原 toolbar+table+pagination 块与对应 scoped 样式(`__toolbar/__toolbar-right/__links/__pagination`),在 `el-tabs` 两个 `el-tab-pane` 内各放一个 `<formal-settlement-table-panel>`(DRY,共用同一组件);新增 `handlePageChange({current,size})`、`handleAction({type,row})` 分发行操作;`handlePrint(row)` 改为接收行参数(不再用 selectedOne);删除无用 `handleSizeChange`。
|
||
- 验证:Vite build 通过(EXIT=0),无编译错误。待用户在 2889 刷新核对:应付/应收两个 tab 各自带完整表格与工具栏、切换 tab 触发 reload。
|
||
|
||
## 预结算单结算汇率输入框居左
|
||
- 需求:`/settlement/pre-settlement` 弹窗中「结算汇率」字段(el-input-number)默认居中,要求改为居左。
|
||
- 改动:
|
||
1. `src/option/settlement/preSettlementForm.js`:`exchangeRate` 字段新增 `class: 'exchange-rate-input'`。
|
||
2. `src/views/settlement/components/pre-settlement-editor.vue`:
|
||
- `el-input-number` 上绑定 `:class="field.class"`。
|
||
- scoped style 的 `&__form` 内增加 `:deep(.exchange-rate-input .el-input__inner) { text-align: left; }`。
|
||
- 影响:仅针对「结算汇率」字段,不改动其他数字输入框对齐方式。
|
||
|
||
## transport-reconciliation:同样把表格放进 tabs
|
||
- 需求:`/settlement/transport-reconciliation` 与 formal-settlement 同样问题——`el-tabs`(应付/应收) 是空 type 切换器、工具栏+表格在 tabs 外;要求把表格放进 tabs 内。
|
||
- 改动:
|
||
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(历史未提交改动),已被本次需求覆盖。
|
||
|
||
## master-order-dispatch 起-终路由条左侧节点被裁切修复
|
||
- 问题:`/business/master-order?mode=dispatch` 顶部 overview 的路由节点条(起/经/终),最左侧"起(梧州段)"被裁掉半字。根因:`.route-overview` 用 `justify-content: flex-end` 右对齐 + `overflow-x:auto`,节点总宽(4×130+3×56=688px)超出右侧栏可用宽度时,溢出从左侧跑出可视区,且节点 `flex:0 0 130px` 写死、长名字会撑爆。
|
||
- 改动(`src/views/business/components/master-order-dispatch.vue` scoped 样式,3 处):
|
||
1. `.route-overview`:`justify-content:flex-end` → `flex-start`;padding 改为 `8px 24px 0`(左右留白,滚动时两端节点完整可见)。
|
||
2. `.route-overview__node`:`flex:0 0 130px` → `flex:0 0 auto; min-width:130px; max-width:200px; padding:0 4px`;strong/small 加 `max-width:100%; overflow:hidden; text-overflow:ellipsis`(长名字省略号不撑爆)。
|
||
3. `.route-overview__line`:`flex:1 0 56px; min-width:56px` → `flex:0 1 56px; min-width:24px`(line 可收缩,滚动兜底更平滑)。
|
||
- 说明:1200px media query 里原有 `justify-content:flex-start` 现与默认一致,冗余但无害,保留未删。仅样式改动,无 JS 逻辑变化。
|
||
|
||
## master-order-dispatch 路由节点地址/联系人加 tooltip(hover 提示完整内容)
|
||
- 需求:起-终节点条地址过长截断("九头山货..."等)时,鼠标移上去能看到完整内容。
|
||
- 改动(`src/views/business/components/master-order-dispatch.vue` 模板,21-45 行):起/经、终节点各自的 strong(名称)+ 两个 small(地址、联系人)共 6 个文本元素分别用 `<el-tooltip placement="top" :show-after="120">` 包裹,`:content` 与原文本一致;保持原有 `text-overflow:ellipsis` 截断视觉不变。
|
||
- `:show-after="120"` 让鼠标停留 120ms 才弹,避免快速划过连续触发多个 tooltip;`placement="top"` 配合节点垂直居中位置弹出,体验稳定。
|
||
- 风险:仅模板增加 6 个 el-tooltip 实例,无 JS/style 改动;与之前段头 `el-tooltip`(segment-checkbox-label)用法一致。
|
||
|
||
## shipping-template(发货模板)表单页:模板信息+基本信息 4 列 + label 统一宽度
|
||
- 需求:`/business/shipping-template/form` 的「模板信息」「基本信息」两组改 4 列;左侧 label 宽度一致右对齐;全站统一(6 汉字宽、超出换行)。
|
||
- 改动 3 处:
|
||
1. `business-crud-page.vue` `buildFormGroupOption` 新增 `isShippingTemplatePage` 分支:对 groups[0](模板信息)、groups[1](基本信息)的非标题、非 span24 列设 `span:6`(该页分组:templateInfoTitle/basicInfoTitle/shippingInfoTitle/goodsInfoTitle/attachmentTitle 均已在 sectionTitleProps,发货信息及之后组保持原样)。
|
||
2. `src/option/business/shipping-template.js`:option 顶层加 `labelWidth: 100`(覆盖 createCrudOption 的 'auto',全表单 label 一致 100px;右对齐已由 labelPosition:'right' 保证)。
|
||
3. `src/styles/element-ui.scss` `.shipping-template-dialog .el-form-item__label { white-space: normal; line-height: 20px }`(长 label 换行,独立表单页容器也是 div.shipping-template-dialog,class 命中)。
|
||
- 模式沉淀:contract(isContractConfig 首组)/ shipping-template(前两组)都走 buildFormGroupOption 统一处理;普通 el-col 循环页直接改 span;CSS grid 页改 repeat 数 + label 规则。4 列=span 6,6 汉字=100px。
|
||
|
||
## transport-plan / waybill-manage 表单页:整表单 4 列 + label 统一(全站统一)
|
||
- `business-crud-page.vue` `buildFormGroupOption` 重构:抽取 `setFourColumns(group)` helper(非标题、非 span24 列设 span:6);contract→首组、shipping-template→前两组、transport_plan/waybill_manage→**所有分组**统一 4 列(这两页很多字段无显式 span 会落到 Avue 默认 12=2 列,是之前不 4 列的原因)。
|
||
- `waybill-manage.js` option 加 `labelWidth:100`(transport-plan.js 上轮已加);element-ui.scss 追加 `.waybill-manage-dialog .el-form-item__label` 换行规则(transport-plan-dialog 上轮已加)。
|
||
- 经验:Avue 表单「没 4 列」先查是否有字段漏设 span(默认 12);统一 4 列优先走 buildFormGroupOption 的页面级分支,避免逐个字段改。
|
||
|
||
## ⚠️ option.labelWidth 必须放在 createCrudOption 展开之后
|
||
- 第一次给 transport-plan.js、waybill-manage.js 加 `labelWidth: 100` 时写在 `...createCrudOption(...)` **之前**,被 createCrudOption 自带 `labelWidth: 'auto'` 覆盖,label 仍是 auto(按内容参差,看着像"150 不统一")。shipping-template 当时写在 createCrudOption 之后才生效。
|
||
- 教训:业务 option 文件顶层 `export const option = { labelWidth: 100, ...createCrudOption([...]) }` 写法**无效**,必须 `export const option = { ...createCrudOption([...]), labelWidth: 100, dialogWidth, ... }` 后写覆盖前写。
|
||
|
||
## payable-detail 主表格单据号列固定左侧
|
||
- 需求:`/settlement/payable-detail` 主表格除序号外,「单据号」列也固定左侧(横向滚动时始终可见)。
|
||
- 改动(2 处):
|
||
1. `src/option/settlement/receivable-payable-detail.js`:`documentNo` 列加 `fixed: 'left'`。
|
||
2. `src/views/settlement/receivable-payable-detail.vue`:主表格 v-for 动态列加 `:fixed="column.fixed"`(模板需显式透传才生效)。
|
||
- 注意:payable-detail 与 receivable-detail 共用同一组件,应收明细页同步生效(两侧一致)。左侧固定区 = 选择框52 + 序号64 + 单据号180。
|
||
|
||
## project-apply 列表列全部居中
|
||
- 需求:`/business/project-apply` avue-crud 列表所有列居中看效果。
|
||
- 改动(单文件 `src/views/business/project-apply.vue` `buildTableOption()`):column map 展开时加 `align:'center'` + `headerAlign:'center'`。avue 中 align 只管单元格内容,表头需 headerAlign 单独设。
|
||
- 弹窗内子表格(客户/承运商/材料/变更记录/选人)本就 align="center",无需动。Vite 2889 已 HMR。
|
||
|
||
## project-apply 审批状态列改纯文字
|
||
- 需求:审批状态列从 el-tag 改为纯文字。
|
||
- 改动(单文件 `src/views/business/project-apply.vue`):`#approvalStatus` 插槽去掉 `<el-tag>` 包裹,直接输出 `displayStatus(row,'approvalStatus')`;删除已无引用的 `statusTagType()` 方法。Vite 2889 编译 200。
|
||
|
||
## 全站表格列居中(含操作列)
|
||
- 需求:project-apply 居中效果被确认后,要求操作列按钮也居中,并应用到全站表格。
|
||
- 改动(`src/styles/element-ui.scss`,2 处全局规则):
|
||
1. `.avue-crud .avue-crud__menu.avue-crud__menu`:`justify-content: start` → `center`,`text-align: left` → `center`(Avue 操作列按钮居中,含下拉更多按钮)。
|
||
2. 表头背景规则后新增全站规则:`.el-table th.el-table__cell .cell, .el-table td.el-table__cell .cell { text-align: center }`(所有 el-table 表头+单元格内容居中,命中固定列;.cell 直接设置覆盖 el-table-column align 的继承值)。
|
||
- project-apply.vue 页面级 `align:'center'` 保留(双保险,无害);手写表格操作列 `.cell:has(> .el-link)` 本就 `justify-content:center`。
|
||
- 注意:全站居中会覆盖个别页面金额列 `align: right` 等显式右对齐,后续若某页要右对齐需页面级更高特异性覆盖。
|
||
|
||
## ⚠️ Vite optimizeDeps 缓存坑(patch node_modules 后必须重启 dev server)
|
||
- 修改 `node_modules/@smallwei/avue/lib/...` 这种深度依赖后,HMR **不会重新打包**:Vite 首次启动时已把整个 Avue ES module 预打包到 `node_modules/.vite/deps/@smallwei_avue.js`,缓存的 chunk 持续被 dev server 返回,导致代码修改"看起来没生效"。
|
||
- 解法(任选其一):
|
||
1. 重启 dev server(Vite 会重新 optimizeDeps)。
|
||
2. 手动删 `node_modules/.vite/deps/@smallwei_avue.js` + `_metadata.json`,再让 server 收到请求时触发重新打包(最干净,连同 `_metadata.json` 一起删,否则 fileHash 缓存会让它误以为已最新)。
|
||
- 经验:以后再 patch 任何被 Vite optimizeDeps 预打包的依赖(如 element-plus / avue / wangeditor 等),都要重启 server 才能生效。
|
||
|
||
## 全站弹窗/表单 label 去掉冒号(pnpm patch 修复 Avue 默认值)
|
||
- 需求:全站所有 el-form / avue-form 的字段 label(车站名称:、所属省份: 等)后冒号要去掉。
|
||
- 关键事实(重要,避免重复踩坑):
|
||
- Element Plus 的 label-suffix 不是用 `::after` 渲染,而是把后缀直接拼接到 label 文本节点:
|
||
```js
|
||
// node_modules/element-plus/es/components/form/src/form-item.vue...mjs:115
|
||
const currentLabel = computed(() => `${props.label || ""}${formContext?.labelSuffix || ""}`);
|
||
```
|
||
- EP el-form 的 labelSuffix prop 默认 `''`(空),不产生冒号;冒号来自 Avue。
|
||
- Avue 默认 `labelSuffix: ":"`,逻辑 `this.tableOption.labelSuffix || ":"`(空串 falsy 回落 `":"`),透传给 el-form 的 `label-suffix` prop。
|
||
- **踩坑**:Avue package.json 有 `"module": "es/index.mjs"` 和 `"main": "lib/index.js"`。Vite 用 ES 模块版(`es/`),不是 CommonJS 版(`lib/`)。**pnpm patch 必须同时覆盖 `es/` 和 `lib/` 两个文件**,否则 Vite 加载的 `es/` 版本未被 patch,冒号照旧!
|
||
- 另一个坑:Vite 把 Avue 预打包到 `node_modules/.vite/deps/@smallwei_avue.js`。patch 后必须删整个 `.vite` 目录 + 重启 dev server,否则预打包缓存仍是旧代码。
|
||
- 实施(pnpm patch + 手动补 es/ 版本):
|
||
1. `pnpm patch @smallwei/avue` → 临时目录,编辑 `lib/.../index2.js`。
|
||
2. `pnpm patch-commit <临时目录>` → 生成 `patches/@smallwei__avue.patch`(仅含 lib/ 改动)。
|
||
3. **手动更新 patch 文件**:追加 `es/packages/element-plus/form/index2.mjs` 的 diff(同样 `|| ":"` → `|| ""`)。
|
||
4. **手动编辑 node_modules** 中 `es/.../index2.mjs`(pnpm patch 只生成了 lib/ 的改动,es/ 版本需手动改)。
|
||
5. 删 `node_modules/.vite` 整个目录 → 重启 `pnpm dev` → Vite 重新预打包(含 es/ patch)→ 浏览器强刷。
|
||
- patch 文件:`patches/@smallwei__avue.patch`(含 es/ + lib/ 两处 diff)。
|
||
- pnpm 配置:`pnpm-workspace.yaml` 内 `patchedDependencies: { '@smallwei/avue': patches/@smallwei__avue.patch }`。
|
||
- ⚠️ 提交时务必带上:`patches/`、`pnpm-workspace.yaml`、`pnpm-lock.yaml`,缺一不可。
|
||
- ⚠️ `pnpm install` 会从 patch 文件重新应用补丁——如果 patch 文件没有 es/ 的 diff,es/ 版本会被还原为原始代码(冒号回来)。已手动补上 es/ diff 到 patch 文件。
|