提交
This commit is contained in:
1 parent
e46c0480d4
commit
cedb7ee681
12 files changed
+2677
-2680
No files matched your search
@@ -15,36 +15,7 @@
|
||||
<div class="carrier-view-body" v-loading="loading">
|
||||
<section class="carrier-view-top">
|
||||
<h3 class="carrier-view-block-title">承运商信息</h3>
|
||||
<dl v-if="carrier" class="carrier-view-kv-grid">
|
||||
<div class="carrier-view-kv">
|
||||
<dt>承运商名称</dt>
|
||||
<dd>{{ carrier.carrierName || '—' }}</dd>
|
||||
</div>
|
||||
<div class="carrier-view-kv">
|
||||
<dt>联系人</dt>
|
||||
<dd>{{ carrier.contactName || '—' }}</dd>
|
||||
</div>
|
||||
<div class="carrier-view-kv">
|
||||
<dt>联系电话</dt>
|
||||
<dd>{{ carrier.contactPhone || '—' }}</dd>
|
||||
</div>
|
||||
<div class="carrier-view-kv">
|
||||
<dt>合作状态</dt>
|
||||
<dd>
|
||||
<el-tag :type="getPlCarrierStatusTagType(carrier.status)" size="small">
|
||||
{{ getPlCarrierStatusLabel(carrier.status) }}
|
||||
</el-tag>
|
||||
</dd>
|
||||
</div>
|
||||
<div class="carrier-view-kv">
|
||||
<dt>创建时间</dt>
|
||||
<dd>{{ formatDateTime(carrier.createTime) }}</dd>
|
||||
</div>
|
||||
<div class="carrier-view-kv carrier-view-kv-span">
|
||||
<dt>备注</dt>
|
||||
<dd>{{ carrier.remark || '—' }}</dd>
|
||||
</div>
|
||||
</dl>
|
||||
<ViewKvTable v-if="carrier" :fields="carrierViewFields" mode="triple" />
|
||||
</section>
|
||||
|
||||
<section class="carrier-view-bottom">
|
||||
@@ -80,6 +51,8 @@
|
||||
import { Close } from '@element-plus/icons-vue'
|
||||
import { carrierApi, vehicleApi, type Carrier } from '@/api/pl'
|
||||
import PlVehicleViewPanel from '@/components/business/pl-vehicle-view-panel/index.vue'
|
||||
import ViewKvTable from '@/components/business/system-view-dialog/ViewKvTable.vue'
|
||||
import type { ViewField } from '@/components/business/system-view-dialog/types'
|
||||
import {
|
||||
loadVehicleViewBundles,
|
||||
type VehicleViewBundle
|
||||
@@ -106,6 +79,24 @@ const carrier = ref<Carrier | null>(null)
|
||||
const vehicleBundles = ref<VehicleViewBundle[]>([])
|
||||
const activeTab = ref('')
|
||||
|
||||
const carrierViewFields = computed<ViewField[]>(() => {
|
||||
const c = carrier.value
|
||||
if (!c) return []
|
||||
|
||||
return [
|
||||
{ label: '承运商名称', value: c.carrierName },
|
||||
{ label: '联系人', value: c.contactName || '—' },
|
||||
{ label: '联系电话', value: c.contactPhone || '—' },
|
||||
{
|
||||
label: '合作状态',
|
||||
value: getPlCarrierStatusLabel(c.status),
|
||||
tagType: getPlCarrierStatusTagType(c.status)
|
||||
},
|
||||
{ label: '创建时间', value: formatDateTime(c.createTime) },
|
||||
{ label: '备注', value: c.remark || '—', span: 'full' }
|
||||
]
|
||||
})
|
||||
|
||||
watch(
|
||||
() => [props.visible, props.carrierId] as const,
|
||||
async ([visible, carrierId]) => {
|
||||
@@ -164,20 +155,6 @@ function handleClosed() {
|
||||
border-bottom: 1px solid #e2e8f0;
|
||||
}
|
||||
|
||||
.carrier-view-kv-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
gap: 12px 20px;
|
||||
}
|
||||
|
||||
.carrier-view-kv {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.carrier-view-kv-span {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.carrier-view-empty {
|
||||
margin: 0;
|
||||
font-size: 13px;
|
||||
@@ -193,16 +170,4 @@ function handleClosed() {
|
||||
padding-top: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.carrier-view-kv-grid {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.carrier-view-kv-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -10,40 +10,25 @@
|
||||
>
|
||||
<h4 class="cert-view-card-title">证书 {{ index + 1 }}</h4>
|
||||
|
||||
<dl class="cert-view-kv-grid">
|
||||
<div class="cert-view-kv">
|
||||
<dt>证书名称</dt>
|
||||
<dd>{{ cert.certName || '—' }}</dd>
|
||||
</div>
|
||||
<div class="cert-view-kv">
|
||||
<dt>证号</dt>
|
||||
<dd>{{ cert.certNo || '—' }}</dd>
|
||||
</div>
|
||||
<div class="cert-view-kv">
|
||||
<dt>有效期</dt>
|
||||
<dd>
|
||||
<el-tag v-if="cert.expireDate" :type="getExpireTagType(cert.expireDate)" size="small">
|
||||
{{ cert.expireDate }}
|
||||
</el-tag>
|
||||
<span v-else>—</span>
|
||||
</dd>
|
||||
</div>
|
||||
<div class="cert-view-kv">
|
||||
<dt>提醒天数</dt>
|
||||
<dd>{{ cert.remindDays ?? 30 }} 天</dd>
|
||||
</div>
|
||||
<div class="cert-view-kv cert-view-kv-span">
|
||||
<dt>附件</dt>
|
||||
<dd>
|
||||
<AttachmentUploadField
|
||||
v-if="cert.attachmentUrls"
|
||||
:model-value="cert.attachmentUrls"
|
||||
disabled
|
||||
/>
|
||||
<span v-else class="view-empty-inline">—</span>
|
||||
</dd>
|
||||
</div>
|
||||
</dl>
|
||||
<div class="cert-view-kv-table-group">
|
||||
<ViewKvTable :fields="buildCertViewFields(cert)" mode="triple" />
|
||||
<table
|
||||
v-if="cert.attachmentUrls"
|
||||
class="cert-view-attachment-table view-kv-table view-kv-table--triple"
|
||||
>
|
||||
<tbody>
|
||||
<tr class="row-long">
|
||||
<th>附件</th>
|
||||
<td colspan="5">
|
||||
<AttachmentUploadField
|
||||
:model-value="cert.attachmentUrls"
|
||||
disabled
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -51,6 +36,8 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import AttachmentUploadField from '@/components/business/attachment-upload-field/index.vue'
|
||||
import ViewKvTable from '@/components/business/system-view-dialog/ViewKvTable.vue'
|
||||
import type { ViewField } from '@/components/business/system-view-dialog/types'
|
||||
import type { CertRead } from '@/api/pl'
|
||||
|
||||
withDefaults(
|
||||
@@ -71,6 +58,19 @@ function getExpireTagType(dateStr: string | undefined) {
|
||||
if (diffDays <= 30) return 'warning'
|
||||
return 'success'
|
||||
}
|
||||
|
||||
function buildCertViewFields(cert: CertRead): ViewField[] {
|
||||
return [
|
||||
{ label: '证书名称', value: cert.certName || '—' },
|
||||
{ label: '证号', value: cert.certNo || '—' },
|
||||
{
|
||||
label: '有效期',
|
||||
value: cert.expireDate || '—',
|
||||
tagType: cert.expireDate ? getExpireTagType(cert.expireDate) : undefined
|
||||
},
|
||||
{ label: '提醒天数', value: `${cert.remindDays ?? 30} 天` }
|
||||
]
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@@ -109,33 +109,47 @@ function getExpireTagType(dateStr: string | undefined) {
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.cert-view-kv-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
gap: 12px 20px;
|
||||
}
|
||||
.cert-view-kv-table-group {
|
||||
border: 1px solid var(--border, #d9e8e2);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
|
||||
.cert-view-kv {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.cert-view-kv-span {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.view-empty-inline {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
.cert-view-kv-grid {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
:deep(.view-kv-table-wrap) {
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.cert-view-kv-grid {
|
||||
grid-template-columns: 1fr;
|
||||
.cert-view-attachment-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 14px;
|
||||
table-layout: fixed;
|
||||
border-top: 1px solid #eef2f6;
|
||||
|
||||
th {
|
||||
width: 10%;
|
||||
padding: 10px 12px;
|
||||
background: var(--table-head, #f8fafc);
|
||||
color: var(--text-muted, #64748b);
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
text-align: left;
|
||||
vertical-align: top;
|
||||
border-right: 1px solid #eef2f6;
|
||||
white-space: normal;
|
||||
word-break: break-word;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 10px 14px;
|
||||
font-weight: 600;
|
||||
color: var(--text, #1e293b);
|
||||
vertical-align: top;
|
||||
word-break: break-word;
|
||||
line-height: 1.45;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
+31
-36
@@ -10,20 +10,7 @@
|
||||
</el-tag>
|
||||
</h4>
|
||||
|
||||
<dl class="personnel-view-kv-grid">
|
||||
<div class="personnel-view-kv">
|
||||
<dt>手机号</dt>
|
||||
<dd>{{ person.phoneNo || '—' }}</dd>
|
||||
</div>
|
||||
<div class="personnel-view-kv">
|
||||
<dt>年龄</dt>
|
||||
<dd>{{ person.age ?? '—' }}</dd>
|
||||
</div>
|
||||
<div class="personnel-view-kv personnel-view-kv-span">
|
||||
<dt>备注</dt>
|
||||
<dd>{{ person.remark || '—' }}</dd>
|
||||
</div>
|
||||
</dl>
|
||||
<ViewKvTable :fields="personnelViewFields" mode="triple" />
|
||||
|
||||
<div class="personnel-certs-block">
|
||||
<p class="personnel-certs-title">人员证书</p>
|
||||
@@ -34,11 +21,13 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import PlCertViewList from '@/components/business/pl-cert-view-list/index.vue'
|
||||
import ViewKvTable from '@/components/business/system-view-dialog/ViewKvTable.vue'
|
||||
import type { ViewField } from '@/components/business/system-view-dialog/types'
|
||||
import type { CertRead, VehiclePersonnelRow } from '@/api/pl'
|
||||
|
||||
type VehiclePersonnelViewRow = VehiclePersonnelRow & { certList?: CertRead[] }
|
||||
|
||||
withDefaults(
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
person: VehiclePersonnelViewRow
|
||||
showTitle?: boolean
|
||||
@@ -48,6 +37,32 @@ withDefaults(
|
||||
}
|
||||
)
|
||||
|
||||
const personnelViewFields = computed<ViewField[]>(() => {
|
||||
const person = props.person
|
||||
const fields: ViewField[] = [
|
||||
{ label: '姓名', value: person.personnelName || '—' },
|
||||
{ label: '手机号', value: person.phoneNo || '—' },
|
||||
{ label: '年龄', value: person.age ?? '—' },
|
||||
{
|
||||
label: '角色',
|
||||
value: getRoleLabel(person.role),
|
||||
tagType: getRoleTagType(person.role)
|
||||
}
|
||||
]
|
||||
|
||||
if (person.role === 'driver') {
|
||||
fields.push({
|
||||
label: '默认司机',
|
||||
value: person.isDefault === 1 ? '是' : '否',
|
||||
tagType: person.isDefault === 1 ? 'success' : 'info'
|
||||
})
|
||||
}
|
||||
|
||||
fields.push({ label: '备注', value: person.remark || '—', span: 'full' })
|
||||
|
||||
return fields
|
||||
})
|
||||
|
||||
function getRoleLabel(role: string) {
|
||||
const map: Record<string, string> = {
|
||||
driver: '司机',
|
||||
@@ -76,22 +91,8 @@ function getRoleTagType(role: string) {
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.personnel-view-kv-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 12px 20px;
|
||||
margin: 0 0 12px;
|
||||
}
|
||||
|
||||
.personnel-view-kv {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.personnel-view-kv-span {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.personnel-certs-block {
|
||||
margin-top: 12px;
|
||||
padding-top: 12px;
|
||||
border-top: 1px solid #e2e8f0;
|
||||
}
|
||||
@@ -102,10 +103,4 @@ function getRoleTagType(role: string) {
|
||||
font-weight: 600;
|
||||
color: #1e293b;
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.personnel-view-kv-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -19,48 +19,7 @@
|
||||
<div v-show="!collapsible || expanded" class="vehicle-view-panel-body">
|
||||
<section class="vehicle-view-section">
|
||||
<h4 v-if="!collapsible" class="vehicle-view-section-title">车辆信息</h4>
|
||||
<dl class="vehicle-view-kv-grid">
|
||||
<div class="vehicle-view-kv">
|
||||
<dt>车牌号</dt>
|
||||
<dd>{{ detail.licensePlate || '—' }}</dd>
|
||||
</div>
|
||||
<div class="vehicle-view-kv">
|
||||
<dt>车辆类型</dt>
|
||||
<dd>
|
||||
<el-tag :type="getPlVehicleTypeTagType(detail.vehicleType)" size="small">
|
||||
{{ getPlVehicleTypeLabel(detail.vehicleType) }}
|
||||
</el-tag>
|
||||
</dd>
|
||||
</div>
|
||||
<div class="vehicle-view-kv">
|
||||
<dt>承运商</dt>
|
||||
<dd>{{ detail.carrierName || '—' }}</dd>
|
||||
</div>
|
||||
<div class="vehicle-view-kv">
|
||||
<dt>载重(吨)</dt>
|
||||
<dd>{{ detail.loadCapacity ?? '—' }}</dd>
|
||||
</div>
|
||||
<div class="vehicle-view-kv">
|
||||
<dt>车辆状态</dt>
|
||||
<dd>
|
||||
<el-tag :type="getPlVehicleStatusTagType(detail.vehicleStatus)" size="small">
|
||||
{{ getPlVehicleStatusLabel(detail.vehicleStatus) }}
|
||||
</el-tag>
|
||||
</dd>
|
||||
</div>
|
||||
<div class="vehicle-view-kv">
|
||||
<dt>关联人员摘要</dt>
|
||||
<dd>{{ detail.personnelSummary || '—' }}</dd>
|
||||
</div>
|
||||
<div class="vehicle-view-kv vehicle-view-kv-span">
|
||||
<dt>备注</dt>
|
||||
<dd>{{ detail.remark || '—' }}</dd>
|
||||
</div>
|
||||
<div class="vehicle-view-kv">
|
||||
<dt>创建时间</dt>
|
||||
<dd>{{ formatDateTime(detail.createTime) }}</dd>
|
||||
</div>
|
||||
</dl>
|
||||
<ViewKvTable :fields="vehicleViewFields" mode="triple" />
|
||||
</section>
|
||||
|
||||
<section class="vehicle-view-section">
|
||||
@@ -76,6 +35,8 @@
|
||||
<script setup lang="ts">
|
||||
import { ArrowDown } from '@element-plus/icons-vue'
|
||||
import PlVehicleCertPersonnelTabs from '@/components/business/pl-vehicle-cert-personnel-tabs/index.vue'
|
||||
import ViewKvTable from '@/components/business/system-view-dialog/ViewKvTable.vue'
|
||||
import type { ViewField } from '@/components/business/system-view-dialog/types'
|
||||
import type { VehiclePersonnelViewRow } from '@/components/business/pl-vehicle-personnel-view-list/index.vue'
|
||||
import type { VehicleDetail } from '@/api/pl'
|
||||
import { formatDateTime } from '@/utils/format'
|
||||
@@ -102,6 +63,28 @@ const props = withDefaults(
|
||||
|
||||
const expanded = ref(props.defaultExpanded)
|
||||
|
||||
const vehicleViewFields = computed<ViewField[]>(() => {
|
||||
const d = props.detail
|
||||
return [
|
||||
{ label: '车牌号', value: d.licensePlate },
|
||||
{
|
||||
label: '车辆类型',
|
||||
value: getPlVehicleTypeLabel(d.vehicleType),
|
||||
tagType: getPlVehicleTypeTagType(d.vehicleType)
|
||||
},
|
||||
{ label: '承运商', value: d.carrierName || '—' },
|
||||
{ label: '载重(吨)', value: d.loadCapacity ?? '—' },
|
||||
{
|
||||
label: '车辆状态',
|
||||
value: getPlVehicleStatusLabel(d.vehicleStatus),
|
||||
tagType: getPlVehicleStatusTagType(d.vehicleStatus)
|
||||
},
|
||||
{ label: '关联人员摘要', value: d.personnelSummary || '—', span: true },
|
||||
{ label: '创建时间', value: formatDateTime(d.createTime) },
|
||||
{ label: '备注', value: d.remark || '—', span: 'full' }
|
||||
]
|
||||
})
|
||||
|
||||
watch(
|
||||
() => props.defaultExpanded,
|
||||
value => {
|
||||
@@ -170,30 +153,4 @@ watch(
|
||||
border-left: 3px solid #10b981;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.vehicle-view-kv-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
gap: 12px 20px;
|
||||
}
|
||||
|
||||
.vehicle-view-kv {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.vehicle-view-kv-span {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
.vehicle-view-kv-grid {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.vehicle-view-kv-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in new issue
Block a user