|
@@ -1,107 +1,243 @@
|
|
|
<template>
|
|
<template>
|
|
|
<view class="container">
|
|
<view class="container">
|
|
|
- <!-- 订单状态 -->
|
|
|
|
|
- <view class="card status-card">
|
|
|
|
|
- <view class="status-left">
|
|
|
|
|
- <view class="status-icon-wrapper">
|
|
|
|
|
- <text class="status-icon">✓</text>
|
|
|
|
|
- </view>
|
|
|
|
|
- <text class="status-text">已支付</text>
|
|
|
|
|
- </view>
|
|
|
|
|
- <text class="invoice-status">未开票</text>
|
|
|
|
|
|
|
+ <!-- 加载中 -->
|
|
|
|
|
+ <view v-if="loading" class="loading-wrapper">
|
|
|
|
|
+ <text>加载中...</text>
|
|
|
</view>
|
|
</view>
|
|
|
|
|
|
|
|
- <!-- 订单明细 -->
|
|
|
|
|
- <view class="card detail-card">
|
|
|
|
|
- <view class="card-header">
|
|
|
|
|
- <text class="card-title">订单明细</text>
|
|
|
|
|
- </view>
|
|
|
|
|
- <view class="product-item">
|
|
|
|
|
- <view class="product-image">
|
|
|
|
|
- <image src="https://trae-api-cn.mchost.guru/api/ide/v1/text_to_image?prompt=small%20brown%20bread%20in%20plastic%20container&image_size=square" mode="aspectFill"></image>
|
|
|
|
|
- </view>
|
|
|
|
|
- <view class="product-info">
|
|
|
|
|
- <text class="product-name">测试0.44</text>
|
|
|
|
|
- <text class="product-price">销售单价 ¥0.44</text>
|
|
|
|
|
|
|
+ <!-- 订单详情 -->
|
|
|
|
|
+ <view v-else-if="order">
|
|
|
|
|
+ <!-- 订单状态 -->
|
|
|
|
|
+ <view class="card status-card">
|
|
|
|
|
+ <view class="status-left">
|
|
|
|
|
+ <view class="status-icon-wrapper" :class="getStatusClass(order.status)">
|
|
|
|
|
+ <text class="status-icon">✓</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <text class="status-text">{{ order.statusText || getStatusText(order.status) }}</text>
|
|
|
</view>
|
|
</view>
|
|
|
- <text class="product-quantity">x1</text>
|
|
|
|
|
|
|
+ <text class="invoice-status">未开票</text>
|
|
|
</view>
|
|
</view>
|
|
|
- <view class="amount-row">
|
|
|
|
|
- <text class="amount-label">实付款</text>
|
|
|
|
|
- <view class="amount-value-wrapper">
|
|
|
|
|
- <text class="amount-prefix">合计</text>
|
|
|
|
|
- <text class="amount-symbol">¥</text>
|
|
|
|
|
- <text class="amount-integer">0.44</text>
|
|
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 订单明细 -->
|
|
|
|
|
+ <view class="card detail-card">
|
|
|
|
|
+ <view class="card-header">
|
|
|
|
|
+ <text class="card-title">订单明细</text>
|
|
|
</view>
|
|
</view>
|
|
|
- </view>
|
|
|
|
|
- <view class="card-footer-actions">
|
|
|
|
|
- <button class="action-btn-outline" @click="applyRefund">申请退款</button>
|
|
|
|
|
- <button class="action-btn-primary" @click="printOrder">打印订单</button>
|
|
|
|
|
- <button class="action-btn-primary" @click="exportImage">导出图片</button>
|
|
|
|
|
- </view>
|
|
|
|
|
- </view>
|
|
|
|
|
-
|
|
|
|
|
- <!-- 订单信息 -->
|
|
|
|
|
- <view class="card info-card">
|
|
|
|
|
- <view class="card-header">
|
|
|
|
|
- <text class="card-title">订单信息</text>
|
|
|
|
|
- </view>
|
|
|
|
|
- <view class="info-list">
|
|
|
|
|
- <view class="info-row">
|
|
|
|
|
- <text class="info-label">订单编号</text>
|
|
|
|
|
- <view class="info-value-group">
|
|
|
|
|
- <text class="info-value">2601081537467989</text>
|
|
|
|
|
- <view class="copy-btn">
|
|
|
|
|
- <view class="copy-icon-box"></view>
|
|
|
|
|
- </view>
|
|
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 商品列表 -->
|
|
|
|
|
+ <view v-for="(product, index) in order.products" :key="index" class="product-item">
|
|
|
|
|
+ <view class="product-image">
|
|
|
|
|
+ <image v-if="product.image" :src="product.image" mode="aspectFill"></image>
|
|
|
|
|
+ <view v-else class="image-placeholder"></view>
|
|
|
</view>
|
|
</view>
|
|
|
|
|
+ <view class="product-info">
|
|
|
|
|
+ <text class="product-name">{{ product.name }}</text>
|
|
|
|
|
+ <text class="product-price">销售单价 ¥{{ product.price.toFixed(2) }}</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <text class="product-quantity">x{{ product.quantity }}</text>
|
|
|
</view>
|
|
</view>
|
|
|
- <view class="info-row">
|
|
|
|
|
- <text class="info-label">下单时间</text>
|
|
|
|
|
- <text class="info-value">2026-01-08 15:37:03</text>
|
|
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 总价 -->
|
|
|
|
|
+ <view class="amount-row">
|
|
|
|
|
+ <text class="amount-label">实付款</text>
|
|
|
|
|
+ <view class="amount-value-wrapper">
|
|
|
|
|
+ <text class="amount-prefix">合计</text>
|
|
|
|
|
+ <text class="amount-symbol">¥</text>
|
|
|
|
|
+ <text class="amount-integer">{{ order.totalAmount.toFixed(2) }}</text>
|
|
|
|
|
+ </view>
|
|
|
</view>
|
|
</view>
|
|
|
- <view class="info-row">
|
|
|
|
|
- <text class="info-label">支付时间</text>
|
|
|
|
|
- <text class="info-value">2026-01-08 15:37:49</text>
|
|
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 操作按钮 -->
|
|
|
|
|
+ <view class="card-footer-actions">
|
|
|
|
|
+ <button v-if="canRefund(order)" class="action-btn-outline" @click="applyRefund">申请退款</button>
|
|
|
|
|
+ <button class="action-btn-primary" @click="printOrder">打印订单</button>
|
|
|
|
|
+ <button class="action-btn-primary" @click="exportImage">导出图片</button>
|
|
|
</view>
|
|
</view>
|
|
|
- <view class="info-row">
|
|
|
|
|
- <text class="info-label">支付方式</text>
|
|
|
|
|
- <text class="info-value">微信</text>
|
|
|
|
|
|
|
+ </view>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 订单信息 -->
|
|
|
|
|
+ <view class="card info-card">
|
|
|
|
|
+ <view class="card-header">
|
|
|
|
|
+ <text class="card-title">订单信息</text>
|
|
|
</view>
|
|
</view>
|
|
|
- <view class="info-row">
|
|
|
|
|
- <text class="info-label">门店详情</text>
|
|
|
|
|
- <view class="info-link">
|
|
|
|
|
- <text class="link-text">查看详情</text>
|
|
|
|
|
- <text class="link-arrow">></text>
|
|
|
|
|
|
|
+ <view class="info-list">
|
|
|
|
|
+ <view class="info-row">
|
|
|
|
|
+ <text class="info-label">订单编号</text>
|
|
|
|
|
+ <view class="info-value-group">
|
|
|
|
|
+ <text class="info-value">{{ order.orderNo }}</text>
|
|
|
|
|
+ <view class="copy-btn" @click="copyText(order.orderNo)">
|
|
|
|
|
+ <view class="copy-icon-box"></view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="info-row" v-if="order.hahaOrderNo">
|
|
|
|
|
+ <text class="info-label">哈哈订单号</text>
|
|
|
|
|
+ <view class="info-value-group">
|
|
|
|
|
+ <text class="info-value">{{ order.hahaOrderNo }}</text>
|
|
|
|
|
+ <view class="copy-btn" @click="copyText(order.hahaOrderNo)">
|
|
|
|
|
+ <view class="copy-icon-box"></view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="info-row">
|
|
|
|
|
+ <text class="info-label">下单时间</text>
|
|
|
|
|
+ <text class="info-value">{{ formatTime(order.createTime) }}</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="info-row" v-if="order.payTime">
|
|
|
|
|
+ <text class="info-label">支付时间</text>
|
|
|
|
|
+ <text class="info-value">{{ formatTime(order.payTime) }}</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="info-row">
|
|
|
|
|
+ <text class="info-label">支付方式</text>
|
|
|
|
|
+ <text class="info-value">微信</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="info-row">
|
|
|
|
|
+ <text class="info-label">设备编号</text>
|
|
|
|
|
+ <text class="info-value">{{ order.deviceSn }}</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="info-row" v-if="order.confidence">
|
|
|
|
|
+ <text class="info-label">AI识别置信度</text>
|
|
|
|
|
+ <text class="info-value">{{ (order.confidence * 100).toFixed(1) }}%</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="info-row" v-if="order.videoUrl">
|
|
|
|
|
+ <text class="info-label">识别视频</text>
|
|
|
|
|
+ <view class="info-link" @click="viewVideo(order.videoUrl)">
|
|
|
|
|
+ <text class="link-text">查看视频</text>
|
|
|
|
|
+ <text class="link-arrow">></text>
|
|
|
|
|
+ </view>
|
|
|
</view>
|
|
</view>
|
|
|
- </view>
|
|
|
|
|
- <view class="info-row">
|
|
|
|
|
- <text class="info-label">设备名称</text>
|
|
|
|
|
- <text class="info-value">长田</text>
|
|
|
|
|
- </view>
|
|
|
|
|
- <view class="info-row">
|
|
|
|
|
- <text class="info-label">设备编号</text>
|
|
|
|
|
- <text class="info-value">B142977</text>
|
|
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
|
|
|
|
|
<!-- 底部提示 -->
|
|
<!-- 底部提示 -->
|
|
|
<view class="footer-note">
|
|
<view class="footer-note">
|
|
|
- <text>如有疑问,请联系商家:18371997424</text>
|
|
|
|
|
|
|
+ <text>如有疑问,请联系客服</text>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
|
import { ref, onMounted } from 'vue';
|
|
import { ref, onMounted } from 'vue';
|
|
|
|
|
+import { getOrderDetail, OrderInfo } from '../../api/order';
|
|
|
|
|
+
|
|
|
|
|
+const order = ref<OrderInfo | null>(null);
|
|
|
|
|
+const loading = ref(false);
|
|
|
|
|
+const orderId = ref<number | null>(null);
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 获取订单状态文本
|
|
|
|
|
+ */
|
|
|
|
|
+const getStatusText = (status: number) => {
|
|
|
|
|
+ const statusMap: any = {
|
|
|
|
|
+ 0: '待支付',
|
|
|
|
|
+ 1: '已完成',
|
|
|
|
|
+ 2: '已取消'
|
|
|
|
|
+ };
|
|
|
|
|
+ return statusMap[status] || '未知';
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 获取状态样式
|
|
|
|
|
+ */
|
|
|
|
|
+const getStatusClass = (status: number) => {
|
|
|
|
|
+ if (status === 1) return 'status-success';
|
|
|
|
|
+ if (status === 0) return 'status-pending';
|
|
|
|
|
+ if (status === 2) return 'status-cancelled';
|
|
|
|
|
+ return '';
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 判断是否可以退款
|
|
|
|
|
+ */
|
|
|
|
|
+const canRefund = (order: OrderInfo) => {
|
|
|
|
|
+ return order.status === 1; // 只有已完成的订单可以退款
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 格式化时间
|
|
|
|
|
+ */
|
|
|
|
|
+const formatTime = (time: string | undefined) => {
|
|
|
|
|
+ if (!time) return '-';
|
|
|
|
|
+ // 如果已经是格式化的时间字符串,直接返回
|
|
|
|
|
+ if (typeof time === 'string' && time.includes('-')) {
|
|
|
|
|
+ return time.replace('T', ' ').substring(0, 19);
|
|
|
|
|
+ }
|
|
|
|
|
+ return time;
|
|
|
|
|
+};
|
|
|
|
|
|
|
|
|
|
+/**
|
|
|
|
|
+ * 加载订单详情
|
|
|
|
|
+ */
|
|
|
|
|
+const loadOrderDetail = async () => {
|
|
|
|
|
+ if (!orderId.value) {
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: '订单ID不存在',
|
|
|
|
|
+ icon: 'none'
|
|
|
|
|
+ });
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ loading.value = true;
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ uni.showLoading({
|
|
|
|
|
+ title: '加载中...',
|
|
|
|
|
+ mask: true
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ // 调用真实接口获取订单详情
|
|
|
|
|
+ const orderDetail = await getOrderDetail({ orderId: orderId.value });
|
|
|
|
|
+ order.value = orderDetail;
|
|
|
|
|
+
|
|
|
|
|
+ uni.hideLoading();
|
|
|
|
|
+ } catch (error: any) {
|
|
|
|
|
+ uni.hideLoading();
|
|
|
|
|
+ console.error('加载订单详情失败:', error);
|
|
|
|
|
+ // 错误已在request工具中显示
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ uni.navigateBack();
|
|
|
|
|
+ }, 1500);
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ loading.value = false;
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 页面加载时获取订单详情
|
|
|
|
|
+ */
|
|
|
|
|
+onMounted(() => {
|
|
|
|
|
+ const pages = getCurrentPages();
|
|
|
|
|
+ const currentPage = pages[pages.length - 1] as any;
|
|
|
|
|
+ const options = currentPage.options || {};
|
|
|
|
|
+
|
|
|
|
|
+ if (options.orderId) {
|
|
|
|
|
+ orderId.value = parseInt(options.orderId);
|
|
|
|
|
+ loadOrderDetail();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: '订单ID不存在',
|
|
|
|
|
+ icon: 'none'
|
|
|
|
|
+ });
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ uni.navigateBack();
|
|
|
|
|
+ }, 1500);
|
|
|
|
|
+ }
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 申请退款
|
|
|
|
|
+ */
|
|
|
const applyRefund = () => {
|
|
const applyRefund = () => {
|
|
|
|
|
+ if (!order.value) return;
|
|
|
uni.navigateTo({
|
|
uni.navigateTo({
|
|
|
- url: '/pages/refund/refund'
|
|
|
|
|
|
|
+ url: '/pages/refund/refund?orderId=' + order.value.id
|
|
|
});
|
|
});
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+/**
|
|
|
|
|
+ * 打印订单
|
|
|
|
|
+ */
|
|
|
const printOrder = () => {
|
|
const printOrder = () => {
|
|
|
uni.showToast({
|
|
uni.showToast({
|
|
|
title: '打印订单功能开发中',
|
|
title: '打印订单功能开发中',
|
|
@@ -109,12 +245,41 @@ const printOrder = () => {
|
|
|
});
|
|
});
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+/**
|
|
|
|
|
+ * 导出图片
|
|
|
|
|
+ */
|
|
|
const exportImage = () => {
|
|
const exportImage = () => {
|
|
|
uni.showToast({
|
|
uni.showToast({
|
|
|
title: '导出图片功能开发中',
|
|
title: '导出图片功能开发中',
|
|
|
icon: 'none'
|
|
icon: 'none'
|
|
|
});
|
|
});
|
|
|
};
|
|
};
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 复制文本
|
|
|
|
|
+ */
|
|
|
|
|
+const copyText = (text: string) => {
|
|
|
|
|
+ uni.setClipboardData({
|
|
|
|
|
+ data: text,
|
|
|
|
|
+ success: () => {
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: '复制成功',
|
|
|
|
|
+ icon: 'success'
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 查看视频
|
|
|
|
|
+ */
|
|
|
|
|
+const viewVideo = (url: string) => {
|
|
|
|
|
+ // TODO: 实现视频播放功能
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: '视频播放功能开发中',
|
|
|
|
|
+ icon: 'none'
|
|
|
|
|
+ });
|
|
|
|
|
+};
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<style>
|
|
<style>
|
|
@@ -125,6 +290,15 @@ const exportImage = () => {
|
|
|
box-sizing: border-box;
|
|
box-sizing: border-box;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+.loading-wrapper {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ min-height: 400rpx;
|
|
|
|
|
+ font-size: 28rpx;
|
|
|
|
|
+ color: #999;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
/* 通用卡片样式 */
|
|
/* 通用卡片样式 */
|
|
|
.card {
|
|
.card {
|
|
|
background-color: #ffffff;
|
|
background-color: #ffffff;
|
|
@@ -157,6 +331,18 @@ const exportImage = () => {
|
|
|
margin-right: 16rpx;
|
|
margin-right: 16rpx;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+.status-icon-wrapper.status-success {
|
|
|
|
|
+ background-color: #7ED321;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.status-icon-wrapper.status-pending {
|
|
|
|
|
+ background-color: #FF9100;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.status-icon-wrapper.status-cancelled {
|
|
|
|
|
+ background-color: #999999;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
.status-icon {
|
|
.status-icon {
|
|
|
color: #ffffff;
|
|
color: #ffffff;
|
|
|
font-size: 28rpx;
|
|
font-size: 28rpx;
|
|
@@ -212,6 +398,16 @@ const exportImage = () => {
|
|
|
border-radius: 8rpx;
|
|
border-radius: 8rpx;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+.image-placeholder {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+ background-color: #f5f5f5;
|
|
|
|
|
+ border-radius: 8rpx;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
.product-info {
|
|
.product-info {
|
|
|
flex: 1;
|
|
flex: 1;
|
|
|
}
|
|
}
|