瀏覽代碼

删除签到积分模块

zbb 3 月之前
父節點
當前提交
6db18faba3
共有 4 個文件被更改,包括 524 次插入702 次删除
  1. 0 11
      app/(tabs)/mine.tsx
  2. 0 9
      app/integral/_layout.tsx
  3. 0 682
      app/integral/index.tsx
  4. 524 0
      app/orders/shop.tsx

+ 0 - 11
app/(tabs)/mine.tsx

@@ -32,7 +32,6 @@ export default function MineScreen() {
   const [userInfo, setUserInfo] = useState<UserInfo | null>(null);
   const [indexData, setIndexData] = useState<IndexData | null>(null);
   const [inviteShow, setInviteShow] = useState(false);
-  const [showCredit, setShowCredit] = useState(false);
   const [filingInfo, setFilingInfo] = useState<{ state: number; data: string } | null>(null);
   const [showWallet, setShowWallet] = useState(false);
   const kefuRef = useRef<KefuPopupRef>(null);
@@ -50,10 +49,6 @@ export default function MineScreen() {
       const inviteConfig = await getParamConfig('invite_config');
       setInviteShow(inviteConfig?.state !== 0);
 
-      // 获取积分显示配置
-      const creditConfig = await getParamConfig('credit_show');
-      setShowCredit(creditConfig?.state !== 0);
-
       // 获取备案信息
       const filingConfig = await getParamConfig('beian_icp');
       if (filingConfig) {
@@ -313,12 +308,6 @@ export default function MineScreen() {
                   <Text style={styles.funcText}>邀新有礼</Text>
                 </TouchableOpacity>
               )}
-              {showCredit && (
-                <TouchableOpacity style={styles.funcItem} onPress={() => handleMenuPress('/integral')}>
-                  <Image source={{ uri: Images.mine.kaixinintegral }} style={styles.funcIcon} contentFit="contain" />
-                  <Text style={styles.funcText}>签到领积分</Text>
-                </TouchableOpacity>
-              )}
               <TouchableOpacity style={styles.funcItem} onPress={() => handleMenuPress('/message')}>
                 <Image source={{ uri: Images.mine.message }} style={styles.funcIcon} contentFit="contain" />
                 <Text style={styles.funcText}>系统消息</Text>

+ 0 - 9
app/integral/_layout.tsx

@@ -1,9 +0,0 @@
-import { Stack } from 'expo-router';
-
-export default function IntegralLayout() {
-  return (
-    <Stack screenOptions={{ headerShown: false }}>
-      <Stack.Screen name="index" />
-    </Stack>
-  );
-}

+ 0 - 682
app/integral/index.tsx

@@ -1,682 +0,0 @@
-import { Image } from 'expo-image';
-import { useRouter } from 'expo-router';
-import React, { useCallback, useEffect, useState } from 'react';
-import {
-    Alert,
-    ImageBackground,
-    ScrollView,
-    StatusBar,
-    StyleSheet,
-    Text,
-    TouchableOpacity,
-    View,
-} from 'react-native';
-import { useSafeAreaInsets } from 'react-native-safe-area-context';
-
-import { Images } from '@/constants/images';
-import services from '@/services/api';
-
-interface DayInfo {
-  text: string;
-  date: string;
-  isFutureDate: boolean;
-  istoday: boolean;
-  isSignIn: boolean;
-}
-
-interface RecordItem {
-  id: string;
-  credit: number;
-  createTime: string;
-}
-
-export default function IntegralScreen() {
-  const router = useRouter();
-  const insets = useSafeAreaInsets();
-  
-  const [integral, setIntegral] = useState(0);
-  const [daysIntegral, setDaysIntegral] = useState(0);
-  const [istodaySignIn, setIstodaySignIn] = useState(false);
-  const [record, setRecord] = useState<RecordItem[]>([]);
-  const [dataInfo, setDataInfo] = useState<DayInfo[]>([]);
-  const [todayIntegral, setTodayIntegral] = useState(1);
-  const [tomorrowIntegral, setTomorrowIntegral] = useState(1);
-  const [isTooltip, setIsTooltip] = useState(false);
-
-  // 格式化数字为两位
-  const padWithZeros = (number: number, length: number) => {
-    return String(number).padStart(length, '0');
-  };
-
-  // 设置日期数据
-  const setDate = useCallback(() => {
-    const now = new Date();
-    const dataInfoArr: DayInfo[] = [];
-
-    // 前4天
-    for (let i = -4; i <= 0; i++) {
-      const date = new Date(now);
-      date.setDate(date.getDate() + i);
-      const m = date.getMonth() + 1;
-      const d = date.getDate();
-      const y = date.getFullYear();
-      
-      dataInfoArr.push({
-        text: `${m}.${d}`,
-        date: `${y}-${padWithZeros(m, 2)}-${padWithZeros(d, 2)}`,
-        isFutureDate: false,
-        istoday: i === 0,
-        isSignIn: false,
-      });
-    }
-
-    // 明天
-    const tomorrow = new Date(now);
-    tomorrow.setDate(tomorrow.getDate() + 1);
-    const tm = tomorrow.getMonth() + 1;
-    const td = tomorrow.getDate();
-    const ty = tomorrow.getFullYear();
-    
-    dataInfoArr.push({
-      text: `${tm}.${td}`,
-      date: `${ty}-${padWithZeros(tm, 2)}-${padWithZeros(td, 2)}`,
-      isFutureDate: true,
-      istoday: false,
-      isSignIn: false,
-    });
-
-    setDataInfo(dataInfoArr);
-    return dataInfoArr;
-  }, []);
-
-  // 获取积分信息
-  const getInfo = useCallback(async () => {
-    try {
-      // Use wallet service info instead of user service getWalletInfo
-      const info = await services.wallet.info('USER_CREDIT');
-      setIntegral(info?.balance || 0);
-    } catch (error) {
-      console.error('获取积分失败:', error);
-    }
-  }, []);
-
-  // 获取积分规则
-  const showRule = async () => {
-    try {
-      const res = await services.user.getParamConfig('credit_sign');
-      if (res && res.data) {
-        Alert.alert('积分规则', res.data.replace(/<[^>]+>/g, '')); // Strip HTML tags for Alert
-      }
-    } catch (error) {
-       console.error('获取规则失败:', error);
-    }
-  };
-
-  // 获取签到记录
-  const getData = useCallback(async (dateInfo: DayInfo[]) => {
-    try {
-      const fourDaysAgo = new Date();
-      fourDaysAgo.setDate(fourDaysAgo.getDate() - 4);
-      const m = fourDaysAgo.getMonth() + 1;
-      const d = fourDaysAgo.getDate();
-      const y = fourDaysAgo.getFullYear();
-      
-      const param = {
-        createTime: `${y}-${padWithZeros(m, 2)}-${padWithZeros(d, 2)}`,
-      };
-
-      const res = await services.user.getCreditRecord(param);
-      const recordData = res?.data || [];
-      setRecord(recordData);
-
-      // 今天日期
-      const now = new Date();
-      const todayStr = `${now.getFullYear()}-${padWithZeros(now.getMonth() + 1, 2)}-${padWithZeros(now.getDate(), 2)}`;
-
-      // 更新签到状态
-      const updatedDataInfo = dateInfo.map(item => {
-        const newItem = { ...item };
-        
-        // 检查是否已签到
-        for (const rec of recordData) {
-          const createTime = rec.createTime?.slice(0, 10);
-          if (createTime === item.date) {
-            newItem.isSignIn = true;
-            if (item.date === todayStr) {
-              setIstodaySignIn(true);
-            }
-          }
-        }
-        
-        return newItem;
-      });
-
-      setDataInfo(updatedDataInfo);
-
-      // 计算签到积分
-      let total = 0;
-      for (const rec of recordData) {
-        if (rec.credit > 0) {
-          total += rec.credit;
-        }
-      }
-      setDaysIntegral(total);
-
-      // 计算今天和明天的积分
-      if (recordData.length > 0) {
-        const lastCredit = recordData[0]?.credit || 1;
-        const yesterday = new Date();
-        yesterday.setDate(yesterday.getDate() - 1);
-        const yesterdayStr = `${yesterday.getFullYear()}-${padWithZeros(yesterday.getMonth() + 1, 2)}-${padWithZeros(yesterday.getDate(), 2)}`;
-        const lastRecordDate = recordData[0]?.createTime?.slice(0, 10);
-
-        if (yesterdayStr === lastRecordDate) {
-          setTodayIntegral(lastCredit + 1);
-          setTomorrowIntegral(lastCredit + 2);
-        } else {
-          setTodayIntegral(lastCredit);
-          setTomorrowIntegral(Math.min(lastCredit + 1, 7));
-        }
-      }
-    } catch (error) {
-      console.error('获取签到记录失败:', error);
-    }
-  }, []);
-
-  // 初始化
-  useEffect(() => {
-    const dateInfo = setDate();
-    getInfo();
-    getData(dateInfo);
-  }, [setDate, getInfo, getData]);
-
-  // 签到
-  const handleSignIn = async () => {
-    if (istodaySignIn) {
-      Alert.alert('提示', '今天已签到');
-      return;
-    }
-
-    try {
-      const res = await services.user.signIn();
-      if (res?.code === 0) {
-        Alert.alert('提示', '签到成功');
-        setIstodaySignIn(true);
-        
-        // Optimistic update for UI
-        const optimisticDateInfo = dataInfo.map(item => {
-             if (item.istoday) {
-                 return { ...item, isSignIn: true };
-             }
-             return item;
-        });
-        setDataInfo(optimisticDateInfo);
-
-        // Delay fetch to ensure backend data consistency
-        setTimeout(() => {
-            const dateInfo = setDate();
-            getInfo();
-            getData(dateInfo);
-        }, 500);
-      } else {
-        Alert.alert('提示', res?.msg || '签到失败');
-      }
-    } catch (error) {
-      console.error('签到失败:', error);
-      Alert.alert('提示', '签到失败');
-    }
-  };
-
-  const handleBack = () => {
-    router.back();
-  };
-
-  return (
-    <View style={styles.container}>
-      <StatusBar barStyle="dark-content" />
-      
-      {/* 顶部导航 */}
-      <View style={[styles.header, { paddingTop: insets.top }]}>
-        <TouchableOpacity style={styles.backBtn} onPress={handleBack}>
-          <Text style={styles.backIcon}>‹</Text>
-        </TouchableOpacity>
-        <Text style={styles.title}>我的积分</Text>
-        <View style={styles.placeholder} />
-      </View>
-
-      <ScrollView style={styles.scrollView} showsVerticalScrollIndicator={false}>
-        {/* 头部积分展示 */}
-        <ImageBackground
-          source={{ uri: Images.integral?.head || Images.common.commonBg }}
-          style={styles.headerBg}
-          resizeMode="cover"
-        >
-          <Text style={styles.integralNum}>{integral}</Text>
-          <TouchableOpacity 
-            style={styles.allBox}
-            onPress={() => setIsTooltip(!isTooltip)}
-          >
-            <Text style={styles.allText}>所有积分</Text>
-            <Image
-              source={{ uri: Images.integral?.greetings }}
-              style={styles.infoIcon}
-              contentFit="contain"
-            />
-            {isTooltip && (
-                <ImageBackground 
-                    source={{uri: Images.integral?.tooltip }} 
-                    style={styles.tooltip}
-                    resizeMode="stretch"
-                >
-                    <Text style={styles.tooltipText}>消费积分与签到积分总和</Text>
-                </ImageBackground>
-            )}
-          </TouchableOpacity>
-          <View style={styles.todayBox}>
-            <Text style={styles.todayText}>
-              今日已获得<Text style={styles.todayNum}>{istodaySignIn ? todayIntegral : 0}</Text>积分
-            </Text>
-          </View>
-          
-          <TouchableOpacity style={styles.ruleBtn} onPress={showRule}>
-             <Text style={styles.ruleText}>积分规则</Text>
-          </TouchableOpacity>
-        </ImageBackground>
-
-        <View style={styles.content}>
-          {/* 签到面板 */}
-          <View style={styles.panel}>
-            <View style={styles.panelTitle}>
-              <View style={styles.panelTitleLeft}>
-                <Image
-                  source={{ uri: Images.integral?.goldCoins }}
-                  style={styles.goldIcon}
-                  contentFit="contain"
-                />
-                <Text style={styles.panelTitleText}>签到领积分</Text>
-              </View>
-              <Text style={[styles.panelTitleRight, istodaySignIn && styles.signedText]}>
-                {istodaySignIn ? '今日已签到' : '今日未签到'}
-              </Text>
-            </View>
-
-            <Text style={styles.explain}>
-              已签到{record.filter(r => r.credit > 0).length}天,共获得<Text style={styles.highlightText}>{daysIntegral}</Text>积分
-            </Text>
-
-            {/* 签到进度 */}
-            <View style={styles.progressBox}>
-              <View style={styles.lineBox}>
-                {[1, 2, 3, 4, 5].map((_, index) => (
-                  <View key={index} style={styles.lineSection}>
-                    <View style={[styles.line, styles.lineOn]} />
-                  </View>
-                ))}
-              </View>
-
-              <View style={styles.daysBox}>
-                {dataInfo.map((item, index) => (
-                  <View key={index} style={styles.dayItem}>
-                    <TouchableOpacity
-                      style={styles.dayCircleBox}
-                      onPress={item.istoday && !istodaySignIn ? handleSignIn : undefined}
-                      activeOpacity={item.istoday && !istodaySignIn ? 0.7 : 1}
-                    >
-                      {item.istoday && !istodaySignIn ? (
-                        <ImageBackground
-                          source={{ uri: Images.integral?.basisBg }}
-                          style={styles.dayCircleBg}
-                          resizeMode="contain"
-                        >
-                          <View style={[styles.dayCircle, styles.todayCircle]}>
-                            <Text style={styles.todayCircleText}>+{todayIntegral}</Text>
-                          </View>
-                        </ImageBackground>
-                      ) : item.isFutureDate ? (
-                        <View style={[styles.dayCircle, styles.futureCircle]}>
-                          <Text style={styles.futureText}>+{tomorrowIntegral}</Text>
-                        </View>
-                      ) : item.isSignIn ? (
-                        <View style={[styles.dayCircle, styles.signedCircle]}>
-                          <Text style={styles.checkIcon}>✓</Text>
-                        </View>
-                      ) : (
-                        <View style={[styles.dayCircle, styles.missedCircle]}>
-                          <Text style={styles.missedIcon}>✗</Text>
-                        </View>
-                      )}
-                    </TouchableOpacity>
-                    <Text style={[styles.dayText, item.istoday && styles.todayDayText]}>
-                      {item.istoday ? '今天' : item.text}
-                    </Text>
-                  </View>
-                ))}
-              </View>
-            </View>
-          </View>
-
-          {/* 积分明细 */}
-          <View style={styles.listSection}>
-            <Text style={styles.listTitle}>积分明细</Text>
-            {record.map((item, index) => (
-              <View key={item.id || index} style={styles.listItem}>
-                <View style={styles.listItemLeft}>
-                  <Text style={styles.listItemTitle}>
-                    {item.credit > 0 ? '积分签到获得' : '大转盘消费'}
-                  </Text>
-                  <Text style={styles.listItemTime}>{item.createTime}</Text>
-                </View>
-                <Text style={[
-                  styles.listItemCredit,
-                  item.credit > 0 ? styles.creditPositive : styles.creditNegative
-                ]}>
-                  {item.credit > 0 ? '+' : ''}{item.credit}
-                </Text>
-              </View>
-            ))}
-            {record.length === 0 && (
-              <View style={styles.emptyBox}>
-                <Text style={styles.emptyText}>暂无积分记录</Text>
-              </View>
-            )}
-          </View>
-        </View>
-      </ScrollView>
-    </View>
-  );
-}
-
-const styles = StyleSheet.create({
-  container: {
-    flex: 1,
-    backgroundColor: '#F8FAFB',
-  },
-  header: {
-    flexDirection: 'row',
-    alignItems: 'center',
-    justifyContent: 'space-between',
-    paddingHorizontal: 10,
-    height: 80,
-    backgroundColor: 'transparent',
-    position: 'absolute',
-    top: 0,
-    left: 0,
-    right: 0,
-    zIndex: 100,
-  },
-  backBtn: {
-    width: 40,
-    height: 40,
-    justifyContent: 'center',
-    alignItems: 'center',
-  },
-  backIcon: {
-    fontSize: 32,
-    color: '#000',
-    fontWeight: 'bold',
-  },
-  title: {
-    fontSize: 15,
-    fontWeight: 'bold',
-    color: '#000',
-  },
-  placeholder: {
-    width: 40,
-  },
-  scrollView: {
-    flex: 1,
-  },
-  headerBg: {
-    width: '100%',
-    height: 283,
-    paddingTop: 100,
-    alignItems: 'center',
-    position: 'relative',
-  },
-  integralNum: {
-    fontSize: 48,
-    fontWeight: '400',
-    color: '#5B460F',
-    textAlign: 'center',
-  },
-  allBox: {
-    flexDirection: 'row',
-    alignItems: 'center',
-    marginTop: 7,
-    marginBottom: 12,
-    position: 'relative',
-  },
-  allText: {
-    fontSize: 12,
-    color: '#C8B177',
-  },
-  infoIcon: {
-    width: 16,
-    height: 16,
-    marginLeft: 4,
-  },
-  tooltip: {
-      position: 'absolute',
-      width: 150,
-      height: 27,
-      top: 15,
-      left: 30, // Adjust execution based on design
-      justifyContent: 'center',
-      alignItems: 'center',
-      zIndex: 999,
-      paddingHorizontal: 5,
-  },
-  tooltipText: {
-      color: '#fff',
-      fontSize: 10,
-  },
-  todayBox: {
-    backgroundColor: 'rgba(0,0,0,0.08)',
-    borderRadius: 217,
-    paddingHorizontal: 15,
-    paddingVertical: 5,
-  },
-  todayText: {
-    fontSize: 12,
-    color: '#8A794F',
-  },
-  todayNum: {
-    fontWeight: '800',
-    color: '#5B460F',
-  },
-  ruleBtn: {
-    position: 'absolute',
-    right: 0,
-    top: 130, // Half of 260rpx approx
-    backgroundColor: '#fff',
-    borderTopLeftRadius: 20,
-    borderBottomLeftRadius: 20,
-    paddingHorizontal: 10,
-    paddingVertical: 6,
-    zIndex: 10,
-  },
-  ruleText: {
-    fontSize: 12,
-    color: '#333',
-  },
-  content: {
-    paddingHorizontal: 10,
-    marginTop: -50,
-  },
-  panel: {
-    backgroundColor: '#fff',
-    borderRadius: 15,
-    padding: 12,
-  },
-  panelTitle: {
-    flexDirection: 'row',
-    justifyContent: 'space-between',
-    alignItems: 'center',
-    paddingHorizontal: 10,
-  },
-  panelTitleLeft: {
-    flexDirection: 'row',
-    alignItems: 'center',
-  },
-  goldIcon: {
-    width: 24,
-    height: 24,
-    marginRight: 6,
-  },
-  panelTitleText: {
-    fontSize: 16,
-    fontWeight: '700',
-    color: '#3D3D3D',
-  },
-  panelTitleRight: {
-    fontSize: 12,
-    color: '#FC7D2E',
-  },
-  signedText: {
-    color: '#999',
-  },
-  explain: {
-    fontSize: 12,
-    color: '#999',
-    paddingHorizontal: 10,
-    marginTop: 7,
-    marginBottom: 11,
-  },
-  highlightText: {
-    color: '#FC7D2E',
-  },
-  progressBox: {
-    paddingTop: 20,
-  },
-  lineBox: {
-    flexDirection: 'row',
-    paddingHorizontal: 10,
-  },
-  lineSection: {
-    flex: 1,
-  },
-  line: {
-    height: 1,
-    backgroundColor: '#9E9E9E',
-  },
-  lineOn: {
-    backgroundColor: '#FC7D2E',
-  },
-  daysBox: {
-    flexDirection: 'row',
-    marginTop: -25,
-  },
-  dayItem: {
-    flex: 1,
-    alignItems: 'center',
-  },
-  dayCircleBox: {
-    width: 46,
-    height: 46,
-    justifyContent: 'center',
-    alignItems: 'center',
-    marginBottom: 3,
-  },
-  dayCircleBg: {
-    width: 46,
-    height: 46,
-    justifyContent: 'center',
-    alignItems: 'center',
-  },
-  dayCircle: {
-    width: 32,
-    height: 32,
-    borderRadius: 16,
-    justifyContent: 'center',
-    alignItems: 'center',
-  },
-  todayCircle: {
-    backgroundColor: '#FC7D2E',
-  },
-  todayCircleText: {
-    color: '#fff',
-    fontSize: 12,
-    fontWeight: 'bold',
-  },
-  futureCircle: {
-    backgroundColor: '#F4F6F8',
-    borderWidth: 1,
-    borderColor: 'rgba(226,226,226,0.5)',
-  },
-  futureText: {
-    color: '#505050',
-    fontSize: 12,
-  },
-  signedCircle: {
-    backgroundColor: '#FFE7C4',
-  },
-  checkIcon: {
-    color: '#FC7D2E',
-    fontSize: 16,
-    fontWeight: 'bold',
-  },
-  missedCircle: {
-    backgroundColor: '#F4F6F8',
-  },
-  missedIcon: {
-    color: '#999',
-    fontSize: 16,
-  },
-  dayText: {
-    fontSize: 12,
-    color: '#9E9E9E',
-  },
-  todayDayText: {
-    color: '#FC7D2E',
-  },
-  listSection: {
-    backgroundColor: '#fff',
-    borderRadius: 15,
-    padding: 12,
-    marginTop: 10,
-    marginBottom: 30,
-  },
-  listTitle: {
-    fontSize: 16,
-    fontWeight: '700',
-    color: '#3D3D3D',
-    marginBottom: 10,
-  },
-  listItem: {
-    flexDirection: 'row',
-    justifyContent: 'space-between',
-    alignItems: 'center',
-    paddingVertical: 14,
-    borderBottomWidth: 1,
-    borderBottomColor: 'rgba(0,0,0,0.05)',
-  },
-  listItemLeft: {},
-  listItemTitle: {
-    fontSize: 14,
-    color: '#333',
-    marginBottom: 3,
-  },
-  listItemTime: {
-    fontSize: 12,
-    color: '#999',
-  },
-  listItemCredit: {
-    fontSize: 18,
-    fontWeight: '700',
-  },
-  creditPositive: {
-    color: '#588CFF',
-  },
-  creditNegative: {
-    color: '#FC7D2E',
-  },
-  emptyBox: {
-    paddingVertical: 50,
-    alignItems: 'center',
-  },
-  emptyText: {
-    fontSize: 14,
-    color: '#999',
-  },
-});
-

+ 524 - 0
app/orders/shop.tsx

@@ -0,0 +1,524 @@
+import { Image } from 'expo-image';
+import { useLocalSearchParams, useRouter } from 'expo-router';
+import React, { useCallback, useEffect, useState } from 'react';
+import {
+    ActivityIndicator,
+    Alert,
+    Clipboard,
+    ImageBackground,
+    RefreshControl,
+    ScrollView,
+    StatusBar,
+    StyleSheet,
+    Text,
+    TouchableOpacity,
+    View
+} from 'react-native';
+import { useSafeAreaInsets } from 'react-native-safe-area-context';
+
+import { Images } from '@/constants/images';
+import { getOrders, OrderItem } from '@/services/mall';
+
+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' },
+];
+
+export default function ShopOrdersScreen() {
+  const router = useRouter();
+  const insets = useSafeAreaInsets();
+
+  const params = useLocalSearchParams();
+  const [loading, setLoading] = useState(true);
+  const [refreshing, setRefreshing] = useState(false);
+  const [activeTab, setActiveTab] = useState(() => {
+    if (params.active) return parseInt(params.active as string, 10);
+    return 0;
+  });
+  const [orders, setOrders] = useState<OrderItem[]>([]);
+  const [page, setPage] = useState(1);
+
+  const loadData = useCallback(async (tabValue?: string, refresh = false) => {
+    if (refresh) {
+      setRefreshing(true);
+      setPage(1);
+    } else {
+      setLoading(true);
+    }
+    try {
+      let tabId: any = tabValue;
+      if (tabValue === 'all') tabId = undefined;
+      
+      const data = await getOrders(refresh ? 1 : page, 10, tabId);
+      if (data?.records) {
+        setOrders(refresh ? data.records : [...orders, ...data.records]);
+      }
+    } catch (error) {
+      console.error('加载商城订单失败:', error);
+    }
+    setLoading(false);
+    setRefreshing(false);
+  }, [page, orders]);
+
+  useEffect(() => {
+    loadData(tabs[activeTab].value, true);
+  }, [activeTab]);
+
+  const onRefresh = () => {
+    loadData(tabs[activeTab].value, true);
+  };
+
+  const switchTab = (index: number) => {
+    if (index !== activeTab) {
+      setActiveTab(index);
+      setOrders([]);
+    }
+  };
+
+  const goBack = () => {
+    router.back();
+  };
+
+  const goBox = () => {
+    router.replace('/orders' as any);
+  };
+
+  const copyTradeNo = (tradeNo: string) => {
+    Clipboard.setString(tradeNo);
+    Alert.alert('提示', '订单号已复制');
+  };
+
+  const getStatusInfo = (status: number) => {
+    switch (status) {
+      case 0: return { text: '待支付', color: '#F62C71' };
+      case 99: return { text: '已完成', color: '#20D7EF' };
+      case 1: return { text: '待发货', color: '#F62C71' };
+      case 2: return { text: '待收货', color: '#F62C71' };
+      case 10: return { text: '已取消', color: '#999' };
+      case 11: return { text: '超时取消', color: '#999' };
+      case 12: return { text: '系统取消', color: '#999' };
+      default: return { text: '未知', color: '#999' };
+    }
+  };
+
+  return (
+    <View style={styles.container}>
+      <StatusBar barStyle="light-content" />
+      <ImageBackground
+        source={{ uri: Images.mine.kaixinMineBg }}
+        style={styles.background}
+        resizeMode="cover"
+      >
+        <View style={[styles.header, { paddingTop: insets.top }]}>
+          <TouchableOpacity style={styles.backBtn} onPress={goBack}>
+            <Text style={styles.backText}>‹</Text>
+          </TouchableOpacity>
+          <Text style={styles.headerTitle}>商城订单</Text>
+          <View style={styles.placeholder} />
+        </View>
+
+        <View style={styles.tabBar}>
+          <ScrollView horizontal showsHorizontalScrollIndicator={false} style={styles.tabScroll}>
+            {tabs.map((tab, index) => (
+              <TouchableOpacity
+                key={index}
+                onPress={() => switchTab(index)}
+                activeOpacity={0.8}
+              >
+                <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>
+            ))}
+          </ScrollView>
+        </View>
+
+        <ScrollView
+          style={styles.scrollView}
+          showsVerticalScrollIndicator={false}
+          refreshControl={
+            <RefreshControl refreshing={refreshing} onRefresh={onRefresh} tintColor="#fff" />
+          }
+        >
+          {loading && orders.length === 0 ? (
+            <View style={styles.loadingContainer}>
+              <ActivityIndicator size="large" color="#fff" />
+            </View>
+          ) : orders.length === 0 ? (
+            <View style={styles.emptyContainer}>
+              <Text style={styles.emptyText}>暂无订单</Text>
+            </View>
+          ) : (
+            orders.map((item) => {
+              const statusInfo = getStatusInfo(item.status);
+              return (
+                <ImageBackground
+                  key={item.tradeNo}
+                  source={{ uri: Images.common.itemBg }}
+                  style={styles.orderCard}
+                  resizeMode="stretch"
+                >
+                  <View style={styles.cardContent}>
+                    {/* 顶部信息 */}
+                    <View style={styles.orderTop}>
+                      <View style={styles.flexRow}>
+                        <Text style={styles.orderTimeText}>下单时间:{item.createTime}</Text>
+                        {item.type === 2 && <View style={styles.presellTag}><Text style={styles.presellText}>预售订单</Text></View>}
+                      </View>
+                      <Text style={[styles.orderStatusText, { 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 }}
+                        style={styles.productImgBg}
+                        resizeMode="stretch"
+                      >
+                        <Image source={{ uri: item.goodsCover }} style={styles.goodsImage} contentFit="cover" />
+                      </ImageBackground>
+                      <View style={styles.goodsInfo}>
+                        <Text style={styles.goodsName} numberOfLines={1}>{item.goodsName}</Text>
+                        <View style={styles.priceRow}>
+                          <Text style={styles.goodsPrice}>¥{item.paymentAmount}</Text>
+                          <Text style={styles.goodsQty}>X{item.quantity}</Text>
+                        </View>
+                        {(item.couponAmount ?? 0) > 0 && (
+                          <Text style={styles.discountText}>使用优惠券-{item.couponAmount}</Text>
+                        )}
+                        
+                        <View style={styles.totalRow}>
+                          <View style={styles.totalItem}>
+                            <Text style={styles.totalLabel}>总价:</Text>
+                            <Text style={styles.totalValueSymbol}>¥</Text>
+                            <Text style={styles.totalValue}>{item.totalAmount || item.paymentAmount}</Text>
+                          </View>
+                          <View style={[styles.totalItem, { marginLeft: 12 }]}>
+                            <Text style={styles.payLabel}>{item.status === 0 ? '需付款:' : '实付款:'}</Text>
+                            <Text style={styles.payValueSymbol}>¥</Text>
+                            <Text style={styles.payValue}>{item.paidAmount || item.paymentAmount}</Text>
+                          </View>
+                        </View>
+                      </View>
+                    </View>
+
+                    {/* 订单号 & 复制 */}
+                    <View style={styles.orderNoRow}>
+                      <Text style={styles.orderNo} numberOfLines={1}>订单号:{item.tradeNo}</Text>
+                      <TouchableOpacity style={styles.copyBtn} onPress={() => copyTradeNo(item.tradeNo)}>
+                        <Text style={styles.copyBtnText}>复制</Text>
+                      </TouchableOpacity>
+                    </View>
+
+                    {/* 功能按钮 */}
+                    <View style={styles.orderFooter}>
+                      {item.status === 0 && (
+                        <TouchableOpacity style={styles.actionBtn}>
+                          <Text style={styles.actionBtnText}>付款</Text>
+                        </TouchableOpacity>
+                      )}
+                      {item.status === 1 && (
+                        <TouchableOpacity style={[styles.actionBtn, styles.infoBtn]}>
+                          <Text style={styles.actionBtnText}>修改地址</Text>
+                        </TouchableOpacity>
+                      )}
+                      {item.status === 2 && (
+                        <TouchableOpacity style={styles.actionBtn}>
+                          <Text style={styles.actionBtnText}>确认收货</Text>
+                        </TouchableOpacity>
+                      )}
+                      {[2, 99].includes(item.status) && (
+                        <TouchableOpacity style={[styles.actionBtn, { marginLeft: 8 }]}>
+                          <Text style={styles.actionBtnText}>物流信息</Text>
+                        </TouchableOpacity>
+                      )}
+                    </View>
+                  </View>
+                </ImageBackground>
+              );
+            })
+          )}
+          <View style={{ height: 80 }} />
+        </ScrollView>
+
+        {/* 奖池订单入口 */}
+        <TouchableOpacity style={[styles.floatBtn, { bottom: insets.bottom + 154 }]} onPress={goBox}>
+          <Image source={{ uri: Images.mine.boxOrder }} style={styles.floatIcon} contentFit="contain" />
+        </TouchableOpacity>
+      </ImageBackground>
+    </View>
+  );
+}
+
+const styles = StyleSheet.create({
+  container: {
+    flex: 1,
+    backgroundColor: '#1a1a2e',
+  },
+  background: {
+    flex: 1,
+  },
+  header: {
+    flexDirection: 'row',
+    alignItems: 'center',
+    justifyContent: 'space-between',
+    paddingHorizontal: 15,
+    paddingBottom: 10,
+  },
+  backBtn: {
+    width: 40,
+    height: 40,
+    justifyContent: 'center',
+    alignItems: 'center',
+  },
+  backText: {
+    color: '#fff',
+    fontSize: 32,
+    fontWeight: 'bold',
+  },
+  headerTitle: {
+    color: '#fff',
+    fontSize: 15,
+    fontWeight: 'bold',
+  },
+  placeholder: {
+    width: 40,
+  },
+  tabBar: {
+    height: 50,
+    marginHorizontal: 10,
+    marginBottom: 7,
+  },
+  tabScroll: {
+    flex: 1,
+  },
+  tabItem: {
+    width: 80,
+    height: 40,
+    justifyContent: 'center',
+    alignItems: 'center',
+    marginRight: 10,
+    paddingTop: 4,
+  },
+  tabText: {
+    color: '#000',
+    fontSize: 14,
+    fontWeight: '400',
+  },
+  tabTextActive: {
+    fontWeight: 'bold',
+  },
+  scrollView: {
+    flex: 1,
+    paddingHorizontal: 10,
+  },
+  loadingContainer: {
+    paddingTop: 100,
+    alignItems: 'center',
+  },
+  emptyContainer: {
+    paddingTop: 100,
+    alignItems: 'center',
+  },
+  emptyText: {
+    color: '#999',
+    fontSize: 14,
+  },
+  orderCard: {
+    marginVertical: 10,
+    minHeight: 220,
+  },
+  cardContent: {
+    paddingHorizontal: 20,
+    paddingVertical: 10,
+  },
+  orderTop: {
+    flexDirection: 'row',
+    justifyContent: 'space-between',
+    paddingVertical: 15,
+    borderBottomWidth: 1,
+    borderBottomColor: '#CDCDCD',
+    alignItems: 'center',
+  },
+  flexRow: {
+    flexDirection: 'row',
+    alignItems: 'center',
+  },
+  orderTimeText: {
+    fontSize: 12,
+    color: '#333',
+  },
+  presellTag: {
+    backgroundColor: '#F1423D',
+    borderRadius: 11,
+    paddingHorizontal: 8,
+    height: 22,
+    justifyContent: 'center',
+    marginLeft: 8,
+  },
+  presellText: {
+    color: '#fff',
+    fontSize: 12,
+  },
+  orderStatusText: {
+    fontSize: 12,
+    fontWeight: '500',
+  },
+  timeoutText: {
+    fontSize: 11,
+    color: '#999',
+    marginTop: 5,
+  },
+  orderMiddle: {
+    flexDirection: 'row',
+    paddingVertical: 12,
+    borderBottomWidth: 1,
+    borderBottomColor: '#eee',
+  },
+  productImgBg: {
+    width: 70,
+    height: 70,
+    padding: 7,
+  },
+  goodsImage: {
+    width: '100%',
+    height: '100%',
+    borderRadius: 3,
+  },
+  goodsInfo: {
+    flex: 1,
+    marginLeft: 12,
+    justifyContent: 'center',
+  },
+  goodsName: {
+    fontSize: 14,
+    color: '#333',
+    fontWeight: 'bold',
+  },
+  priceRow: {
+    flexDirection: 'row',
+    justifyContent: 'space-between',
+    marginTop: 8,
+  },
+  goodsPrice: {
+    fontSize: 14,
+    color: '#333',
+    fontWeight: 'bold',
+  },
+  goodsQty: {
+    fontSize: 12,
+    color: '#333',
+  },
+  discountText: {
+    fontSize: 12,
+    color: '#F1423D',
+    marginTop: 4,
+  },
+  totalRow: {
+    flexDirection: 'row',
+    alignItems: 'center',
+    marginTop: 8,
+  },
+  totalItem: {
+    flexDirection: 'row',
+    alignItems: 'baseline',
+  },
+  totalLabel: {
+    fontSize: 11,
+    color: '#666',
+  },
+  totalValueSymbol: {
+    fontSize: 11,
+    color: '#666',
+  },
+  totalValue: {
+    fontSize: 14,
+    color: '#666',
+    fontWeight: 'bold',
+  },
+  payLabel: {
+    fontSize: 12,
+    color: '#F1423D',
+  },
+  payValueSymbol: {
+    fontSize: 12,
+    color: '#F1423D',
+  },
+  payValue: {
+    fontSize: 18,
+    color: '#F1423D',
+    fontWeight: 'bold',
+  },
+  orderNoRow: {
+    flexDirection: 'row',
+    alignItems: 'center',
+    justifyContent: 'space-between',
+    paddingVertical: 12,
+    borderBottomWidth: 1,
+    borderBottomColor: '#CDCDCD',
+  },
+  orderNo: {
+    flex: 1,
+    fontSize: 12,
+    color: '#666',
+  },
+  copyBtn: {
+    paddingHorizontal: 6,
+    paddingVertical: 3,
+    backgroundColor: '#1FA4FF',
+    borderRadius: 4,
+  },
+  copyBtnText: {
+    color: '#fff',
+    fontSize: 12,
+  },
+  orderFooter: {
+    flexDirection: 'row',
+    justifyContent: 'flex-end',
+    paddingVertical: 12,
+  },
+  actionBtn: {
+    height: 24,
+    paddingHorizontal: 10,
+    backgroundColor: '#1FA4FF',
+    borderRadius: 12,
+    justifyContent: 'center',
+    alignItems: 'center',
+  },
+  infoBtn: {
+    backgroundColor: '#1FA4FF',
+  },
+  actionBtnText: {
+    color: '#fff',
+    fontSize: 12,
+  },
+  floatBtn: {
+    position: 'absolute',
+    left: 10,
+    width: 60,
+    height: 63,
+  },
+  floatIcon: {
+    width: '100%',
+    height: '100%',
+  },
+});