Files
tms-erp-web/.workbuddy/memory/MEMORY.md
T
gxwebsoft 5bb072223f feat(loading-manage): 配载管理详情及重新派单改用独立页面
- 新增 `/business/loading-manage/detail` 路由,详情页由独立页面承载
- 统一将新增、编辑、详情和重新派单均采用独立表单页/详情页显示
- 修改组件内逻辑,新增 `isStandalonePage` 计算属性统一控制页面与弹窗切换
- 修改列表页链接及操作行为,详情和重新派单按钮跳转至对应独立页面
- 去除旧详情弹窗模式,相关样式调整支持独立页面自然滚动
- 添加路由监听,支持页面刷新和切换时正确初始化详情或表单数据
- 兼容老链接 `/business/loading-manage?detailId=x` 自动跳详情新路由
- 修正弹窗底栏样式,去除写死间距,统一由全局规则控制
- 代码中禁止顶层 scoped style 使用 `//` 注释,改用 `/* */` 避免编译错误
2026-09-17 22:40:41 +08:00

39 lines
4.8 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,后者功能滞后)。
## 页面结构:列表 + 独立表单页 + 独立详情页(同一组件分流)
- `src/router/views/index.js` 里三条静态/菜单路由指向同一个 .vue:`/xxx`(后端菜单)、`/xxx/form``/xxx/detail`form/detail 都是 `component: Layout` + 空 children`meta: { keepAlive: false }`detail 额外带 `activeMenu: '/xxx'`
- 组件内按 `$route.path` 分流(如 `isFormPage` / `isDetailPage` / `isListPage`),列表部分统一 `v-if="!isStandalonePage"` 隐藏搜索栏/工具栏/表格/分页。
- 路由记录不同但组件相同 → Vue 复用实例,所以**必须**在 `watch: { $route(to, from) }` 里重新 init`mounted` 只覆盖「直接打开/刷新」场景。切换详情与表单时不要只比 id,还要看当前 `dialogMode` 是否匹配。
- 跳转:`this.$router.push({ path: '/xxx/form', query: { mode, id, name: '新增xxx' } })`;标签标题由 avue-router 取 `query.name`。关闭:`this.$router.$avueRouter?.closeTag?.()` + push 列表。
- 已按此模式:contract-manageform+detail)、waybill-manage、loading-manage(新增/编辑/重新派单/详情,2026-09-17 完成)。
- 底栏文案:只读详情页用「关闭」;表单页沿用「关闭/暂存/确认」。
## 样式硬规则
- 底部操作栏:`display:flex; justify-content:flex-end;`**不写 gap**(间距由 Element Plus 默认 `.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;中间步骤 = `type="primary" plain`;主操作 = `type="primary"`(禁绿色 success,禁两个蓝实心)。顺序 `[辅助工具][取消][保存草稿][提交]`
- ⚠️ **`<style scoped lang="scss">` 顶层禁止 `//` 行注释**Vite5 + sass modern-compiler + scoped 会报 `Unexpected '/'.`,样式模块直接 HTTP 500(块内的 `//` 正常)。顶层统一用 `/* */`
- 独立页顶部标题用 `.archive-page-form__title`(全局:18px/600 + 4px 主色竖条),或 business-crud-page 的 `formPageTitle` prop。
- 弹窗分组统一全局 `<section-card>`(白卡 + 4px 主色竖条);弹窗灰底 `#f5f6fa` 由全局 `.el-dialog__body` 提供。
- 上传证件区:`width:100%; max-width:240px` + `.el-upload{height:151px}`,禁止写死 px。
- 其他全站细则(表格线 #EFF1F7、偶数行 #FAFAFA、搜索栏 8px 行距 / label≥160px / `searchIndex:4`、操作列宽度与纯文字链接、表格内嵌控件全宽、`.el-tag.status-text` 文字化)见 `src/styles/element-ui.scss` 与 AGENTS.md 4.4。
## 表单文案
- placeholder 只写 `请输入` / `请选择`,不带字段名;必须保留的例外:`请输入或选择车辆`、日期区间 `起/止`、示例值(`如:京A12345`)。
- 校验 message 必须带字段名(`请选择准驾车型`)。
- Avue 配置化表单:option 各列加 `placeholder`;搜索栏可用 `withSearchPlaceholders([...])`
- 存量的独立页 `max-height:78vh` 内嵌滚动盒写法是历史遗留,新做页面应让内容随 `#avue-view`(自身 `overflow-y:auto`)自然滚动 + 固定底栏。
## 复用与工具
- `business/components/business-crud-page.vue`option 由 `crudOption` prop 经 `cloneOption` 克隆;独立表单页走 `PageAvueForm`;自定义详情弹窗 `detailButton + detailSections`
- SFC 自检:项目根目录写临时脚本用 `@vue/compiler-sfc` 的 parse + compileScript + compileTemplate(脚本必须放根目录,放 /tmp 找不到 node_modules)。
- 更快的改后自检(dev server 已在 2889 时):`curl "localhost:2889/src/xxx.vue"`(模板+脚本)与 `curl "localhost:2889/src/xxx.vue?vue&type=style&index=0&scoped=true&lang.scss"`(样式),HTTP 200 即编译通过、500 会返回带堆栈的错误页。
- ⚠️ `vite build` 会在 `src/page/login/facelogin.vue` 处被 WorkBuddy 沙箱的敏感内容保护中断(环境问题,非代码问题),不能作为唯一校验手段。
- dev`VITE_APP_API=/api`vite 代理 `172.16.203.228:8000`;改 .env / vite.config.mjs 须重启。
## 导出(后端 FastExcel
- 前端 `exportColumns` 后端未使用,导出列以 `XxxExportExcel.java` 为准。
- BladeX `BeanUtil`(继承 Spring BeanUtils)字段类型不兼容时**静默跳过**:实体 `Date createTime` → Excel `LocalDateTime` 会丢值,须在 Service 手动 `DateUtil.fromDate(...)` 赋值(参考 Waybill / InsuranceRecord)。
- 排查导出文件用 Python `zipfile``xl/worksheets/sheet1.xml` 看有无 `<v>` 与 numFmt,无需 openpyxl。