Эх сурвалжийг харах

refactor: 结算页改为绿色弧顶 + 弧内仅标题和返回键

skyline 1 долоо хоног өмнө
parent
commit
917e9f35b4

+ 161 - 294
haha-mp/src/pages/orderComplete/orderComplete.vue

@@ -8,143 +8,106 @@
 
     <!-- 订单完成内容 -->
     <view v-else-if="order" class="content">
-      <!-- 顶部成功状态 -->
-      <view class="success-header">
-        <!-- 弧形装饰背景 -->
-        <view class="header-arc" />
-
-        <!-- 微信支付分标识 -->
-        <view class="payscore-badge">
-          <view class="payscore-badge-icon">
-            <svg viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg">
-              <circle cx="24" cy="24" r="22" fill="#07C160" />
-              <path d="M14 24 L20 30 L34 18" stroke="#fff" stroke-width="3.5" fill="none" stroke-linecap="round" stroke-linejoin="round" />
-            </svg>
+      <!-- 绿色弧顶 -->
+      <view class="arc-header">
+        <view class="arc-bg" />
+        <view class="arc-nav">
+          <view class="back-btn" @click="goBack">
+            <text class="back-arrow">‹</text>
           </view>
-          <text class="payscore-badge-text">微信支付分</text>
+          <text class="arc-title">支付完成</text>
+          <view class="back-btn placeholder" />
         </view>
+      </view>
 
+      <!-- 弧线下内容 -->
+      <view class="body-content">
         <!-- 成功图标 -->
         <view class="success-icon-wrapper">
           <view class="success-icon">
-            <view class="check-circle" />
             <view class="check-stem" />
           </view>
         </view>
 
         <text class="success-title">支付成功</text>
         <text class="success-amount">¥{{ (order.paidAmount || order.totalAmount || 0).toFixed(2) }}</text>
-        <text class="success-subtitle">计入微信支付分按时支付记录</text>
-      </view>
 
-      <!-- 商品清单 -->
-      <view class="card products-card">
-        <view class="card-header">
-          <text class="card-title">商品清单</text>
-          <text class="card-count">共 {{ order.products?.length || 0 }} 件</text>
+        <!-- 微信支付分标识 -->
+        <view class="payscore-tag">
+          <svg viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg" class="payscore-tag-icon">
+            <circle cx="24" cy="24" r="22" fill="#07C160" />
+            <path d="M14 24 L20 30 L34 18" stroke="#fff" stroke-width="3.5" fill="none" stroke-linecap="round" stroke-linejoin="round" />
+          </svg>
+          <text class="payscore-tag-text">微信支付分 · 计入按时支付记录</text>
         </view>
-        <view class="product-list">
-          <view v-for="(product, index) in order.products" :key="index" class="product-item">
-            <view class="product-thumb">
-              <text class="product-thumb-text">{{ (product.name || '商')[0] }}</text>
-            </view>
-            <view class="product-body">
-              <text class="product-name">{{ product.name }}</text>
-              <text class="product-unit-price">¥{{ product.price.toFixed(2) }}</text>
-            </view>
-            <view class="product-right">
-              <text class="product-qty">×{{ product.quantity }}</text>
-              <text class="product-subtotal">¥{{ (product.price * product.quantity).toFixed(2) }}</text>
+
+        <!-- 商品清单 -->
+        <view class="card products-card">
+          <view class="card-header">
+            <text class="card-title">商品清单</text>
+            <text class="card-count">共 {{ order.products?.length || 0 }} 件</text>
+          </view>
+          <view class="product-list">
+            <view v-for="(product, index) in order.products" :key="index" class="product-item">
+              <view class="product-thumb">
+                <text class="product-thumb-text">{{ (product.name || '商')[0] }}</text>
+              </view>
+              <view class="product-body">
+                <text class="product-name">{{ product.name }}</text>
+                <text class="product-unit-price">¥{{ product.price.toFixed(2) }}</text>
+              </view>
+              <view class="product-right">
+                <text class="product-qty">×{{ product.quantity }}</text>
+                <text class="product-subtotal">¥{{ (product.price * product.quantity).toFixed(2) }}</text>
+              </view>
             </view>
           </view>
