fix(订单管理): 统一订单详情状态标签与抽屉样式

- 中台/实物/网盘订单详情状态统一 el-tag 展示,补齐待评价/售后中映射;业务状态推导抽为 getOrderBusinessStatus 复用
- 网盘订单详情按实物详情版式重写(头部摘要+边框卡片页签),列表状态映射补全
- 详情抽屉 body 左右归零,摘要项改弹性换行,颜色统一主题令牌;列表去掉与标签重复的「部分退款中」副行
This commit is contained in:
吴昊天 2026-10-13 18:07:35 +08:00
parent 2765e2a514
commit 55e4f23738
8 changed files with 539 additions and 396 deletions

View File

@ -315,7 +315,7 @@ function buildAddress(addr) {
display: flex;
margin-top: 16px;
font-size: 13px;
color: #666666;
color: var(--prev-color-text-primary);
&:nth-child(3n + 1) {
padding-right: 20px;

View File

@ -14,8 +14,10 @@
<li class="item">
<div class="title">订单状态</div>
<div>
{{ getStatusLabel(detailData.status_code) }}
<span v-if="detailData.refund_status == 1" style="color: #ed4014">
<el-tag :type="getStatusClass(detailData.status_code)">{{
getStatusLabel(detailData.status_code)
}}</el-tag>
<span v-if="detailData.refund_status == 1" style="color: #ed4014; margin-left: 4px">
{{ detailData.is_all_refund ? '退款中' : '部分退款中' }}
</span>
</div>
@ -116,14 +118,31 @@ function getStatusLabel(code) {
const map = {
pending_payment: '待支付',
processing: '待处理',
pending_review: '待评价',
completed: '已完成',
canceled: '已取消',
after_sale: '售后中',
refunding: '退款中',
refunded: '已退款',
};
return map[code] || code || '--';
}
/* 与列表 getStatusClass 同口径 */
function getStatusClass(code) {
const map = {
pending_payment: 'warning',
processing: 'primary',
pending_review: 'success',
completed: 'success',
canceled: 'danger',
after_sale: 'warning',
refunding: 'warning',
refunded: 'info',
};
return map[code] || 'info';
}
function formatDate(date) {
const d = new Date(date);
return `${d.getFullYear()}/${(d.getMonth() + 1).toString().padStart(2, '0')}/${d
@ -199,8 +218,9 @@ defineExpose({ loadDetail });
padding: 0;
.item {
flex: none;
width: 200px;
flex: 1 1 auto;
min-width: 0;
padding-right: 16px;
font-size: 14px;
line-height: 14px;
color: var(--prev-color-text-regular);
@ -209,7 +229,7 @@ defineExpose({ loadDetail });
margin-bottom: 12px;
font-size: 13px;
line-height: 13px;
color: #666666;
color: var(--prev-color-text-primary);
}
.value1 {

View File

@ -268,7 +268,13 @@
</div></template
>
</el-dialog>
<el-drawer v-model="detailDrawerVisible" title="订单详情" size="720px" @opened="onDetailDrawerOpened">
<el-drawer
v-model="detailDrawerVisible"
title="订单详情"
size="720px"
class="order-detail-drawer"
@opened="onDetailDrawerOpened"
>
<OrderCenterDetail :id="detailOrderId" ref="orderDetailRef" />
</el-drawer>
</div>
@ -638,4 +644,9 @@ onMounted(() => {
margin: 0;
padding: 0 20px;
}
/* 详情抽屉 body 左右归零(全局 variables.scss 为 20px 35px),与实物/网盘订单详情抽屉一致 */
:deep(.order-detail-drawer .el-drawer__body) {
padding: 20px 0 !important;
}
</style>

View File

@ -183,3 +183,42 @@ export function saveOrderIntegral(data) {
export function getOrderExpress(orderNo) {
return request.get('normal/order/express/' + orderNo);
}
/**
* 订单业务状态:与订单列表 OrderTable 的 getBusinessStatus 同口径,
* 供详情弹窗等场景复用(列表/详情状态展示保持一致)
*/
export function getOrderBusinessStatus(row = {}) {
if (row.is_del === 1) {
return { code: 'deleted', text: '已删除', type: 'danger' };
}
if (row.status_code === 'pending_payment') {
return { code: 'pending_payment', text: '待支付', type: 'warning' };
}
if (row.status_code === 'canceled') {
return { code: 'canceled', text: '已取消', type: 'danger' };
}
if (row.status_code === 'after_sale' || row.status_code === 'refunding') {
return { code: 'after_sale', text: '退换/售后', type: 'info' };
}
if (row.status_code === 'refunded') {
return { code: 'refunded', text: '已退款', type: 'info' };
}
if (row.status_code === 'processing') {
// 到店自提订单显示待到店;其余按发货进度拆分待发货/待收货
if (row.extra_info?.delivery_type === 'pickup') {
return { code: 'pending_pickup', text: '待到店', type: 'warning' };
}
if (!row.delivery_time || row.delivery_time === 0) {
return { code: 'pending_shipped', text: '待发货', type: 'danger' };
}
return { code: 'pending_receive', text: '待收货', type: 'primary' };
}
if (row.status_code === 'pending_review') {
return { code: 'pending_review', text: '待评价', type: 'success' };
}
if (row.status_code === 'completed') {
return { code: 'completed', text: '已完成', type: 'success' };
}
return { code: row.status_code, text: row.status_code || '未知', type: 'info' };
}

View File

@ -14,8 +14,8 @@
<li class="item">
<div class="title">订单状态</div>
<div>
{{ detailData.status_text || '--' }}
<span v-if="detailData.refund_status == 1" style="color: #ed4014">
<el-tag :type="businessStatus.type">{{ businessStatus.text }}</el-tag>
<span v-if="detailData.refund_status == 1" style="color: #ed4014; margin-left: 4px">
{{ detailData.is_all_refund ? '退款中' : '部分退款中' }}
</span>
</div>
@ -449,7 +449,7 @@ import { useRoute } from 'vue-router';
import { ElMessage } from 'element-plus';
import orderIcon from '@/assets/images/order_icon.png';
import request from '@/libs/request';
import { getOrderExpress } from '../normalOrder';
import { getOrderExpress, getOrderBusinessStatus } from '../normalOrder';
defineOptions({ name: 'normalOrderDetail' });
@ -471,6 +471,9 @@ const orderItems = computed(() => {
return detailData.value.order_items || detailData.value.cartInfo || [];
});
/** 订单状态与列表同口径(待发货/待收货/待到店等业务状态) */
const businessStatus = computed(() => getOrderBusinessStatus(detailData.value || {}));
/** 售后进度数据(后端注入到 detail.extend.after_sale) */
const afterSaleInfo = computed(() => {
if (!detailData.value) return null;
@ -658,14 +661,17 @@ defineExpose({ loadDetail });
.list {
display: flex;
flex-wrap: wrap;
row-gap: 16px;
margin-top: 20px;
overflow: hidden;
list-style: none;
padding: 0;
.item {
flex: none;
width: 200px;
flex: 1 1 auto;
min-width: 0;
padding-right: 16px;
font-size: 14px;
line-height: 14px;
color: var(--prev-color-text-regular);

View File

@ -106,7 +106,6 @@
<el-tag :type="getBusinessStatus(scope.row).type">
{{ getRowStatusLabel(scope.row) }}
</el-tag>
<div v-if="!scope.row.is_all_refund && scope.row.refund_status === 1" class="trip">部分退款中</div>
</template>
</el-table-column>
<el-table-column label="售后" width="100">
@ -643,12 +642,6 @@ defineExpose({ selectedIds, page });
font-weight: bold;
}
.trip {
color: #ed4014;
font-size: 12px;
margin-top: 2px;
}
:deep(.el-dropdown-link) {
cursor: pointer;
color: var(--prev-color-primary);

View File

@ -6,329 +6,324 @@
<div v-if="!loading && orderInfo.order_no">
<!-- 头部摘要 -->
<el-card shadow="never" class="mt16">
<template #header
><div class="head">
<div class="full">
<img class="order-icon" src="@/assets/images/order_icon.png" alt="" />
<div class="text">
<div class="title">网盘商品订单</div>
<div>订单号:{{ orderInfo.order_no }}</div>
</div>
<div class="head">
<div class="full">
<img class="order_icon" src="@/assets/images/order_icon.png" alt="" />
<div class="text">
<div class="title">网盘商品订单</div>
<div>订单号:{{ orderInfo.order_no }}</div>
</div>
</div>
<ul class="list">
<li class="item">
<div class="title">订单状态</div>
<div>
<el-tag :type="statusType(orderInfo.status_code)">
{{ statusLabel(orderInfo.status_code) }}
</el-tag>
<span v-if="orderInfo.refund_status == 1" style="color: #ed4014; margin-left: 4px">
{{ orderInfo.is_all_refund ? '退款中' : '部分退款中' }}
</span>
</div>
<ul class="head-list">
<li class="item">
<div class="label">订单状态</div>
<div>
<el-tag :type="statusType(orderInfo.status_code)">
{{ statusLabel(orderInfo.status_code) }}
</el-tag>
<span v-if="orderInfo.refund_status == 1" style="color: #ed4014; margin-left: 4px">
{{ orderInfo.is_all_refund ? '退款中' : '部分退款中' }}
</span>
</div>
</li>
<li class="item">
<div class="label">订单金额</div>
<div class="price">¥{{ orderInfo.total_price || '0.00' }}</div>
</li>
<li class="item" v-if="orderInfo.refund_status == 2">
<div class="label">实际退款</div>
<div>¥{{ orderInfo.refunded_price || '0.00' }}</div>
</li>
<li class="item">
<div class="label">支付方式</div>
<div>{{ orderInfo.pay_type_name || orderInfo.pay_type || '--' }}</div>
</li>
<li class="item">
<div class="label">支付时间</div>
<div>{{ fmt(orderInfo.pay_time) }}</div>
</li>
<li class="item">
<div class="label">业务状态</div>
<div>
<el-tag v-if="orderInfo.business_status" :type="tagType(orderInfo.business_status)">
{{ orderInfo.business_status.text }}
</el-tag>
<span v-else>--</span>
</div>
</li>
</ul>
</div></template
>
</el-card>
</li>
<li class="item">
<div class="title">订单金额</div>
<div class="value1">¥{{ orderInfo.total_price || '0.00' }}</div>
</li>
<li class="item" v-if="orderInfo.refund_status == 2">
<div class="title">实际退款</div>
<div>¥{{ orderInfo.refunded_price || '0.00' }}</div>
</li>
<li class="item">
<div class="title">支付方式</div>
<div>{{ orderInfo.pay_type_name || orderInfo.pay_type || '--' }}</div>
</li>
<li class="item">
<div class="title">支付时间</div>
<div>{{ fmt(orderInfo.pay_time) }}</div>
</li>
<li class="item">
<div class="title">业务状态</div>
<div>
<el-tag v-if="orderInfo.business_status" :type="tagType(orderInfo.business_status)">
{{ orderInfo.business_status.text }}
</el-tag>
<span v-else>--</span>
</div>
</li>
</ul>
</div>
<!-- 订单信息 Tab -->
<el-card shadow="never" class="mt16">
<el-tabs v-model="activeTab">
<el-tab-pane label="订单信息" name="detail">
<!-- 商品信息 -->
<div class="section" v-if="orderItems.length">
<div class="section-title">商品信息</div>
<el-table :data="orderItems" stripe class="goods-table">
<el-table-column label="商品" min-width="300">
<template #default="{ row }">
<div class="goods-cell">
<el-image :src="row.image" class="goods-img" />
<div class="goods-meta">
<p class="goods-name">{{ row.store_name }}</p>
<p v-if="row.sku" class="goods-sku">{{ row.sku }}</p>
</div>
<el-tabs type="border-card" v-model="activeTab">
<el-tab-pane label="订单信息" name="detail">
<!-- 商品信息 -->
<div class="section" v-if="orderItems.length">
<div class="section-title">商品信息</div>
<el-table :data="orderItems" stripe class="goods-table">
<el-table-column label="商品" min-width="300">
<template #default="{ row }">
<div class="goods-cell">
<el-image :src="row.image" class="goods-img" />
<div class="goods-meta">
<p class="goods-name">{{ row.store_name }}</p>
<p v-if="row.sku" class="goods-sku">{{ row.sku }}</p>
</div>
</template>
</el-table-column>
<el-table-column label="单价" width="100">
<template #default="{ row }">¥{{ row.true_price || row.price }}</template>
</el-table-column>
<el-table-column label="数量" width="80" prop="cart_num" />
<el-table-column label="小计" width="120">
<template #default="{ row }"
>¥{{ (parseFloat(row.true_price || row.price) * row.cart_num).toFixed(2) }}</template
>
</el-table-column>
</el-table>
</div>
<!-- 用户信息 -->
<div class="section">
<div class="section-title">用户信息</div>
<el-row :gutter="24" class="detail-grid">
<el-col :span="8"
><div class="detail-item">
<span class="label">用户名称:</span><span class="value">{{ orderInfo.nickname || '--' }}</span>
</div></el-col
>
<el-col :span="8"
><div class="detail-item">
<span class="label">联系电话:</span><span class="value">{{ orderInfo.user_phone || '--' }}</span>
</div></el-col
>
</el-row>
</div>
<!-- 订单信息 -->
<div class="section">
<div class="section-title">订单信息</div>
<el-row :gutter="24" class="detail-grid">
<el-col :span="8"
><div class="detail-item">
<span class="label">创建时间:</span><span class="value">{{ fmt(orderInfo.add_time) }}</span>
</div></el-col
>
<el-col :span="8"
><div class="detail-item">
<span class="label">商品总数:</span><span class="value">{{ orderInfo.total_num }}</span>
</div></el-col
>
<el-col :span="8"
><div class="detail-item">
<span class="label">商品总价:</span><span class="value">¥{{ orderInfo.total_price }}</span>
</div></el-col
>
<el-col :span="8"
><div class="detail-item">
<span class="label">优惠券金额:</span
><span class="value">-¥{{ orderInfo.coupon_price || '0.00' }}</span>
</div></el-col
>
<el-col :span="8"
><div class="detail-item">
<span class="label">积分抵扣:</span
><span class="value">-¥{{ orderInfo.deduction_price || '0.00' }}</span>
</div></el-col
>
<el-col :span="8"
><div class="detail-item">
<span class="label">会员等级优惠:</span
><span class="value">-¥{{ orderInfo.member_level_discount || '0.00' }}</span>
</div></el-col
>
<el-col :span="8"
><div class="detail-item">
<span class="label">付费会员优惠:</span
><span class="value">-¥{{ orderInfo.vip_discount || '0.00' }}</span>
</div></el-col
>
<el-col :span="8"
><div class="detail-item">
<span class="label price-label">实际支付:</span
><span class="value price-value">¥{{ orderInfo.pay_price || '0.00' }}</span>
</div></el-col
>
</el-row>
</div>
<!-- 网盘商品扩展信息 -->
<div class="section" v-if="orderInfo.virtual_extend">
<div class="section-title">网盘商品信息</div>
<el-row :gutter="24" class="detail-grid">
<el-col :span="8"
><div class="detail-item">
<span class="label">商品ID:</span
><span class="value">{{ orderInfo.virtual_extend.product_id || '--' }}</span>
</div></el-col
>
<el-col :span="8"
><div class="detail-item">
<span class="label">状态:</span
><span class="value">
<el-tag :type="statusType(orderInfo.virtual_extend.status)">
{{ orderInfo.virtual_extend.status_text || statusLabel(orderInfo.virtual_extend.status) }}
</el-tag>
</span>
</div></el-col
>
<el-col :span="8"
><div class="detail-item">
<span class="label">发放时间:</span
><span class="value">{{ fmt(orderInfo.virtual_extend.send_time) }}</span>
</div></el-col
>
<el-col :span="8"
><div class="detail-item">
<span class="label">完成时间:</span
><span class="value">{{ fmt(orderInfo.virtual_extend.complete_time) }}</span>
</div></el-col
>
</el-row>
</div>
<!-- 发货/交付信息 -->
<div class="section" v-if="orderInfo.virtual_extend && orderInfo.virtual_extend.delivery_info">
<div class="section-title">交付信息</div>
<el-row :gutter="24" class="detail-grid">
<el-col :span="24"
><div class="detail-item">
<span class="label">交付内容:</span
><span class="value" style="white-space: pre-wrap">{{
orderInfo.virtual_extend.delivery_info
}}</span>
</div></el-col
>
</el-row>
</div>
<!-- 发票信息 -->
<div class="section" v-if="orderInfo.invoice && Object.keys(orderInfo.invoice).length">
<div class="section-title">发票信息</div>
<el-row :gutter="24" class="detail-grid">
<el-col :span="8"
><div class="detail-item">
<span class="label">发票抬头:</span><span class="value">{{ orderInfo.invoice.name || '--' }}</span>
</div></el-col
>
<el-col :span="8" v-if="orderInfo.invoice.header_type === 2 && orderInfo.invoice.type === 1"
><div class="detail-item">
<span class="label">企业税号:</span
><span class="value">{{ orderInfo.invoice.duty_number || '--' }}</span>
</div></el-col
>
<el-col :span="8" v-if="orderInfo.invoice.header_type === 2 && orderInfo.invoice.type === 1"
><div class="detail-item">
<span class="label">发票类型:</span><span class="value">电子普通发票</span>
</div></el-col
>
<el-col :span="8" v-if="orderInfo.invoice.header_type === 2 && orderInfo.invoice.type === 1"
><div class="detail-item">
<span class="label">发票抬头类型:</span><span class="value">企业</span>
</div></el-col
>
<el-col :span="8" v-if="orderInfo.invoice.header_type === 1 && orderInfo.invoice.type === 1"
><div class="detail-item">
<span class="label">真实姓名:</span><span class="value">{{ orderInfo.invoice.name || '--' }}</span>
</div></el-col
>
<el-col :span="8" v-if="orderInfo.invoice.header_type === 1 && orderInfo.invoice.type === 1"
><div class="detail-item">
<span class="label">联系电话:</span
><span class="value">{{ orderInfo.invoice.drawer_phone || '--' }}</span>
</div></el-col
>
<el-col :span="8" v-if="orderInfo.invoice.header_type === 2 && orderInfo.invoice.type === 1"
><div class="detail-item">
<span class="label">联系电话:</span
><span class="value">{{ orderInfo.invoice.user_phone || '--' }}</span>
</div></el-col
>
<el-col :span="8" v-if="orderInfo.invoice.header_type === 2 && orderInfo.invoice.type === 1"
><div class="detail-item">
<span class="label">联系邮箱:</span
><span class="value">{{ orderInfo.invoice.email || '--' }}</span>
</div></el-col
>
<el-col :span="8"
><div class="detail-item">
<span class="label">开票状态:</span
><span class="value">{{ orderInfo.invoice.is_invoice ? '已开票' : '未开票' }}</span>
</div></el-col
>
</el-row>
</div>
<!-- 买家留言 -->
<div class="section">
<div class="section-title">买家留言</div>
<el-row :gutter="24" class="detail-grid">
<el-col :span="24"
><div class="detail-item">
<span class="value">{{ orderInfo.mark || '--' }}</span>
</div></el-col
>
</el-row>
</div>
<!-- 表单信息 -->
<div class="section" v-if="orderInfo.custom_form && orderInfo.custom_form.length">
<div class="section-title">表单信息</div>
<el-row :gutter="24" class="detail-grid">
<template v-for="(item, idx) in orderInfo.custom_form" :key="idx">
<el-col :span="8" v-if="item.label !== 'img'">
<div class="detail-item">
<span class="label">{{ item.title }}:</span><span class="value">{{ item.value }}</span>
</div>
</el-col>
<el-col :span="24" v-else>
<div class="detail-item">
<span class="label">{{ item.title }}:</span>
<span class="value">
<img v-for="(img, i) in item.value" :key="i" :src="img" class="form-img" v-viewer />
</span>
</div>
</el-col>
</div>
</template>
</el-row>
</div>
<!-- 订单备注 -->
<div class="section">
<div class="section-title">订单备注</div>
<el-row :gutter="24" class="detail-grid">
<el-col :span="24"
><div class="detail-item">
<span class="value">{{ orderInfo.remark || '--' }}</span>
</div></el-col
</el-table-column>
<el-table-column label="单价" width="100">
<template #default="{ row }">¥{{ row.true_price || row.price }}</template>
</el-table-column>
<el-table-column label="数量" width="80" prop="cart_num" />
<el-table-column label="小计" width="120">
<template #default="{ row }"
>¥{{ (parseFloat(row.true_price || row.price) * row.cart_num).toFixed(2) }}</template
>
</el-row>
</div>
</el-tab-pane>
</el-table-column>
</el-table>
</div>
<el-tab-pane label="订单进度" name="timeline">
<div class="tl-section" v-if="orderInfo.timeline && orderInfo.timeline.length">
<el-timeline>
<el-timeline-item
v-for="(item, index) in orderInfo.timeline"
:key="index"
:timestamp="item.time"
:color="index === 0 ? '#409eff' : '#e4e7ed'"
>
<span class="tl-title">{{ item.title }}</span>
<span class="tl-desc">{{ item.desc }}</span>
</el-timeline-item>
</el-timeline>
</div>
</el-tab-pane>
</el-tabs>
</el-card>
<!-- 用户信息 -->
<div class="section">
<div class="section-title">用户信息</div>
<el-row :gutter="24" class="detail-grid">
<el-col :span="8"
><div class="detail-item">
<span class="label">用户名称:</span><span class="value">{{ orderInfo.nickname || '--' }}</span>
</div></el-col
>
<el-col :span="8"
><div class="detail-item">
<span class="label">联系电话:</span><span class="value">{{ orderInfo.user_phone || '--' }}</span>
</div></el-col
>
</el-row>
</div>
<!-- 订单信息 -->
<div class="section">
<div class="section-title">订单信息</div>
<el-row :gutter="24" class="detail-grid">
<el-col :span="8"
><div class="detail-item">
<span class="label">创建时间:</span><span class="value">{{ fmt(orderInfo.add_time) }}</span>
</div></el-col
>
<el-col :span="8"
><div class="detail-item">
<span class="label">商品总数:</span><span class="value">{{ orderInfo.total_num }}</span>
</div></el-col
>
<el-col :span="8"
><div class="detail-item">
<span class="label">商品总价:</span><span class="value">¥{{ orderInfo.total_price }}</span>
</div></el-col
>
<el-col :span="8"
><div class="detail-item">
<span class="label">优惠券金额:</span
><span class="value">-¥{{ orderInfo.coupon_price || '0.00' }}</span>
</div></el-col
>
<el-col :span="8"
><div class="detail-item">
<span class="label">积分抵扣:</span
><span class="value">-¥{{ orderInfo.deduction_price || '0.00' }}</span>
</div></el-col
>
<el-col :span="8"
><div class="detail-item">
<span class="label">会员等级优惠:</span
><span class="value">-¥{{ orderInfo.member_level_discount || '0.00' }}</span>
</div></el-col
>
<el-col :span="8"
><div class="detail-item">
<span class="label">付费会员优惠:</span
><span class="value">-¥{{ orderInfo.vip_discount || '0.00' }}</span>
</div></el-col
>
<el-col :span="8"
><div class="detail-item">
<span class="label price-label">实际支付:</span
><span class="value price-value">¥{{ orderInfo.pay_price || '0.00' }}</span>
</div></el-col
>
</el-row>
</div>
<!-- 网盘商品扩展信息 -->
<div class="section" v-if="orderInfo.virtual_extend">
<div class="section-title">网盘商品信息</div>
<el-row :gutter="24" class="detail-grid">
<el-col :span="8"
><div class="detail-item">
<span class="label">商品ID:</span
><span class="value">{{ orderInfo.virtual_extend.product_id || '--' }}</span>
</div></el-col
>
<el-col :span="8"
><div class="detail-item">
<span class="label">状态:</span
><span class="value">
<el-tag :type="statusType(orderInfo.virtual_extend.status)">
{{ orderInfo.virtual_extend.status_text || statusLabel(orderInfo.virtual_extend.status) }}
</el-tag>
</span>
</div></el-col
>
<el-col :span="8"
><div class="detail-item">
<span class="label">发放时间:</span
><span class="value">{{ fmt(orderInfo.virtual_extend.send_time) }}</span>
</div></el-col
>
<el-col :span="8"
><div class="detail-item">
<span class="label">完成时间:</span
><span class="value">{{ fmt(orderInfo.virtual_extend.complete_time) }}</span>
</div></el-col
>
</el-row>
</div>
<!-- 发货/交付信息 -->
<div class="section" v-if="orderInfo.virtual_extend && orderInfo.virtual_extend.delivery_info">
<div class="section-title">交付信息</div>
<el-row :gutter="24" class="detail-grid">
<el-col :span="24"
><div class="detail-item">
<span class="label">交付内容:</span
><span class="value" style="white-space: pre-wrap">{{
orderInfo.virtual_extend.delivery_info
}}</span>
</div></el-col
>
</el-row>
</div>
<!-- 发票信息 -->
<div class="section" v-if="orderInfo.invoice && Object.keys(orderInfo.invoice).length">
<div class="section-title">发票信息</div>
<el-row :gutter="24" class="detail-grid">
<el-col :span="8"
><div class="detail-item">
<span class="label">发票抬头:</span><span class="value">{{ orderInfo.invoice.name || '--' }}</span>
</div></el-col
>
<el-col :span="8" v-if="orderInfo.invoice.header_type === 2 && orderInfo.invoice.type === 1"
><div class="detail-item">
<span class="label">企业税号:</span
><span class="value">{{ orderInfo.invoice.duty_number || '--' }}</span>
</div></el-col
>
<el-col :span="8" v-if="orderInfo.invoice.header_type === 2 && orderInfo.invoice.type === 1"
><div class="detail-item">
<span class="label">发票类型:</span><span class="value">电子普通发票</span>
</div></el-col
>
<el-col :span="8" v-if="orderInfo.invoice.header_type === 2 && orderInfo.invoice.type === 1"
><div class="detail-item">
<span class="label">发票抬头类型:</span><span class="value">企业</span>
</div></el-col
>
<el-col :span="8" v-if="orderInfo.invoice.header_type === 1 && orderInfo.invoice.type === 1"
><div class="detail-item">
<span class="label">真实姓名:</span><span class="value">{{ orderInfo.invoice.name || '--' }}</span>
</div></el-col
>
<el-col :span="8" v-if="orderInfo.invoice.header_type === 1 && orderInfo.invoice.type === 1"
><div class="detail-item">
<span class="label">联系电话:</span
><span class="value">{{ orderInfo.invoice.drawer_phone || '--' }}</span>
</div></el-col
>
<el-col :span="8" v-if="orderInfo.invoice.header_type === 2 && orderInfo.invoice.type === 1"
><div class="detail-item">
<span class="label">联系电话:</span
><span class="value">{{ orderInfo.invoice.user_phone || '--' }}</span>
</div></el-col
>
<el-col :span="8" v-if="orderInfo.invoice.header_type === 2 && orderInfo.invoice.type === 1"
><div class="detail-item">
<span class="label">联系邮箱:</span
><span class="value">{{ orderInfo.invoice.email || '--' }}</span>
</div></el-col
>
<el-col :span="8"
><div class="detail-item">
<span class="label">开票状态:</span
><span class="value">{{ orderInfo.invoice.is_invoice ? '已开票' : '未开票' }}</span>
</div></el-col
>
</el-row>
</div>
<!-- 买家留言 -->
<div class="section">
<div class="section-title">买家留言</div>
<el-row :gutter="24" class="detail-grid">
<el-col :span="24"
><div class="detail-item">
<span class="value">{{ orderInfo.mark || '--' }}</span>
</div></el-col
>
</el-row>
</div>
<!-- 表单信息 -->
<div class="section" v-if="orderInfo.custom_form && orderInfo.custom_form.length">
<div class="section-title">表单信息</div>
<el-row :gutter="24" class="detail-grid">
<template v-for="(item, idx) in orderInfo.custom_form" :key="idx">
<el-col :span="8" v-if="item.label !== 'img'">
<div class="detail-item">
<span class="label">{{ item.title }}:</span><span class="value">{{ item.value }}</span>
</div>
</el-col>
<el-col :span="24" v-else>
<div class="detail-item">
<span class="label">{{ item.title }}:</span>
<span class="value">
<img v-for="(img, i) in item.value" :key="i" :src="img" class="form-img" v-viewer />
</span>
</div>
</el-col>
</template>
</el-row>
</div>
<!-- 订单备注 -->
<div class="section">
<div class="section-title">订单备注</div>
<el-row :gutter="24" class="detail-grid">
<el-col :span="24"
><div class="detail-item">
<span class="value">{{ orderInfo.remark || '--' }}</span>
</div></el-col
>
</el-row>
</div>
</el-tab-pane>
<el-tab-pane label="订单进度" name="timeline">
<div class="tl-section" v-if="orderInfo.timeline && orderInfo.timeline.length">
<el-timeline>
<el-timeline-item
v-for="(item, index) in orderInfo.timeline"
:key="index"
:timestamp="item.time"
:color="index === 0 ? '#409eff' : '#e4e7ed'"
>
<span class="tl-title">{{ item.title }}</span>
<span class="tl-desc">{{ item.desc }}</span>
</el-timeline-item>
</el-timeline>
</div>
<div v-else class="empty-tips">暂无订单进度</div>
</el-tab-pane>
</el-tabs>
</div>
<div v-else-if="!loading" class="empty-tip">
<el-empty description="订单信息未找到"></el-empty>
@ -362,7 +357,8 @@ function dateFormat(ts) {
const statusLabelMap = {
pending_payment: '待支付',
processing: '待处理',
processing: '处理中',
pending_review: '待评价',
completed: '已完成',
canceled: '已取消',
refunding: '退款中',
@ -372,6 +368,7 @@ const statusLabelMap = {
const statusTypeMap = {
pending_payment: 'warning',
processing: 'primary',
pending_review: 'success',
completed: 'success',
canceled: 'info',
refunding: 'danger',
@ -439,65 +436,120 @@ async function loadDetail() {
}
</script>
<style scoped>
.mt16 {
margin-top: 16px;
<style lang="scss" scoped>
/* 边框卡片型页签:去除自带边框/阴影,仅保留页签排版(与实物订单详情一致) */
:deep(.el-tabs--border-card > .el-tabs__header .el-tabs__item.is-active) {
border-bottom: none;
}
:deep(.el-tabs__item) {
height: 40px !important;
line-height: 40px !important;
}
/* 头部摘要 */
.head {
padding: 0;
padding: 0 30px 24px;
.full {
display: flex;
align-items: center;
.order_icon {
width: 60px;
height: 60px;
}
.text {
align-self: center;
flex: 1;
min-width: 0;
padding-left: 12px;
font-size: 13px;
color: var(--prev-color-text-primary);
.title {
margin-bottom: 10px;
font-weight: 500;
font-size: 16px;
line-height: 16px;
color: var(--prev-color-text-regular);
}
}
}
.list {
display: flex;
flex-wrap: wrap;
row-gap: 16px;
margin-top: 20px;
overflow: hidden;
list-style: none;
padding: 0;
.item {
flex: 1 1 auto;
min-width: 0;
padding-right: 16px;
font-size: 14px;
line-height: 14px;
color: var(--prev-color-text-regular);
.title {
margin-bottom: 12px;
font-size: 13px;
line-height: 13px;
color: var(--prev-color-text-primary);
}
.value1 {
color: #f56022;
font-weight: bold;
}
}
}
}
.head .full {
display: flex;
align-items: center;
margin-bottom: 16px;
:deep(.el-tabs--border-card > .el-tabs__content) {
/* 与 .head 的 30px 左右缩进对齐(抽屉 body 左右已由列表页归零) */
padding: 0 30px;
}
.head .order-icon {
width: 50px;
height: 50px;
margin-right: 12px;
:deep(.el-tabs--border-card > .el-tabs__header),
:deep(.el-tabs--border-card > .el-tabs__header .el-tabs__item:active) {
border: none;
height: 40px;
}
.head .text {
flex: 1;
}
.head .text .title {
font-size: 16px;
:deep(.el-tabs--border-card > .el-tabs__header .el-tabs__item.is-active) {
border: none;
border-top: 2px solid var(--prev-color-primary);
font-size: 13px;
font-weight: 500;
color: var(--prev-color-text-regular);
margin-bottom: 6px;
line-height: 16px;
}
.head .text div {
:deep(.el-tabs--border-card > .el-tabs__header .el-tabs__item) {
border: none;
margin-top: 0;
transition: none;
height: 40px !important;
line-height: 40px !important;
width: 92px !important;
font-size: 13px;
color: var(--prev-color-text-primary);
}
.head-list {
display: flex;
list-style: none;
padding: 0;
margin: 0;
flex-wrap: wrap;
}
.head-list .item {
flex: 0 0 160px;
margin-top: 12px;
font-size: 14px;
font-weight: 400;
color: var(--prev-color-text-regular);
}
.head-list .item .label {
font-size: 13px;
color: var(--prev-color-text-secondary);
margin-bottom: 8px;
}
.head-list .item .price {
color: #ed4014;
font-weight: bold;
:deep(.el-tabs--border-card) {
border: none;
box-shadow: none;
}
/* section 通用 */
.section {
padding: 20px 0;
border-bottom: 1px dashed #eee;
border-bottom: 1px dashed var(--prev-border-color-lighter);
}
.section:last-child {
border-bottom: none;
@ -510,6 +562,7 @@ async function loadDetail() {
color: var(--prev-color-text-regular);
margin-bottom: 16px;
}
.detail-grid {
padding: 0;
}
@ -517,7 +570,7 @@ async function loadDetail() {
display: flex;
padding: 8px 0;
font-size: 13px;
color: #666;
color: var(--prev-color-text-primary);
}
.detail-item .label {
flex-shrink: 0;
@ -526,6 +579,7 @@ async function loadDetail() {
}
.detail-item .value {
flex: 1;
min-width: 0;
word-break: break-all;
}
.price-label {
@ -581,6 +635,11 @@ async function loadDetail() {
/* 时间线 */
.tl-section {
padding: 16px 0;
/* EP 时间线默认 padding-left 40px,叠加 tabs 缩进后过深,收齐到内容左缘 */
:deep(.el-timeline) {
padding-left: 4px;
}
}
:deep(.el-timeline-item__content .tl-title) {
font-size: 13px;
@ -594,19 +653,11 @@ async function loadDetail() {
}
.empty-tip {
padding: 60px 0;
padding: 40px;
}
:deep(.el-tabs--border-card > .el-tabs__content) {
/* 独立路由详情页:.head 无缩进,tabs 内容对齐 */
padding: 0;
}
:deep(.el-tabs--border-card) {
border: none;
box-shadow: none;
}
:deep(.el-tabs__item) {
height: 40px !important;
line-height: 40px !important;
.empty-tips {
padding: 20px 0;
color: var(--prev-color-text-secondary);
font-size: 13px;
}
</style>

View File

@ -69,7 +69,7 @@
</div>
</el-card>
<el-drawer v-model="detailVisible" title="订单详情" size="720px" destroy-on-close>
<el-drawer v-model="detailVisible" title="订单详情" size="720px" class="order-detail-drawer" destroy-on-close>
<OrderDetail :order-no="detailOrderNo" :show-back="false" />
</el-drawer>
</div>
@ -103,11 +103,29 @@ function dateFormat(ts) {
}
function statusType(status) {
const map = { pending_payment: 'warning', completed: 'success', closed: 'info' };
const map = {
pending_payment: 'warning',
processing: 'primary',
pending_review: 'success',
completed: 'success',
canceled: 'info',
refunding: 'danger',
refunded: 'info',
closed: 'info',
};
return map[status] || 'info';
}
function statusLabel(status) {
const map = { pending_payment: '待付款', completed: '已完成', closed: '已关闭' };
const map = {
pending_payment: '待付款',
processing: '处理中',
pending_review: '待评价',
completed: '已完成',
canceled: '已取消',
refunding: '退款中',
refunded: '已退款',
closed: '已关闭',
};
return map[status] || status;
}
async function loadList() {
@ -143,8 +161,13 @@ function openDetail(orderNo) {
loadList();
</script>
<style scoped>
<style lang="scss" scoped>
.mt16 {
margin-top: 16px;
}
/* 详情抽屉 body 左右归零(全局 variables.scss 为 20px 35px),与实物订单详情抽屉一致 */
:deep(.order-detail-drawer .el-drawer__body) {
padding: 20px 0 !important;
}
</style>