style(transportCapacity): 优化船舶表单布局和标签样式

- 船舶表单“安放龙骨日期/建造完工日期”label宽度收窄至88px并支持换行
- 船舶证书信息两块表单调整为4列布局,字段span由8改为6
- contract-manage和track-tracking页签名标签最大宽度限制为96px,防止过宽
- project-apply业务部门选择组件改用el-tree-select支持树形选择,辅助函数新增
- 全局样式调整el-tree-select及el-cascader去除圆圈,改用箭头和文字高亮展示
- 控制节点展开箭头、选中状态和悬浮效果统一视觉风格
This commit is contained in:
2026-08-27 16:40:38 +08:00
parent 9342e674c5
commit fc70aeb2af
6 changed files with 165 additions and 40 deletions
+35 -12
View File
@@ -157,21 +157,19 @@
/>
</el-form-item>
<el-form-item label="业务部门" prop="businessDeptId">
<el-select
<el-tree-select
v-model="form.businessDeptId"
placeholder="请选择业务部门"
:data="businessDeptTreeOptions"
:props="{ label: 'label', value: 'value', children: 'children' }"
node-key="value"
check-strictly
filterable
clearable
:render-after-expand="false"
style="width: 100%"
:disabled="isBasicInfoReadonly"
@change="handleBusinessDeptChange"
>
<el-option
v-for="item in deptOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
/>
</el-form-item>
<el-form-item label="承办部门" prop="undertakeDeptId">
<el-cascader
@@ -990,6 +988,7 @@ export default {
},
deptOptions: [],
deptTreeOptions: [],
businessDeptTreeOptions: [],
deptCascaderProps: {
label: 'label',
value: 'value',
@@ -1765,8 +1764,9 @@ export default {
];
},
handleBusinessDeptChange(value) {
const dept = this.deptOptions.find(item => 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 => ({