Преглед на файлове

奖池订单 Tab 栏 UI 已还原

zbb преди 3 месеца
родител
ревизия
f5358f0602
променени са 3 файла, в които са добавени 265 реда и са изтрити 129 реда
  1. 8 5
      app/(tabs)/mine.tsx
  2. 255 124
      app/orders/index.tsx
  3. 2 0
      constants/images.ts

+ 8 - 5
app/(tabs)/mine.tsx

@@ -332,7 +332,7 @@ export default function MineScreen() {
 
           {/* 订单入口 */}
           <ImageBackground
-            source={{ uri: Images.mine.userSection2Bg }}
+            source={{ uri: Images.welfare.roomBg }}
             style={styles.orderBox}
             resizeMode="stretch"
           >
@@ -495,7 +495,7 @@ const styles = StyleSheet.create({
     fontSize: 12,
   },
   funcBox: {
-    height: 115,
+    height: 115, // 原项目 230rpx
     marginHorizontal: 0,
     paddingTop: 20,
     paddingHorizontal: 10,
@@ -505,15 +505,18 @@ const styles = StyleSheet.create({
     justifyContent: 'space-around',
   },
   funcItem: {
+    flex: 1,
     alignItems: 'center',
   },
   funcIcon: {
-    width: 59,
-    height: 57,
+    width: 59, // 原项目 118rpx
+    height: 57, // 原项目 114rpx
   },
   funcText: {
     color: '#000',
-    fontSize: 12,
+    fontSize: 12, // 原项目 24rpx
+    fontWeight: '400',
+    marginTop: 4,
   },
   orderBox: {
     marginHorizontal: 8,

+ 255 - 124
app/orders/index.tsx

@@ -1,5 +1,5 @@
 import { Image } from 'expo-image';
-import { useRouter } from 'expo-router';
+import { useLocalSearchParams, useRouter } from 'expo-router';
 import React, { useCallback, useEffect, useState } from 'react';
 import {
     ActivityIndicator,
@@ -15,29 +15,52 @@ import {
 import { useSafeAreaInsets } from 'react-native-safe-area-context';
 
 import { Images } from '@/constants/images';
-import { getOrders, OrderItem } from '@/services/mall';
+import { getAwardOrders } from '@/services/award';
+
+const LEVEL_MAP: Record<string, { title: string; color: string }> = {
+  A: { title: '超神', color: '#ff0000' },
+  B: { title: '欧皇', color: '#ffae00' },
+  C: { title: '隐藏', color: '#9745e6' },
+  D: { title: '普通款', color: '#666666' },
+};
 
 const tabs = [
-  { label: '全部', value: 'all' },
-  { label: '待付款', value: 'to_pay' },
-  { label: '待补款', value: 'to_payLeft' },
-  { label: '待发货', value: 'to_delivery' },
-  { label: '待收货', value: 'to_receive' },
   { label: '已完成', value: 'complete' },
   { label: '未完成', value: 'uncomplete' },
 ];
 
+interface AwardOrderItem {
+  tradeNo: string;
+  createTime: string;
+  status: number;
+  luckPool: {
+    name: string;
+    cover: string;
+  };
+  price: number;
+  quantity: number;
+  couponAmount: number;
+  magicAmount: number;
+  paymentAmount: number;
+  paymentTimeoutTime?: string;
+  itemList?: Array<{
+    spu: { cover: string };
+    level: string;
+  }>;
+}
+
 export default function OrdersScreen() {
   const router = useRouter();
   const insets = useSafeAreaInsets();
+  const params = useLocalSearchParams();
 
   const [loading, setLoading] = useState(true);
   const [refreshing, setRefreshing] = useState(false);
-  const [activeTab, setActiveTab] = useState(0);
-  const [orders, setOrders] = useState<OrderItem[]>([]);
+  const [activeTab, setActiveTab] = useState(params.tab === '4' ? 1 : 0);
+  const [orders, setOrders] = useState<AwardOrderItem[]>([]);
   const [page, setPage] = useState(1);
 
-  const loadData = useCallback(async (tab?: number, refresh = false) => {
+  const loadData = useCallback(async (tabValue?: string, refresh = false) => {
     if (refresh) {
       setRefreshing(true);
       setPage(1);
@@ -45,7 +68,7 @@ export default function OrdersScreen() {
       setLoading(true);
     }
     try {
-      const data = await getOrders(refresh ? 1 : page, 10, tab);
+      const data = await getAwardOrders(refresh ? 1 : page, 10, tabValue);
       if (data?.records) {
         setOrders(refresh ? data.records : [...orders, ...data.records]);
       }
@@ -71,14 +94,22 @@ export default function OrdersScreen() {
     }
   };
 
-  const goToDetail = (tradeNo: string) => {
-    router.push(`/orders/${tradeNo}` as any);
-  };
-
   const goBack = () => {
     router.back();
   };
 
+  const goToShopOrders = () => {
+    router.push('/orders/shop' as any);
+  };
+
+  const getStatusText = (status: number) => {
+    if (status === 99) return { text: '已完成', color: '#20D7EF' };
+    if (status === 0) return { text: '待支付', color: '#F62C71' };
+    if (status === 10) return { text: '用户取消', color: '#999' };
+    if (status === 11) return { text: '超时取消', color: '#999' };
+    return { text: '未知', color: '#999' };
+  };
+
   return (
     <View style={styles.container}>
       <StatusBar barStyle="light-content" />
@@ -90,9 +121,9 @@ export default function OrdersScreen() {
         {/* 顶部导航 */}
         <View style={[styles.header, { paddingTop: insets.top }]}>
           <TouchableOpacity style={styles.backBtn} onPress={goBack}>
-            <Text style={styles.backText}></Text>
+            <Text style={styles.backText}></Text>
           </TouchableOpacity>
-          <Text style={styles.headerTitle}>我的订单</Text>
+          <Text style={styles.headerTitle}>奖池订单</Text>
           <View style={styles.placeholder} />
         </View>
 
@@ -101,12 +132,18 @@ export default function OrdersScreen() {
           {tabs.map((tab, index) => (
             <TouchableOpacity
               key={index}
-              style={[styles.tabItem, activeTab === index && styles.tabItemActive]}
               onPress={() => switchTab(index)}
+              activeOpacity={0.8}
             >
-              <Text style={[styles.tabText, activeTab === index && styles.tabTextActive]}>
-                {tab.label}
-              </Text>
+              <ImageBackground
+                source={{ uri: activeTab === index ? Images.home.typeBgOn : Images.home.typeBg }}
+                style={styles.tabItem}
+                resizeMode="stretch"
+              >
+                <Text style={[styles.tabText, activeTab === index && styles.tabTextActive]}>
+                  {tab.label}
+                </Text>
+              </ImageBackground>
             </TouchableOpacity>
           ))}
         </View>
@@ -127,52 +164,97 @@ export default function OrdersScreen() {
               <Text style={styles.emptyText}>暂无订单</Text>
             </View>
           ) : (
-            orders.map((item) => (
-              <TouchableOpacity
-                key={item.tradeNo}
-                style={styles.orderItem}
-                onPress={() => goToDetail(item.tradeNo)}
-              >
+            orders.map((item) => {
+              const statusInfo = getStatusText(item.status);
+              return (
                 <ImageBackground
+                  key={item.tradeNo}
                   source={{ uri: Images.common.itemBg }}
-                  style={styles.orderItemBg}
+                  style={styles.orderCard}
                   resizeMode="stretch"
                 >
-                  <View style={styles.orderHeader}>
-                    <Text style={styles.orderNo}>订单号:{item.tradeNo}</Text>
-                    <Text style={styles.orderStatus}>{item.statusText}</Text>
-                  </View>
-                  <View style={styles.orderContent}>
-                    <Image source={item.goodsCover} style={styles.goodsImage} contentFit="cover" />
-                    <View style={styles.goodsInfo}>
-                      <Text style={styles.goodsName} numberOfLines={2}>{item.goodsName}</Text>
-                      <View style={styles.goodsBottom}>
-                        <Text style={styles.goodsPrice}>¥{item.paymentAmount}</Text>
-                        <Text style={styles.goodsQty}>x{item.quantity}</Text>
+                  <View style={styles.cardContent}>
+                    {/* 顶部信息 */}
+                    <View style={styles.orderTop}>
+                      <Text style={styles.orderTime}>下单时间:{item.createTime}</Text>
+                      <Text style={[styles.orderStatus, { color: statusInfo.color }]}>
+                        {statusInfo.text}
+                      </Text>
+                    </View>
+                    {item.status === 0 && item.paymentTimeoutTime && (
+                      <Text style={styles.timeoutText}>
+                        {item.paymentTimeoutTime} 将自动取消该订单,如有优惠券,将自动退回
+                      </Text>
+                    )}
+
+                    {/* 中间商品信息 */}
+                    <View style={styles.orderMiddle}>
+                      <ImageBackground 
+                        source={{ uri: Images.box?.detail?.firstItemBg || Images.common.itemBg }} 
+                        style={styles.productImgBg}
+                      >
+                        <Image 
+                          source={{ uri: item.luckPool?.cover }} 
+                          style={styles.productImg} 
+                          contentFit="cover" 
+                        />
+                      </ImageBackground>
+                      <View style={styles.productInfo}>
+                        <Text style={styles.productName} numberOfLines={1}>{item.luckPool?.name}</Text>
+                        <View style={styles.priceRow}>
+                          <Text style={styles.priceText}>¥{item.price}</Text>
+                          <Text style={styles.qtyText}>X{item.quantity}</Text>
+                        </View>
+                        <Text style={styles.discountText}>
+                          使用优惠券-{item.couponAmount} 使用果实-{item.magicAmount}
+                        </Text>
+                        <View style={styles.paymentRow}>
+                          <Text style={styles.discountText}>实付款:</Text>
+                          <Text style={styles.paymentAmount}>¥{item.paymentAmount}</Text>
+                        </View>
                       </View>
                     </View>
-                  </View>
-                  <View style={styles.orderFooter}>
-                    <Text style={styles.orderTime}>{item.createTime}</Text>
-                    <View style={styles.orderActions}>
-                      {item.status === 1 && (
-                        <TouchableOpacity style={styles.actionBtn}>
-                          <Text style={styles.actionBtnText}>去支付</Text>
-                        </TouchableOpacity>
-                      )}
-                      {item.status === 3 && (
-                        <TouchableOpacity style={styles.actionBtn}>
-                          <Text style={styles.actionBtnText}>确认收货</Text>
+
+                    {/* 底部商品列表 */}
+                    {item.status === 99 && item.itemList && item.itemList.length > 0 && (
+                      <ScrollView horizontal showsHorizontalScrollIndicator={false} style={styles.itemList}>
+                        {item.itemList.map((goods, idx) => {
+                          const levelInfo = LEVEL_MAP[goods.level] || LEVEL_MAP.D;
+                          return (
+                            <View key={idx} style={styles.itemBox}>
+                              <View style={styles.itemImgBox}>
+                                <Image source={{ uri: goods.spu?.cover }} style={styles.itemImg} contentFit="contain" />
+                              </View>
+                              <View style={[styles.levelTag, { backgroundColor: levelInfo.color }]}>
+                                <Text style={styles.levelText}>{levelInfo.title}</Text>
+                              </View>
+                            </View>
+                          );
+                        })}
+                      </ScrollView>
+                    )}
+
+                    {/* 未完成订单显示订单号 */}
+                    {item.status !== 99 && (
+                      <View style={styles.orderNoRow}>
+                        <Text style={styles.orderNoText} numberOfLines={1}>订单号:{item.tradeNo}</Text>
+                        <TouchableOpacity style={styles.copyBtn}>
+                          <Text style={styles.copyBtnText}>复制</Text>
                         </TouchableOpacity>
-                      )}
-                    </View>
+                      </View>
+                    )}
                   </View>
                 </ImageBackground>
-              </TouchableOpacity>
-            ))
+              );
+            })
           )}
-          <View style={{ height: 20 }} />
+          <View style={{ height: 80 }} />
         </ScrollView>
+
+        {/* 商城订单入口 */}
+        <TouchableOpacity style={[styles.shopOrderBtn, { bottom: insets.bottom + 154 }]} onPress={goToShopOrders}>
+          <Image source={{ uri: Images.mine.shopOrder }} style={styles.shopOrderIcon} contentFit="contain" />
+        </TouchableOpacity>
       </ImageBackground>
     </View>
   );
@@ -201,43 +283,40 @@ const styles = StyleSheet.create({
   },
   backText: {
     color: '#fff',
-    fontSize: 24,
+    fontSize: 32,
+    fontWeight: 'bold',
   },
   headerTitle: {
     color: '#fff',
-    fontSize: 18,
-    fontWeight: '600',
+    fontSize: 15,
+    fontWeight: 'bold',
   },
   placeholder: {
     width: 40,
   },
   tabBar: {
     flexDirection: 'row',
-    backgroundColor: 'rgba(255,255,255,0.1)',
-    marginHorizontal: 15,
-    borderRadius: 8,
-    paddingVertical: 5,
+    marginHorizontal: 10,
+    marginBottom: 15,
   },
   tabItem: {
-    flex: 1,
+    width: 80, // 原项目 160rpx
+    height: 40, // 原项目 80rpx
+    justifyContent: 'center',
     alignItems: 'center',
-    paddingVertical: 8,
-  },
-  tabItemActive: {
-    borderBottomWidth: 2,
-    borderBottomColor: '#ff6b00',
+    marginRight: 10, // 原项目 20rpx
   },
   tabText: {
-    color: '#999',
-    fontSize: 14,
+    color: '#000',
+    fontSize: 14, // 原项目 28rpx
+    fontWeight: '400',
   },
   tabTextActive: {
-    color: '#ff6b00',
-    fontWeight: '600',
+    fontWeight: 'bold',
   },
   scrollView: {
     flex: 1,
-    paddingHorizontal: 15,
+    paddingHorizontal: 10,
   },
   loadingContainer: {
     paddingTop: 100,
@@ -251,88 +330,140 @@ const styles = StyleSheet.create({
     color: '#999',
     fontSize: 14,
   },
-  orderItem: {
-    marginTop: 10,
+  orderCard: {
+    marginVertical: 10,
+    minHeight: 200,
   },
-  orderItemBg: {
-    borderRadius: 12,
-    overflow: 'hidden',
+  cardContent: {
+    padding: 15,
   },
-  orderHeader: {
+  orderTop: {
     flexDirection: 'row',
     justifyContent: 'space-between',
-    alignItems: 'center',
-    padding: 12,
+    paddingBottom: 10,
     borderBottomWidth: 1,
-    borderBottomColor: 'rgba(0,0,0,0.1)',
+    borderBottomColor: '#CDCDCD',
   },
-  orderNo: {
-    color: '#666',
+  orderTime: {
     fontSize: 12,
+    color: '#666',
   },
   orderStatus: {
-    color: '#ff6b00',
-    fontSize: 13,
-    fontWeight: '500',
+    fontSize: 12,
+  },
+  timeoutText: {
+    fontSize: 11,
+    color: '#999',
+    marginTop: 5,
   },
-  orderContent: {
+  orderMiddle: {
     flexDirection: 'row',
-    padding: 12,
+    paddingVertical: 12,
   },
-  goodsImage: {
-    width: 80,
-    height: 80,
-    borderRadius: 8,
-    backgroundColor: '#fff',
+  productImgBg: {
+    width: 90,
+    height: 90,
+    padding: 8,
+  },
+  productImg: {
+    width: '100%',
+    height: '100%',
+    borderRadius: 3,
   },
-  goodsInfo: {
+  productInfo: {
     flex: 1,
     marginLeft: 12,
     justifyContent: 'space-between',
   },
-  goodsName: {
-    color: '#333',
+  productName: {
     fontSize: 14,
-    lineHeight: 20,
+    color: '#333',
+    fontWeight: 'bold',
   },
-  goodsBottom: {
+  priceRow: {
     flexDirection: 'row',
     justifyContent: 'space-between',
+  },
+  priceText: {
+    fontSize: 14,
+    color: '#333',
+  },
+  qtyText: {
+    fontSize: 14,
+    color: '#333',
+  },
+  discountText: {
+    fontSize: 12,
+    color: '#F1423D',
+    fontWeight: '500',
+  },
+  paymentRow: {
+    flexDirection: 'row',
     alignItems: 'center',
   },
-  goodsPrice: {
-    color: '#ff6b00',
+  paymentAmount: {
     fontSize: 16,
-    fontWeight: '600',
+    color: '#F1423D',
+    fontWeight: 'bold',
   },
-  goodsQty: {
-    color: '#666',
-    fontSize: 13,
+  itemList: {
+    marginTop: 5,
+    paddingBottom: 10,
   },
-  orderFooter: {
-    flexDirection: 'row',
-    justifyContent: 'space-between',
+  itemBox: {
+    marginRight: 10,
     alignItems: 'center',
-    padding: 12,
-    borderTopWidth: 1,
-    borderTopColor: 'rgba(0,0,0,0.1)',
   },
-  orderTime: {
-    color: '#999',
-    fontSize: 12,
+  itemImgBox: {
+    width: 60,
+    height: 65,
+    backgroundColor: '#fff',
+    borderRadius: 3,
+    overflow: 'hidden',
+  },
+  itemImg: {
+    width: '100%',
+    height: '100%',
+  },
+  levelTag: {
+    width: '100%',
+    paddingVertical: 2,
+    alignItems: 'center',
+  },
+  levelText: {
+    color: '#fff',
+    fontSize: 10,
+    fontWeight: 'bold',
   },
-  orderActions: {
+  orderNoRow: {
     flexDirection: 'row',
+    alignItems: 'center',
+    justifyContent: 'space-between',
+    height: 29,
   },
-  actionBtn: {
-    paddingHorizontal: 16,
-    paddingVertical: 6,
-    backgroundColor: '#ff6b00',
-    borderRadius: 15,
-    marginLeft: 10,
+  orderNoText: {
+    flex: 1,
+    fontSize: 12,
+    color: '#666',
   },
-  actionBtnText: {
+  copyBtn: {
+    paddingHorizontal: 6,
+    paddingVertical: 3,
+    backgroundColor: '#1FA4FF',
+    borderRadius: 4,
+  },
+  copyBtnText: {
     color: '#fff',
-    fontSize: 13,
+    fontSize: 12,
+  },
+  shopOrderBtn: {
+    position: 'absolute',
+    left: 10,
+    width: 60,
+    height: 63,
+  },
+  shopOrderIcon: {
+    width: '100%',
+    height: '100%',
   },
 });

+ 2 - 0
constants/images.ts

@@ -147,6 +147,7 @@ export const Images = {
     },
   },
   welfare: {
+    roomBg: `${CDN_BASE}/welfare/roomBg.png`,
     kaixinWelfareBg: `${CDN_BASE}/welfare/kaixinWelfareBg.png`,
     kaixinRoomBg: `${CDN_BASE}/welfare/kaixinRoomBg.png`,
     kaixinRoom1: `${CDN_BASE}/welfare/kaixinRoom1.png`,
@@ -226,6 +227,7 @@ export const Images = {
     magicTypeBg: `${CDN_BASE}/mine/magicTypeBg.png`,
     stoneBg: `${CDN_BASE}/mine/stoneBg.png`,
     avatarBorderBg: `${CDN_BASE}/common/noavatar.png`,  // 头像边框背景
+    shopOrder: `${CDN_BASE}/mine/shopOrder.png`,  // 商城订单入口图标
   },
   // 地址相关
   address: {