style(contract): 优化合同管理页面表单样式与布局
- 调整合同管理备注输入框行数和最大长度 - 细化合同变更页面表单项间距和对齐方式 - 统一弹窗表单项的底部间距样式,改为注释禁用 - 调整 port-terminal 和 region 组件的表单项底部间距 - 修改 vite 配置中 API 请求代理地址 - 优化凭证执行详情搜索表单列宽布局 - 在运单管理页面更新型号字段为非必填,调整变更记录内容格式化显示 - 引入并使用 formatRouteChangeContent 工具函数 - 统一明细按钮显示逻辑,草稿状态也显示详情按钮 - 新增路由变更相关工具函数与样式支持
This commit is contained in:
@@ -2993,9 +2993,10 @@
|
||||
<el-table-column prop="changeUser" label="变更人" min-width="120" />
|
||||
<el-table-column prop="content" label="变更内容" min-width="360">
|
||||
<template #default="{ row }">
|
||||
<div class="business-crud-page__route-change-record-content">
|
||||
{{ row.content || '-' }}
|
||||
</div>
|
||||
<div
|
||||
class="business-crud-page__route-change-record-content"
|
||||
v-text="formatRouteChangeContent(row.content)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="remark" label="备注" min-width="200" show-overflow-tooltip />
|
||||
@@ -5282,6 +5283,7 @@ import { formatContractOptionLabel } from '@/utils/contract';
|
||||
import { openImportDialog } from '@/utils/import-excel';
|
||||
import { normalizeMapSearchResults, searchAmapPlaceText } from '@/utils/map-search';
|
||||
import { loadMeasurementUnitOptions } from '@/utils/measurement-unit';
|
||||
import { formatRouteChangeContent } from '@/utils/route-change';
|
||||
import { applyTableMenuWidth } from '@/utils/table-menu';
|
||||
import { downloadFileByUrl, downloadXls } from '@/utils/util';
|
||||
import { isMobile } from '@/utils/validate';
|
||||
@@ -6628,6 +6630,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
formatContractOptionLabel,
|
||||
formatRouteChangeContent,
|
||||
initStandaloneFormPage() {
|
||||
if (!this.isStandaloneFormPage) return;
|
||||
const mode = this.$route.query.mode === 'edit' ? 'edit' : 'add';
|
||||
@@ -15898,6 +15901,9 @@ export default {
|
||||
|
||||
&__route-change-record-content {
|
||||
white-space: pre-wrap;
|
||||
overflow-wrap: anywhere;
|
||||
word-break: break-word;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
</dd>
|
||||
</div>
|
||||
</dl>
|
||||
<div class="route-map"><template v-for="(route, index) in segments" :key="route.segmentNo"><div class="route-map__node"><span :class="['route-badge', index ? 'middle' : 'start']">{{ index ? '经' : '起' }}</span><strong>{{ segmentLocationName(route, 'departure') }}</strong><small>{{ route.departureAddress || '-' }}</small><small class="route-map__progress">{{ index ? `已到达 ${quantity(segments[index - 1].arrivedQuantity)}/${quantity(master.totalQuantity)} ${plannedUnit(segments[index - 1])}` : `已调度 ${quantity(route.dispatchedQuantity)}/${quantity(master.totalQuantity)} ${plannedUnit(route)}` }}</small><small v-if="index" class="route-map__progress">已调度 {{ quantity(route.dispatchedQuantity) }}/{{ quantity(master.totalQuantity) }} {{ plannedUnit(route) }}</small></div><div class="route-map__line"></div><div v-if="index === segments.length - 1" class="route-map__node"><span class="route-badge end">终</span><strong>{{ segmentLocationName(route, 'arrival') }}</strong><small>{{ route.arrivalAddress || '-' }}</small><small class="route-map__progress">已到达 {{ quantity(route.arrivedQuantity) }}/{{ quantity(master.totalQuantity) }} {{ plannedUnit(route) }}</small></div></template></div>
|
||||
<div class="route-map"><template v-for="(route, index) in segments" :key="route.segmentNo"><div class="route-map__node"><span :class="['route-badge', index ? 'middle' : 'start']">{{ index ? '经' : '起' }}</span><strong>{{ segmentLocationName(route, 'departure') }}</strong><small>{{ formatRegionAddress(route.departureAddress) || '-' }}</small><small class="route-map__progress">{{ index ? `已到达 ${quantity(segments[index - 1].arrivedQuantity)}/${quantity(master.totalQuantity)} ${plannedUnit(segments[index - 1])}` : `已调度 ${quantity(route.dispatchedQuantity)}/${quantity(master.totalQuantity)} ${plannedUnit(route)}` }}</small><small v-if="index" class="route-map__progress">已调度 {{ quantity(route.dispatchedQuantity) }}/{{ quantity(master.totalQuantity) }} {{ plannedUnit(route) }}</small></div><div class="route-map__line"></div><div v-if="index === segments.length - 1" class="route-map__node"><span class="route-badge end">终</span><strong>{{ segmentLocationName(route, 'arrival') }}</strong><small>{{ formatRegionAddress(route.arrivalAddress) || '-' }}</small><small class="route-map__progress">已到达 {{ quantity(route.arrivedQuantity) }}/{{ quantity(master.totalQuantity) }} {{ plannedUnit(route) }}</small></div></template></div>
|
||||
</section>
|
||||
|
||||
<el-dialog v-model="documentPreviewVisible" :title="previewFile.name || '附件预览'" append-to-body destroy-on-close width="90%" top="4vh">
|
||||
@@ -110,6 +110,7 @@ import { getList as getCustomerArchiveList } from '@/api/vehicle/customer-archiv
|
||||
import { CaretBottom, CaretTop } from '@element-plus/icons-vue';
|
||||
import { ElImageViewer } from 'element-plus';
|
||||
import { OpenFileViewer } from '@open-file-viewer/vue';
|
||||
import { formatRegionAddress } from '@/utils/region-address';
|
||||
import { fallbackPlugin, imagePlugin, officePlugin, pdfPlugin, textPlugin } from '@open-file-viewer/core';
|
||||
import '@open-file-viewer/core/style.css';
|
||||
import pdfWorkerSrc from 'pdfjs-dist/build/pdf.worker.mjs?url';
|
||||
@@ -164,6 +165,7 @@ export default {
|
||||
} finally { this.loading = false; }
|
||||
},
|
||||
methods: {
|
||||
formatRegionAddress,
|
||||
quantity(value) { const number = Number(value || 0); return Number.isInteger(number) ? number : number.toFixed(3).replace(/\.?0+$/, ''); },
|
||||
segmentNumber(route, index) { return String(route.segmentNo || '').replace(/^段/, '') || index + 1; },
|
||||
isSegmentExpanded(segmentNo) { return Boolean(this.expandedSegments[segmentNo]); },
|
||||
|
||||
@@ -21,10 +21,10 @@
|
||||
<div class="route-overview__node">
|
||||
<span :class="['route-badge', index === 0 ? 'start' : 'middle']">{{ index === 0 ? '起' : '经' }}</span>
|
||||
<el-tooltip :content="route.departureName || '-'" placement="top" :show-after="120">
|
||||
<strong>{{ route.departureName || '-' }}</strong>
|
||||
<strong>{{ dispatchLocationName(route, 'departure') }}</strong>
|
||||
</el-tooltip>
|
||||
<el-tooltip :content="route.departureAddress || '-'" placement="top" :show-after="120">
|
||||
<small>{{ route.departureAddress || '-' }}</small>
|
||||
<small>{{ formatRegionAddress(route.departureAddress) || '-' }}</small>
|
||||
</el-tooltip>
|
||||
<el-tooltip :content="contactText(route.departureContact, route.departurePhone)" placement="top" :show-after="120">
|
||||
<small>{{ contactText(route.departureContact, route.departurePhone) }}</small>
|
||||
@@ -34,10 +34,10 @@
|
||||
<div v-if="index === routes.length - 1" class="route-overview__node">
|
||||
<span class="route-badge end">终</span>
|
||||
<el-tooltip :content="route.arrivalName || '-'" placement="top" :show-after="120">
|
||||
<strong>{{ route.arrivalName || '-' }}</strong>
|
||||
<strong>{{ dispatchLocationName(route, 'arrival') }}</strong>
|
||||
</el-tooltip>
|
||||
<el-tooltip :content="route.arrivalAddress || '-'" placement="top" :show-after="120">
|
||||
<small>{{ route.arrivalAddress || '-' }}</small>
|
||||
<small>{{ formatRegionAddress(route.arrivalAddress) || '-' }}</small>
|
||||
</el-tooltip>
|
||||
<el-tooltip :content="contactText(route.arrivalContact, route.arrivalPhone)" placement="top" :show-after="120">
|
||||
<small>{{ contactText(route.arrivalContact, route.arrivalPhone) }}</small>
|
||||
@@ -324,6 +324,7 @@ import {
|
||||
resolvePriceUnitByQuantityUnit,
|
||||
} from '@/utils/currency';
|
||||
import { loadMeasurementUnitOptions } from '@/utils/measurement-unit';
|
||||
import { formatRegionAddress } from '@/utils/region-address';
|
||||
import { isMobile } from '@/utils/validate';
|
||||
|
||||
const unwrapRecords = res => {
|
||||
@@ -851,7 +852,12 @@ export default {
|
||||
const mileage = Number(value);
|
||||
return Number.isFinite(mileage) && mileage >= 0 ? String(Math.trunc(mileage)) : '';
|
||||
},
|
||||
addressText(name, address) { return [name, address].filter(Boolean).join(' / ') || '-'; },
|
||||
formatRegionAddress,
|
||||
addressText(name, address) {
|
||||
// 名称与详细地址都要按「市 区县」展示;两者格式化后相同时只展示一次
|
||||
const values = [this.formatRegionAddress(name), this.formatRegionAddress(address)].filter(Boolean);
|
||||
return [...new Set(values)].join(' / ') || '-';
|
||||
},
|
||||
contactText(name, phone) { return [name, phone].filter(Boolean).join(' - ') || '-'; },
|
||||
dateStartLabel(route) { return route.documentType === '计划单' ? '计划开始日期' : '预计发货日期'; },
|
||||
dateEndLabel(route) { return route.documentType === '计划单' ? '计划结束日期' : '预计完成日期'; },
|
||||
|
||||
@@ -153,11 +153,24 @@
|
||||
@click="handleTransportSecondaryAddressInputClick('departure')"
|
||||
>
|
||||
<template #suffix>
|
||||
<el-icon @click.stop="openTransportMapDialog('departure')">
|
||||
<el-icon
|
||||
class="shipping-template-page__map-suffix"
|
||||
@click.stop="openTransportMapDialog('departure')"
|
||||
>
|
||||
<Location />
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
<el-tooltip content="选择常用地址" placement="top">
|
||||
<el-button
|
||||
class="shipping-template-page__address-pick-btn"
|
||||
type="primary"
|
||||
:icon="OfficeBuilding"
|
||||
link
|
||||
:disabled="transportAddressSelectDisabled"
|
||||
@click="openTransportAddressPicker('departure')"
|
||||
/>
|
||||
</el-tooltip>
|
||||
<span>联系人</span>
|
||||
<el-input
|
||||
v-model="form.departureContact"
|
||||
@@ -166,16 +179,6 @@
|
||||
/>
|
||||
<span>联系方式</span>
|
||||
<el-input v-model="form.departurePhone" placeholder="请输入" :disabled="dialogReadonly" />
|
||||
<el-tooltip content="选择常用地址" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
:disabled="transportAddressSelectDisabled"
|
||||
@click="openTransportAddressPicker('departure')"
|
||||
>
|
||||
选择
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -197,25 +200,28 @@
|
||||
@click="handleTransportSecondaryAddressInputClick('arrival')"
|
||||
>
|
||||
<template #suffix>
|
||||
<el-icon @click.stop="openTransportMapDialog('arrival')">
|
||||
<el-icon
|
||||
class="shipping-template-page__map-suffix"
|
||||
@click.stop="openTransportMapDialog('arrival')"
|
||||
>
|
||||
<Location />
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
<el-tooltip content="选择常用地址" placement="top">
|
||||
<el-button
|
||||
class="shipping-template-page__address-pick-btn"
|
||||
type="primary"
|
||||
:icon="OfficeBuilding"
|
||||
link
|
||||
:disabled="transportAddressSelectDisabled"
|
||||
@click="openTransportAddressPicker('arrival')"
|
||||
/>
|
||||
</el-tooltip>
|
||||
<span>联系人</span>
|
||||
<el-input v-model="form.arrivalContact" placeholder="请输入" :disabled="dialogReadonly" />
|
||||
<span>联系方式</span>
|
||||
<el-input v-model="form.arrivalPhone" placeholder="请输入" :disabled="dialogReadonly" />
|
||||
<el-tooltip content="选择常用地址" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
:disabled="transportAddressSelectDisabled"
|
||||
@click="openTransportAddressPicker('arrival')"
|
||||
>
|
||||
选择
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1122,7 +1128,7 @@ import { loadMeasurementUnitOptions } from '@/utils/measurement-unit';
|
||||
import { normalizeMapSearchResults, searchAmapPlaceText } from '@/utils/map-search';
|
||||
import { downloadFileByUrl, downloadXls } from '@/utils/util';
|
||||
import { isMobile } from '@/utils/validate';
|
||||
import { Location } from '@element-plus/icons-vue';
|
||||
import { Location, OfficeBuilding } from '@element-plus/icons-vue';
|
||||
import { ElImageViewer } from 'element-plus';
|
||||
import { OpenFileViewer } from '@open-file-viewer/vue';
|
||||
import {
|
||||
@@ -1273,6 +1279,7 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
Location,
|
||||
OfficeBuilding,
|
||||
form: {},
|
||||
query: {},
|
||||
loading: true,
|
||||
@@ -3421,10 +3428,25 @@ export default {
|
||||
.shipping-template-page__route-row {
|
||||
display: grid;
|
||||
grid-template-columns:
|
||||
minmax(160px, 1fr) minmax(220px, 2fr) auto minmax(140px, 1fr) auto minmax(160px, 1fr)
|
||||
auto;
|
||||
minmax(160px, 1fr) minmax(220px, 2fr) 40px auto minmax(140px, 1fr) auto
|
||||
minmax(160px, 1fr);
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
|
||||
.shipping-template-page__address-pick-btn {
|
||||
:deep(.el-icon) {
|
||||
font-size: 22px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.shipping-template-page__map-suffix {
|
||||
cursor: pointer;
|
||||
color: #909399;
|
||||
font-size: 18px;
|
||||
|
||||
&:hover {
|
||||
color: #409eff;
|
||||
}
|
||||
}
|
||||
.shipping-template-page__address-map-input {
|
||||
cursor: pointer;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="voucher-folder-page voucher-folder-page--embedded">
|
||||
<section class="voucher-folder-page__search">
|
||||
<el-form :model="query" label-position="right" label-width="160px">
|
||||
<el-form :model="query" label-position="right">
|
||||
<div class="voucher-folder-page__search-grid">
|
||||
<el-form-item label="车牌号">
|
||||
<el-input v-model="query.plateNo" clearable placeholder="请输入" />
|
||||
@@ -196,7 +196,7 @@ watch(
|
||||
}
|
||||
&__search-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 360px 360px 1fr;
|
||||
grid-template-columns: 220px 220px 1fr;
|
||||
gap: 8px 24px;
|
||||
}
|
||||
&__search-actions {
|
||||
|
||||
@@ -1334,7 +1334,7 @@
|
||||
:disabled="dialogReadonly"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="型号" required>
|
||||
<el-form-item label="型号">
|
||||
<el-input
|
||||
v-model="form.model"
|
||||
placeholder="选择货物自动回填"
|
||||
@@ -3022,9 +3022,10 @@
|
||||
<el-table-column prop="changeUser" label="变更人" min-width="120" />
|
||||
<el-table-column prop="content" label="变更内容" min-width="360">
|
||||
<template #default="{ row }">
|
||||
<div class="waybill-manage-page__route-change-record-content">
|
||||
{{ row.content || '-' }}
|
||||
</div>
|
||||
<div
|
||||
class="waybill-manage-page__route-change-record-content"
|
||||
v-text="formatRouteChangeContent(row.content)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="remark" label="备注" min-width="200" show-overflow-tooltip />
|
||||
@@ -3666,6 +3667,7 @@ import { wgs84ToGcj02 } from '@/utils/coordinate';
|
||||
import { openImportDialog } from '@/utils/import-excel';
|
||||
import { normalizeMapSearchResults, searchAmapPlaceText } from '@/utils/map-search';
|
||||
import { loadMeasurementUnitOptions } from '@/utils/measurement-unit';
|
||||
import { formatRouteChangeContent } from '@/utils/route-change';
|
||||
import { applyTableMenuWidth } from '@/utils/table-menu';
|
||||
import { downloadFileByUrl, downloadXls } from '@/utils/util';
|
||||
import { isMobile } from '@/utils/validate';
|
||||
@@ -4753,6 +4755,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
formatContractOptionLabel,
|
||||
formatRouteChangeContent,
|
||||
// 页面被 keep-alive 缓存/卸载时调用,关闭本页所有 append-to-body 的弹窗,
|
||||
// 避免 Teleport 出去的 DOM 残留在 body 上盖住后续页面(详见 data 里的说明)。
|
||||
closeInnerDialogs() {
|
||||
@@ -5218,10 +5221,11 @@ export default {
|
||||
return true;
|
||||
},
|
||||
showDetailButton(row) {
|
||||
// 草稿与其它状态统一走「详情」(独立详情页 / 详情弹窗),
|
||||
// 不再对草稿单独降级为 avue 的「查看」表单弹窗,避免同一列出现两种弹窗形态。
|
||||
if (!this.config.detailButton || !this.hasPermission(`${this.config.permission}_view`))
|
||||
return false;
|
||||
const status = this.statusValue(row);
|
||||
return status !== 'draft';
|
||||
return true;
|
||||
},
|
||||
formatDetailValue(row, prop) {
|
||||
if (!row) return '-';
|
||||
@@ -11844,6 +11848,9 @@ export default {
|
||||
|
||||
&__route-change-record-content {
|
||||
white-space: pre-wrap;
|
||||
overflow-wrap: anywhere;
|
||||
word-break: break-word;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
&__common-address-toolbar {
|
||||
|
||||
Reference in New Issue
Block a user