1、车船模块fix bug
2、运力模块fix bug 3、新增设备台账 4、其他bug 修复 5、调整组织、人员模块
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
<template>
|
||||
<el-dialog :model-value="modelValue" title="船舶综合台账" width="96%" top="3vh" append-to-body destroy-on-close @update:model-value="$emit('update:modelValue', $event)">
|
||||
<div v-loading="detailLoading" class="ship-ledger">
|
||||
<section v-for="section in sections" :key="section.title" class="ship-ledger__section">
|
||||
<div class="dialog-section-title">{{ section.title }}</div>
|
||||
<el-descriptions :column="3" border>
|
||||
<el-descriptions-item v-for="item in section.items" :key="item.label" :label="item.label">
|
||||
{{ display(item) }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</section>
|
||||
<section class="ship-ledger__section">
|
||||
<div class="dialog-section-title">证书附件</div>
|
||||
<div class="ship-ledger__images">
|
||||
<div v-for="item in imageFields" :key="item.prop" class="ship-ledger__image-item">
|
||||
<span>{{ item.label }}</span>
|
||||
<el-image v-if="shipDetail[item.prop]" :src="shipDetail[item.prop]" :preview-src-list="imageUrls" preview-teleported fit="cover" />
|
||||
<el-empty v-else :image-size="36" description="暂无附件" />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<el-tabs v-model="activeTab" @tab-change="loadRecords">
|
||||
<el-tab-pane v-for="tab in tabs" :key="tab.name" :label="tab.label" :name="tab.name" />
|
||||
</el-tabs>
|
||||
<el-table v-loading="tableLoading" :data="records" border stripe>
|
||||
<el-table-column type="index" label="序号" width="70" align="center" />
|
||||
<el-table-column v-for="column in activeColumns" :key="column.prop" :prop="column.prop" :label="column.label" :min-width="column.width || 140" show-overflow-tooltip />
|
||||
</el-table>
|
||||
<div class="ship-ledger__pagination"><el-pagination v-model:current-page="page.current" v-model:page-size="page.size" :page-sizes="[10, 20, 50]" :total="page.total" layout="total, sizes, prev, pager, next" @size-change="handlePageChange" @current-change="loadRecords" /></div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getDetail } from '@/api/transportCapacity/transport-ship';
|
||||
import { getList as insurance } from '@/api/vehicle/insurance-record';
|
||||
import { getList as violation } from '@/api/vehicle/violation-record';
|
||||
import { getList as maintenance } from '@/api/vehicle/maintenance-record';
|
||||
import { getList as maintenancePlan } from '@/api/vehicle/maintenance-plan';
|
||||
import { getList as accident } from '@/api/vehicle/accident-record';
|
||||
import { getList as annualInspection } from '@/api/vehicle/annual-inspection-record';
|
||||
import { getList as change } from '@/api/vehicle/transport-change-record';
|
||||
import { getList as oilElectric } from '@/api/vehicle/oil-electric-record';
|
||||
import { getList as otherExpense } from '@/api/vehicle/other-expense-record';
|
||||
|
||||
const columns = (...items) => items.map(([label, prop]) => ({ label, prop }));
|
||||
const tabConfigs = [
|
||||
['insurance', '保险记录', insurance, columns(['船号', 'vehicleNo'], ['保险类型', 'insuranceType'], ['开始日期', 'startDate'], ['结束日期', 'endDate'], ['保费', 'premium'], ['保单号', 'policyNo'])],
|
||||
['violation', '违章记录', violation, columns(['船号', 'vehicleNo'], ['驾驶人/船长', 'driverName'], ['类型', 'violationType'], ['事项', 'violationItem'], ['违章时间', 'violationTime'], ['罚款金额', 'fineAmount'])],
|
||||
['maintenance', '维修记录', maintenance, columns(['船号', 'vehicleNo'], ['维修人', 'maintainer'], ['维修时间', 'maintenanceTime'], ['维修位置', 'location'], ['费用', 'cost'])],
|
||||
['maintenancePlan', '保养记录', maintenancePlan, columns(['船号', 'vehicleNo'], ['保养人', 'maintainer'], ['保养时间', 'maintenanceTime'], ['保养项目', 'maintenanceItem'], ['费用', 'cost'])],
|
||||
['accident', '事故记录', accident, columns(['船号', 'vehicleNo'], ['事故时间', 'accidentTime'], ['事故地点', 'accidentLocation'], ['事故类型', 'accidentType'], ['损失金额', 'lossAmount'])],
|
||||
['annualInspection', '年检记录', annualInspection, columns(['船号', 'vehicleNo'], ['年检日期', 'inspectionDate'], ['年检有效期至', 'inspectionEndDate'], ['年检机构', 'inspectionOrganization'], ['费用', 'cost'])],
|
||||
['change', '变更记录', change, columns(['船号', 'vehicleNo'], ['变更类型', 'changeType'], ['变更时间', 'changeTime'], ['变更前内容', 'beforeChange'], ['变更后内容', 'afterChange'])],
|
||||
['equipment', '设备台账', null, columns(['设备编码', 'equipmentCode'], ['设备名称', 'equipmentName'], ['设备类型', 'equipmentType'], ['安装日期', 'installDate'], ['状态', 'status'])],
|
||||
['oilElectric', '油电台账', oilElectric, columns(['船号', 'vehicleNo'], ['加油/充电日期', 'recordDate'], ['类型', 'energyType'], ['数量', 'quantity'], ['金额', 'amount'])],
|
||||
['otherExpense', '其他费用记录', otherExpense, columns(['船号', 'vehicleNo'], ['费用日期', 'expenseDate'], ['费用类型', 'expenseType'], ['金额', 'amount'], ['备注', 'remark'])],
|
||||
].map(([name, label, request, cols]) => ({ name, label, request, columns: cols }));
|
||||
|
||||
export default {
|
||||
props: { modelValue: Boolean, ship: { type: Object, default: () => ({}) } }, emits: ['update:modelValue'],
|
||||
data() { return { detailLoading: false, tableLoading: false, shipDetail: {}, activeTab: 'insurance', records: [], page: { current: 1, size: 10, total: 0 } }; },
|
||||
computed: {
|
||||
tabs() { return tabConfigs; }, activeConfig() { return tabConfigs.find(item => item.name === this.activeTab) || tabConfigs[0]; }, activeColumns() { return this.activeConfig.columns; },
|
||||
imageFields() { return [['船舶所有权证书', 'ownershipCertImage'], ['内河船舶安全与环保证书', 'safetyCertImage'], ['船舶国籍证书', 'nationalityCertImage'], ['最低安全配员证书', 'safeManningCertImage'], ['船舶营业运输证', 'businessTransportCertImage'], ['光船租赁登记证书', 'leaseContractImage']].map(([label, prop]) => ({ label, prop })); },
|
||||
imageUrls() { return this.imageFields.map(item => this.shipDetail[item.prop]).filter(Boolean); },
|
||||
sections() { const s = this.shipDetail; return [
|
||||
{ title: '船舶基本信息', items: [['船舶所属组织', 'organizationName'], ['船名', 'shipName'], ['安放龙骨日期/建造完工日期', 'constructionDate'], ['总长(m)', 'totalLength'], ['船宽(m)', 'shipWidth'], ['型深(m)', 'moldedDepth'], ['最大船高(m)', 'maxShipHeight'], ['空载吃水(t)', 'lightDraft'], ['满载吃水(t)', 'fullLoadDraft'], ['航区', 'navigationArea']] },
|
||||
{ title: '船舶证书信息', items: [['登记号码', 'ownershipRegistrationNo'], ['初次登记号码', 'initialRegistrationNo'], ['船舶所有人', 'shipOwner'], ['取得所有权日期', 'ownershipAcquisitionDate'], ['船舶识别号', 'shipIdentifierNo'], ['总吨', 'grossTonnage'], ['净吨', 'netTonnage'], ['船检登记号', 'shipInspectionNo'], ['船舶类型', 'shipType'], ['国籍证书有效期', 'nationalityCertDate'], ['最低安全配员证书有效期', 'safeManningCertDate'], ['起租日期', 'leaseStartDate'], ['终止日期', 'leaseEndDate'], ['船舶承租人', 'shipLessee'], ['营业运输证证书编号', 'businessTransportCertNo'], ['营业运输证发证日期', 'businessTransportCertIssueDate'], ['营业运输证有效期至', 'businessTransportCertEndDate'], ['船舶经营人', 'shipOperator']] },
|
||||
].map(section => ({ ...section, items: section.items.map(([label, prop]) => ({ label, prop, value: prop === 'constructionDate' ? `${s.keelLayingDate || '-'} / ${s.buildCompletionDate || '-'}` : prop === 'nationalityCertDate' ? `${s.nationalityCertStartDate || '-'} 至 ${s.nationalityCertEndDate || '-'}` : prop === 'safeManningCertDate' ? `${s.safeManningCertStartDate || '-'} 至 ${s.safeManningCertEndDate || '-'}` : s[prop] })) })); },
|
||||
},
|
||||
watch: { modelValue(value) { if (value) this.initialize(); } },
|
||||
methods: {
|
||||
display(item) { return item.value === null || item.value === undefined || item.value === '' ? '-' : item.value; },
|
||||
async initialize() { this.activeTab = 'insurance'; this.page.current = 1; this.shipDetail = { ...this.ship }; if (this.ship.id) { this.detailLoading = true; try { const res = await getDetail(this.ship.id); this.shipDetail = { ...this.ship, ...(res.data.data || {}) }; } finally { this.detailLoading = false; } } this.loadRecords(); },
|
||||
async loadRecords() { const { request } = this.activeConfig; if (!request) { this.records = []; this.page.total = 0; return; } this.tableLoading = true; try { const res = await request(this.page.current, this.page.size, { vehicleNo: this.shipDetail.shipName || this.ship.shipName, vehicleType: '船舶' }); const data = res.data.data || {}; this.records = data.records || []; this.page.total = data.total || 0; } finally { this.tableLoading = false; } },
|
||||
handlePageChange() { this.page.current = 1; this.loadRecords(); },
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.ship-ledger__section { margin-bottom: 16px; }
|
||||
.ship-ledger__images { display: flex; gap: 16px; overflow-x: auto; padding: 12px 0; }
|
||||
.ship-ledger__image-item { width: 150px; flex: 0 0 150px; text-align: center; color: #606266; }
|
||||
.ship-ledger__image-item > span { display: block; margin-bottom: 8px; }
|
||||
.ship-ledger__image-item :deep(.el-image) { width: 150px; height: 110px; border: 1px solid #eff1f7; }
|
||||
.ship-ledger__image-item :deep(.el-empty) { height: 110px; border: 1px solid #eff1f7; }
|
||||
.ship-ledger__pagination { display: flex; justify-content: flex-end; margin-top: 16px; }
|
||||
</style>
|
||||
@@ -0,0 +1,141 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:model-value="modelValue"
|
||||
title="车辆综合台账"
|
||||
width="96%"
|
||||
top="3vh"
|
||||
append-to-body
|
||||
destroy-on-close
|
||||
@update:model-value="$emit('update:modelValue', $event)"
|
||||
>
|
||||
<div v-loading="detailLoading" class="vehicle-ledger">
|
||||
<section class="vehicle-ledger__overview">
|
||||
<div class="vehicle-ledger__title">
|
||||
<span>{{ vehicleDetail.plateNo || vehicle.plateNo }}</span>
|
||||
<el-tag :type="plateColorType">{{ vehicleDetail.plateColor || '-' }}</el-tag>
|
||||
<el-tag type="primary">{{ vehicleDetail.businessRelation || '-' }}</el-tag>
|
||||
</div>
|
||||
<el-descriptions :column="4" border>
|
||||
<el-descriptions-item label="所属组织">{{ vehicleDetail.organizationName || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="车辆类型">{{ vehicleDetail.vehicleType || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="能源类型">{{ vehicleDetail.energyType || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="外廓尺寸(mm)">{{ dimensions }}</el-descriptions-item>
|
||||
<el-descriptions-item label="核定载质量(KG)">{{ vehicleDetail.approvedLoadKg ?? '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="准牵引总质量(KG)">{{ vehicleDetail.tractionMassKg ?? '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="行驶证档案编号">{{ vehicleDetail.drivingLicenseNo || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="道路运输证号">{{ vehicleDetail.roadTransportCertNo || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="行驶证有效期">{{ vehicleDetail.drivingLicenseEndDate || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="道路运输证有效期">{{ vehicleDetail.roadTransportCertEndDate || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="道路运输证年审有效期">{{ vehicleDetail.annualReviewEndDate || '-' }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<div class="vehicle-ledger__images">
|
||||
<div v-for="item in imageFields" :key="item.prop" class="vehicle-ledger__image-item">
|
||||
<span>{{ item.label }}</span>
|
||||
<el-image
|
||||
v-if="vehicleDetail[item.prop]"
|
||||
:src="vehicleDetail[item.prop]"
|
||||
:preview-src-list="imageUrls"
|
||||
preview-teleported
|
||||
fit="cover"
|
||||
/>
|
||||
<el-empty v-else :image-size="36" description="暂无图片" />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<el-tabs v-model="activeTab" class="vehicle-ledger__tabs" @tab-change="loadRecords">
|
||||
<el-tab-pane v-for="tab in tabs" :key="tab.name" :label="tab.label" :name="tab.name" />
|
||||
</el-tabs>
|
||||
<el-table v-loading="tableLoading" :data="records" border stripe>
|
||||
<el-table-column type="index" label="序号" width="70" align="center" />
|
||||
<el-table-column
|
||||
v-for="column in activeColumns"
|
||||
:key="column.prop"
|
||||
:prop="column.prop"
|
||||
:label="column.label"
|
||||
:min-width="column.width || 140"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
</el-table>
|
||||
<div class="vehicle-ledger__pagination">
|
||||
<el-pagination
|
||||
v-model:current-page="page.current"
|
||||
v-model:page-size="page.size"
|
||||
:page-sizes="[10, 20, 50]"
|
||||
:total="page.total"
|
||||
layout="total, sizes, prev, pager, next"
|
||||
@size-change="handlePageChange"
|
||||
@current-change="loadRecords"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getDetail } from '@/api/transportCapacity/transport-vehicle';
|
||||
import { getList as getInsuranceList } from '@/api/vehicle/insurance-record';
|
||||
import { getList as getViolationList } from '@/api/vehicle/violation-record';
|
||||
import { getList as getMaintenanceList } from '@/api/vehicle/maintenance-record';
|
||||
import { getList as getMaintenancePlanList } from '@/api/vehicle/maintenance-plan';
|
||||
import { getList as getTireList } from '@/api/vehicle/tire-replacement-record';
|
||||
import { getList as getAccidentList } from '@/api/vehicle/accident-record';
|
||||
import { getList as getAnnualInspectionList } from '@/api/vehicle/annual-inspection-record';
|
||||
import { getList as getMileageList } from '@/api/vehicle/mileage-record';
|
||||
import { getList as getChangeList } from '@/api/vehicle/transport-change-record';
|
||||
import { getList as getOilElectricList } from '@/api/vehicle/oil-electric-record';
|
||||
import { getList as getEtcList } from '@/api/vehicle/etc-record';
|
||||
import { getList as getOtherExpenseList } from '@/api/vehicle/other-expense-record';
|
||||
|
||||
const cols = (...items) => items.map(([label, prop, width]) => ({ label, prop, width }));
|
||||
const tabConfigs = [
|
||||
['insurance', '保险记录', getInsuranceList, cols(['车牌号', 'vehicleNo'], ['保险类型', 'insuranceType'], ['开始日期', 'startDate'], ['结束日期', 'endDate'], ['保费', 'premium'], ['保单号', 'policyNo'])],
|
||||
['violation', '违章记录', getViolationList, cols(['车牌号', 'vehicleNo'], ['驾驶人', 'driverName'], ['类型', 'violationType'], ['事项', 'violationItem'], ['违章时间', 'violationTime'], ['罚款金额', 'fineAmount'])],
|
||||
['maintenance', '维修记录', getMaintenanceList, cols(['车牌号', 'vehicleNo'], ['维修人', 'maintainer'], ['维修时间', 'maintenanceTime'], ['维修位置', 'location'], ['费用', 'cost'], ['维修单位', 'company'])],
|
||||
['maintenancePlan', '保养记录', getMaintenancePlanList, cols(['车牌号', 'vehicleNo'], ['保养人', 'maintainer'], ['保养时间', 'maintenanceTime'], ['保养项目', 'maintenanceItem'], ['费用', 'cost'], ['下次保养时间', 'nextMaintenanceTime'])],
|
||||
['tire', '换胎记录', getTireList, cols(['车牌号', 'vehicleNo'], ['更换时间', 'replacementTime'], ['轮胎品牌', 'tireBrand'], ['轮胎规格', 'tireSpec'], ['费用', 'cost'])],
|
||||
['accident', '事故记录', getAccidentList, cols(['车牌号', 'vehicleNo'], ['事故时间', 'accidentTime'], ['事故地点', 'accidentLocation'], ['事故类型', 'accidentType'], ['损失金额', 'lossAmount'])],
|
||||
['annualInspection', '年检记录', getAnnualInspectionList, cols(['车牌号', 'vehicleNo'], ['年检日期', 'inspectionDate'], ['年检有效期至', 'inspectionEndDate'], ['年检机构', 'inspectionOrganization'], ['费用', 'cost'])],
|
||||
['mileage', '里程记录', getMileageList, cols(['车牌号', 'vehicleNo'], ['记录时间', 'recordTime'], ['里程数', 'mileage'], ['里程单位', 'mileageUnit'], ['备注', 'remark'])],
|
||||
['change', '变更记录', getChangeList, cols(['车牌号', 'vehicleNo'], ['变更类型', 'changeType'], ['变更时间', 'changeTime'], ['变更前内容', 'beforeChange'], ['变更后内容', 'afterChange'])],
|
||||
['equipment', '设备台账', null, cols(['设备编码', 'equipmentCode'], ['设备名称', 'equipmentName'], ['设备类型', 'equipmentType'], ['安装日期', 'installDate'], ['状态', 'status'])],
|
||||
['oilElectric', '油电台账', getOilElectricList, cols(['车牌号', 'vehicleNo'], ['加油/充电日期', 'recordDate'], ['类型', 'energyType'], ['数量', 'quantity'], ['金额', 'amount'])],
|
||||
['etc', 'ETC记录', getEtcList, cols(['车牌号', 'vehicleNo'], ['交易日期', 'transactionDate'], ['交易金额', 'amount'], ['交易地点', 'location'], ['ETC卡号', 'etcCardNo'])],
|
||||
['otherExpense', '其他费用记录', getOtherExpenseList, cols(['车牌号', 'vehicleNo'], ['费用日期', 'expenseDate'], ['费用类型', 'expenseType'], ['金额', 'amount'], ['备注', 'remark'])],
|
||||
].map(([name, label, request, columns]) => ({ name, label, request, columns }));
|
||||
|
||||
export default {
|
||||
props: { modelValue: Boolean, vehicle: { type: Object, default: () => ({}) } },
|
||||
emits: ['update:modelValue'],
|
||||
data() {
|
||||
return { detailLoading: false, tableLoading: false, vehicleDetail: {}, activeTab: 'insurance', records: [], page: { current: 1, size: 10, total: 0 } };
|
||||
},
|
||||
computed: {
|
||||
tabs() { return tabConfigs; },
|
||||
activeConfig() { return tabConfigs.find(item => item.name === this.activeTab) || tabConfigs[0]; },
|
||||
activeColumns() { return this.activeConfig.columns; },
|
||||
dimensions() { const v = this.vehicleDetail; return [v.outerLength, v.outerWidth, v.outerHeight].filter(item => item !== null && item !== undefined && item !== '').join('×') || '-'; },
|
||||
plateColorType() { return { 黄牌: 'warning', 蓝牌: 'primary', 绿牌: 'success' }[this.vehicleDetail.plateColor] || 'info'; },
|
||||
imageFields() { return [['行驶证主页面', 'drivingLicenseImage'], ['行驶证主页反页', 'drivingLicenseMainBack'], ['行驶证副页正页', 'drivingLicenseViceFront'], ['行驶证副页反页', 'drivingLicenseViceBack'], ['道路运输证', 'roadTransportCertImage']].map(([label, prop]) => ({ label, prop })); },
|
||||
imageUrls() { return this.imageFields.map(item => this.vehicleDetail[item.prop]).filter(Boolean); },
|
||||
},
|
||||
watch: { modelValue(value) { if (value) this.initialize(); } },
|
||||
methods: {
|
||||
async initialize() { this.activeTab = 'insurance'; this.page.current = 1; this.vehicleDetail = { ...this.vehicle }; if (this.vehicle.id) { this.detailLoading = true; try { const res = await getDetail(this.vehicle.id); this.vehicleDetail = { ...this.vehicle, ...(res.data.data || {}) }; } finally { this.detailLoading = false; } } this.loadRecords(); },
|
||||
async loadRecords() { const { request } = this.activeConfig; if (!request) { this.records = []; this.page.total = 0; return; } this.tableLoading = true; try { const res = await request(this.page.current, this.page.size, { vehicleNo: this.vehicleDetail.plateNo || this.vehicle.plateNo, vehicleType: '车辆' }); const data = res.data.data || {}; this.records = data.records || []; this.page.total = data.total || 0; } finally { this.tableLoading = false; } },
|
||||
handlePageChange() { this.page.current = 1; this.loadRecords(); },
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.vehicle-ledger__overview { padding: 16px; border: 1px solid #eff1f7; }
|
||||
.vehicle-ledger__title { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; font-size: 26px; font-weight: 600; }
|
||||
.vehicle-ledger__images { display: flex; gap: 16px; margin-top: 16px; overflow-x: auto; }
|
||||
.vehicle-ledger__image-item { width: 150px; flex: 0 0 150px; color: #606266; text-align: center; }
|
||||
.vehicle-ledger__image-item > span { display: block; margin-bottom: 8px; }
|
||||
.vehicle-ledger__image-item :deep(.el-image) { width: 150px; height: 110px; border: 1px solid #eff1f7; }
|
||||
.vehicle-ledger__image-item :deep(.el-empty) { height: 110px; border: 1px solid #eff1f7; }
|
||||
.vehicle-ledger__tabs { margin-top: 16px; }
|
||||
.vehicle-ledger__pagination { display: flex; justify-content: flex-end; margin-top: 16px; }
|
||||
</style>
|
||||
Reference in New Issue
Block a user