diff --git a/.workbuddy/memory/2026-08-14.md b/.workbuddy/memory/2026-08-14.md index 26ebf84..46bd283 100644 --- a/.workbuddy/memory/2026-08-14.md +++ b/.workbuddy/memory/2026-08-14.md @@ -50,3 +50,29 @@ - 需求:用户截图反馈 `/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 真正做法是:手写 `` + `#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-template(business-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` 规则(与 shipping-template 同结构,但弹窗体用 `max-height:72vh` **封顶**而非占满整屏,内容少时随内容变矮、内容多时窗内滚动;footer 同样 sticky 贴底)。 +- 关键技术点:Avue 内置弹窗 footer 的真实 class 是 `.avue-dialog__footer`,且**渲染在 `.el-dialog__body` 内部**;贴底必须用 `position: sticky; bottom: 0`(flex `margin-top:auto` 在滚动容器内仍会随内容滚走,无效)。这与手写 el-dialog(footer 在 body 外、class 为 `.el-dialog__footer`)不同。 +- 验证:dev server(2889) HMR 自动生效;刷新后重开「新增」即可见(弹窗封顶 72vh、底部"提交/取消"常驻可见)。 diff --git a/.workbuddy/memory/MEMORY.md b/.workbuddy/memory/MEMORY.md index 50a2e95..02793e7 100644 --- a/.workbuddy/memory/MEMORY.md +++ b/.workbuddy/memory/MEMORY.md @@ -31,6 +31,7 @@ - `.el-dialog__body { max-height: calc(100vh - 200px); overflow-y: auto; overflow-x: hidden; }` —— 内容超高时独立滚动,footer(位于 body 之外)始终可见。 - `.el-dialog__footer { margin:0; padding:12px 20px; background:#fff; border-top:1px solid var(--el-border-color-lighter,#ebeef5); box-shadow:0 -2px 8px rgba(0,0,0,.04); border-radius:0 0 var(--el-dialog-border-radius,4px); .el-button+.el-button{margin-left:8px} }` —— 视觉底栏(白底+上边框+轻阴影),与主内容区分。 - **注意**:`.el-dialog__body` 的 `max-height` 会作用于所有弹窗(含纯展示/表格弹窗),无 footer 的弹窗不受影响;project-apply 自身 `.project-apply-dialog .el-dialog__body{76vh}` 特异性更高仍优先。如需让某弹窗豁免,加更具体 class 覆盖即可。 +- **Avue 内置 CRUD 弹窗的 footer 真实 class(重要,易踩坑)**:Avue 内置弹窗的"提交/取消"按钮 class 是 `.avue-dialog__footer`(**不是** `.el-dialog__footer`),且**渲染在 `.el-dialog__body` 内部**、随 body 滚动会滚出视口。要让它像手写 `#footer` 那样始终贴底,必须针对 `.avue-dialog__footer` 用 `position: sticky; bottom: 0; flex: none; background: #fff`(配合 body `flex` 列布局 + `overflow-y:auto`)。手写 `el-dialog` 的 footer 才是 `.el-dialog__footer` 且在 body 外、天然可见。典型落地见 `shipping-template-dialog` / `transport-plan-dialog` 两条全局规则。 ### 上传证件区域尺寸规范(transportCapacity 模块强制) - **比例**:中国二代身份证标准尺寸 85.6 × 53.98 mm → 宽:高 = **1.586 : 1**(横放) diff --git a/src/option/business/contract-manage.js b/src/option/business/contract-manage.js index 31c163f..fd5ba32 100644 --- a/src/option/business/contract-manage.js +++ b/src/option/business/contract-manage.js @@ -619,6 +619,6 @@ export const option = createCrudOption([ option.span = 8; option.dialogWidth = 1480; -option.dialogTop = '10px'; +option.dialogTop = '4vh'; option.dialogCloseBtn = true; option.menuWidth = 320; diff --git a/src/option/business/process-config.js b/src/option/business/process-config.js index 7a21f9d..4194f23 100644 --- a/src/option/business/process-config.js +++ b/src/option/business/process-config.js @@ -181,7 +181,7 @@ export const option = { viewBtn: false, editBtn: false, delBtn: false, - dialogTop: '10px', + dialogTop: '4vh', dialogWidth: '96%', menuWidth: 220, }; diff --git a/src/option/business/shipping-template.js b/src/option/business/shipping-template.js index bc573b4..efa9933 100644 --- a/src/option/business/shipping-template.js +++ b/src/option/business/shipping-template.js @@ -269,6 +269,8 @@ export const option = { })), ]) ), - dialogWidth: '96%', - dialogTop: '10px', + dialogWidth: '92%', + dialogTop: '4vh', + // 自定义弹窗 class,用于让新增/编辑弹窗体占满视口高度、视觉居中(参照 vehicle/customer-archive) + dialogCustomClass: 'shipping-template-dialog', }; diff --git a/src/option/business/transport-plan.js b/src/option/business/transport-plan.js index 4aebdac..5d5fd8f 100644 --- a/src/option/business/transport-plan.js +++ b/src/option/business/transport-plan.js @@ -603,4 +603,6 @@ export const option = { ]) ), dialogWidth: '96%', + dialogTop: '4vh', + dialogCustomClass: 'transport-plan-dialog', }; diff --git a/src/option/business/waybill-manage.js b/src/option/business/waybill-manage.js index e3b4958..8ebee78 100644 --- a/src/option/business/waybill-manage.js +++ b/src/option/business/waybill-manage.js @@ -707,7 +707,7 @@ export const option = { searchLabel: '状态', searchOrder: 11, dicData: waybillStatusOptions, - minWidth: 120, + minWidth: 82, fixed: 'right', addDisplay: false, editDisplay: false, @@ -930,6 +930,6 @@ export const option = { ]) ), dialogWidth: '96%', - dialogTop: '10px', + dialogTop: '4vh', menuWidth: 280, }; diff --git a/src/styles/element-ui.scss b/src/styles/element-ui.scss index 9f83e18..10f6b70 100644 --- a/src/styles/element-ui.scss +++ b/src/styles/element-ui.scss @@ -456,6 +456,67 @@ //background: #f5f6fa; } +// 发货模板新增/编辑弹窗:参照 vehicle/customer-archive 的视觉 +// 弹窗体占满视口高度(顶部 4vh、底部留白),内容较少时也保持高大、视觉居中; +// 解除全局 80vh 上限并由 flex 控制,底部操作栏(avue 内置 footer,渲染在 body 内部)sticky 贴底始终可见 +.shipping-template-dialog.el-dialog { + margin-top: 4vh !important; + margin-bottom: 0 !important; + height: calc(100vh - 4vh - 24px); + display: flex; + flex-direction: column; +} + +.shipping-template-dialog .el-dialog__header { + flex: none; +} + +.shipping-template-dialog .el-dialog__body { + flex: 1 1 auto; + min-height: 0; + max-height: none !important; + display: flex; + flex-direction: column; + overflow-y: auto; +} + +.shipping-template-dialog .avue-dialog__footer { + position: sticky; + bottom: 0; + flex: none; + background: #fff; +} + +// 运输计划新增/编辑弹窗:参照 vehicle/customer-archive,弹窗体封顶 72vh, +// 内容较少时弹窗随内容变矮,内容超出 72vh 时窗内滚动; +// 底部操作栏(avue 内置 footer,渲染在 body 内部)sticky 贴底始终可见 +.transport-plan-dialog.el-dialog { + margin-top: 4vh !important; + max-height: 72vh; + display: flex; + flex-direction: column; +} + +.transport-plan-dialog .el-dialog__header { + flex: none; +} + +.transport-plan-dialog .el-dialog__body { + flex: 1 1 auto; + min-height: 0; + max-height: none !important; + display: flex; + flex-direction: column; + overflow-y: auto; +} + +.transport-plan-dialog .avue-dialog__footer { + position: sticky; + bottom: 0; + flex: none; + background: #fff; +} + // 统一表格线条颜色 .el-table { --el-table-border-color: #eff1f7; diff --git a/vite.config.mjs b/vite.config.mjs index 8c0a2a9..09134a0 100644 --- a/vite.config.mjs +++ b/vite.config.mjs @@ -50,26 +50,26 @@ export default ({ __VUE_I18N_LEGACY_API__: true, __INTLIFY_PROD_DEVTOOLS__: false, }, - server: { - port: 2888, - proxy: { - '/api': { - target: 'http://localhost', - //target: 'https://saber3.bladex.cn/api', - changeOrigin: true, - rewrite: path => path.replace(/^\/api/, ''), - }, - }, - }, // server: { - // port: 2889, + // port: 2888, // proxy: { // '/api': { - // target: 'http://172.16.203.228:8000', + // target: 'http://localhost', + // //target: 'https://saber3.bladex.cn/api', // changeOrigin: true, + // rewrite: path => path.replace(/^\/api/, ''), // }, // }, // }, + server: { + port: 2889, + proxy: { + '/api': { + target: 'http://172.16.203.228:8000', + changeOrigin: true, + }, + }, + }, resolve: { alias: { '~': resolve(__dirname, './'),