Merge remote-tracking branch 'websoft/master'

This commit is contained in:
2026-09-02 15:11:34 +08:00
11 changed files with 344 additions and 240 deletions
+52
View File
@@ -0,0 +1,52 @@
# 2026-09-02 工作日志
## 合同/运力页「到期快捷筛选」标签统一改为独立一行
- 需求:把 avue-crud 搜索栏 `#search-menu` 里的 `<el-check-tag>` 到期快捷筛选组,移出搜索栏、单独成一行(搜索卡下方、表格上方),不加卡片包裹。
- 实现:改用 avue-crud 的 `#header` 插槽承载该组;CSS 由 `order:-1; margin-right:12px; min-width:0`(搜索按钮行内联)改为 `margin-bottom:12px`(独立行)。
- 涉及文件(4 处,均已改):
- `src/views/business/contract-manage.vue`(首改,用 `.contract-manage-page__expiry-search`
- `src/views/transportCapacity/vehicle.vue``.transport-vehicle-page__expiry-tags`
- `src/views/transportCapacity/driver.vue``.driver-page__expiry-tags`
- `src/views/transportCapacity/ship.vue``.transport-ship-page__expiry-tags`
- 各页变量名保留原样(contract-manage 用 contractExpiryScope/changeExpiryScope/contractExpiryStats;运力页用 query.expireStatus/handleExpireChange/expiryStat)。
- 已补改并修正:`payment/bill-ledger` 页。用户要求"放在卡片下面"(搜索白卡之外、表格之上独立一行),非卡片内分行。最终方案:把到期快捷筛选整组(标签 DOM + `shortcutOptions` 计算属性 + `handleShortcutChange`)从子组件 `bill-ledger-search.vue` 提升到页面 `bill-ledger.vue`,置于 `<bill-ledger-search>``<bill-ledger-table>` 之间(卡片下、表格上)。
- `bill-ledger-search.vue`:删除标签 DOM、`.bill-ledger-search__actions`/`.bill-ledger-search__actions-tags` CSS、`counts` prop、`shortcutOptions`/`handleShortcutChange`;按钮行 `.bill-ledger-search__actions-buttons` 恢复单行右对齐(`margin-bottom:8px`)。
- `bill-ledger.vue`:模板插入 `<div class="bill-ledger-page__expiry-tags">`(绑定 `query.expiryShortcut`@change`handleShortcutChange``handleSearch`);脚本加 `shortcutOptions` computed(用 `counts`+ `handleShortcutChange` method;新增 `<style scoped>` 写入 `.bill-ledger-page__expiry-tags`flex 行、`margin:8px 0`)。`emptyQuery()` 已含 `expiryShortcut:'all'`,无回归。
- 选中态样式统一:去掉 `.bill-ledger-page__expiry-tags :deep(.el-check-tag.is-checked)``background-color:#409eff` + `color:#fff` 蓝底白字覆盖,改用 Element Plus 默认浅蓝底深蓝字,与合同页一致。
## transportCapacity/ship 新增弹窗 input 宽度统一
- 问题:新增/修改弹窗内输入控件宽度不一致(文本框明显窄于下拉框、日期框)。
- 根因:`src/views/transportCapacity/ship.vue` 末尾 scoped 样式中独有 `.el-input__wrapper{width:150px !important}`,把文本框包裹层强制压成 150px,而 `el-select`(用 `.el-select__wrapper`)、日期/数字框不受影响 → 文本框与下拉框宽度不齐。同模块的 driver.vue / vehicle.vue 均无此规则。
- 修复:
1. 删除 `.el-input__wrapper{width:150px!important}` 异常规则。
2. 增强 `.ship-form` 内输入控件的 100% 宽度覆盖,补齐 `.el-select__wrapper` / `.el-cascader` / `.el-input__wrapper`,使文本框/下拉/日期/数字框均 100% 填满所在栅格列。
- 说明:弹窗仍保留不同栅格列宽(span6/8/12/16)的密集布局,同行字段已等宽;若需跨行全部 input 绝对像素等宽(统一栅格列宽),需进一步重排。
- 二次排查(用户反馈仍不一致):把 `.ship-form` 内控件 100% 覆盖从通用 `:deep(.el-input)` 改为更具体的 `:deep(.el-form-item__content > .el-input)` 并加 `!important`,同步覆盖 `.el-input__wrapper`/`.el-select__wrapper`,确保不会被 Element Plus 变量或更具体选择器压回默认/较窄宽度。请用户刷新浏览器验证。
- 三次修复(用户反馈第一行 span=6+6+12 三个字段宽度仍不齐):放弃「width: 100% 撑满 col」方案,改用「对齐 vehicle/customer-archive 的 `.archive-form` 风格」——label 固定 `calc(6em + 24px)` + 控件统一 `250px + max-width: 100%`。根因:`el-cascader` 默认 `display: inline-block`,即使 width: 100% 也不易撑满 col-content(与 input 视觉差 ~150px vs ~280px);span=6+6+12 下两列 form-item__content 实际不等宽(label-width=100 被长 label 撑开)。新方案固定 250px 后三字段视觉一致,参照客商档案。
- 同时清理模板中冗余 `label-width="88px"`(会被新 CSS 强制覆盖失效)。
## transportCapacity/ship 证书信息分组:附件下放到对应分组末尾 + label 缩短
- 需求:1. 「船舶国籍证书」「内河船舶最低安全配员证书」分组里 label 「证书有效期自」偏长,改短为「有效期自」(与下面统一)。2. 底部集中的 `.cert-upload-grid` 上传区调整到各证书分组末尾,让附件与字段同组。
- 修改:
- `src/views/transportCapacity/ship.vue` 模板 line 392/4312 处 `label="证书有效期自"``label="有效期自"`
- 模板结构重组:删除底部 `<el-row class="cert-upload-grid">...</el-row>`(原 line 472-548),把 6 个 `<image-upload-field>` 分别插入对应 `cert-block` 末尾(每个用 `class="ship-upload-item"`,独立 `<el-row :gutter="18"><el-col :span="8">`):
- 船舶所有权证书分组 → `ownershipCertImage`
- 内河船舶安全与环保证书分组 → `safetyCertImage`
- 船舶国籍证书分组 → `nationalityCertImage`
- 内河船舶最低安全配员证书分组 → `safeManningCertImage`
- 光船租赁登记证明书分组 → `leaseContractImage`label="光船租赁登记证书"
- 船舶营业运输证书分组 → `businessTransportCertImage`label="船舶营业运输证"
- 样式清理:删除无用的 `.cert-upload-grid { padding-top:8px }` / `.cert-upload-spacer { height:1px }`;保留 `.cert-block` / `.cert-block__title` / `.ship-upload-item``margin-bottom:14px`)。
- 验证:用户刷新浏览器看新布局。
## transportCapacity/ship 组合控件宽度对齐 250px 体系
- 问题:基础船舶信息里「安放龙骨日期/建造完工日期」的起止两个 date-picker、「航区」的 select 都是 `flex:1` 撑满所在 span=12 整列(约 498px),明显比单字段 250px 宽,视觉不协调。
- 修复(`src/views/transportCapacity/ship.vue` 末尾 scoped 样式):
- `.date-range-inline :deep(.el-date-editor)``flex:1; min-width:0` 增加 `max-width: 250px` → 两个 date-picker 在窗够宽时各对齐 250px、彼此等宽,窄窗时 flex:1 收缩不溢出。
- `.navigation-area-field :deep(.el-select)``flex:1; min-width:0` 增加 `max-width: 250px` → 航区 select 对齐 250px 单字段。
- 说明:`flex:1` 保底防溢出,`max-width:250px` 把组合控件拉回与单字段一致的 250px 体系(受所在列宽限制,安放龙骨 span=12 在常规窗宽下两个 date-picker 约 226px 等宽,更宽窗自动到 250px)。
## business/project-apply.vue 表单「业务部门/承办部门」级联选择器宽度统一
- 问题:项目新增/编辑表单(含独立表单页 `/business/project-apply/form`)中,业务部门、承办部门两个 `el-cascader` 的按钮宽度与同行的 select/input 不一致。
- 根因:scoped 样式里强制 100% 宽度的控件列表(`el-input` / `el-select` / `el-tree-select` / `el-date-editor`)漏了 `el-cascader`,导致级联选择器按内容宽度收缩,未填满栅格列。
- 修复:`src/views/business/project-apply.vue` 末尾 scoped 样式 `.project-apply-form` 的 100% 宽度规则补上 `:deep(.el-cascader)`。Vite HMR 已自动生效,无需重启 dev。
@@ -179,6 +179,9 @@ export default {
}, },
}; };
}, },
created() {
this.onLoad();
},
computed: { computed: {
...mapGetters(['permission', 'userInfo']), ...mapGetters(['permission', 'userInfo']),
isAdmin() { isAdmin() {
+52 -31
View File
@@ -11,37 +11,44 @@
</el-col> </el-col>
<el-col class="region-page__form-panel" :span="18"> <el-col class="region-page__form-panel" :span="18">
<basic-container> <basic-container>
<el-form class="region-page__search" :model="searchForm" inline> <section-card>
<el-form-item label="区域编码"> <el-form class="region-page__search" :model="searchForm" inline>
<el-input v-model="searchForm.code" clearable placeholder="请输入区域编码" /> <div style="display: flex; justify-content: space-between">
</el-form-item> <el-form-item label="区域编码">
<el-form-item label="区域名称"> <el-input v-model="searchForm.code" clearable placeholder="请输入区域编码" />
<el-input v-model="searchForm.name" clearable placeholder="请输入区域名称" /> </el-form-item>
</el-form-item> <el-form-item label="区域名称">
<el-form-item label="区域层级"> <el-input v-model="searchForm.name" clearable placeholder="请输入区域名称" />
<el-select v-model="searchForm.regionLevel" clearable placeholder="请选择区域层级"> </el-form-item>
<el-option label="省份" :value="1" /> <el-form-item label="区域层级">
<el-option label="省市" :value="2" /> <el-select v-model="searchForm.regionLevel" clearable placeholder="请选择" style="width: 200px;">
<el-option label="区县" :value="3" /> <el-option label="省份" :value="1" />
</el-select> <el-option label="省市" :value="2" />
</el-form-item> <el-option label="区县" :value="3" />
<el-form-item label="数据来源"> </el-select>
<el-select v-model="searchForm.dataSource" clearable placeholder="请选择数据来源"> </el-form-item>
<el-option label="手动录入" value="手动录入" /> <el-form-item label="数据来源">
<el-option label="初始化导入" value="初始化导入" /> <el-select v-model="searchForm.dataSource" clearable placeholder="请选择" style="width: 200px;">
</el-select> <el-option label="手动录入" value="手动录入" />
</el-form-item> <el-option label="初始化导入" value="初始化导入" />
<el-form-item label="启停状态"> </el-select>
<el-select v-model="searchForm.status" clearable placeholder="请选择启停状态"> </el-form-item>
<el-option label="启用" :value="1" /> </div>
<el-option label="停用" :value="2" /> <div style="display: flex; flex-direction: row; align-items: center; justify-content: space-between;">
</el-select> <el-form-item label="启停状态">
</el-form-item> <el-select v-model="searchForm.status" clearable placeholder="请选择" style="width: 200px;">
<el-form-item class="region-page__search-actions"> <el-option label="启用" :value="1" />
<el-button type="primary" @click="handleSearch">搜索</el-button> <el-option label="停用" :value="2" />
<el-button @click="handleSearchReset">清空</el-button> </el-select>
</el-form-item> </el-form-item>
</el-form> <el-form-item class="region-page__search-actions">
<el-button type="primary" @click="handleSearch">搜索</el-button>
<el-button @click="handleSearchReset">清空</el-button>
</el-form-item>
</div>
</el-form>
</section-card>
<el-button-group> <el-button-group>
<el-button <el-button
v-if="permission.region_add" v-if="permission.region_add"
@@ -157,10 +164,12 @@ import { openImportDialog } from '@/utils/import-excel';
import { getToken } from '@/utils/auth'; import { getToken } from '@/utils/auth';
import NProgress from 'nprogress'; import NProgress from 'nprogress';
import 'nprogress/nprogress.css'; import 'nprogress/nprogress.css';
import SectionCard from '@/components/section-card/main.vue';
const ROOT_PARENT_CODE = '0'; const ROOT_PARENT_CODE = '0';
export default { export default {
components: { SectionCard },
data() { data() {
return { return {
topCode: ROOT_PARENT_CODE, topCode: ROOT_PARENT_CODE,
@@ -750,4 +759,16 @@ export default {
max-width: 100%; max-width: 100%;
} }
} }
.el-form--inline .el-form-item{
margin-right: 10px !important;
}
.region-page__tree-panel .avue-tree__filter{
padding: 0 !important;
}
.el-button-group--horizontal{
margin-bottom: 12px !important;
}
.el-form-item{
margin-bottom: 8px !important;
}
</style> </style>
+5 -9
View File
@@ -32,7 +32,7 @@
</el-button> </el-button>
</template> </template>
<template #search-menu> <template #header>
<div class="contract-manage-page__expiry-search"> <div class="contract-manage-page__expiry-search">
<el-check-tag <el-check-tag
v-for="item in expiryTagOptions" v-for="item in expiryTagOptions"
@@ -98,6 +98,7 @@
<template v-else> <template v-else>
<div class="archive-page-form__title">{{ formPageTitle }}</div> <div class="archive-page-form__title">{{ formPageTitle }}</div>
<el-form <el-form
ref="contractForm" ref="contractForm"
:model="form" :model="form"
@@ -813,7 +814,7 @@ const defaultSettlementRule = () => ({
cycleDays: '', cycleDays: '',
}); });
const defaultForm = () => ({ const defaultForm = () => ({
contractCategory: '客户合同', contractCategory: '',
contractNo: '', contractNo: '',
contractName: '', contractName: '',
projectId: '', projectId: '',
@@ -2157,13 +2158,8 @@ export default {
align-items: center; align-items: center;
flex-wrap: wrap; flex-wrap: wrap;
gap: 8px; gap: 8px;
margin-right: 8px; margin-top: 8px;
} margin-bottom: 16px;
// 将 #search-menu slot 容器(即"时间段快捷筛选"排到查询 / 重置 / 收起之前
// .avue-form__menu 本身就是 flex + flex-end,整组内容自然靠右,无需额外推挤
:deep(.avue-crud__search .avue-form__menu > .contract-manage-page__expiry-search) {
order: -1;
} }
&__footer { &__footer {
+21 -10
View File
@@ -253,7 +253,7 @@
</el-form-item> </el-form-item>
<el-form-item prop="fundLimit" class="project-apply-form__tip-label"> <el-form-item prop="fundLimit" class="project-apply-form__tip-label">
<template #label> <template #label>
<span>项目资金使用额度(万元)</span> <span>项目资金使用额度</span>
<el-tooltip content="实际业务回款周期内付款" placement="top"> <el-tooltip content="实际业务回款周期内付款" placement="top">
<el-icon class="project-apply-form__label-tip"><QuestionFilled /></el-icon> <el-icon class="project-apply-form__label-tip"><QuestionFilled /></el-icon>
</el-tooltip> </el-tooltip>
@@ -263,11 +263,13 @@
placeholder="请输入" placeholder="请输入"
@input="value => handleNumberInput('fundLimit', value)" @input="value => handleNumberInput('fundLimit', value)"
@blur="formatAmountField('fundLimit')" @blur="formatAmountField('fundLimit')"
/> >
<template #suffix>万元</template>
</el-input>
</el-form-item> </el-form-item>
<el-form-item prop="receivableLimit" class="project-apply-form__tip-label"> <el-form-item prop="receivableLimit" class="project-apply-form__tip-label">
<template #label> <template #label>
<span>项目应收账款额度(万元)</span> <span>项目应收账款额度</span>
<el-tooltip content="回款期内最大应收账款额" placement="top"> <el-tooltip content="回款期内最大应收账款额" placement="top">
<el-icon class="project-apply-form__label-tip"><QuestionFilled /></el-icon> <el-icon class="project-apply-form__label-tip"><QuestionFilled /></el-icon>
</el-tooltip> </el-tooltip>
@@ -277,7 +279,9 @@
placeholder="请输入" placeholder="请输入"
@input="value => handleNumberInput('receivableLimit', value)" @input="value => handleNumberInput('receivableLimit', value)"
@blur="formatAmountField('receivableLimit')" @blur="formatAmountField('receivableLimit')"
/> >
<template #suffix>万元</template>
</el-input>
</el-form-item> </el-form-item>
<el-form-item label="应收账款回款期限" prop="receivableDays"> <el-form-item label="应收账款回款期限" prop="receivableDays">
<el-input <el-input
@@ -346,11 +350,13 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="项目规模万元" prop="projectScale"> <el-form-item label="项目规模" prop="projectScale">
<el-input <el-input
v-model="form.projectScale" v-model="form.projectScale"
@input="value => handleNumberInput('projectScale', value)" @input="value => handleNumberInput('projectScale', value)"
/> >
<template #suffix>万元</template>
</el-input>
</el-form-item> </el-form-item>
<el-form-item label="结算方式" prop="settlementMode"> <el-form-item label="结算方式" prop="settlementMode">
<el-select v-model="form.settlementMode" placeholder="请选择结算方式" clearable> <el-select v-model="form.settlementMode" placeholder="请选择结算方式" clearable>
@@ -362,17 +368,21 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="预估利润万元" prop="estimatedProfit"> <el-form-item label="预估利润" prop="estimatedProfit">
<el-input <el-input
v-model="form.estimatedProfit" v-model="form.estimatedProfit"
@input="value => handleNumberInput('estimatedProfit', value)" @input="value => handleNumberInput('estimatedProfit', value)"
/> >
<template #suffix>万元</template>
</el-input>
</el-form-item> </el-form-item>
<el-form-item label="资金需求万元" prop="fundDemand"> <el-form-item label="资金需求" prop="fundDemand">
<el-input <el-input
v-model="form.fundDemand" v-model="form.fundDemand"
@input="value => handleNumberInput('fundDemand', value)" @input="value => handleNumberInput('fundDemand', value)"
/> >
<template #suffix>万元</template>
</el-input>
</el-form-item> </el-form-item>
<el-form-item label="项目经办人" prop="handlerUserId"> <el-form-item label="项目经办人" prop="handlerUserId">
<el-input <el-input
@@ -2224,6 +2234,7 @@ export default {
:deep(.el-input), :deep(.el-input),
:deep(.el-select), :deep(.el-select),
:deep(.el-tree-select), :deep(.el-tree-select),
:deep(.el-cascader),
:deep(.el-date-editor) { :deep(.el-date-editor) {
width: 100%; width: 100%;
} }
+40 -1
View File
@@ -2,11 +2,20 @@
<basic-container class="bill-ledger-page"> <basic-container class="bill-ledger-page">
<bill-ledger-search <bill-ledger-search
:query="query" :query="query"
:counts="counts"
:loading="loading" :loading="loading"
@search="handleSearch" @search="handleSearch"
@reset="resetSearch" @reset="resetSearch"
/> />
<div class="bill-ledger-page__expiry-tags">
<el-check-tag
v-for="item in shortcutOptions"
:key="item.value"
:checked="query.expiryShortcut === item.value"
@change="handleShortcutChange(item.value)"
>
{{ item.label }}
</el-check-tag>
</div>
<bill-ledger-table <bill-ledger-table
:rows="rows" :rows="rows"
:loading="loading" :loading="loading"
@@ -124,7 +133,21 @@ export default {
mounted() { mounted() {
this.loadData(); this.loadData();
}, },
computed: {
shortcutOptions() {
return [
{ label: `全部(${this.counts.all || 0}`, value: 'all' },
{ label: `30天内到期(${this.counts.within30 || 0}`, value: 'within30' },
{ label: `90天内到期(${this.counts.within90 || 0}`, value: 'within90' },
{ label: `90天以上(${this.counts.over90 || 0}`, value: 'over90' },
];
},
},
methods: { methods: {
handleShortcutChange(value) {
this.query.expiryShortcut = value;
this.handleSearch();
},
unwrapData(response) { unwrapData(response) {
const body = response?.data || response || {}; const body = response?.data || response || {};
return body?.data || body; return body?.data || body;
@@ -233,3 +256,19 @@ export default {
}, },
}; };
</script> </script>
<style scoped lang="scss">
.bill-ledger-page__expiry-tags {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 8px;
margin-top: 16px;
margin-bottom: 6px;
:deep(.el-check-tag) {
margin: 0;
white-space: nowrap;
}
}
</style>
@@ -43,33 +43,21 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
</div> </div>
<div class="bill-ledger-search__actions"> <div class="bill-ledger-search__actions-buttons">
<div class="bill-ledger-search__actions-tags"> <el-button type="primary" :loading="loading" @click="$emit('search')">
<el-check-tag <el-icon><Search /></el-icon>
v-for="item in shortcutOptions" <span>搜索</span>
:key="item.value" </el-button>
:checked="query.expiryShortcut === item.value" <el-button @click="$emit('reset')">
@change="handleShortcutChange(item.value)" <el-icon><Delete /></el-icon>
> <span>重置</span>
{{ item.label }} </el-button>
</el-check-tag> <el-tooltip :content="expanded ? '折叠' : '展开'" placement="top">
</div> <el-button text @click="expanded = !expanded">
<div class="bill-ledger-search__actions-buttons"> <el-icon><component :is="expanded ? ArrowUp : ArrowDown" /></el-icon>
<el-button type="primary" :loading="loading" @click="$emit('search')"> <span>{{ expanded ? '折叠' : '展开' }}</span>
<el-icon><Search /></el-icon>
<span>搜索</span>
</el-button> </el-button>
<el-button @click="$emit('reset')"> </el-tooltip>
<el-icon><Delete /></el-icon>
<span>重置</span>
</el-button>
<el-tooltip :content="expanded ? '折叠' : '展开'" placement="top">
<el-button text @click="expanded = !expanded">
<el-icon><component :is="expanded ? ArrowUp : ArrowDown" /></el-icon>
<span>{{ expanded ? '折叠' : '展开' }}</span>
</el-button>
</el-tooltip>
</div>
</div> </div>
</el-form> </el-form>
</section> </section>
@@ -83,7 +71,6 @@ export default {
name: 'BillLedgerSearch', name: 'BillLedgerSearch',
props: { props: {
query: { type: Object, required: true }, query: { type: Object, required: true },
counts: { type: Object, default: () => ({}) },
loading: { type: Boolean, default: false }, loading: { type: Boolean, default: false },
}, },
emits: ['search', 'reset'], emits: ['search', 'reset'],
@@ -98,22 +85,6 @@ export default {
maturityStatusOptions, maturityStatusOptions,
}; };
}, },
computed: {
shortcutOptions() {
return [
{ label: `全部(${this.counts.all || 0}`, value: 'all' },
{ label: `30天内到期(${this.counts.within30 || 0}`, value: 'within30' },
{ label: `90天内到期(${this.counts.within90 || 0}`, value: 'within90' },
{ label: `90天以上(${this.counts.over90 || 0}`, value: 'over90' },
];
},
},
methods: {
handleShortcutChange(value) {
this.query.expiryShortcut = value;
this.$emit('search');
},
},
}; };
</script> </script>
@@ -136,34 +107,13 @@ export default {
.bill-ledger-search :deep(.el-date-editor) { .bill-ledger-search :deep(.el-date-editor) {
width: 100%; width: 100%;
} }
.bill-ledger-search__actions { .bill-ledger-search__actions-buttons {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: flex-end; justify-content: flex-end;
gap: 8px; gap: 8px;
margin-bottom: 8px; margin-bottom: 8px;
} }
.bill-ledger-search__actions-buttons {
display: flex;
align-items: center;
gap: 8px;
}
.bill-ledger-search__actions-tags {
display: flex;
align-items: center;
justify-content: flex-end;
flex-wrap: wrap;
gap: 8px;
}
.bill-ledger-search__actions-tags :deep(.el-check-tag) {
margin: 0;
white-space: nowrap;
}
.bill-ledger-search__actions-tags :deep(.el-check-tag.is-checked),
.bill-ledger-search__actions-tags :deep(.el-check-tag.is-checked:hover) {
background-color: #409eff;
color: #fff;
}
@media (max-width: 1200px) { @media (max-width: 1200px) {
.bill-ledger-search__grid { .bill-ledger-search__grid {
grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-columns: repeat(2, minmax(0, 1fr));
+3 -4
View File
@@ -41,7 +41,7 @@
>批量删除 >批量删除
</el-button> </el-button>
</template> </template>
<template #search-menu> <template #header>
<div class="driver-page__expiry-tags"> <div class="driver-page__expiry-tags">
<el-check-tag <el-check-tag
v-for="item in expiryTagOptions" v-for="item in expiryTagOptions"
@@ -1724,9 +1724,8 @@ export default {
flex-wrap: wrap; flex-wrap: wrap;
align-items: center; align-items: center;
gap: 8px; gap: 8px;
order: -1; margin-top: 8px;
margin-right: 12px; margin-bottom: 16px;
min-width: 0;
:deep(.el-check-tag) { :deep(.el-check-tag) {
margin: 0; margin: 0;
+137 -107
View File
@@ -44,7 +44,7 @@
批量删除 批量删除
</el-button> </el-button>
</template> </template>
<template #search-menu> <template #header>
<div class="transport-ship-page__expiry-tags"> <div class="transport-ship-page__expiry-tags">
<el-check-tag <el-check-tag
v-for="item in expiryTagOptions" v-for="item in expiryTagOptions"
@@ -161,11 +161,7 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item <el-form-item label="安放龙骨日期/建造完工日期" prop="keelLayingDate">
label="安放龙骨日期/建造完工日期"
prop="keelLayingDate"
label-width="88px"
>
<div class="date-range-inline"> <div class="date-range-inline">
<el-date-picker <el-date-picker
v-model="shipForm.keelLayingDate" v-model="shipForm.keelLayingDate"
@@ -316,6 +312,21 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row :gutter="18">
<el-col :span="8">
<image-upload-field
label="船舶所有权证书"
prop="ownershipCertImage"
:value="shipForm.ownershipCertImage"
:readonly="readonly"
:headers="uploadHeaders"
large
class-prefix="ship"
class="ship-upload-item"
@success="url => handleShipCertificateUploadSuccess('ownershipCertImage', url)"
/>
</el-col>
</el-row>
</div> </div>
<div class="cert-block"> <div class="cert-block">
@@ -357,13 +368,28 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row :gutter="18">
<el-col :span="8">
<image-upload-field
label="内河船舶安全与环保证书"
prop="safetyCertImage"
:value="shipForm.safetyCertImage"
:readonly="readonly"
:headers="uploadHeaders"
large
class-prefix="ship"
class="ship-upload-item"
@success="url => handleShipCertificateUploadSuccess('safetyCertImage', url)"
/>
</el-col>
</el-row>
</div> </div>
<div class="cert-block"> <div class="cert-block">
<div class="cert-block__title">船舶国籍证书</div> <div class="cert-block__title">船舶国籍证书</div>
<el-row :gutter="18"> <el-row :gutter="18">
<el-col :span="16"> <el-col :span="16">
<el-form-item label="证书有效期自" prop="nationalityCertStartDate"> <el-form-item label="有效期自" prop="nationalityCertStartDate">
<div class="date-range-inline"> <div class="date-range-inline">
<el-date-picker <el-date-picker
v-model="shipForm.nationalityCertStartDate" v-model="shipForm.nationalityCertStartDate"
@@ -381,13 +407,28 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row :gutter="18">
<el-col :span="8">
<image-upload-field
label="船舶国籍证书"
prop="nationalityCertImage"
:value="shipForm.nationalityCertImage"
:readonly="readonly"
:headers="uploadHeaders"
large
class-prefix="ship"
class="ship-upload-item"
@success="url => handleShipCertificateUploadSuccess('nationalityCertImage', url)"
/>
</el-col>
</el-row>
</div> </div>
<div class="cert-block"> <div class="cert-block">
<div class="cert-block__title">内河船舶最低安全配员证书</div> <div class="cert-block__title">内河船舶最低安全配员证书</div>
<el-row :gutter="18"> <el-row :gutter="18">
<el-col :span="16"> <el-col :span="16">
<el-form-item label="证书有效期自" prop="safeManningCertStartDate"> <el-form-item label="有效期自" prop="safeManningCertStartDate">
<div class="date-range-inline"> <div class="date-range-inline">
<el-date-picker <el-date-picker
v-model="shipForm.safeManningCertStartDate" v-model="shipForm.safeManningCertStartDate"
@@ -405,6 +446,21 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row :gutter="18">
<el-col :span="8">
<image-upload-field
label="内河船舶最低安全配员证书"
prop="safeManningCertImage"
:value="shipForm.safeManningCertImage"
:readonly="readonly"
:headers="uploadHeaders"
large
class-prefix="ship"
class="ship-upload-item"
@success="url => handleShipCertificateUploadSuccess('safeManningCertImage', url)"
/>
</el-col>
</el-row>
</div> </div>
<div class="cert-block"> <div class="cert-block">
@@ -435,6 +491,21 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row :gutter="18">
<el-col :span="8">
<image-upload-field
label="光船租赁登记证书"
prop="leaseContractImage"
:value="shipForm.leaseContractImage"
:readonly="readonly"
:headers="uploadHeaders"
large
class-prefix="ship"
class="ship-upload-item"
@success="url => handleShipCertificateUploadSuccess('leaseContractImage', url)"
/>
</el-col>
</el-row>
</div> </div>
<div class="cert-block"> <div class="cert-block">
@@ -471,85 +542,22 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row :gutter="18">
<el-col :span="8">
<image-upload-field
label="船舶营业运输证"
prop="businessTransportCertImage"
:value="shipForm.businessTransportCertImage"
:readonly="readonly"
:headers="uploadHeaders"
large
class-prefix="ship"
class="ship-upload-item"
@success="url => handleShipCertificateUploadSuccess('businessTransportCertImage', url)"
/>
</el-col>
</el-row>
</div> </div>
<el-row class="cert-upload-grid" :gutter="18">
<el-col :span="8">
<image-upload-field
label="船舶所有权证书"
prop="ownershipCertImage"
:value="shipForm.ownershipCertImage"
:readonly="readonly"
:headers="uploadHeaders"
large
class-prefix="ship"
@success="url => handleShipCertificateUploadSuccess('ownershipCertImage', url)"
/>
</el-col>
<el-col :span="8">
<image-upload-field
label="内河船舶安全与环保证书"
prop="safetyCertImage"
:value="shipForm.safetyCertImage"
:readonly="readonly"
:headers="uploadHeaders"
large
class-prefix="ship"
@success="url => handleShipCertificateUploadSuccess('safetyCertImage', url)"
/>
</el-col>
<el-col :span="8">
<image-upload-field
label="船舶国籍证书"
prop="nationalityCertImage"
:value="shipForm.nationalityCertImage"
:readonly="readonly"
:headers="uploadHeaders"
large
class-prefix="ship"
@success="url => handleShipCertificateUploadSuccess('nationalityCertImage', url)"
/>
</el-col>
<el-col :span="8">
<image-upload-field
label="内河船舶最低安全配员证书"
prop="safeManningCertImage"
:value="shipForm.safeManningCertImage"
:readonly="readonly"
:headers="uploadHeaders"
large
class-prefix="ship"
@success="url => handleShipCertificateUploadSuccess('safeManningCertImage', url)"
/>
</el-col>
<el-col :span="8">
<div class="cert-upload-spacer"></div>
</el-col>
<el-col :span="8">
<image-upload-field
label="光船租赁登记证书"
prop="leaseContractImage"
:value="shipForm.leaseContractImage"
:readonly="readonly"
:headers="uploadHeaders"
large
class-prefix="ship"
@success="url => handleShipCertificateUploadSuccess('leaseContractImage', url)"
/>
</el-col>
<el-col :span="8">
<image-upload-field
label="船舶营业运输证"
prop="businessTransportCertImage"
:value="shipForm.businessTransportCertImage"
:readonly="readonly"
:headers="uploadHeaders"
large
class-prefix="ship"
@success="url => handleShipCertificateUploadSuccess('businessTransportCertImage', url)"
/>
</el-col>
</el-row>
</section-card> </section-card>
</el-form> </el-form>
<template #footer> <template #footer>
@@ -1199,9 +1207,8 @@ export default {
flex-wrap: wrap; flex-wrap: wrap;
align-items: center; align-items: center;
gap: 8px; gap: 8px;
order: -1; margin-top: 8px;
margin-right: 12px; margin-bottom: 16px;
min-width: 0;
:deep(.el-check-tag) { :deep(.el-check-tag) {
margin: 0; margin: 0;
@@ -1216,18 +1223,47 @@ export default {
} }
.ship-form { .ship-form {
:deep(.el-date-editor.el-input), // 对齐 vehicle/customer-archive 的 .archive-form 风格:
:deep(.el-date-editor.el-input__wrapper), // label 固定 calc(6em + 24px) 容纳 6 汉字 + 长 label 自动折行;
:deep(.el-select), // 控件统一 250px + max-width: 100%,保证 cascader / input / select / date-picker 等混排时宽度一致。
:deep(.el-input), // 修复前:第一行 span=6+6+12 布局下 el-cascader (默认 inline-block) 与 el-input 实际宽度差很大,
:deep(.el-input-number) { // 加上 label-width="100" 在长 label 上被撑开,导致 3 个控件视觉宽度比不一致。
width: 100%;
:deep(.el-form-item__label) {
flex: 0 0 calc(6em + 24px) !important;
width: calc(6em + 24px) !important;
height: auto;
white-space: normal !important;
word-break: break-all;
overflow-wrap: anywhere;
line-height: 18px;
} }
// label 固定宽度:可容纳 6 个汉字,超出自动换行 // label 与控件垂直居中(避免长 label 折行时视觉错位)
:deep(.el-form-item__label) { :deep(.el-form-item) {
white-space: normal; align-items: center;
line-height: 20px; }
// 必填星号 * 与首行文字垂直居中(多行 label 时 :before 与文字行盒高度不一致的修复)
:deep(.el-form-item.is-required .el-form-item__label) {
align-items: flex-start;
}
:deep(.el-form-item.is-required .el-form-item__label::before) {
display: inline-block;
height: 18px;
line-height: 18px;
margin-right: 4px;
}
// 所有控件统一 250pxcol 宽不足时由 max-width: 100% 兜底收缩)
:deep(.el-form-item__content > .el-input),
:deep(.el-form-item__content > .el-input-number),
:deep(.el-form-item__content > .el-select),
:deep(.el-form-item__content > .el-cascader),
:deep(.el-form-item__content > .el-date-editor) {
width: 250px;
max-width: 100%;
} }
} }
@@ -1241,6 +1277,7 @@ export default {
.date-range-inline :deep(.el-date-editor) { .date-range-inline :deep(.el-date-editor) {
flex: 1; flex: 1;
min-width: 0; min-width: 0;
max-width: 250px;
} }
.navigation-area-field { .navigation-area-field {
@@ -1253,6 +1290,7 @@ export default {
.navigation-area-field :deep(.el-select) { .navigation-area-field :deep(.el-select) {
flex: 1; flex: 1;
min-width: 0; min-width: 0;
max-width: 250px;
} }
.navigation-info-icon { .navigation-info-icon {
@@ -1274,14 +1312,6 @@ export default {
line-height: 20px; line-height: 20px;
} }
.cert-upload-grid {
padding-top: 8px;
}
.cert-upload-spacer {
height: 1px;
}
.ship-upload-item { .ship-upload-item {
margin-bottom: 14px; margin-bottom: 14px;
} }
+3 -4
View File
@@ -41,7 +41,7 @@
>批量删除 >批量删除
</el-button> </el-button>
</template> </template>
<template #search-menu> <template #header>
<div class="transport-vehicle-page__expiry-tags"> <div class="transport-vehicle-page__expiry-tags">
<el-check-tag <el-check-tag
v-for="item in expiryTagOptions" v-for="item in expiryTagOptions"
@@ -1407,9 +1407,8 @@ export default {
flex-wrap: wrap; flex-wrap: wrap;
align-items: center; align-items: center;
gap: 8px; gap: 8px;
order: -1; margin-top: 8px;
margin-right: 12px; margin-bottom: 16px;
min-width: 0;
:deep(.el-check-tag) { :deep(.el-check-tag) {
margin: 0; margin: 0;
+13 -9
View File
@@ -297,8 +297,8 @@
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="6">
<el-form-item label="地址" prop="registeredDetailAddress" required> <el-form-item label="所在地区" prop="registeredDetailAddress" required>
<div class="archive-form__address"> <div class="archive-form__address">
<el-cascader <el-cascader
ref="registeredRegionCascader" ref="registeredRegionCascader"
@@ -310,14 +310,18 @@
filterable filterable
@change="handleRegisteredRegionChange" @change="handleRegisteredRegionChange"
/> />
<el-input
v-model="archiveForm.registeredDetailAddress"
maxlength="255"
placeholder="请输入详细地址"
/>
</div> </div>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="6">
<el-form-item label="详细地址" prop="registeredDetailAddress" required>
<el-input
v-model="archiveForm.registeredDetailAddress"
maxlength="255"
placeholder="请输入详细地址"
/>
</el-form-item>
</el-col>
</el-row> </el-row>
</section-card> </section-card>
@@ -4757,8 +4761,8 @@ export default {
.archive-form__address { .archive-form__address {
:deep(.el-cascader) { :deep(.el-cascader) {
flex: 0 0 250px; flex: 0 0 240px;
width: 250px; width: 240px;
min-width: 0; min-width: 0;
} }