Files
tms-erp-web/.workbuddy/memory/2026-08-14.md
T
gxwebsoft 8897f61bfa fix(loading-manage): 调整搜索栏标签宽度至88px
- 将 `/business/loading-manage` 页面搜索栏所有 label 宽度由160px改为88px
- 修改 `src/views/business/loading-manage.vue` 第4行 `<el-form>` 的 `label-width` 属性值
- 该改动违反 AGENTS.md 4.4 节规范,后续如需恢复需回滚

fix(transport-plan): 修复新增/编辑弹窗高度为固定72vh

- 补全并恢复 `.shipping-template-dialog` 全局CSS规则,解决样式未生效问题
- 新增 `.transport-plan-dialog` CSS规则,设置弹窗高度固定为72vh
- 弹窗内容少时保留底部空白,多时窗口内容可滚动,底部操作栏保持sticky粘贴底部
- 更新 `src/option/business/transport-plan.js`,补 `dialogCustomClass:'transport-plan-dialog'`
- `src/styles/element-ui.scss` 调整内边距与视觉对齐

- **补充说明**:Avue内置弹窗footer为`.avue-dialog__footer`且位于`.el-dialog__body`内,必须用`position: sticky; bottom: 0`实现底部固定效果
2026-08-14 15:42:16 +08:00