-        </view>
 
-        <!-- 优惠信息 -->
-        <view v-if="order.discountAmount && order.discountAmount > 0" class="discount-row">
-          <text class="discount-label">优惠金额</text>
-          <text class="discount-value">-¥{{ order.discountAmount.toFixed(2) }}</text>
-        </view>
-      </view>
-
-      <!-- 支付合计 -->
-      <view class="card total-card">
-        <view class="total-row">
-          <text class="total-label">合计</text>
-          <view class="total-amount-wrapper">
-            <text class="total-symbol">¥</text>
-            <text class="total-amount">{{ (order.paidAmount || order.totalAmount || 0).toFixed(2) }}</text>
+          <view v-if="order.discountAmount && order.discountAmount > 0" class="discount-row">
+            <text class="discount-label">优惠金额</text>
+            <text class="discount-value">-¥{{ order.discountAmount.toFixed(2) }}</text>
           </view>
         </view>
-        <view class="total-method">
-          <text class="method-icon">💳</text>
-          <text class="method-text">{{ payMethodText }}</text>
-        </view>
-      </view>
 
-      <!-- 订单详情 -->
-      <view class="card detail-card">
-        <view class="card-header">
-          <text class="card-title">订单详情</text>
-        </view>
-        <view class="detail-list">
-          <view class="detail-item">
-            <text class="detail-label">开始时间</text>
-            <text class="detail-value">{{ formatTime(order.createTime) }}</text>
-          </view>
-          <view class="detail-item" v-if="order.payTime">
-            <text class="detail-label">结束时间</text>
-            <text class="detail-value">{{ formatTime(order.payTime) }}</text>
-          </view>
-          <view class="detail-item">
-            <text class="detail-label">服务单号</text>
-            <text class="detail-value detail-code">{{ order.outTradeNo || '-' }}</text>
-          </view>
-          <view class="detail-item">
-            <text class="detail-label">商户单号</text>
-            <text class="detail-value detail-code">{{ order.orderNo }}</text>
-          </view>
-          <view class="detail-item detail-link-item" @click="goToOrderDetail">
-            <text class="detail-label">交易账单</text>
-            <view class="detail-link">
-              <text class="link-text">查看详情</text>
-              <text class="link-arrow">›</text>
-            </view>
+        <!-- 支付方式 -->
+        <view class="card total-card">
+          <view class="total-row">
+            <text class="total-label">支付方式</text>
+            <text class="total-value">{{ payMethodText }}</text>
           </view>
         </view>
-      </view>
 
-      <!-- 底部品牌区 -->
-      <view class="footer-brand">
-        <view class="footer-divider-row">
-          <view class="footer-divider" />
-          <text class="footer-divider-text">安全支付保障</text>
-          <view class="footer-divider" />
-        </view>
-        <view class="footer-icons">
-          <view class="footer-icon-item">
-            <svg viewBox="0 0 40 40" xmlns="http://www.w3.org/2000/svg" class="footer-icon-svg">
-              <circle cx="20" cy="20" r="18" fill="#07C160" opacity="0.15" />
-              <path d="M12 22 L16 26 L28 16" stroke="#07C160" stroke-width="2.5" fill="none" stroke-linecap="round" stroke-linejoin="round" />
-            </svg>
-            <text class="footer-icon-label">实名认证</text>
-          </view>
-          <view class="footer-icon-item">
-            <svg viewBox="0 0 40 40" xmlns="http://www.w3.org/2000/svg" class="footer-icon-svg">
-              <circle cx="20" cy="20" r="18" fill="#07C160" opacity="0.15" />
-              <rect x="12" y="14" width="16" height="14" rx="2" stroke="#07C160" stroke-width="2" fill="none" />
-              <circle cx="20" cy="22" r="3" fill="#07C160" />
-            </svg>
-            <text class="footer-icon-label">资金安全</text>
+        <!-- 订单详情 -->
+        <view class="card detail-card">
+          <view class="card-header">
+            <text class="card-title">订单详情</text>
           </view>
