213 lines
8.2 KiB
Vue
213 lines
8.2 KiB
Vue
<template>
|
||
<view class="od-page">
|
||
<!-- Loading -->
|
||
<view v-if="loading" class="od-page__loading">
|
||
<text class="od-page__loading-text">订单加载中...</text>
|
||
</view>
|
||
|
||
<template v-else-if="order">
|
||
<!-- Status Hero -->
|
||
<view class="od-page__status-hero">
|
||
<view class="od-page__status-deco1" />
|
||
<view class="od-page__status-deco2" />
|
||
<view class="od-page__status-row">
|
||
<view class="od-page__status-icon">
|
||
<text class="od-page__status-icon-text">🕐</text>
|
||
</view>
|
||
<view class="od-page__status-text">
|
||
<text class="od-page__status-title">{{ order.statusText }}</text>
|
||
<text class="od-page__status-desc">{{ statusDescription }}</text>
|
||
</view>
|
||
</view>
|
||
<view class="od-page__status-badge">
|
||
<text>{{ sceneLabel }} · {{ orderSubtitle }}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- Store Card -->
|
||
<view class="od-page__card">
|
||
<view class="od-page__store">
|
||
<view class="od-page__store-icon">
|
||
<text>🏠</text>
|
||
</view>
|
||
<view class="od-page__store-info">
|
||
<text class="od-page__store-name">{{ order.storeName }}</text>
|
||
<text class="od-page__store-addr">{{ storeAddress }}</text>
|
||
</view>
|
||
<view class="od-page__store-call">
|
||
<text>📞</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- Fulfillment Info -->
|
||
<view class="od-page__card">
|
||
<view class="od-page__fulfill">
|
||
<view v-if="order.tableNo" class="od-page__fulfill-row">
|
||
<text class="od-page__fulfill-label">桌号</text>
|
||
<view class="od-page__table-badge">
|
||
<text>{{ order.tableNo }}</text>
|
||
</view>
|
||
</view>
|
||
<view class="od-page__fulfill-row">
|
||
<text class="od-page__fulfill-label">联系人</text>
|
||
<text class="od-page__fulfill-value">{{ order.customerName }}</text>
|
||
</view>
|
||
<view class="od-page__fulfill-row">
|
||
<text class="od-page__fulfill-label">手机号</text>
|
||
<text class="od-page__fulfill-value">{{ order.customerPhone }}</text>
|
||
</view>
|
||
<view class="od-page__fulfill-hint">
|
||
<text>🛡</text>
|
||
<text class="od-page__fulfill-hint-text">{{ fulfillmentHint }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- Timeline -->
|
||
<view v-if="order.timeline.length" class="od-page__card">
|
||
<view class="od-page__timeline-section">
|
||
<text class="od-page__section-title">📋 订单进度</text>
|
||
<view class="od-page__timeline">
|
||
<view
|
||
v-for="(node, index) in order.timeline"
|
||
:key="index"
|
||
class="od-page__tl-node"
|
||
:class="timelineNodeClass(index)"
|
||
>
|
||
<view class="od-page__tl-dot">
|
||
<text v-if="index < currentTimelineIndex" class="od-page__tl-check">✓</text>
|
||
<text v-else-if="index === currentTimelineIndex" class="od-page__tl-pulse">●</text>
|
||
</view>
|
||
<view class="od-page__tl-content">
|
||
<text class="od-page__tl-title">{{ node.statusText }}</text>
|
||
<text class="od-page__tl-time">{{ node.occurredAt }}</text>
|
||
<text v-if="node.notes" class="od-page__tl-sub">{{ node.notes }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- Products + Fees -->
|
||
<view class="od-page__card">
|
||
<view class="od-page__goods-section">
|
||
<text class="od-page__section-title">🛍 商品明细</text>
|
||
<view class="od-page__goods-list">
|
||
<view v-for="item in order.items" :key="item.id" class="od-page__good">
|
||
<view class="od-page__good-img-placeholder" />
|
||
<view class="od-page__good-info">
|
||
<text class="od-page__good-name">{{ item.productName }}</text>
|
||
<text v-if="item.skuName" class="od-page__good-spec">{{ item.skuName }}</text>
|
||
</view>
|
||
<view class="od-page__good-right">
|
||
<text class="od-page__good-price"><text class="od-page__good-unit">¥</text>{{ item.subTotalText }}</text>
|
||
<text class="od-page__good-qty">×{{ item.quantity }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="od-page__divider" />
|
||
|
||
<view class="od-page__fees">
|
||
<view class="od-page__fee-row">
|
||
<text class="od-page__fee-label">商品小计</text>
|
||
<text class="od-page__fee-value">¥{{ formatPrice(order.itemsAmount) }}</text>
|
||
</view>
|
||
<view class="od-page__fee-row">
|
||
<text class="od-page__fee-label">打包费</text>
|
||
<text class="od-page__fee-value">¥{{ formatPrice(order.packagingFee) }}</text>
|
||
</view>
|
||
<view v-if="order.deliveryFee > 0" class="od-page__fee-row">
|
||
<text class="od-page__fee-label">配送费</text>
|
||
<text class="od-page__fee-value">¥{{ formatPrice(order.deliveryFee) }}</text>
|
||
</view>
|
||
<view v-if="order.discountAmount > 0" class="od-page__fee-row">
|
||
<text class="od-page__fee-label">优惠抵扣</text>
|
||
<text class="od-page__fee-value od-page__fee-value--green">-¥{{ formatPrice(order.discountAmount) }}</text>
|
||
</view>
|
||
<view class="od-page__fee-row od-page__fee-row--total">
|
||
<text class="od-page__fee-label">实付金额</text>
|
||
<text class="od-page__fee-value od-page__fee-value--total">
|
||
<text class="od-page__fee-unit">¥</text>{{ formatPrice(order.paidAmount || order.payableAmount) }}
|
||
</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- Order Info -->
|
||
<view class="od-page__card">
|
||
<view class="od-page__info-section">
|
||
<text class="od-page__section-title">📄 订单信息</text>
|
||
<view class="od-page__info-rows">
|
||
<view class="od-page__info-row">
|
||
<text class="od-page__info-label">订单编号</text>
|
||
<text class="od-page__info-value">{{ order.orderNo }}</text>
|
||
</view>
|
||
<view class="od-page__info-row">
|
||
<text class="od-page__info-label">下单时间</text>
|
||
<text class="od-page__info-value">{{ order.createdAt }}</text>
|
||
</view>
|
||
<view v-if="order.paidAt" class="od-page__info-row">
|
||
<text class="od-page__info-label">支付时间</text>
|
||
<text class="od-page__info-value">{{ order.paidAt }}</text>
|
||
</view>
|
||
<view class="od-page__info-row">
|
||
<text class="od-page__info-label">支付状态</text>
|
||
<text class="od-page__info-value">{{ order.paymentStatusText }}</text>
|
||
</view>
|
||
<view v-if="order.remark" class="od-page__info-row">
|
||
<text class="od-page__info-label">订单备注</text>
|
||
<view class="od-page__info-remark">
|
||
<text>{{ order.remark }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- Bottom Bar -->
|
||
<view class="od-page__bottom-bar">
|
||
<view class="od-page__btn-outline" @click="handleContact">
|
||
<text>📞 联系门店</text>
|
||
</view>
|
||
<view class="od-page__btn-primary" @click="handlePrimaryAction">
|
||
<text>{{ order.actionText || '再来一单' }}</text>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<!-- Not found -->
|
||
<view v-else class="od-page__empty">
|
||
<text class="od-page__empty-title">未找到对应订单</text>
|
||
<view class="od-page__empty-btn" @click="goOrders">
|
||
<text>返回订单列表</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { useOrderDetailPage } from './composables/useOrderDetailPage'
|
||
|
||
const {
|
||
fulfillmentHint,
|
||
formatPrice,
|
||
goOrders,
|
||
handleContact,
|
||
handlePrimaryAction,
|
||
loading,
|
||
order,
|
||
orderSubtitle,
|
||
sceneLabel,
|
||
statusDescription,
|
||
storeAddress,
|
||
timelineNodeClass
|
||
} = useOrderDetailPage()
|
||
</script>
|
||
|
||
<style lang="scss">
|
||
@use './styles/index.scss';
|
||
</style>
|