Squashed commit of the following:

commit 9e260ddcd8
Author: 浅念 <email@sample.com>
Date:   Thu Sep 18 09:49:33 2025 +0800

    修改 kpi

commit 6feb3ace75
Author: 浅念 <email@sample.com>
Date:   Thu Sep 18 09:42:44 2025 +0800

    kpi 统计

commit ec257a246d
Author: 浅念 <email@sample.com>
Date:   Wed Sep 17 17:04:35 2025 +0800

    修改 弹框表格

commit fa764852ab
Author: 浅念 <email@sample.com>
Date:   Wed Sep 17 15:54:35 2025 +0800

    添加 账户简称

commit 65f7f4a123
Author: 浅念 <email@sample.com>
Date:   Wed Sep 17 15:10:28 2025 +0800

    品牌加热门  修改 仪表盘接口

commit 922cfec81d
Author: 浅念 <email@sample.com>
Date:   Tue Sep 16 15:57:17 2025 +0800

    调整备货单  crm 端页面

commit 5c8df36f12
Author: 浅念 <email@sample.com>
Date:   Mon Sep 15 17:14:38 2025 +0800

    调整备货单 及各页面名称

commit 5503a14408
Author: 浅念 <email@sample.com>
Date:   Fri Sep 12 18:10:03 2025 +0800

    账户添加公司

commit 3439b45d9a
Author: 浅念 <email@sample.com>
Date:   Fri Sep 12 17:53:26 2025 +0800

    修改终版备货单

commit 045d13eb7b
Author: 浅念 <email@sample.com>
Date:   Fri Sep 12 17:49:07 2025 +0800

    修改备货单 等页面

commit da690dfa06
Author: 浅念 <email@sample.com>
Date:   Thu Sep 11 17:44:37 2025 +0800

    修改 备货单 详情

commit 853e9591b3
Author: 浅念 <email@sample.com>
Date:   Wed Sep 10 18:11:39 2025 +0800

    修改 备货单页面

commit 9052bd1027
Author: 浅念 <email@sample.com>
Date:   Tue Sep 9 20:53:30 2025 +0800

    备货单  审核功能

commit 079d9babb8
Merge: ebd7479 91d810b
Author: 浅念 <email@sample.com>
Date:   Tue Sep 9 14:51:43 2025 +0800

    Merge branch 'feature/crm_pc' of http://219.157.255.213:25311/xinyouhe/art-design into feature/crm_vehicle

commit ebd7479573
Merge: 64e53b6 459d306
Author: 浅念 <email@sample.com>
Date:   Tue Sep 9 13:57:28 2025 +0800

    Merge branch 'feature/crm_pc' of http://219.157.255.213:25311/xinyouhe/art-design into feature/crm_vehicle

commit 64e53b6ee9
Author: 浅念 <email@sample.com>
Date:   Mon Sep 8 19:09:55 2025 +0800

    备货单 加 审批流程

commit 9bd7c89cb4
Author: 浅念 <email@sample.com>
Date:   Thu Sep 4 15:09:17 2025 +0800

    车辆信息,备货单  等页面