-          <view class="footer-icon-item">
-            <svg viewBox="0 0 40 40" xmlns="http://www.w3.org/2000/svg" class="footer-icon-svg">
-              <circle cx="20" cy="20" r="18" fill="#07C160" opacity="0.15" />
-              <path d="M14 20 L18 24 L26 16" stroke="#07C160" stroke-width="2.5" fill="none" stroke-linecap="round" stroke-linejoin="round" />
-            </svg>
-            <text class="footer-icon-label">隐私保护</text>
+          <view class="detail-list">
+            <view class="detail-item">
+              <text class="detail-label">开始时间</text>
+              <text class="detail-value">{{ formatTime(order.createTime) }}</text>
+            </view>
+            <view class="detail-item" v-if="order.payTime">
+              <text class="detail-label">结束时间</text>
+              <text class="detail-value">{{ formatTime(order.payTime) }}</text>
+            </view>
+            <view class="detail-item" v-if="order.storeName">
+              <text class="detail-label">服务地点</text>
+              <text class="detail-value">{{ order.storeName }}</text>
+            </view>
+            <view class="detail-item">
+              <text class="detail-label">服务单号</text>
+              <text class="detail-value detail-code">{{ order.outTradeNo || order.orderNo }}</text>
+            </view>
+            <view class="detail-item detail-link-item" @click="goToOrderDetail">
+              <text class="detail-label">交易账单</text>
+              <view class="detail-link">
+                <text class="link-text">查看详情</text>
+                <text class="link-arrow">›</text>
+              </view>
+            </view>
           </view>
         </view>
-        <text class="footer-powered">微信支付分 · 先享后付</text>
       </view>
     </view>
   </view>
@@ -185,6 +148,10 @@ const formatTime = (time: string | undefined) => {
   }
 };
 
