Files
tms-erp-web/.workbuddy/memory/MEMORY.md
T
gxwebsoft 986feff7b7 fix(waybill-manage): 修复运单详情弹窗残留问题
- 页面形态状态(列表/独立表单页/独立详情页)在实例创建时锁定,避免随路由变化切换导致弹窗残留
- 模板中形态相关所有判定改为使用锁定状态变量,保证渲染一致性
- 修改 detailContainer、crudContainer、pageFormOption 等方法使用锁定状态,避免缓存实例 option 变形
- 新增 closeInnerDialogs 方法,在组件 deactivated 和 beforeUnmount 生命周期关闭所有 append-to-body 弹窗
- 解决标签页 keep-alive 机制下弹窗 Teleport 持续遗留导致界面异常的问题
- 对运单管理页面多处弹窗和视图控制做统一修复,提升页面稳定性和体验
2026-09-18 11:29:52 +08:00

35 lines
4.3 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.
# 项目长期记忆(tms-erp-web-ws / Saber3
配套后端:`/Users/gxwebsoft/JAVA/tms-api`(不是 tms-erp-api-ws,后者功能滞后)。
## 列表 + 独立表单页 + 独立详情页(同一组件分流)
- `/xxx``/xxx/form``/xxx/detail` 指向同一 .vueform/detail 为 `component: Layout` + 空 children、`meta:{keepAlive:false}`detail 带 `activeMenu:'/xxx'`
- 组件内按 `$route.path` 分流,列表部分 `v-if="!isStandalonePage"` 隐藏;路由不同但组件相同 → 必须 `watch:{$route}` 重新 init。
- 跳转 `push({path:'/xxx/form',query:{mode,id,name}})`,标签标题取 `query.name`;只读详情底栏「关闭」,表单页「关闭/暂存/确认」。
## ⚠️ keep-alive 缓存引起的两个同源坑(`tab.js` + `layout.vue`
`tab.js` 按 fullPath 建 wrapper`layout.vue``<keep-alive :include="tagsKeep">` 缓存,**每标签一实例且永不销毁**;实例 deactivate 后**仍会随全局 `$route` 重渲染**。由此:
**坑一:独立页容器禁止用 `<component :is>` 在 div 与 el-dialog 间切换**
- 机制:`:is` 由 div 翻回 `el-dialog` + `v-model` 仍 true + `append-to-body` → 弹窗 Teleport 进 body`TeleportImpl.move` 忽略 `moveType`**不会把 teleport 的 DOM 搬回 storage container** → 点左侧菜单又冒出旧弹窗。
- 修法:独立页固定 `<div v-if="isXxxPage">`;另加 `deactivated(){closeInnerDialogs()}` + `beforeUnmount()` 收起页内 append-to-body 二级弹窗(子组件里写 `deactivated` 也有效)。
- 已修:loading-manage、project-apply、waybill-manage-page2026-09-18,后者用 `formPageLocked/detailPageLocked/formModeLocked` 锁形态)。未修:`settlement/components/{pre,formal}-settlement-editor.vue``transport-reconciliation-editor.vue``waybill-import-dialog.vue`
**坑二:宿主 view 把全局 `$route.query.*` 直接绑给子组件 prop**
- 现象:打开 A 页详情却弹「运单管理不存在」这类**用错 id** 的后端报错(可重复多条),还莫名多出别的标签。
- 机制:`waybill-manage-detail.vue``:detail-id="$route.query.id"` → 旧缓存实例把「当前页的 id」灌进来 → 触发 `openDetail` → 用别人的 id 查自己的接口 → 后端「XX 不存在」→ 全局 axios 拦截器红字弹出(几个旧标签就几条)。其 `isStandaloneXxxPage` 是 live computed(false) → 还会误 `push` 出新标签。
- 修法:`created()``routePathLocked = $route.path`watcher/跳转方法先判 `if ($route.path !== routePathLocked) return;`;宿主 view 绑定也加路径守卫。
- 同理:按 id 批量查详情处(如 `restoreWaybillRows`)虽有 `.catch`,但**拦截器已弹过提示**,catch 拦不住。
## 样式硬规则
- 底栏:`flex; justify-content:flex-end`、**不写 gap**(靠 EP 默认 `.el-button+.el-button{margin-left:12px}`)。浮动底栏必须 `position:fixed`(祖先 overflow:hidden 使 sticky 失效)+ `:global(.avue--collapse .x){left:60px}``:global(.avue-layout--horizontal .x){left:0}``:global()` 包整个选择器。
- 按钮层级:次要=不写 type;中间步骤=`primary plain`;主操作=`primary`(禁绿色、禁两个蓝实心)。顺序 `[辅助][取消][保存草稿][提交]`
- 独立页标题 `.archive-page-form__title`;分组用全局 `<section-card>`;上传证件区 `width:100%; max-width:240px` + `.el-upload{height:151px}`
- ⚠️ `<style scoped lang="scss">` **顶层禁 `//` 注释**Vite5+sass 报 `Unexpected '/'` → 样式模块 500),顶层用 `/* */`
- 其余细则见 `src/styles/element-ui.scss` 与 AGENTS.md 4.4。
## 表单文案 / 自检 / 导出
- placeholder 只写 `请输入`/`请选择`;例外:`请输入或选择车辆`、日期区间 `起/止`、示例值。校验 message 必须带字段名。
- `business-crud-page.vue`option 经 `cloneOption` 克隆,独立表单页走 `PageAvueForm`
- 自检:dev(2889) 时 `curl "localhost:2889/src/xxx.vue"``"...?vue&type=style&index=0&scoped=true&lang.scss"`200 通过、500 报错。`vite build` 会在 `facelogin.vue` 被沙箱中断,不能作唯一校验。dev`VITE_APP_API=/api`,代理 `172.16.203.228:8000`
- 导出:前端 `exportColumns` 后端未用,以 `XxxExportExcel.java` 为准;BladeX `BeanUtil` 类型不兼容静默跳过(`Date``LocalDateTime` 丢值,须 `DateUtil.fromDate(...)`)。