This commit is contained in:
浅念
2025-09-18 09:55:10 +08:00
parent 91d810b33a
commit a514bf4009
88 changed files with 27057 additions and 491 deletions
@@ -0,0 +1,419 @@
<template>
<div class="order-detail-content">
<!-- 基本信息 -->
<div class="basic-info-section">
<div class="basic-info-item">
<span class="label">备货单编号:</span>
<span class="value">{{ orderData.order_no || orderData.orderNo || '—' }}</span>
</div>
<div class="basic-info-item">
<span class="label">业务员:</span>
<span class="value">{{ orderData.salesperson_snapshot || orderData.salesperson || '—' }}</span>
</div>
</div>
<!-- 客户信息 -->
<div class="customer-info-table">
<table class="info-table">
<tr>
<td>
<span class="info-label"> 阿里订单号/PI号:</span>
<span class="info-value">{{ orderData.pi_no || orderData.piNo || '—' }}</span>
</td>
<td>
<span class="info-label"> 日期:</span>
<span class="info-value">{{ orderData.created_at || orderData.date || '—' }}</span>
</td>
<td>
<span class="info-label"> 清关目的国:</span>
<span class="info-value">{{ orderData.clearance_country_snapshot || orderData.clearanceCountry || '—' }}</span>
</td>
<td>
<span class="info-label"> 客户来源:</span>
<span class="info-value">{{ orderData.customer_source_snapshot || orderData.customerSource || '—' }}</span>
</td>
<td>
<span class="info-label"> 客户名称:</span>
<span class="info-value">{{ orderData.customer_snapshot || orderData.customerName || '—' }}</span>
</td>
<td>
<span class="info-label"> 客户所在国:</span>
<span class="info-value">{{ orderData.customer_country_snapshot || orderData.customerCountry || '—' }}</span>
</td>
</tr>
</table>
</div>
<!-- 订单详情表格(ArtTable) -->
<div class="table-section">
<ArtTable :data="vehItems" border :pagination="false">
<template #default>
<ElTableColumn label="编号" width="60" align="center">
<template #default="scope">{{ scope.$index + 1 }}</template>
</ElTableColumn>
<ElTableColumn label="车型" min-width="160">
<template #default="scope">
{{ scope.row.model_snapshot || scope.row.model || '—' }}
<span v-if="scope.row.mileage > 0">({{ scope.row.mileage }}km)</span>
</template>
</ElTableColumn>
<ElTableColumn label="数量/台" width="90" align="center">
<template #default="scope">{{ scope.row.num ?? scope.row.quantity ?? 1 }}</template>
</ElTableColumn>
<ElTableColumn label="颜色/外" align="center" prop="color_exterior_snapshot" />
<ElTableColumn label="内饰" min-width="120" align="center" prop="color_interior_snapshot" />
<ElTableColumn label="改装" min-width="120" align="center" prop="modify" />
<ElTableColumn label="官方指导价/二手挂牌价" min-width="175" align="center">
<template #default="scope">
<span v-if="scope.row.mileage > 0">
{{ scope.row.listing_price?.currency_info || scope.row.listing_price?.amount || scope.row.discount || '—' }}
</span>
<span v-else>
{{ scope.row.official_price?.currency_info || scope.row.official_price?.amount || scope.row.discount || '—' }}
</span>
</template>
</ElTableColumn>
<ElTableColumn label="优惠" min-width="120" align="center">
<template #default="scope">
<span v-if="scope.row.mileage > 0">
{{ scope.row.reduction_price?.currency_info || scope.row.reduction_price?.amount || scope.row.discount || '—' }}
</span>
<span v-else>
{{ scope.row.discount_price?.currency_info || scope.row.discount_price?.amount || scope.row.discount || '—' }}
</span>
</template>
</ElTableColumn>
<ElTableColumn label="手续费" min-width="120" align="center">
<template #default="scope">{{ scope.row.handling_fee?.currency_info || scope.row.handling_fee?.amount || scope.row.discount || '—' }}</template>
</ElTableColumn>
<ElTableColumn label="改装费" min-width="120" align="center">
<template #default="scope">{{ scope.row.retrofit_fee?.currency_info || scope.row.retrofit_fee?.amount || scope.row.discount || '—' }}</template>
</ElTableColumn>
<ElTableColumn label="FOB运费" min-width="120" align="center">
<template #default="scope">{{ scope.row.fob_transport_fee?.currency_info || scope.row.fob_transport_fee?.amount || scope.row.discount || '—' }}</template>
</ElTableColumn>
<ElTableColumn label="港杂费" min-width="120" align="center">
<template #default="scope">{{ scope.row.port_misc_fee?.currency_info || scope.row.port_misc_fee?.amount || scope.row.discount || '—' }}</template>
</ElTableColumn>
<ElTableColumn label="海运费" min-width="120" align="center">
<template #default="scope">{{ scope.row.ocean_freight?.currency_info || scope.row.ocean_freight?.amount || scope.row.discount || '—' }}</template>
</ElTableColumn>
<ElTableColumn label="单价" min-width="120" align="center">
<template #default="scope">{{ scope.row.unit_price?.currency_info || scope.row.unit_price?.amount || scope.row.discount || '—' }}</template>
</ElTableColumn>
<ElTableColumn label="总价" min-width="120" align="center">
<template #default="scope">{{ scope.row.total_price?.currency_info || scope.row.total_price?.amount || scope.row.discount || '—' }}</template>
</ElTableColumn>
<ElTableColumn fixed="right" label="利润" min-width="120" align="center">
<template #default="scope">{{ scope.row.profit?.currency_info || scope.row.profit?.amount || scope.row.discount || '—' }}</template>
</ElTableColumn>
</template>
</ArtTable>
<div class="order-summary">
<div class="summary-item">
<span class="label">合同汇率:</span>
<span class="value">{{ orderData.contract_exchange_rate || orderData.contractRate || '—' }}</span>
</div>
<div class="summary-item">
<span class="label">合计到岸价:</span>
<span class="value">${{ formatPrice(Number(orderData.cif_total_amount?.amount ?? orderData.totalCif ?? 0)) }}</span>
</div>
<div class="summary-item">
<span class="label">利润:</span>
<span class="value">{{ orderData.profit_total?.currency_info || orderData.profit_total?.amount || '—' }}</span>
</div>
</div>
</div>
<!-- 物流信息 -->
<div class="customer-info-table">
<table class="info-table">
<tr>
<td>
<span class="info-label"> 清关人:</span>
<span class="info-value">{{ orderData.declarant_name || orderData.declarant || '—' }}</span>
</td>
<td>
<span class="info-label"> 预计发运日期:</span>
<span class="info-value">{{ orderData.eta_ship_date || orderData.etaShipDate || '—' }}</span>
</td>
<td>
<span class="info-label"> 出运方式:</span>
<span class="info-value">{{ orderData.shipping_method_snapshot || orderData.shippingMethod || '—' }}</span>
</td>
<td>
<span class="info-label"> 国内收货港:</span>
<span class="info-value">{{ orderData.domestic_port_snapshot || orderData.domesticPort || '—' }}</span>
</td>
<td>
<span class="info-label"> 贸易条款/清关目的港:</span>
<span class="info-value">{{ orderData.trade_term_snapshot || orderData.tradeTerms || '—' }}/{{ orderData.clearance_port_snapshot || '—' }}</span>
</td>
<td>
<span class="info-label"> 最迟到港时间:</span>
<span class="info-value">{{ orderData.latest_arrival_date || orderData.latestArrival || '—' }}</span>
</td>
</tr>
</table>
</div>
<!-- 计划收款信息 -->
<div class="payment-section" v-if="(orderData.account_list && orderData.account_list.length) || (orderData.payments && orderData.payments.length)">
<div class="table-wrapper">
<table class="payment-table">
<thead>
<tr>
<th style="width: 140px"></th>
<th>序号</th>
<th>汇款国</th>
<th>日期</th>
<th>币种</th>
<th>账户</th>
<th>汇款人</th>
<th>金额</th>
</tr>
</thead>
<tbody>
<tr v-for="(row, index) in paymentTableData" :key="index">
<td v-if="index === 0" :rowspan="paymentTableData.length">计划收款信息</td>
<td>{{ row.serial }}</td>
<td>{{ row.country }}</td>
<td>{{ row.date }}</td>
<td>{{ row.currency }}</td>
<td>{{ row.account }}</td>
<td>{{ row.remitter }}</td>
<td>{{ row.amount }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent, computed } from 'vue'
export default defineComponent({
name: 'OrderDetailContent',
props: {
orderData: {
type: Object as () => any,
default: () => ({})
}
},
setup(props) {
const paymentTableData = computed(() => {
const list = (props.orderData as any).account_list
? (props.orderData as any).account_list.map((p: any, idx: number) => ({
group: '计划收款信息',
serial: `收款${idx + 1}`,
country: p.remit_country_name_snapshot || '—',
date: p.remit_date || '—',
currency: p.currency_name_snapshot || '—',
account: p.account_name_snapshot || '—',
remitter: p.remitter_name || '—',
amount: `$${formatPrice(Number(p.amount || 0))}`
}))
: (props.orderData as any).payments || []
if (!list.length) return []
return list
})
const formatPrice = (price?: number): string => {
if (price === undefined || price === null) return '0.00'
return Number(price).toLocaleString('en-US', {
minimumFractionDigits: 2,
maximumFractionDigits: 2
})
}
const vehItems = computed(() => {
return (props.orderData as any).veh_list || (props.orderData as any).items || []
})
return {
paymentTableData,
vehItems,
formatPrice
}
}
})
</script>
<style scoped lang="scss">
.order-detail-content {
font-family: 'Microsoft YaHei', Arial, sans-serif;
font-size: 14px;
line-height: 1.4;
color: #333;
}
.basic-info-section {
display: flex;
justify-content: center;
gap: 40px;
margin-bottom: 20px;
}
.basic-info-item {
display: flex;
align-items: center;
.label {
font-weight: 600;
color: #333;
margin-right: 8px;
white-space: nowrap;
}
.value {
color: #666;
}
}
.customer-info-table {
margin: 20px 0px;
}
.info-table {
width: 100%;
border-collapse: collapse;
background: white;
td {
padding: 12px 12px;
border: 1px solid #d9d9d9;
font-size: 13px;
}
.info-value {
font-weight: 600;
color: #333;
text-align: right;
}
.info-label {
color: #666;
padding-right: 20px;
}
}
.table-section {
margin: 0;
}
.table-wrapper {
overflow-x: auto;
border: 1px solid #e4e7ed;
}
.order-table {
width: 100%;
border-collapse: collapse;
background: white;
font-size: 13px;
th {
background: #f5f7fa;
color: #333;
font-weight: bold;
padding: 12px 8px;
text-align: center;
border: 1px solid #d9d9d9;
white-space: nowrap;
font-size: 13px;
}
td {
padding: 10px 8px;
text-align: center;
border: 1px solid #d9d9d9;
color: #333;
font-size: 13px;
}
.col-no {
width: 60px;
}
.col-model {
max-width: 160px;
// text-align: left;
}
tbody tr:hover {
background: #e6f7ff;
}
}
.payment-section {
margin: 20px 0;
}
/* 订单底部汇总样式 */
.order-summary {
display: flex;
justify-content: flex-end;
align-items: center;
gap: 12px;
padding: 8px 12px;
background: #f9fafb;
border: 1px solid #e5e7eb;
border-top: none;
border-radius: 0 0 4px 4px;
flex-wrap: wrap;
}
.order-summary .summary-item {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 6px 10px;
// background: #fff;
// border: 1px solid #e5e7eb;
border-radius: 4px;
white-space: nowrap;
}
.order-summary .label {
color: #666;
}
.order-summary .value {
font-weight: 600;
color: #111;
}
/* ArtTable 表头背景色 */
.table-section :deep(.el-table__header th) {
background-color: #f5f7fa;
color: #333;
font-weight: 600;
}
.table-section :deep(.el-table__header .cell) {
padding: 12px 8px;
}
.payment-table {
width: 100%;
border-collapse: collapse;
background: white;
font-size: 13px;
}
.payment-table th {
background: #f5f7fa;
color: #333;
font-weight: 600;
text-align: center;
border: 1px solid #d9d9d9;
padding: 12px 8px;
white-space: nowrap;
}
.payment-table td {
text-align: center;
color: #333;
border: 1px solid #d9d9d9;
padding: 10px 8px;
vertical-align: middle;
}
/* 打印优化 */
@media print {
.order-detail-content {
font-size: 12px;
}
.order-table {
page-break-inside: avoid;
}
}
</style>