From 9342e674c584c1c51333265cf31b0c7fd4d3a285 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=B5=B5=E5=BF=A0=E6=9E=97?= <170083662@qq.com>
Date: Thu, 27 Aug 2026 15:55:17 +0800
Subject: [PATCH 1/3] =?UTF-8?q?style(contract-manage):=20=E4=BC=98?=
=?UTF-8?q?=E5=8C=96=E6=8F=8F=E8=BF=B0=E7=BB=84=E4=BB=B6=E5=B8=83=E5=B1=80?=
=?UTF-8?q?=E5=92=8C=E6=A0=B7=E5=BC=8F=E8=B0=83=E6=95=B4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 将多个 el-descriptions 组件的 columns 属性从3调整为4,提升信息展示密度
- 扩展备注栏跨度以适应新列数布局
- 修改网格布局grid-template-columns为4列,调整列间距与行间距适配新样式
- 调整部分宽度属性,使界面自适应更合理
- 在customer-archive视图中移除多余的section-card标签,清理无用代码
- 修改全局样式element-ui.scss中的表单项底部间距由1px改为8px,提升控件间距协调性
- 优化输入框及下拉框占位符及选中值颜色,使视觉识别度更高且统一全站设计规范
---
src/styles/element-ui.scss | 15 ++++++++++++---
src/views/business/contract-manage.vue | 17 +++++++++--------
src/views/vehicle/customer-archive.vue | 2 --
3 files changed, 21 insertions(+), 13 deletions(-)
diff --git a/src/styles/element-ui.scss b/src/styles/element-ui.scss
index e47a785..c19dc9f 100644
--- a/src/styles/element-ui.scss
+++ b/src/styles/element-ui.scss
@@ -127,7 +127,7 @@
.avue-crud__search .el-form-item--small.el-form-item,
.avue-crud__search .el-form-item--large.el-form-item,
.avue-crud__search .el-form-item--medium.el-form-item {
- margin-bottom: 1px;
+ margin-bottom: 8px;
}
.avue-crud__search .el-form-item__label {
@@ -1072,8 +1072,8 @@
font-size: var(--el-form-label-font-size);
}
-// ============ 加深输入框 / 下拉框占位符颜色 ============
-// 客户反馈默认 placeholder 灰色(#a8abb2)太浅,统一加深一档到 #909399(Element Plus 次级文字标准灰)。
+// ============ 输入框 / 下拉框占位符与选中值颜色 ============
+// 客户反馈默认 placeholder 灰色(#a8abb2)太浅,统一加深到 #909399(Element Plus 次级文字标准灰)。
// 同时覆盖原生 input/textarea 与 el-select 的占位文本,保证全站一致。
// 注:.el-select__placeholder.is-transparent 是聚焦未选值时的透明态,无需处理。
.el-input__inner,
@@ -1092,6 +1092,15 @@
}
}
+// 未选中:占位符用次级灰 #909399
.el-select__placeholder {
color: #909399 !important;
}
+
+// 已选中:选中文本用主文字色 #333333,与占位符明显区分。
+// 注意:Element Plus 选中值节点同时带 el-select__selected-item 与 el-select__placeholder 两个类,
+// 而上面占位符规则用了 !important,故此处必须同样 !important 才能胜出(本规则 specificity 更高)。
+// 仅作用于非禁用态,禁用态保留 Element Plus 的禁用灰(--el-select-disabled-color),避免被覆盖。
+.el-select__wrapper:not(.is-disabled) .el-select__selected-item {
+ color: #606266 !important;
+}
diff --git a/src/views/business/contract-manage.vue b/src/views/business/contract-manage.vue
index 77f0e57..cb388b0 100644
--- a/src/views/business/contract-manage.vue
+++ b/src/views/business/contract-manage.vue
@@ -577,7 +577,7 @@
-
@@ -520,7 +519,6 @@
@size-change="size => handleDetailSizeChange('contact', size)"
@current-change="page => handleDetailCurrentChange('contact', page)"
/>
-
From fc70aeb2af6fa21b2075e24b5cfa335aaad312df Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=B5=B5=E5=BF=A0=E6=9E=97?= <170083662@qq.com>
Date: Thu, 27 Aug 2026 16:40:38 +0800
Subject: [PATCH 2/3] =?UTF-8?q?style(transportCapacity):=20=E4=BC=98?=
=?UTF-8?q?=E5=8C=96=E8=88=B9=E8=88=B6=E8=A1=A8=E5=8D=95=E5=B8=83=E5=B1=80?=
=?UTF-8?q?=E5=92=8C=E6=A0=87=E7=AD=BE=E6=A0=B7=E5=BC=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 船舶表单“安放龙骨日期/建造完工日期”label宽度收窄至88px并支持换行
- 船舶证书信息两块表单调整为4列布局,字段span由8改为6
- contract-manage和track-tracking页签名标签最大宽度限制为96px,防止过宽
- project-apply业务部门选择组件改用el-tree-select支持树形选择,辅助函数新增
- 全局样式调整el-tree-select及el-cascader去除圆圈,改用箭头和文字高亮展示
- 控制节点展开箭头、选中状态和悬浮效果统一视觉风格
---
.workbuddy/memory/2026-08-27.md | 11 ++++
src/styles/element-ui.scss | 89 ++++++++++++++++++++++++++
src/views/business/contract-manage.vue | 1 +
src/views/business/project-apply.vue | 47 ++++++++++----
src/views/transit/track-tracking.vue | 1 +
src/views/transportCapacity/ship.vue | 56 ++++++++--------
6 files changed, 165 insertions(+), 40 deletions(-)
diff --git a/.workbuddy/memory/2026-08-27.md b/.workbuddy/memory/2026-08-27.md
index 223e37b..ee5c31c 100644
--- a/.workbuddy/memory/2026-08-27.md
+++ b/.workbuddy/memory/2026-08-27.md
@@ -28,3 +28,14 @@
- 已去 gap 的 footer 容器:`vehicle/customer-archive.vue`(`.archive-form__footer`)、`business/components/master-order-editor.vue`(`footer`)、`business/components/master-order-dispatch.vue`(`.segment-actions`/`.pending-actions`)、`business/project-apply.vue`(`.project-apply-dialog__footer`)、`business/components/business-crud-page.vue`(`.business-crud-form-page-dialog .avue-form__menu`)、payment 6 个表单页(`*__actions`)、`settlement/components/pre-settlement-editor.vue`(`&__page-actions`)、`settlement/components/formal-settlement-editor.vue`(`.formal-editor__page-actions`)、`settlement/receivable-payable-detail.vue`(`.settlement-detail-page__actions`)。
- 风控:确认 Avue 的 `.avue-form__menu`/`.avue-dialog__footer` 自身不带按钮间距,去掉 gap 后由 EP 默认 12px margin 接管(不会贴死)。
- 范围说明:本次聚焦近几轮在统一的模块(vehicle/payment/business/settlement)。若要把 loading-manage、contract-manage、transit 等其它模块的底部栏也纳入,需再处理。
+
+## 船舶表单「安放龙骨日期/建造完工日期」label 收窄并换行
+- 起因:用户截图 `transportCapacity/ship` 新增船舶弹窗,指出该字段 label 宽达 185px,要求最大 88px 并允许换行。
+- 改动:`src/views/transportCapacity/ship.vue` 第 169 行,给该 `el-form-item` 增加 `label-width="88px"` 覆盖全局 `label-width="100"`;全局 `.ship-form :deep(.el-form-item__label)` 已设置 `white-space: normal; line-height: 20px`,换行已支持。
+
+## 船舶证书信息两块表单改 4 列
+- 起因:用户截图 `transportCapacity/ship` 船舶证书信息,指出「船舶所有权证书」「内河船舶安全与环保证书」两块想改成 4 列。
+- 改动:`src/views/transportCapacity/ship.vue`
+ - 「船舶所有权证书」5 个字段:第一行 `登记号码/初次登记号码/船舶所有人/取得所有权日期` 4 列,第二行 `船舶识别号` 1 列(所有 `el-col :span="8"` → `:span="6"`)。
+ - 「内河船舶安全与环保证书」4 个字段:合并为一行 4 列(`总吨/净吨/船检登记号/船舶类型`),`el-col :span="8"` → `:span="6"`。
+- 未改动:船舶国籍证书、最低安全配员证书(日期范围,保持 `span=16` 整行)、光船租赁登记证明书、船舶营业运输证书(用户未要求)。
diff --git a/src/styles/element-ui.scss b/src/styles/element-ui.scss
index c19dc9f..8b1d793 100644
--- a/src/styles/element-ui.scss
+++ b/src/styles/element-ui.scss
@@ -1104,3 +1104,92 @@
.el-select__wrapper:not(.is-disabled) .el-select__selected-item {
color: #606266 !important;
}
+
+// ============ 全局 el-tree-select 样式:隐藏圆圈/复选框,统一为树形 ▶ 箭头展开风格 ============
+// 目标:将所有带 ○/●/☑ 圆圈的 tree-select 下拉改为纯树形展开(▶ 箭头 + 选中蓝字),与截图2一致。
+.el-tree-select {
+ // 隐藏下拉面板内的 checkbox / radio 圆圈
+ .el-tree-node__content > .el-checkbox {
+ display: none;
+ }
+
+ // 展开箭头始终可见(即使叶子节点也保留占位,保证对齐)
+ .el-tree-node__expand-icon {
+ font-size: 12px;
+ color: #c0c4cc;
+
+ &.is-leaf {
+ // 叶子节点:透明占位符,保持缩进对齐
+ color: transparent;
+ &::before {
+ display: none;
+ }
+ }
+
+ &:not(.is-leaf) {
+ // 可展开节点:hover 加深
+ &:hover {
+ color: #909399;
+ }
+ }
+ }
+
+ // 选中节点:蓝色文字高亮(替代原来的 ● 实心圆)
+ .el-tree-node.is-current > .el-tree-node__content {
+ color: var(--el-color-primary, #409eff);
+ font-weight: 600;
+ }
+
+ // hover 态
+ .el-tree-node__content:hover {
+ background-color: var(--el-fill-color-light, #f5f7fa);
+ }
+
+ // 节点标签文字
+ .el-tree-node__label {
+ font-size: 14px;
+ color: #333333;
+ }
+
+ // 选中节点的标签颜色继承 is-current 的蓝色
+ .el-tree-node.is-current > .el-tree-node__content > .el-tree-node__label {
+ color: inherit;
+ }
+}
+
+// ============ 全局 el-cascader(checkStrictly)样式:隐藏 ○/● 单选圆圈 ============
+// 当 el-cascader 配置 checkStrictly:true 时,面板内每项前显示 el-radio 圆圈。
+// 全局隐藏这些圆圈,改为纯文字选中高亮风格,与 tree-select 统一。
+.el-cascader-panel {
+ // 隐藏级联面板内的 radio 单选圆圈
+ .el-cascader-node__prefix {
+ .el-radio {
+ display: none;
+ }
+ }
+
+ // 选中项:蓝色文字 + 加粗(替代原来的 ● 实心圆)
+ .el-cascader-node.is-active {
+ .el-cascader-node__label {
+ color: var(--el-color-primary, #409eff);
+ font-weight: 600;
+ }
+ }
+
+ // hover 态
+ .el-cascader-node:hover {
+ background-color: var(--el-fill-color-light, #f5f7fa);
+ }
+
+ // 节点标签默认颜色
+ .el-cascader-node__label {
+ font-size: 14px;
+ color: #333333;
+ }
+
+ // 禁用态
+ .el-cascader-node.is-disabled {
+ color: var(--el-text-color-placeholder, #c0c4cc);
+ cursor: not-allowed;
+ }
+}
diff --git a/src/views/business/contract-manage.vue b/src/views/business/contract-manage.vue
index cb388b0..57bc771 100644
--- a/src/views/business/contract-manage.vue
+++ b/src/views/business/contract-manage.vue
@@ -2345,6 +2345,7 @@ export default {
:deep(.el-descriptions__label) {
display: inline-block;
min-width: 96px;
+ max-width: 96px;
padding-right: 12px;
color: #606266;
text-align: right;
diff --git a/src/views/business/project-apply.vue b/src/views/business/project-apply.vue
index e08cfc1..4a6ac3f 100644
--- a/src/views/business/project-apply.vue
+++ b/src/views/business/project-apply.vue
@@ -157,21 +157,19 @@
/>
-
-
-
+ />
item.value === value);
- this.form.businessDeptName = dept ? dept.rawLabel : '';
+ // el-tree-select 返回的是 node-key 值,从树中查找节点获取名称
+ const label = this.findDeptLabel(this.businessDeptTreeOptions, value);
+ this.form.businessDeptName = label;
this.$refs.projectForm?.validateField('businessDeptId');
},
handleUndertakeDeptChange(value) {
@@ -1785,6 +1785,10 @@ export default {
this.dialogType === 'add' ? this.excludeExternalOrganization(deptTree) : deptTree;
this.deptOptions = this.flattenDept(deptTree);
this.deptTreeOptions = this.toDeptCascaderOptions(undertakeDeptTree);
+ // 业务部门用 el-tree-select,需要树形数据(label/value/children 格式)
+ this.businessDeptTreeOptions = this.toTreeSelectOptions(
+ this.dialogType === 'add' ? this.excludeExternalOrganization(deptTree) : deptTree
+ );
});
},
excludeExternalOrganization(list = []) {
@@ -1821,6 +1825,25 @@ export default {
return result;
}, []);
},
+ // 将后端部门树转为 el-tree-select 需要的 {label, value, children} 格式
+ toTreeSelectOptions(list = []) {
+ return (list || []).map(item => ({
+ label: item.title || item.deptName || item.name,
+ value: item.id,
+ children: item.children?.length ? this.toTreeSelectOptions(item.children) : undefined,
+ }));
+ },
+ // 从树形数据中根据 value 查找 label
+ findDeptLabel(tree, value) {
+ for (const node of tree) {
+ if (node.value === value) return node.label;
+ if (node.children?.length) {
+ const found = this.findDeptLabel(node.children, value);
+ if (found) return found;
+ }
+ }
+ return '';
+ },
loadCargoTypeOptions() {
getSystemDictionary({ code: 'type_of_goods' }).then(res => {
this.cargoTypeOptions = (res.data.data || []).map(item => ({
diff --git a/src/views/transit/track-tracking.vue b/src/views/transit/track-tracking.vue
index 0c88b84..ff65190 100644
--- a/src/views/transit/track-tracking.vue
+++ b/src/views/transit/track-tracking.vue
@@ -279,6 +279,7 @@ export default {
:deep(.track-tracking-page__search .el-form-item__label) {
min-width: 96px;
+ max-width: 96px;
font-size: 16px;
font-weight: 600;
}
diff --git a/src/views/transportCapacity/ship.vue b/src/views/transportCapacity/ship.vue
index 732b138..2606c71 100644
--- a/src/views/transportCapacity/ship.vue
+++ b/src/views/transportCapacity/ship.vue
@@ -143,7 +143,7 @@
>
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
-
-
+
-
+
+
+
-
+
-
-
-
+
@@ -279,24 +281,22 @@
船舶所有权证书
-
+
-
+
-
+
-
-
-
+
-
+
+
+
内河船舶安全与环保证书
-
+
-
+
-
+
-
-
-
+
From 58abe5ebdff2565580608ea0db2cc23a722f7544 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=B5=B5=E5=BF=A0=E6=9E=97?= <170083662@qq.com>
Date: Thu, 27 Aug 2026 17:34:22 +0800
Subject: [PATCH 3/3] =?UTF-8?q?feat(vehicle):=20=E5=B0=86=E5=AE=A2?=
=?UTF-8?q?=E5=95=86=E6=A1=A3=E6=A1=88=E6=90=9C=E7=B4=A2=E5=8C=BA=E6=89=80?=
=?UTF-8?q?=E5=B1=9E=E7=BB=84=E7=BB=87=E6=94=B9=E4=B8=BA=E6=A0=91=E5=BD=A2?=
=?UTF-8?q?=E4=B8=8B=E6=8B=89=E7=BB=84=E4=BB=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 搜索区所属组织从扁平 select 切换到多选树形下拉,保持后端字段不变
- 使用 Vue3 h 函数动态渲染 element-plus ElTreeSelect 组件,支持多选和折叠标签
- 修复 Vue 渲染字符串组件名导致控件无法显示的问题,改为直接导入组件对象
- 解决多选模型值写为字符串导致选中失效的状态管理问题,保持 modelValue 为 ID 数组
- 在搜索变更回调中将部门 ID 数组转换为部门名称逗号拼接
---
.workbuddy/memory/2026-08-27.md | 17 ++++++++++
src/styles/element-ui.scss | 7 ++++
src/views/vehicle/customer-archive.vue | 45 ++++++++++++++++++++------
3 files changed, 59 insertions(+), 10 deletions(-)
diff --git a/.workbuddy/memory/2026-08-27.md b/.workbuddy/memory/2026-08-27.md
index ee5c31c..facc5bd 100644
--- a/.workbuddy/memory/2026-08-27.md
+++ b/.workbuddy/memory/2026-08-27.md
@@ -29,6 +29,23 @@
- 风控:确认 Avue 的 `.avue-form__menu`/`.avue-dialog__footer` 自身不带按钮间距,去掉 gap 后由 EP 默认 12px margin 接管(不会贴死)。
- 范围说明:本次聚焦近几轮在统一的模块(vehicle/payment/business/settlement)。若要把 loading-manage、contract-manage、transit 等其它模块的底部栏也纳入,需再处理。
+## 客商档案搜索区「所属组织」从扁平下拉改为树形下拉
+- 起因:用户截图 `/vehicle/customer-archive` 搜索区,指出「所属组织」是扁平下拉,要求统一按新增/编辑表单(多选 `el-tree-select`)实现。
+- 原 column 配置:`prop: 'deptName'` + `search: true` + `searchType: 'select'` + `dicData: [{label:'全部',value:''}, ...flattenDept]`,initDeptTree() 异步把 dicData 写回 column(数据已加载,只是渲染风格不一致)。
+- 改动:
+ - column 移除 `searchType: 'select'`、`searchValue: ''`、`dicData`,仅保留 `search: true, searchOrder: 1`。
+ - `initDeptTree()` 中改写 `deptColumn.renderSearch = scope => this.renderDeptSearch(scope)`。
+ - 新增 `methods.renderDeptSearch(scope)`:通过 `vue` 的 `h` 函数返回一个 `el-tree-select` vnode(多选 + check-strictly + 树形 + 折叠 tag + 全宽),onUpdate 时把 ID 数组按 `deptOptions` 查 rawLabel,逗号拼接写入 `scope.row.deptName`(即 searchForm.deptName),保持后端接口字段不变。
+ - `searchChange/searchReset` 链路无需改:`onLoad` 已通过 `query` 透传 deptName 到后端。
+ - `src/styles/element-ui.scss` 新增 `.avue-crud__search .el-form-item__content > .el-tree-select { width:100%; max-width:100%; }`:搜索区树形下拉全宽兜底,不影响新增/编辑表单(用 `el-col :span=6` 栅格自然分开)。
+- 方案说明:Avue-crud 搜索 form-temp 内部 render 函数支持 column.renderSearch 自定义渲染(`header-search2.mjs` 行 93 `render: ele.renderSearch`),不需要重写整个搜索区;自定义 slot `` 在 el-input 等自闭合组件上无法落地(slot 名不会被 el-input 识别),所以走 renderSearch。
+- 选择项:用户确认「仅替换所属组织一格」「多选」「传 deptName」三项。
+- 排查「出不来了」反馈:主人实测搜索区只有 label,控件区域空白。原因 `h('el-tree-select', {...})` 传字符串时 Vue 3 `_createVNode` 直接把 type 当 ELEMENT(shapeFlag=1)处理,**不会调用 resolveComponent**,结果浏览器渲染出未知标签 ``,内容为空。
+- 修复:从 `element-plus` import `ElTreeSelect` 组件对象,`h(ElTreeSelect, {...})` 走组件 vnode 路径;同时把 `modelValue` 默认值改为 `[]`(多选模式数组要求,避免 el-tree-select 警告)。
+- 教训:Avue `column.render`/`renderSearch` 等接受 vnode 的字段,传字符串组件名时 Vue 不会 resolve,必须直接 import 组件对象或在 setup 内 `resolveComponent()`。
+- 排查「选中不了」反馈:控件显示出来了,但点击树节点无法选中/再选。根因 `onUpdate:modelValue` 里把 `scope.row.deptName` 写成了名字**字符串**,而该字段正是 el-tree-select 的 `modelValue`(多选模式必须是**ID 数组**),第一次选中后 modelValue 变字符串,el-tree-select 内部状态错乱,后续点击无法更新。
+- 修复:renderDeptSearch 的 `onUpdate:modelValue` 只把 `scope.row.deptName` 写成 ID 数组(保留数组形态);在 `searchChange(params, done)` 里把 Avue 拷贝出来的 `params.deptName` 数组(注意:`filterParams` 走 `deepClone`,params 与 scope.row 是不同引用,改它不破坏搜索框显示)按 `deptOptions` 查 rawLabel 再 `join(',')` 转成名字字符串写入 `query`,后端字段 deptName 不变。重置由 Avue `resetForm` 清空 scope.row.deptName 为 `''`,renderDeptSearch 读到非数组回退 `[]` 显示空,无需额外处理。
+
## 船舶表单「安放龙骨日期/建造完工日期」label 收窄并换行
- 起因:用户截图 `transportCapacity/ship` 新增船舶弹窗,指出该字段 label 宽达 185px,要求最大 88px 并允许换行。
- 改动:`src/views/transportCapacity/ship.vue` 第 169 行,给该 `el-form-item` 增加 `label-width="88px"` 覆盖全局 `label-width="100"`;全局 `.ship-form :deep(.el-form-item__label)` 已设置 `white-space: normal; line-height: 20px`,换行已支持。
diff --git a/src/styles/element-ui.scss b/src/styles/element-ui.scss
index 8b1d793..24de5bd 100644
--- a/src/styles/element-ui.scss
+++ b/src/styles/element-ui.scss
@@ -135,6 +135,13 @@
//white-space: nowrap;
}
+// 全宽兜底:搜索表单内树形下拉占满(覆盖默认搜索项宽度)
+// 注意:搜索 form 内的 el-tree-select 也走该规则;新增/编辑表单用 span=6 的栅格自然分开,不受影响。
+.avue-crud__search .el-form-item__content > .el-tree-select {
+ width: 100%;
+ max-width: 100%;
+}
+
.avue-crud__search.el-card {
border: none;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
diff --git a/src/views/vehicle/customer-archive.vue b/src/views/vehicle/customer-archive.vue
index 8bf015f..015eb94 100644
--- a/src/views/vehicle/customer-archive.vue
+++ b/src/views/vehicle/customer-archive.vue
@@ -1361,6 +1361,8 @@