Răsfoiți Sursa

订单列表、订单详情

skyline 4 luni în urmă
părinte
comite
bea0d99ad7

+ 11 - 3
haha-mp/src/pages.json

@@ -1,5 +1,5 @@
 {
-	"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
+	"pages": [
 		{
 			"path": "pages/index/index",
 			"style": {
@@ -28,8 +28,8 @@
 		{
 			"path": "pages/orders/orders",
 			"style": {
-				"navigationBarTitleText": "我的订单",
-				"navigationBarBackgroundColor": "#FFFFFF",
+				"navigationBarTitleText": "订单",
+				"navigationBarBackgroundColor": "#FFD700",
 				"navigationBarTextStyle": "black"
 			}
 		},
@@ -40,6 +40,14 @@
 				"navigationBarBackgroundColor": "#FFFFFF",
 				"navigationBarTextStyle": "black"
 			}
+		},
+		{
+			"path": "pages/orderDetail/orderDetail",
+			"style": {
+				"navigationBarTitleText": "订单详情",
+				"navigationBarBackgroundColor": "#FFD700",
+				"navigationBarTextStyle": "black"
+			}
 		}
 	],
 	"globalStyle": {

+ 396 - 0
haha-mp/src/pages/orderDetail/orderDetail.vue

@@ -0,0 +1,396 @@
+<template>
+  <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>
+    
+    <!-- 订单明细 -->
+    <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>
+        <text class="product-quantity">x1</text>
+      </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>
+      </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>
+        </view>
+        <view class="info-row">
+          <text class="info-label">下单时间</text>
+          <text class="info-value">2026-01-08 15:37:03</text>
+        </view>
+        <view class="info-row">
+          <text class="info-label">支付时间</text>
+          <text class="info-value">2026-01-08 15:37:49</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>
+          <view class="info-link">
+            <text class="link-text">查看详情</text>
+            <text class="link-arrow">></text>
+          </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 class="footer-note">
+      <text>如有疑问,请联系商家:18371997424</text>
+    </view>
+  </view>
+</template>
+
+<script setup lang="ts">
+import { ref, onMounted } from 'vue';
+
+const applyRefund = () => {
+  uni.navigateTo({
+    url: '/pages/refund/refund'
+  });
+};
+
+const printOrder = () => {
+  uni.showToast({
+    title: '打印订单功能开发中',
+    icon: 'none'
+  });
+};
+
+const exportImage = () => {
+  uni.showToast({
+    title: '导出图片功能开发中',
+    icon: 'none'
+  });
+};
+</script>
+
+<style>
+.container {
+  min-height: 100vh;
+  background-color: #f8f8f8;
+  padding: 20rpx;
+  box-sizing: border-box;
+}
+
+/* 通用卡片样式 */
+.card {
+  background-color: #ffffff;
+  border-radius: 16rpx;
+  padding: 30rpx;
+  margin-bottom: 20rpx;
+  box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
+}
+
+/* 订单状态卡片 */
+.status-card {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.status-left {
+  display: flex;
+  align-items: center;
+}
+
+.status-icon-wrapper {
+  width: 44rpx;
+  height: 44rpx;
+  background-color: #7ED321;
+  border-radius: 50%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin-right: 16rpx;
+}
+
+.status-icon {
+  color: #ffffff;
+  font-size: 28rpx;
+  font-weight: bold;
+}
+
+.status-text {
+  font-size: 32rpx;
+  color: #333333;
+  font-weight: 500;
+}
+
+.invoice-status {
+  font-size: 28rpx;
+  color: #FF6B6B;
+}
+
+/* 订单明细卡片 */
+.detail-card {
+  padding: 0;
+  overflow: hidden;
+}
+
+.card-header {
+  padding: 30rpx;
+  border-bottom: 1rpx solid #f5f5f5;
+}
+
+.card-title {
+  font-size: 32rpx;
+  font-weight: bold;
+  color: #333333;
+}
+
+.product-item {
+  display: flex;
+  padding: 30rpx;
+  align-items: flex-start;
+}
+
+.product-image {
+  width: 140rpx;
+  height: 140rpx;
+  background-color: #f9f9f9;
+  border-radius: 8rpx;
+  margin-right: 20rpx;
+  border: 1rpx solid #eeeeee;
+}
+
+.product-image image {
+  width: 100%;
+  height: 100%;
+  border-radius: 8rpx;
+}
+
+.product-info {
+  flex: 1;
+}
+
+.product-name {
+  font-size: 30rpx;
+  color: #333333;
+  margin-bottom: 16rpx;
+  display: block;
+}
+
+.product-price {
+  font-size: 26rpx;
+  color: #999999;
+}
+
+.product-quantity {
+  font-size: 26rpx;
+  color: #999999;
+  margin-top: 60rpx;
+}
+
+.amount-row {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 30rpx;
+  border-top: 1rpx solid #f5f5f5;
+}
+
+.amount-label {
+  font-size: 28rpx;
+  color: #999999;
+}
+
+.amount-value-wrapper {
+  display: flex;
+  align-items: baseline;
+}
+
+.amount-prefix {
+  font-size: 26rpx;
+  color: #333333;
+  margin-right: 10rpx;
+}
+
+.amount-symbol {
+  font-size: 26rpx;
+  color: #333333;
+  font-weight: bold;
+}
+
+.amount-integer {
+  font-size: 36rpx;
+  color: #333333;
+  font-weight: bold;
+}
+
+.card-footer-actions {
+  display: flex;
+  justify-content: flex-end;
+  padding: 20rpx 30rpx 30rpx;
+}
+
+.action-btn-outline {
+  background-color: #f8f8f8;
+  border: 1rpx solid #e0e0e0;
+  border-radius: 12rpx;
+  font-size: 26rpx;
+  color: #666666;
+  margin: 0 0 0 20rpx;
+  padding: 10rpx 24rpx;
+  line-height: 1.5;
+}
+
+.action-btn-outline::after {
+  border: none;
+}
+
+.action-btn-primary {
+  background-color: #FFD200;
+  border-radius: 12rpx;
+  font-size: 26rpx;
+  color: #333333;
+  margin: 0 0 0 20rpx;
+  padding: 10rpx 24rpx;
+  line-height: 1.5;
+  font-weight: 500;
+}
+
+.action-btn-primary::after {
+  border: none;
+}
+
+/* 订单信息卡片 */
+.info-card {
+  padding: 0;
+}
+
+.info-list {
+  padding: 10rpx 30rpx 30rpx;
+}
+
+.info-row {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 24rpx 0;
+  border-bottom: 1rpx solid #f9f9f9;
+}
+
+.info-row:last-child {
+  border-bottom: none;
+}
+
+.info-label {
+  font-size: 28rpx;
+  color: #666666;
+}
+
+.info-value-group {
+  display: flex;
+  align-items: center;
+}
+
+.info-value {
+  font-size: 28rpx;
+  color: #333333;
+}
+
+.copy-btn {
+  margin-left: 10rpx;
+  padding: 4rpx;
+}
+
+.copy-icon-box {
+  width: 28rpx;
+  height: 32rpx;
+  border: 3rpx solid #999999;
+  position: relative;
+  border-radius: 4rpx;
+}
+
+.copy-icon-box::after {
+  content: '';
+  position: absolute;
+  width: 20rpx;
+  height: 24rpx;
+  border: 3rpx solid #999999;
+  background-color: #ffffff;
+  top: -8rpx;
+  right: -8rpx;
+  border-radius: 4rpx;
+}
+
+.info-link {
+  display: flex;
+  align-items: center;
+}
+
+.link-text {
+  font-size: 28rpx;
+  color: #999999;
+  margin-right: 6rpx;
+}
+
+.link-arrow {
+  font-size: 28rpx;
+  color: #cccccc;
+}
+
+/* 底部提示 */
+.footer-note {
+  text-align: center;
+  padding: 40rpx 0;
+}
+
+.footer-note text {
+  font-size: 26rpx;
+  color: #cccccc;
+}
+</style>

+ 168 - 103
haha-mp/src/pages/orders/orders.vue

@@ -1,45 +1,34 @@
 <template>
   <view class="container">
-    <view class="title">我的订单</view>
-    <view class="order-tabs">
-      <view class="tab-item active">全部</view>
-      <view class="tab-item">待支付</view>
-      <view class="tab-item">已完成</view>
-      <view class="tab-item">退款/售后</view>
-    </view>
+    <!-- 订单列表 -->
     <view class="order-list">
-      <view class="order-item">
+      <view v-for="order in orders" :key="order.id" class="order-item">
         <view class="order-header">
-          <view class="order-time">2026-01-23 10:30:00</view>
-          <view class="order-status">已完成</view>
-        </view>
-        <view class="order-products">
-          <view class="product-item">
-            <view class="product-name">可口可乐</view>
-            <view class="product-price">¥3.50</view>
-            <view class="product-quantity">×2</view>
+          <view class="time-invoice-container">
+            <text class="order-time">{{ order.createTime }}</text>
+            <text class="invoice-status">未开票</text>
           </view>
+          <text :class="['order-status', order.status]">{{ getStatusText(order.status) }}</text>
         </view>
-        <view class="order-footer">
-          <view class="order-total">共2件商品 合计:¥7.00</view>
-          <button class="order-button">查看详情</button>
-        </view>
-      </view>
-      <view class="order-item">
-        <view class="order-header">
-          <view class="order-time">2026-01-23 09:15:00</view>
-          <view class="order-status">待支付</view>
-        </view>
-        <view class="order-products">
-          <view class="product-item">
-            <view class="product-name">雪碧</view>
-            <view class="product-price">¥3.50</view>
-            <view class="product-quantity">×1</view>
+        <view class="order-content">
+          <view class="product-image">
+            <image v-if="order.products && order.products[0] && order.products[0].image" :src="order.products[0].image" mode="aspectFill"></image>
+            <view v-else class="image-placeholder"></view>
+          </view>
+          <view class="order-info">
+            <view class="product-name" v-if="order.products && order.products[0]">
+              {{ order.products[0].name }}{{ order.products.length > 1 ? ' 等' : '' }}
+            </view>
+            <view class="price-info">
+              <text class="price-label">实付:</text>
+              <text class="price-value">¥{{ order.amount.toFixed(2) }}</text>
+            </view>
+            <view class="quantity-info">共{{ getQuantity(order) }}件</view>
           </view>
         </view>
         <view class="order-footer">
-          <view class="order-total">共1件商品 合计:¥3.50</view>
-          <button class="order-button">立即支付</button>
+          <button v-if="canRefund(order)" class="action-btn refund-btn" @click.stop="applyRefund(order)">申请退款</button>
+          <button class="action-btn detail-btn" @click.stop="viewOrderDetail(order)">订单详情</button>
         </view>
       </view>
     </view>
@@ -52,135 +41,211 @@ import { mockApi } from '../../utils/mock';
 
 const orders = ref<any[]>([]);
 
+const getStatusText = (status: string) => {
+  const statusMap: any = {
+    'completed': '已完成',
+    'pending': '识别中',
+    'paid': '已支付',
+    'refunded': '已退款'
+  };
+  return statusMap[status] || status;
+};
+
+const getQuantity = (order: any) => {
+  if (!order.products) return 0;
+  return order.products.reduce((acc: number, p: any) => acc + p.quantity, 0);
+};
+
+const canRefund = (order: any) => {
+  return order.status === 'completed' || order.status === 'paid';
+};
+
 onMounted(async () => {
-  const response = await mockApi.getOrders();
+  const response: any = await mockApi.getOrders();
   if (response.success) {
     orders.value = response.data;
   }
 });
+
+const applyRefund = (order: any) => {
+  uni.navigateTo({
+    url: '/pages/refund/refund?id=' + order.id
+  });
+};
+
+const viewOrderDetail = () => {
+  uni.navigateTo({
+    url: '/pages/orderDetail/orderDetail'
+  });
+};
 </script>
 
 <style>
 .container {
   min-height: 100vh;
   background-color: #f5f5f5;
-}
-
-.title {
-  font-size: 36rpx;
-  font-weight: bold;
-  padding: 30rpx;
-  background-color: #fff;
-  border-bottom: 1rpx solid #eee;
-}
-
-.order-tabs {
-  display: flex;
-  background-color: #fff;
-  margin: 20rpx 0;
-  padding: 0 30rpx;
-}
-
-.tab-item {
-  flex: 1;
-  text-align: center;
-  padding: 20rpx 0;
-  font-size: 28rpx;
-  color: #666;
   position: relative;
+  padding-top: 0;
 }
 
-.tab-item.active {
-  color: #FFD700;
-  font-weight: bold;
-}
-
-.tab-item.active::after {
-  content: '';
-  position: absolute;
-  bottom: 0;
-  left: 25%;
-  width: 50%;
-  height: 4rpx;
-  background-color: #FFD700;
-}
-
+/* 订单列表 */
 .order-list {
-  padding: 0 30rpx 30rpx;
+  padding: 10rpx 0 30rpx;
 }
 
+/* 订单项 */
 .order-item {
-  background-color: #fff;
-  border-radius: 10rpx;
-  margin-bottom: 20rpx;
+  background-color: #ffffff;
+  border-radius: 0;
+  margin-bottom: 10rpx;
   overflow: hidden;
+  box-shadow: none;
 }
 
+/* 订单头部 */
 .order-header {
   display: flex;
   justify-content: space-between;
+  align-items: center;
   padding: 20rpx;
   border-bottom: 1rpx solid #f0f0f0;
 }
 
 .order-time {
   font-size: 24rpx;
-  color: #999;
+  color: #666666;
+}
+
+.time-invoice-container {
+  display: flex;
+  align-items: center;
+  flex: 1;
+}
+
+.invoice-status {
+  font-size: 24rpx;
+  color: #ff6666;
+  margin-left: 20rpx;
 }
 
 .order-status {
   font-size: 24rpx;
-  color: #FF6B6B;
 }
 
-.order-products {
+.order-status.paid,
+.order-status.completed {
+  color: #00cc66;
+}
+
+.order-status.refunded {
+  color: #999999;
+}
+
+.order-status.pending {
+  color: #FF9100;
+}
+
+/* 订单内容 */
+.order-content {
+  display: flex;
   padding: 20rpx;
+  border-bottom: 1rpx solid #f0f0f0;
+}
+
+.product-image {
+  width: 100rpx;
+  height: 100rpx;
+  margin-right: 20rpx;
+}
+
+.image-placeholder {
+  width: 100%;
+  height: 100%;
+  background-color: #f5f5f5;
 }
 
-.product-item {
+.order-info {
+  flex: 1;
   display: flex;
+  flex-direction: column;
   justify-content: space-between;
-  align-items: center;
-  padding: 10rpx 0;
+  align-items: flex-end;
 }
 
 .product-name {
   font-size: 28rpx;
-  color: #333;
-  flex: 1;
+  color: #333333;
+  font-weight: 500;
+  width: 100%;
+  text-align: left;
+  margin-bottom: 10rpx;
 }
 
-.product-price {
+.price-info {
   font-size: 28rpx;
-  color: #333;
-  margin: 0 20rpx;
 }
 
-.product-quantity {
-  font-size: 28rpx;
-  color: #666;
+.price-label {
+  color: #666666;
+}
+
+.price-value {
+  color: #333333;
+  font-weight: 500;
+}
+
+.quantity-info {
+  font-size: 24rpx;
+  color: #999999;
 }
 
+/* 订单底部 */
 .order-footer {
   display: flex;
-  justify-content: space-between;
-  align-items: center;
+  justify-content: flex-end;
   padding: 20rpx;
-  border-top: 1rpx solid #f0f0f0;
-  background-color: #f9f9f9;
+  width: 100%;
+  box-sizing: border-box;
 }
 
-.order-total {
-  font-size: 28rpx;
-  color: #333;
+/* 重置按钮默认样式 */
+.action-btn {
+  background-color: #ffffff;
+  color: #333333;
+  border: 1rpx solid #dddddd;
+  padding: 12rpx 24rpx;
+  border-radius: 30rpx;
+  font-size: 24rpx;
+  flex-shrink: 0;
+  text-align: center;
+  white-space: nowrap;
+  min-width: 160rpx;
+  line-height: 1;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin: 0; /* 彻底移除默认 margin */
+  width: auto;
 }
 
-.order-button {
-  background-color: #FFD700;
-  color: #333;
+/* 按钮之间的间距 */
+.action-btn + .action-btn {
+  margin-left: 20rpx;
+}
+
+.action-btn::after {
   border: none;
-  padding: 10rpx 30rpx;
-  border-radius: 20rpx;
-  font-size: 24rpx;
+}
+
+/* 详情按钮高亮 */
+.detail-btn {
+  background-color: #FFD700;
+  border-color: #FFD700;
+  color: #000000;
+  font-weight: 500;
+}
+
+.refund-btn {
+  color: #666666;
 }
 </style>