5bb072223f
- 新增 `/business/loading-manage/detail` 路由,详情页由独立页面承载 - 统一将新增、编辑、详情和重新派单均采用独立表单页/详情页显示 - 修改组件内逻辑,新增 `isStandalonePage` 计算属性统一控制页面与弹窗切换 - 修改列表页链接及操作行为,详情和重新派单按钮跳转至对应独立页面 - 去除旧详情弹窗模式,相关样式调整支持独立页面自然滚动 - 添加路由监听,支持页面刷新和切换时正确初始化详情或表单数据 - 兼容老链接 `/business/loading-manage?detailId=x` 自动跳详情新路由 - 修正弹窗底栏样式,去除写死间距,统一由全局规则控制 - 代码中禁止顶层 scoped style 使用 `//` 注释,改用 `/* */` 避免编译错误
39 lines
4.8 KiB
Markdown
39 lines
4.8 KiB
Markdown
# 项目长期记忆(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-manage(form+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。
|