716ce43862
- 驾驶证有效期必填加红星,长期有效去除必填红星,保持校验逻辑不变 - 统一司机弹窗所有输入框和选择框的placeholder为“请输入”或“请选择”,去除字段名 - 保留复合操作、日期范围起止及默认值说明的特例placeholder不变 - 新增3处自动生成结算单开关后悬浮问号图标和提示,增强用户理解 - customer-archive中新增customerKindOptions和映射,用于客户类别选择 - 提升archive-form label与控件垂直居中样式至全局,修正多页标签顶置问题
10 KiB
10 KiB
项目长期记忆(tms-erp-web-ws / Saber3 客商模块)
设计约定(已确认)
表单 placeholder 统一为「请输入 / 请选择」(不带字段名)
- 规范:输入框 placeholder 只写动作词
请输入/请选择,后面不跟字段名称(label 已说明是什么字段,重复无意义)。 - 已生效页面:waybill-manage、transport-plan、shipping-template、temporary-credit-limit(搜索栏 + 弹窗表单)、driver.vue(2026-09-09 补齐 18 处)。
- 3 类例外必须保留,不要误简化:
- 复合操作:如
请输入或选择车辆(既可键盘输入又可点按钮弹窗选车),丢掉会损失语义。 - 日期区间的
起/止:是起止标记,不是字段提示。 - 默认值说明:如资格证号
默认身份证号、车牌号如:京A12345,属于示例/默认值提示,非「请输入」格式。
- 复合操作:如
- 校验错误提示 message 保持带字段名(如「请选择准驾车型」「请输入档案编号」),与 placeholder 定位不同——报错必须指明具体哪个字段,不能只说「请选择」。
- Avue 配置化表单:在 option 各列加
placeholder;搜索栏可用通用工具withSearchPlaceholders([...])(见 temporary-credit-limit.js)。 - 批量改法:Python 脚本按完整 placeholder 字符串做精确替换,每规则校验
count > 0否则中断,避免误伤;改完用@vue/compiler-sfc的 parse + compileTemplate + compileScript 验证(脚本须放项目根目录下跑,放 /tmp 解析不到 node_modules)。
弹窗分组:统一用全局 <section-card>
- 弹窗 body 背景由
src/styles/element-ui.scss全局.el-dialog__body { background:#f5f6fa; padding:16px }统一灰底。 - 每组 = 白底卡片:4px 主色竖条 + 8px 间距 + 圆角 6px + 淡阴影。组件全局注册
<section-card title="...">,支持#title/#extraslot。 - 仅 3 项的小分组用
el-col :span="8"均分一行。
Avue 内置弹窗用 section-card:dialogCustomClass 透明化 avue-form
- option 顶层加
dialogCustomClass:'xxx-dialog',再在element-ui.scss写三条:.xxx-dialog .avue-form { background:transparent; box-shadow:none; padding:0 }.xxx-dialog .avue-form__group > .el-col > .el-form-item { margin-bottom:0 }.xxx-dialog .avue-dialog__footer, .avue-crud__dialog .xxx-dialog .avue-dialog__footer { margin-top:0 !important }
弹窗底部操作栏浮动(全局 CSS)
.el-dialog__body { max-height:calc(100vh - 200px); overflow-y:auto; overflow-x:hidden }.el-dialog__footer { margin:0; padding:12px 20px; background:#fff; border-top:1px solid #ebeef5; box-shadow:0 -2px 8px rgba(0,0,0,.04) }- Avue 内置弹窗 footer 真实 class 是
.avue-dialog__footer,须position:sticky; bottom:0; flex:none; background:#fff贴底。
上传证件区域尺寸(transportCapacity)
- 身份证/行驶证/道路运输证等固定 240×151px(1.586:1)。
- scoped 覆盖
.xxx-uploader--large { width:240px }与--large .el-upload { width:100%; height:151px }。
上传图片点击放大预览
src/components/image-upload-field/main.vue用<el-image preview-src-list fit="contain" preview-teleported :z-index="3000" @click.stop>,阻止冒泡到 el-upload。
独立表单页标题 archive-page-form__title
- 样式全局化到
src/styles/element-ui.scss:18px/600/#303133 + margin-bottom:20px + 4px 主色竖条 + 8px 间距。 - business-crud-page 系列通过
formPageTitleprop 注入;loading-manage / master-order 手写前置标题。
表格列内嵌输入控件全宽
element-ui.scss全局兜底:.el-table .el-table__body td.el-table__cell .cell > .el-input-number/.el-input/.el-select/.el-date-editor/.el-cascader { width:100% }。
业务状态标签文字化
- 全站"状态语义"的
el-tag加class="status-text",转为普通文字,不带颜色/背景/边框/圆点。 - 实现:
element-ui.scss末尾.el-tag.status-text { ... }。
弹窗 / 独立表单页底栏按钮统一规则
- 排序:从左到右按次→主排(次要居左、主操作居右),主操作永远放最后。
- 顺序模板:
[可选辅助工具(如同步/导入)][取消][保存草稿][提交/确认]
- 顺序模板:
- 容器布局(2026-08-27 改为「去 gap」):
display:flex; justify-content:flex-end;(不写gap)。按钮间距统一由 Element Plus 全局默认的相邻按钮.el-button+.el-button{margin-left:12px}提供,全站恒为 12px。原各 footer 写死的gap:8/12px已全部移除。src/styles/element-ui.scss里.el-dialog__footer .el-button + .el-button也已从8px改12px,与之一致。弹窗关闭按钮继承 Element Plus 自带.el-dialog__footer全局规则(见上条),独立页用.archive-form__footer配.archive-page-form & { position:fixed; right:0; left:230px; bottom:0; z-index:10; margin:0; padding:12px 24px; border-top:1px solid #eff1f7; background:#fff; box-shadow:0 -2px 8px rgba(0,0,0,.06); }。 - ⚠️ 浮动底部必须用
position:fixed,不能用position:sticky:本项目布局.app-main/.basic-container祖先带overflow:hidden,会导致sticky永不触发(footer 不吸底)。固定写法照搬 customer-archive:注意.xxx-actions { position: fixed; right: 0; left: 230px; bottom: 0; margin: 0; z-index: 10; /* flex-end + padding + border-top + 白底 + 上投影 */ } :global(.avue--collapse .xxx-actions) { left: 60px; } /* 侧栏折叠 */ :global(.avue-layout--horizontal .xxx-actions) { left: 0; } /* 横向布局 */:global()要把「整个选择器」包进去(customer-archive 写法),不要只包前缀,否则 scoped 会在中间选择器上追加 data 属性导致不匹配。 - 颜色层级 3 档:
语义 type 备注 次要(取消 / 关闭) 不写 type(默认) 灰描边 - 全站底部操作栏「返回」已统一改为「取消」:独立表单页返回列表、弹窗关闭、主从编辑器返回等场景一律写「取消」;仅只读查看 / 纯关闭场景保留「关闭」。
| 中间步骤(保存草稿 / 按匹配结果更新) |
type="primary" plain| 蓝描边 | | 主操作(提交 / 完成对账 / 复评确认) |type="primary"| 蓝实心 |
- 全站底部操作栏「返回」已统一改为「取消」:独立表单页返回列表、弹窗关闭、主从编辑器返回等场景一律写「取消」;仅只读查看 / 纯关闭场景保留「关闭」。
| 中间步骤(保存草稿 / 按匹配结果更新) |
- 禁区:
- 保存草稿和主操作不允许同为
type="primary",否则两个蓝实心无视觉层级。 - 主操作禁止用
type="success"(绿)。全站统一深蓝实心。
- 保存草稿和主操作不允许同为
- 生效页面(已按规则统一):
business/project-apply.vue(footer + 变更 footer)vehicle/customer-archive.vue全部 5 处 footer(archive-form__footer主表单页 +contact-dialog/receipt-dialog/invoice-dialog子弹窗 +score-detail-dialog含总分合计)business/components/business-crud-page.vue的 PageAvueForm 独立表单页(#menu-form-beforeslot 新增取消按钮,shipping-template 模式验证通过;影响/business/waybill-manage/form、/business/transport-plan/form、/business/shipping-template/form三处独立表单页)business/components/master-order-editor.vue主<footer>(取消 default + 暂存/确认创建 plain + 创建并调度 primary;position:fixed浮动,含avue--collapse/avue-layout--horizontal左偏移)- payment 模块表单页(
__actions均flex-end+position:fixed浮动,含avue--collapse/avue-layout--horizontal左偏移):payment-application-form.vue([取消][保存 plain][提交])invoice-application-form.vue/invoice-receipt-form.vue([取消][同步 plain][保存 plain][提交])bill-ledger-form.vue([取消][确认 primary])bill-payment-form.vue([取消][保存 plain][提交])receipt-flow-form.vue([取消][确认 primary])receipt-claim-record-form.vue(单「关闭」按钮,居中→右对齐浮动)
- settlement 模块:
settlement/components/pre-settlement-editor.vue(弹窗 + pageMode 两处 footer:保存加plain;&__page-actions加position:fixed浮动,含avue--collapse/avue-layout--horizontal左偏移)settlement/components/formal-settlement-editor.vue(.formal-editor__page-actions加position:fixed浮动,含avue--collapse/avue-layout--horizontal左偏移;按钮已[取消][提交]合规)settlement/receivable-payable-detail.vue(生成费用弹窗「上一步」改plain)
- 已合规未动:
settlement/components/transport-reconciliation-editor.vue([取消][保存草稿 plain][按匹配结果更新账单 plain][完成对账 primary])、settlement/components/settlement-adjustment-editor.vue(弹窗[取消][保存 primary])、business/temporary-credit-limit.vue。 - Avue-form footer 结构注意:
#menu-form-beforeslot 内容在 Avue 内置按钮之左;#menu-formslot 在 Avue 内置按钮之右。要实现[次要][Avue 主操作]顺序,把次要按钮放进#menu-form-before,主操作保留 Avue 内置即可。 - Avue 表单 footer 按钮去图标(统一纯文字):Avue 的
avue-form提交/清空按钮内置图标(submitIcon: 'el-icon-check'、emptyIcon: 'el-icon-delete'),且 Avue 源码用|| 'el-icon-xxx'兜底,无法通过 option 配置去掉。已在business-crud-page.vue样式里用:global(.business-crud-form-page-dialog .avue-form__menu .el-icon){display:none}统一隐藏,仅作用于独立表单页(PageAvueForm 容器),不影响其它弹窗。新增/编辑弹窗内的 Avue 表单若也要去图标,复用此选择器即可。 - 复杂 footer 例外:当 footer 需要在按钮组左侧展示「总分合计 / 数量统计」等聚合信息时,块用
flex:1推自己到最左,按钮组按上述规则排在右半边(参考score-detail-dialog)。
关键文件
src/components/section-card/main.vuesrc/styles/element-ui.scsssrc/views/vehicle/customer-archive.vuesrc/views/transportCapacity/{driver,vehicle,ship}.vuesrc/views/business/project-apply.vue
环境注意
- Vite 代理跨域:
axios.withCredentials=true,改.env/vite.config.mjs须重启 dev。
business-crud-page 复用模式
- option 由 prop
crudOption经cloneOption克隆。 - 独立表单页走
PageAvueForm,不包 el-dialog。 - 自定义详情弹窗:
config.detailButton=true+detailSections:[{title, fields}]。