+const goBack = () => {
+  uni.navigateBack();
+};
+
 const loadOrderDetail = async (orderId: string) => {
   loading.value = true;
   try {
@@ -195,7 +162,6 @@ const loadOrderDetail = async (orderId: string) => {
   } catch (error: any) {
     uni.hideLoading();
     logger.error('加载订单完成页失败:', error);
-    // 调试:API 失败时展示占位数据方便调试样式
     order.value = {
       id: '0',
       orderNo: orderId,
@@ -243,7 +209,6 @@ onLoad((options: any) => {
 
 <style lang="scss">
 $wechat-green: #07C160;
-$wechat-green-light: #e8f8ee;
 
 .container {
   min-height: 100vh;
@@ -279,94 +244,95 @@ $wechat-green-light: #e8f8ee;
   color: #999;
 }
 
-.content {
-  padding-bottom: 60rpx;
-}
-
-/* ========== 顶部 ========== */
-.success-header {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  padding: 50rpx 0 56rpx;
-  background: #fff;
+/* ========== 绿色弧顶 ========== */
+.arc-header {
   position: relative;
+  height: 340rpx;
   overflow: hidden;
 }
 
-/* 弧形装饰:一个大椭圆定位在顶部,只露出下半弧 */
-.header-arc {
+.arc-bg {
   position: absolute;
-  top: -280rpx;
+  top: 0;
   left: 50%;
   transform: translateX(-50%);
-  width: 900rpx;
-  height: 560rpx;
-  border-radius: 50%;
-  background: linear-gradient(180deg, #e8f8ee 0%, #f5fdf8 60%, #fff 100%);
-  z-index: 0;
+  width: 120%;
+  height: 340rpx;
+  border-radius: 0 0 50% 50%;
+  background: linear-gradient(180deg, #06AD56 0%, #07C160 100%);
 }
 
-.payscore-badge {
-  display: flex;
-  align-items: center;
-  gap: 8rpx;
-  margin-bottom: 12rpx;
+.arc-nav {
   position: relative;
   z-index: 1;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: 0 24rpx;
+  height: 88rpx;
+  padding-top: env(safe-area-inset-top);
 }
 
-.payscore-badge-icon {
-  width: 32rpx;
-  height: 32rpx;
+.back-btn {
+  width: 64rpx;
+  height: 64rpx;
+  display: flex;
+  align-items: center;
+  justify-content: center;
 
-  svg {
-    width: 100%;
-    height: 100%;
+  &.placeholder {
+    visibility: hidden;
   }
 }
 
-.payscore-badge-text {
-  font-size: 22rpx;
-  color: $wechat-green;
-  font-weight: 500;
+.back-arrow {
+  font-size: 56rpx;
+  color: #fff;
+  font-weight: 300;
+  line-height: 1;
+  margin-top: -4rpx;
 }
 
+.arc-title {
+  font-size: 34rpx;
+  font-weight: 600;
+  color: #fff;
+}
+
+/* ========== 弧线下内容 ========== */
+.body-content {
+  margin-top: -120rpx;
+  position: relative;
+  z-index: 1;
+  padding: 0 24rpx;
+}
+
+/* 成功图标 */
 .success-icon-wrapper {
-  width: 120rpx;
-  height: 120rpx;
+  display: flex;
+  justify-content: center;
   margin-bottom: 24rpx;
   animation: successPop 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
-  position: relative;
-  z-index: 1;
 }
 
 .success-icon {
-  width: 100%;
-  height: 100%;
+  width: 120rpx;
+  height: 120rpx;
   border-radius: 50%;
-  background: $wechat-green;
+  background: #fff;
   display: flex;
   align-items: center;
   justify-content: center;
-  position: relative;
-  box-shadow: 0 8rpx 24rpx rgba(7, 193, 96, 0.3);
-}
-
-.check-circle {
-  width: 100%;
-  height: 100%;
-  border-radius: 50%;
+  box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1);
 }
 
 .check-stem {
-  position: absolute;
-  width: 24rpx;
-  height: 52rpx;
-  border-right: 6rpx solid #fff;
-  border-bottom: 6rpx solid #fff;
+  width: 26rpx;
+  height: 54rpx;
+  border-right: 7rpx solid $wechat-green;
+  border-bottom: 7rpx solid $wechat-green;
   transform: rotate(45deg);
-  margin-top: -6rpx;
+  margin-top: -8rpx;
 }
 
 @keyframes successPop {
@@ -379,34 +345,44 @@ $wechat-green-light: #e8f8ee;
   font-size: 36rpx;
   font-weight: 700;
   color: #1a1a1a;
+  text-align: center;
   margin-bottom: 8rpx;
-  position: relative;
-  z-index: 1;
 }
 
 .success-amount {
   font-size: 56rpx;
   font-weight: 800;
   color: #1a1a1a;
-  margin-bottom: 12rpx;
+  text-align: center;
+  margin-bottom: 20rpx;
   letter-spacing: -1rpx;
-  position: relative;
-  z-index: 1;
 }
 
-.success-subtitle {
+/* 微信支付分标签 */
+.payscore-tag {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  gap: 10rpx;
+  margin-bottom: 28rpx;
+}
+
+.payscore-tag-icon {
+  width: 36rpx;
+  height: 36rpx;
+}
+
+.payscore-tag-text {
   font-size: 24rpx;
   color: #999;
-  position: relative;
-  z-index: 1;
 }
 
 /* ========== 通用卡片 ========== */
 .card {
   background: #fff;
-  margin: 16rpx 24rpx;
   border-radius: 16rpx;
   padding: 28rpx;
+  margin-bottom: 16rpx;
   box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
 }
 
@@ -429,11 +405,6 @@ $wechat-green-light: #e8f8ee;
   color: #999;
 }
 
-.product-list {
-  display: flex;
-  flex-direction: column;
-}
-
 .product-item {
   display: flex;
   align-items: center;
@@ -504,7 +475,6 @@ $wechat-green-light: #e8f8ee;
   font-weight: 500;
 }
 
-/* 优惠 */
 .discount-row {
   display: flex;
   justify-content: space-between;
@@ -525,67 +495,24 @@ $wechat-green-light: #e8f8ee;
   font-weight: 500;
 }
 
-/* ========== 合计卡片 ========== */
-.total-card {
-  background: linear-gradient(135deg, #f9fdfa 0%, #fff 100%);
-  border: 1rpx solid #e8f5ee;
-}
-
+/* ========== 支付方式卡片 ========== */
 .total-row {
   display: flex;
   justify-content: space-between;
-  align-items: baseline;
-}
-
-.total-label {
-  font-size: 30rpx;
-  color: #666;
-  font-weight: 500;
-}
-
-.total-amount-wrapper {
-  display: flex;
-  align-items: baseline;
-  gap: 2rpx;
-}
-
-.total-symbol {
-  font-size: 32rpx;
-  color: #1a1a1a;
-  font-weight: 700;
-}
-
-.total-amount {
-  font-size: 56rpx;
-  color: #1a1a1a;
-  font-weight: 800;
-  letter-spacing: -1rpx;
-}
-
-.total-method {
-  display: flex;
   align-items: center;
-  gap: 8rpx;
-  margin-top: 16rpx;
-  padding-top: 16rpx;
-  border-top: 1rpx dashed #e0e8e2;
 }
 
-.method-icon {
+.total-label {
   font-size: 28rpx;
+  color: #666;
 }
 
-.method-text {
-  font-size: 24rpx;
-  color: #999;
+.total-value {
+  font-size: 26rpx;
+  color: #333;
 }
 
 /* ========== 详情卡片 ========== */
-.detail-list {
-  display: flex;
-  flex-direction: column;
-}
-
 .detail-item {
   display: flex;
   justify-content: space-between;
@@ -614,15 +541,12 @@ $wechat-green-light: #e8f8ee;
   font-size: 22rpx;
   color: #666;
   max-width: 380rpx;
-  font-family: "SF Mono", "Menlo", monospace;
+  font-family: monospace;
 }
 
 .detail-link-item {
   &:active {
-    background: #f9f9f9;
-    margin: 0 -28rpx;
-    padding-left: 28rpx;
-    padding-right: 28rpx;
+    opacity: 0.6;
   }
 }
 
@@ -642,61 +566,4 @@ $wechat-green-light: #e8f8ee;
   color: $wechat-green;
   font-weight: 300;
 }
-
-/* ========== 底部品牌 ========== */
-.footer-brand {
-  padding: 48rpx 24rpx 40rpx;
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  gap: 24rpx;
-}
-
-.footer-divider-row {
-  display: flex;
-  align-items: center;
-  gap: 16rpx;
-  width: 100%;
-}
-
-.footer-divider {
-  flex: 1;
-  height: 1rpx;
-  background: #e0e0e0;
-}
-
-.footer-divider-text {
-  font-size: 22rpx;
-  color: #bbb;
-  flex-shrink: 0;
-}
-
-.footer-icons {
-  display: flex;
-  justify-content: center;
-  gap: 60rpx;
-}
-
-.footer-icon-item {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  gap: 8rpx;
-}
-
-.footer-icon-svg {
-  width: 48rpx;
-  height: 48rpx;
-}
-
-.footer-icon-label {
-  font-size: 20rpx;
-  color: #999;
-}
-
-.footer-powered {
-  font-size: 22rpx;
-  color: #bbb;
-  margin-top: 8rpx;
-}
 </style>