style(settlement): 优化表格列居中及单据号列固定,调整审批状态展示
- payable-detail 单据号列新增固定左侧配置,保障滚动时可见 - receivable-payable-detail 组件表格动态列透传 fixed 属性 - project-apply 列表所有列单元格及表头居中显示,审批状态列改为纯文字 - 全站表格列(含操作列按钮)全局居中,样式统一覆盖 el-table 组件 - 修复 AVUE 依赖表单 label 冒号默认显示,pnpm patch 修改 es 与 lib 版本同步 - 解决 Vite optimizeDeps 缓存问题,patch 依赖后需删除 vite 缓存并重启 dev server - railway-station 弹窗表单全局 labelSuffix 设为空,去除 label 后冒号
This commit is contained in:
@@ -190,3 +190,57 @@
|
|||||||
## ⚠️ option.labelWidth 必须放在 createCrudOption 展开之后
|
## ⚠️ option.labelWidth 必须放在 createCrudOption 展开之后
|
||||||
- 第一次给 transport-plan.js、waybill-manage.js 加 `labelWidth: 100` 时写在 `...createCrudOption(...)` **之前**,被 createCrudOption 自带 `labelWidth: 'auto'` 覆盖,label 仍是 auto(按内容参差,看着像"150 不统一")。shipping-template 当时写在 createCrudOption 之后才生效。
|
- 第一次给 transport-plan.js、waybill-manage.js 加 `labelWidth: 100` 时写在 `...createCrudOption(...)` **之前**,被 createCrudOption 自带 `labelWidth: 'auto'` 覆盖,label 仍是 auto(按内容参差,看着像"150 不统一")。shipping-template 当时写在 createCrudOption 之后才生效。
|
||||||
- 教训:业务 option 文件顶层 `export const option = { labelWidth: 100, ...createCrudOption([...]) }` 写法**无效**,必须 `export const option = { ...createCrudOption([...]), labelWidth: 100, dialogWidth, ... }` 后写覆盖前写。
|
- 教训:业务 option 文件顶层 `export const option = { labelWidth: 100, ...createCrudOption([...]) }` 写法**无效**,必须 `export const option = { ...createCrudOption([...]), labelWidth: 100, dialogWidth, ... }` 后写覆盖前写。
|
||||||
|
|
||||||
|
## payable-detail 主表格单据号列固定左侧
|
||||||
|
- 需求:`/settlement/payable-detail` 主表格除序号外,「单据号」列也固定左侧(横向滚动时始终可见)。
|
||||||
|
- 改动(2 处):
|
||||||
|
1. `src/option/settlement/receivable-payable-detail.js`:`documentNo` 列加 `fixed: 'left'`。
|
||||||
|
2. `src/views/settlement/receivable-payable-detail.vue`:主表格 v-for 动态列加 `:fixed="column.fixed"`(模板需显式透传才生效)。
|
||||||
|
- 注意:payable-detail 与 receivable-detail 共用同一组件,应收明细页同步生效(两侧一致)。左侧固定区 = 选择框52 + 序号64 + 单据号180。
|
||||||
|
|
||||||
|
## project-apply 列表列全部居中
|
||||||
|
- 需求:`/business/project-apply` avue-crud 列表所有列居中看效果。
|
||||||
|
- 改动(单文件 `src/views/business/project-apply.vue` `buildTableOption()`):column map 展开时加 `align:'center'` + `headerAlign:'center'`。avue 中 align 只管单元格内容,表头需 headerAlign 单独设。
|
||||||
|
- 弹窗内子表格(客户/承运商/材料/变更记录/选人)本就 align="center",无需动。Vite 2889 已 HMR。
|
||||||
|
|
||||||
|
## project-apply 审批状态列改纯文字
|
||||||
|
- 需求:审批状态列从 el-tag 改为纯文字。
|
||||||
|
- 改动(单文件 `src/views/business/project-apply.vue`):`#approvalStatus` 插槽去掉 `<el-tag>` 包裹,直接输出 `displayStatus(row,'approvalStatus')`;删除已无引用的 `statusTagType()` 方法。Vite 2889 编译 200。
|
||||||
|
|
||||||
|
## 全站表格列居中(含操作列)
|
||||||
|
- 需求:project-apply 居中效果被确认后,要求操作列按钮也居中,并应用到全站表格。
|
||||||
|
- 改动(`src/styles/element-ui.scss`,2 处全局规则):
|
||||||
|
1. `.avue-crud .avue-crud__menu.avue-crud__menu`:`justify-content: start` → `center`,`text-align: left` → `center`(Avue 操作列按钮居中,含下拉更多按钮)。
|
||||||
|
2. 表头背景规则后新增全站规则:`.el-table th.el-table__cell .cell, .el-table td.el-table__cell .cell { text-align: center }`(所有 el-table 表头+单元格内容居中,命中固定列;.cell 直接设置覆盖 el-table-column align 的继承值)。
|
||||||
|
- project-apply.vue 页面级 `align:'center'` 保留(双保险,无害);手写表格操作列 `.cell:has(> .el-link)` 本就 `justify-content:center`。
|
||||||
|
- 注意:全站居中会覆盖个别页面金额列 `align: right` 等显式右对齐,后续若某页要右对齐需页面级更高特异性覆盖。
|
||||||
|
|
||||||
|
## ⚠️ Vite optimizeDeps 缓存坑(patch node_modules 后必须重启 dev server)
|
||||||
|
- 修改 `node_modules/@smallwei/avue/lib/...` 这种深度依赖后,HMR **不会重新打包**:Vite 首次启动时已把整个 Avue ES module 预打包到 `node_modules/.vite/deps/@smallwei_avue.js`,缓存的 chunk 持续被 dev server 返回,导致代码修改"看起来没生效"。
|
||||||
|
- 解法(任选其一):
|
||||||
|
1. 重启 dev server(Vite 会重新 optimizeDeps)。
|
||||||
|
2. 手动删 `node_modules/.vite/deps/@smallwei_avue.js` + `_metadata.json`,再让 server 收到请求时触发重新打包(最干净,连同 `_metadata.json` 一起删,否则 fileHash 缓存会让它误以为已最新)。
|
||||||
|
- 经验:以后再 patch 任何被 Vite optimizeDeps 预打包的依赖(如 element-plus / avue / wangeditor 等),都要重启 server 才能生效。
|
||||||
|
|
||||||
|
## 全站弹窗/表单 label 去掉冒号(pnpm patch 修复 Avue 默认值)
|
||||||
|
- 需求:全站所有 el-form / avue-form 的字段 label(车站名称:、所属省份: 等)后冒号要去掉。
|
||||||
|
- 关键事实(重要,避免重复踩坑):
|
||||||
|
- Element Plus 的 label-suffix 不是用 `::after` 渲染,而是把后缀直接拼接到 label 文本节点:
|
||||||
|
```js
|
||||||
|
// node_modules/element-plus/es/components/form/src/form-item.vue...mjs:115
|
||||||
|
const currentLabel = computed(() => `${props.label || ""}${formContext?.labelSuffix || ""}`);
|
||||||
|
```
|
||||||
|
- EP el-form 的 labelSuffix prop 默认 `''`(空),不产生冒号;冒号来自 Avue。
|
||||||
|
- Avue 默认 `labelSuffix: ":"`,逻辑 `this.tableOption.labelSuffix || ":"`(空串 falsy 回落 `":"`),透传给 el-form 的 `label-suffix` prop。
|
||||||
|
- **踩坑**:Avue package.json 有 `"module": "es/index.mjs"` 和 `"main": "lib/index.js"`。Vite 用 ES 模块版(`es/`),不是 CommonJS 版(`lib/`)。**pnpm patch 必须同时覆盖 `es/` 和 `lib/` 两个文件**,否则 Vite 加载的 `es/` 版本未被 patch,冒号照旧!
|
||||||
|
- 另一个坑:Vite 把 Avue 预打包到 `node_modules/.vite/deps/@smallwei_avue.js`。patch 后必须删整个 `.vite` 目录 + 重启 dev server,否则预打包缓存仍是旧代码。
|
||||||
|
- 实施(pnpm patch + 手动补 es/ 版本):
|
||||||
|
1. `pnpm patch @smallwei/avue` → 临时目录,编辑 `lib/.../index2.js`。
|
||||||
|
2. `pnpm patch-commit <临时目录>` → 生成 `patches/@smallwei__avue.patch`(仅含 lib/ 改动)。
|
||||||
|
3. **手动更新 patch 文件**:追加 `es/packages/element-plus/form/index2.mjs` 的 diff(同样 `|| ":"` → `|| ""`)。
|
||||||
|
4. **手动编辑 node_modules** 中 `es/.../index2.mjs`(pnpm patch 只生成了 lib/ 的改动,es/ 版本需手动改)。
|
||||||
|
5. 删 `node_modules/.vite` 整个目录 → 重启 `pnpm dev` → Vite 重新预打包(含 es/ patch)→ 浏览器强刷。
|
||||||
|
- patch 文件:`patches/@smallwei__avue.patch`(含 es/ + lib/ 两处 diff)。
|
||||||
|
- pnpm 配置:`pnpm-workspace.yaml` 内 `patchedDependencies: { '@smallwei/avue': patches/@smallwei__avue.patch }`。
|
||||||
|
- ⚠️ 提交时务必带上:`patches/`、`pnpm-workspace.yaml`、`pnpm-lock.yaml`,缺一不可。
|
||||||
|
- ⚠️ `pnpm install` 会从 patch 文件重新应用补丁——如果 patch 文件没有 es/ 的 diff,es/ 版本会被还原为原始代码(冒号回来)。已手动补上 es/ diff 到 patch 文件。
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
diff --git a/es/packages/element-plus/form/index2.mjs b/es/packages/element-plus/form/index2.mjs
|
||||||
|
--- a/es/packages/element-plus/form/index2.mjs
|
||||||
|
+++ b/es/packages/element-plus/form/index2.mjs
|
||||||
|
@@ -100,7 +100,7 @@
|
||||||
|
},
|
||||||
|
labelSuffix() {
|
||||||
|
- return this.tableOption.labelSuffix || ":";
|
||||||
|
+ return this.tableOption.labelSuffix || "";
|
||||||
|
},
|
||||||
|
isMenu() {
|
||||||
|
return this.columnOption.length != 1;
|
||||||
|
diff --git a/lib/packages/element-plus/form/index2.js b/lib/packages/element-plus/form/index2.js
|
||||||
|
--- a/lib/packages/element-plus/form/index2.js
|
||||||
|
+++ b/lib/packages/element-plus/form/index2.js
|
||||||
|
@@ -103,7 +103,7 @@ var script = src_core_create.default({
|
||||||
|
);
|
||||||
|
},
|
||||||
|
labelSuffix() {
|
||||||
|
- return this.tableOption.labelSuffix || ":";
|
||||||
|
+ return this.tableOption.labelSuffix || "";
|
||||||
|
},
|
||||||
|
isMenu() {
|
||||||
|
return this.columnOption.length != 1;
|
||||||
Generated
+7
-2
@@ -4,6 +4,11 @@ settings:
|
|||||||
autoInstallPeers: true
|
autoInstallPeers: true
|
||||||
excludeLinksFromLockfile: false
|
excludeLinksFromLockfile: false
|
||||||
|
|
||||||
|
patchedDependencies:
|
||||||
|
'@smallwei/avue':
|
||||||
|
hash: 4a6fd67ef4dfb390dba7eddaec02dd278bc066e4a5f65f93535b640498907d58
|
||||||
|
path: patches/@smallwei__avue.patch
|
||||||
|
|
||||||
importers:
|
importers:
|
||||||
|
|
||||||
.:
|
.:
|
||||||
@@ -28,7 +33,7 @@ importers:
|
|||||||
version: 1.7.0
|
version: 1.7.0
|
||||||
'@smallwei/avue':
|
'@smallwei/avue':
|
||||||
specifier: ~3.9.2
|
specifier: ~3.9.2
|
||||||
version: 3.9.2(@element-plus/icons-vue@2.3.2(vue@3.5.34))(element-plus@2.14.2(vue@3.5.34))(vue@3.5.34)
|
version: 3.9.2(patch_hash=4a6fd67ef4dfb390dba7eddaec02dd278bc066e4a5f65f93535b640498907d58)(@element-plus/icons-vue@2.3.2(vue@3.5.34))(element-plus@2.14.2(vue@3.5.34))(vue@3.5.34)
|
||||||
animate.css:
|
animate.css:
|
||||||
specifier: ^4.1.1
|
specifier: ^4.1.1
|
||||||
version: 4.1.1
|
version: 4.1.1
|
||||||
@@ -2636,7 +2641,7 @@ snapshots:
|
|||||||
countup.js: 2.10.0
|
countup.js: 2.10.0
|
||||||
signature_pad: 5.1.3
|
signature_pad: 5.1.3
|
||||||
|
|
||||||
'@smallwei/avue@3.9.2(@element-plus/icons-vue@2.3.2(vue@3.5.34))(element-plus@2.14.2(vue@3.5.34))(vue@3.5.34)':
|
'@smallwei/avue@3.9.2(patch_hash=4a6fd67ef4dfb390dba7eddaec02dd278bc066e4a5f65f93535b640498907d58)(@element-plus/icons-vue@2.3.2(vue@3.5.34))(element-plus@2.14.2(vue@3.5.34))(vue@3.5.34)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@element-plus/icons-vue': 2.3.2(vue@3.5.34)
|
'@element-plus/icons-vue': 2.3.2(vue@3.5.34)
|
||||||
axios: 0.21.4
|
axios: 0.21.4
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
patchedDependencies:
|
||||||
|
'@smallwei/avue': patches/@smallwei__avue.patch
|
||||||
@@ -27,7 +27,7 @@ export const searchFields = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
export const tableColumns = [
|
export const tableColumns = [
|
||||||
{ label: '单据号', prop: 'documentNo', minWidth: 180, link: true },
|
{ label: '单据号', prop: 'documentNo', minWidth: 180, link: true, fixed: 'left' },
|
||||||
{ label: '项目名称', prop: 'projectName', minWidth: 120 },
|
{ label: '项目名称', prop: 'projectName', minWidth: 120 },
|
||||||
{ label: '所属组织', prop: 'deptName', minWidth: 120 },
|
{ label: '所属组织', prop: 'deptName', minWidth: 120 },
|
||||||
{ label: '费用日期', prop: 'feeDate', minWidth: 120 },
|
{ label: '费用日期', prop: 'feeDate', minWidth: 120 },
|
||||||
|
|||||||
@@ -651,6 +651,12 @@
|
|||||||
background-color: #fafafa !important;
|
background-color: #fafafa !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 全站统一:表格列内容(表头 + 单元格)居中展示
|
||||||
|
.el-table th.el-table__cell .cell,
|
||||||
|
.el-table td.el-table__cell .cell {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
// 统一 avue-crud 偶数行背景色
|
// 统一 avue-crud 偶数行背景色
|
||||||
.avue-crud .el-table__body-wrapper tr.el-table__row:nth-child(even) td.el-table__cell,
|
.avue-crud .el-table__body-wrapper tr.el-table__row:nth-child(even) td.el-table__cell,
|
||||||
.avue-crud .el-table__body-wrapper tr.el-table__row:nth-child(even) td.el-table-fixed-column--left,
|
.avue-crud .el-table__body-wrapper tr.el-table__row:nth-child(even) td.el-table-fixed-column--left,
|
||||||
@@ -866,9 +872,9 @@
|
|||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: start;
|
justify-content: center;
|
||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
text-align: left;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 全站统一:手写表格操作列中的文字链接保持间距并支持自动换行
|
// 全站统一:手写表格操作列中的文字链接保持间距并支持自动换行
|
||||||
|
|||||||
@@ -205,6 +205,7 @@ export default {
|
|||||||
dialogCustomClass: 'railway-station-edit-dialog',
|
dialogCustomClass: 'railway-station-edit-dialog',
|
||||||
labelPosition: 'right',
|
labelPosition: 'right',
|
||||||
labelWidth: '140px',
|
labelWidth: '140px',
|
||||||
|
labelSuffix: '',
|
||||||
tip: false,
|
tip: false,
|
||||||
searchShow: true,
|
searchShow: true,
|
||||||
searchMenuSpan: 24,
|
searchMenuSpan: 24,
|
||||||
|
|||||||
@@ -55,9 +55,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #approvalStatus="{ row }">
|
<template #approvalStatus="{ row }">
|
||||||
<el-tag :type="statusTagType(row.approvalStatus)">
|
{{ displayStatus(row, 'approvalStatus') }}
|
||||||
{{ displayStatus(row, 'approvalStatus') }}
|
|
||||||
</el-tag>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #menu="{ row, index }">
|
<template #menu="{ row, index }">
|
||||||
@@ -1074,7 +1072,12 @@ export default {
|
|||||||
delBtn: false,
|
delBtn: false,
|
||||||
// 操作列收窄:本项目操作按钮较少,320px 过宽,调整为 220px(链接会自动换行兜底)
|
// 操作列收窄:本项目操作按钮较少,320px 过宽,调整为 220px(链接会自动换行兜底)
|
||||||
menuWidth: 180,
|
menuWidth: 180,
|
||||||
column: (option.column || []).map(column => ({ ...column, display: false })),
|
column: (option.column || []).map(column => ({
|
||||||
|
...column,
|
||||||
|
display: false,
|
||||||
|
align: 'center',
|
||||||
|
headerAlign: 'center',
|
||||||
|
})),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
hasPermission(code) {
|
hasPermission(code) {
|
||||||
@@ -1140,25 +1143,6 @@ export default {
|
|||||||
const item = column && (column.dicData || []).find(dic => dic.value === row[prop]);
|
const item = column && (column.dicData || []).find(dic => dic.value === row[prop]);
|
||||||
return item ? item.label : row[prop] || '未知';
|
return item ? item.label : row[prop] || '未知';
|
||||||
},
|
},
|
||||||
statusTagType(status) {
|
|
||||||
if (
|
|
||||||
[
|
|
||||||
1,
|
|
||||||
'pending',
|
|
||||||
'waiting_dispatch',
|
|
||||||
'processing',
|
|
||||||
'dispatching',
|
|
||||||
'approved',
|
|
||||||
'change_approved',
|
|
||||||
].includes(status)
|
|
||||||
) {
|
|
||||||
return 'success';
|
|
||||||
}
|
|
||||||
if ([2, 'cancelled', 'withdrawn', 'draft'].includes(status)) return 'info';
|
|
||||||
if (['rejected', 'change_rejected'].includes(status)) return 'danger';
|
|
||||||
if (status === 'completed') return 'primary';
|
|
||||||
return 'warning';
|
|
||||||
},
|
|
||||||
onLoad(page, params = {}) {
|
onLoad(page, params = {}) {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
this.api
|
this.api
|
||||||
|
|||||||
@@ -63,6 +63,7 @@
|
|||||||
:label="column.label"
|
:label="column.label"
|
||||||
:min-width="column.minWidth"
|
:min-width="column.minWidth"
|
||||||
:align="column.align || 'center'"
|
:align="column.align || 'center'"
|
||||||
|
:fixed="column.fixed"
|
||||||
show-overflow-tooltip
|
show-overflow-tooltip
|
||||||
>
|
>
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
|
|||||||
Reference in New Issue
Block a user