85 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 2026-08-14 工作记录
## temporary-credit-limit 弹窗 label 固定 6 汉字宽度并换行
- 需求:用户反馈 `/business/temporary-credit-limit` 新增弹窗中 label「已使用项目资金使用额度(万元)」过宽(227px),希望超过 6 个汉字就换行。
## loading-manage 搜索栏 label 宽度 160→88
- 用户要求把 `/business/loading-manage` 页面搜索栏所有 label 宽度从 160px 改为 88px。
- 改动:`src/views/business/loading-manage.vue` 第 4 行 `<el-form ... label-width="88px">`
- 注意事项:AGENTS.md 4.4 节规范"搜索组件 label 宽度统一不小于 160px",本次按用户指令执行但与项目规范冲突;如后续要恢复规范或全站统一,需要回滚。
- 宽度来源:
- `src/option/business/common.js``createCrudOption``labelWidth: 'auto'`
- Avue 会按当前弹窗内最长 label 自动计算宽度,故出现 227px。
- `src/styles/element-ui.scss` 第 164 行 `.el-dialog .el-form-item__label { white-space: nowrap }` 阻止换行。
- 改动:
1. `src/option/business/temporary-credit-limit.js`option 增加 `dialogCustomClass: 'temporary-credit-limit-dialog'`
2. `src/styles/element-ui.scss`:新增 `.temporary-credit-limit-dialog .el-form-item__label` 规则,固定宽度 `calc(6em + 24px)`,并设置 `white-space: normal; word-break: break-all; overflow-wrap: anywhere; line-height: 18px`,实现超长 label 自动换行。
3. 同时给 `.temporary-credit-limit-dialog .el-form-item { align-items: center; }` 保持垂直居中。
- 参考:同文件已有 `.avue-dialog--common-route` 使用相同 6em label 宽度方案。
## transportCapacity/ship 到期筛选标签默认展开并靠前
- 需求:用户反馈 `/transportCapacity/ship` 页面搜索栏的「全部/30天内到期/已到期」标签需要点击「展开」后才显示,希望默认直接显示;且位置要位于搜索按钮前面。
- 原因:`src/option/transportCapacity/transport-ship.js``searchIndex: 4`,默认只展示前 4 个搜索条件,而 `expireStatus``searchOrder: 0`(Avue 越大越靠前)排在第 6 位,因此被折叠到第二行。
- 改动:
- `src/option/transportCapacity/transport-ship.js``searchIndex: 4 → 6`,让全部 6 个搜索条件默认展开,标签无需再点展开即可看到。
- 由于 `expireStatus` 排在最后,展开后它自然位于第二行末尾、搜索按钮之前,满足"移到搜索按钮前面"的要求。
## transportCapacity/vehicle 与 ship 到期筛选标签重构(对齐 driver 的 #search-menu 方案)
- 需求:用户希望 `/transportCapacity/vehicle``/transportCapacity/ship` 的「全部/30天内到期/已到期」标签与 driver 页一致:① 不展开就直接显示;② 移到搜索按钮前面并保留间距。
- 关键差异(排查发现):driver 用 `#search-menu` 插槽把标签渲染在**按钮所在行**;而 vehicle/ship 之前用 `#expireStatus-search` 列插槽,标签被渲染进**搜索条件网格**(位置不对)。
- 改动(两页同样处理):
1. `.vue``<template #expireStatus-search>``<template #search-menu>`,标签 div 内容不变。
2. `.vue` 样式 `__expiry-tags`:去掉 `width: 100%`,改为 `order: -1; margin-right: 12px; min-width: 0;`(与 driver 完全一致,使标签左移并落在搜索按钮前)。
3. option:将 `expireStatus` 列的 `search: true → search: false`(否则会在搜索网格里多渲染一个空输入框);`searchIndex` 设为 ≥ 真实搜索列数(vehicle: `4 → 6`ship 已是 `6`),使 `columnLen ≤ searchIndex`Avue 不再显示「展开」按钮。
- 原理:Avue `header-search3.js``#search-menu` 插槽内容渲染进 `menu-form`,位于默认搜索/重置按钮之后、展开按钮之前;`order: -1` 将标签推到按钮左侧。
- 验证:`node --check` 两个 option 文件通过;页面刷新即可见效果。
## process-config.vue 弹窗重构为手写 el-dialog(对齐 customer-archive 风格)
- 需求:用户要求 `/business/process-config.vue` 排版风格改成和 `/vehicle/customer-archive.vue` 一样,保持风格统一。
- 根因:两页弹窗架构根本不同——customer-archive 用手写 `<el-dialog>` + `section-card` 分组 + `#footer` 按钮;process-config 原用 Avue 内置弹窗(`#basicInfo-form`/`#nodeConfigJson-form` 插槽 + `#menu-form-before` 保存按钮)。要真正统一,只能把 process-config 改成手写弹窗。
- 模板改动(已完成):
- 移除 avue-crud 的 `:before-open`/`@row-save`/`@row-update`/`@row-del``#menu-form-before``#basicInfo-form``#nodeConfigJson-form` 插槽。
-`</avue-crud>` 后新增手写 `<el-dialog class="process-dialog" v-model="processBox" width="92%" top="4vh" append-to-body @closed="resetProcess">`,内部 `<el-form ref="processForm" :model="form" label-width="calc(6em + 24px)" :disabled="dialogReadonly" class="process-form dialog-form-label-fixed">`,含 3 个 `section-card`:基本信息 / 现行过程节点(时间线)/ 节点设置(节点表格);`#footer` 含 保存草稿(plain) + 保存并启用(primary) + 取消/关闭。
- 顶部「新建过程配置」、表格「查看/编辑」链接改调 `openProcessConfig()` / `openProcessConfig(row, true)` / `openProcessConfig(row, false)`
- 脚本改动(本次完成):删除 Avue 生命周期方法 `beforeOpen/rowSave/rowUpdate/submitRow/stopSubmitLoading/handleProcessConfigSave`;新增 `openProcessConfig(row, readonly)`load 详情后 `this.form=data` + `selectedProjectId` + `parseNodeConfig` + 开框;新增则清空表单 + `resetNodeRows`)、`submitProcessConfig(mode)``this.$refs.processForm.validate``syncNodeFields``normalizeRow``validateRow``confirmDuplicateVoucher``api.submit`,成功后关框并刷新)、`resetProcess()``@closed` 重置 `dialogReadonly/submitting/submitStatus/form/selectedProjectId` + `resetNodeRows` + `clearValidate`)。`data()` 已含 `processBox/submitting``computed.dialogTitle``rowDel`/`handleCopy`/`handleAction` 不变(独立 API 调用)。
- option 改动(已完成):`src/option/business/process-config.js``saveBtn/updateBtn/addBtn/viewBtn/editBtn/delBtn:false`,关闭 Avue 内置弹窗按钮。
- 样式:新增 `:deep(.process-dialog .el-dialog__body){max-height:72vh;overflow:auto}`,对齐 customer-archive 的 `.archive-dialog` 滚动行为(长内容时 body 滚动、footer 固定)。
- 验证:`vite build --outDir /tmp/pc-build-check` 全量编译通过(仅动态导入 chunk 警告,与本改动无关);之前 `npm run build` 失败仅因沙箱 safe-delete 守卫清理旧 dist/ 触发,非代码错误。
## contract-manage 到期筛选标签靠右对齐
- 需求:用户截图反馈 `/business/contract-manage` 搜索栏中「全部/30天内到期/90天内到期/90天以上/已到期」标签需要靠右对齐。
- 改动:`src/views/business/components/business-crud-page.vue``.business-crud-page__contract-expiry-search` 样式由 `order: -1; margin-right: auto` 改为 `margin-left: auto`。这样该 slot 内容会被推到 `#search-menu` 行的右侧,搜索/重置按钮留在左侧,与 vehicle/ship 的左侧标签方案相反,符合用户本次要求。
- 验证:`vite build --outDir /tmp/pc-build-check-2` 全量编译通过。
## shipping-template 新增/编辑弹窗居中 + 加高(对齐 customer-archive
- 需求:用户反馈 `/business/shipping-template` 新增弹窗「没居中、高度不够高」,要求参照 `/vehicle/customer-archive` 的做法。
- 根因排查:
- shipping-template 的弹窗是 avue-crud 内置弹窗(business-crud-page + `:crud-option``$refs.crud.rowAdd()` 触发),option 里 `dialogWidth:'96%'``dialogTop:'10px'`
- avue 把 `dialogTop` 映射为 Element Plus `--el-dialog-margin-top``'10px'` 把弹窗死顶在顶部 → 视觉「没居中」。
- avue 内置 footer`.avue-dialog__footer`)渲染在**可滚动 body 内部**,不像 customer-archive 那样用 `#footer` 插槽在滚动区之外;字段多时「保存」按钮要滚动才看得到 → 视觉「高度不够高」。
- customer-archive 真正做法是:手写 `<el-dialog width="92%" top="4vh">` + `#footer` 按钮浮动 + body `max-height:72vh` 内部滚动。
- 改动:
1. `src/option/business/shipping-template.js``dialogWidth:'96%'→'92%'``dialogTop:'10px'→'4vh'`,新增 `dialogCustomClass:'shipping-template-dialog'`avue 会把它作为 class 加到 dialog 上,作为样式钩子)。
2. `src/styles/element-ui.scss`:新增 `.shipping-template-dialog` 规则——弹窗体 `height: calc(100vh - 4vh - 24px)` + flex 列布局占满视口(顶部 4vh、底部留白,视觉居中高大);body `max-height:none !important; overflow-y:auto` 解除全局 80vh 上限;`.avue-dialog__footer``position:sticky; bottom:0; background:#fff` 贴底始终可见,对齐 customer-archive 浮动按钮效果。
- 注意:class 唯一,仅作用于 shipping-templatebusiness-crud-page 被多页共用,但其余页 option 未设该 class);弹窗 `append-to-body`,故样式必须放全局(element-ui.scss)而非组件 scoped 样式。
- 验证:dev server(2889) HMR 自动生效;刷新后重开「新增」即可见效果(未跑全量 build,改动为纯 CSS + option 属性)。
## transport-plan 新增/编辑弹窗固定 72vh(对齐 customer-archive 视觉)
- 需求:用户要求 `/business/transport-plan` 新增/编辑弹窗高度 72vh,与 `/vehicle/customer-archive` 视觉一致。
- 排查发现:上次给 shipping-template 加的 `.shipping-template-dialog` 全局 CSS 规则**未持久化**option 钩子 `dialogCustomClass:'shipping-template-dialog'` 还在,但 `element-ui.scss` 里对应规则丢失),即 shipping-template 弹窗样式实际一直未生效。本次一并补回。
- 改动:
1. `src/option/business/transport-plan.js`:补 `dialogCustomClass:'transport-plan-dialog'`option 已有 `dialogWidth:'96%'``dialogTop:'4vh'`)。
2. `src/styles/element-ui.scss`
- 补回 `.shipping-template-dialog` 规则(弹窗体 `height: calc(100vh - 4vh - 24px)` 占满视口 + flex 列布局;body `max-height:none !important; overflow-y:auto``.avue-dialog__footer { position:sticky; bottom:0; background:#fff }` 贴底)。
- 新增 `.transport-plan-dialog` 规则(弹窗体用 `height:72vh` **固定**高度,内容少时 body 下方留白、内容多时窗内滚动;footer 同样 sticky 贴底)。
- 关键技术点:Avue 内置弹窗 footer 的真实 class 是 `.avue-dialog__footer`,且**渲染在 `.el-dialog__body` 内部**;贴底必须用 `position: sticky; bottom: 0`flex `margin-top:auto` 在滚动容器内仍会随内容滚走,无效)。这与手写 el-dialogfooter 在 body 外、class 为 `.el-dialog__footer`)不同。
- 验证:dev server(2889) HMR 自动生效;刷新后重开「新增」即可见(弹窗固定 72vh、底部"提交/取消"常驻可见)。