| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717 |
- import { Image } from 'expo-image';
- import { useLocalSearchParams, useRouter } from 'expo-router';
- import React, { useCallback, useEffect, useRef, useState } from 'react';
- import {
- ActivityIndicator,
- Animated,
- Dimensions,
- ImageBackground,
- ScrollView,
- StatusBar,
- StyleSheet,
- Text,
- TouchableOpacity,
- View,
- } from 'react-native';
- import { useSafeAreaInsets } from 'react-native-safe-area-context';
- import { Images } from '@/constants/images';
- import { useAuth } from '@/contexts/AuthContext';
- import {
- getBoxDetail,
- getNextBox,
- getPoolDetail,
- getPreBox,
- lockBox,
- poolIn,
- poolOut,
- previewOrder,
- unlockBox,
- } from '@/services/award';
- import { CheckoutModal } from '../award-detail/components/CheckoutModal';
- import { RecordModal } from '../award-detail/components/RecordModal';
- import { RuleModal } from '../award-detail/components/RuleModal';
- import { BoxChooseModal } from './components/BoxChooseModal';
- import { NumChooseModal } from './components/NumChooseModal';
- import { ProductListYfs } from './components/ProductListYfs';
- const { width: SCREEN_WIDTH } = Dimensions.get('window');
- interface PoolData {
- id: string;
- name: string;
- cover: string;
- price: number;
- specialPrice?: number;
- specialPriceFive?: number;
- restrictionQuantity?: number;
- luckGoodsList: ProductItem[];
- luckGoodsLevelProbabilityList?: any[];
- }
- interface ProductItem {
- id: string;
- name: string;
- cover: string;
- level: string;
- probability: number;
- price?: number;
- quantity?: number;
- }
- interface BoxData {
- number: string;
- quantity: number;
- leftQuantity: number;
- leftQuantityA: number;
- leftQuantityB: number;
- leftQuantityC: number;
- leftQuantityD: number;
- lastNumber: number;
- lock?: { locker: string; leftTime: number };
- usedStat?: Record<string, { spuId: string; quantity: number }>;
- prizeList?: any[];
- }
- export default function AwardDetailYfsScreen() {
- const { poolId } = useLocalSearchParams<{ poolId: string }>();
- const router = useRouter();
- const insets = useSafeAreaInsets();
- const { user } = useAuth();
- const [loading, setLoading] = useState(true);
- const [data, setData] = useState<PoolData | null>(null);
- const [products, setProducts] = useState<ProductItem[]>([]);
- const [box, setBox] = useState<BoxData | null>(null);
- const [boxNum, setBoxNum] = useState<string>('');
- const [currentIndex, setCurrentIndex] = useState(0);
- const [leftTime, setLeftTime] = useState(0);
- const [probability, setProbability] = useState<any[]>([]);
- const [scrollTop, setScrollTop] = useState(0);
- const checkoutRef = useRef<any>(null);
- const recordRef = useRef<any>(null);
- const ruleRef = useRef<any>(null);
- const numChooseRef = useRef<any>(null);
- const boxChooseRef = useRef<any>(null);
- const floatAnim = useRef(new Animated.Value(0)).current;
- const timerRef = useRef<ReturnType<typeof setInterval> | null>(null);
- useEffect(() => {
- Animated.loop(
- Animated.sequence([
- Animated.timing(floatAnim, { toValue: 10, duration: 1500, useNativeDriver: true }),
- Animated.timing(floatAnim, { toValue: -10, duration: 1500, useNativeDriver: true }),
- ])
- ).start();
- }, []);
- const loadData = useCallback(async () => {
- if (!poolId) return;
- setLoading(true);
- try {
- const detail = await getPoolDetail(poolId);
- if (detail) {
- setData(detail);
- setProducts(detail.luckGoodsList || []);
- }
- } catch (error) {
- console.error('加载数据失败:', error);
- }
- setLoading(false);
- }, [poolId]);
- const loadBox = useCallback(
- async (num?: string) => {
- if (!poolId) return;
- try {
- const res = await getBoxDetail(poolId, num);
- if (res) handleBoxResult(res);
- } catch (error) {
- console.error('加载盒子失败:', error);
- }
- },
- [poolId]
- );
- const handleBoxResult = (res: any) => {
- const map: Record<string, any> = {};
- if (res.usedStat) {
- res.usedStat.forEach((item: any) => {
- map[item.spuId] = item;
- });
- }
- res.usedStat = map;
- setBox(res);
- setBoxNum(res.number);
- lockTimeStart(res);
- if (res.leftQuantity <= 0) {
- setProbability([
- { level: 'A', probability: 0 },
- { level: 'B', probability: 0 },
- { level: 'C', probability: 0 },
- { level: 'D', probability: 0 },
- ]);
- } else {
- setProbability([
- { level: 'A', probability: ((res.leftQuantityA / res.leftQuantity) * 100).toFixed(2) },
- { level: 'B', probability: ((res.leftQuantityB / res.leftQuantity) * 100).toFixed(2) },
- { level: 'C', probability: ((res.leftQuantityC / res.leftQuantity) * 100).toFixed(2) },
- { level: 'D', probability: ((res.leftQuantityD / res.leftQuantity) * 100).toFixed(2) },
- ]);
- }
- };
- const lockTimeStart = (boxData: BoxData) => {
- lockTimeEnd();
- if (boxData?.lock) {
- setLeftTime(boxData.lock.leftTime);
- timerRef.current = setInterval(() => {
- setLeftTime((prev) => {
- if (prev <= 1) {
- lockTimeEnd();
- loadBox();
- return 0;
- }
- return prev - 1;
- });
- }, 1000);
- }
- };
- const lockTimeEnd = () => {
- if (timerRef.current) {
- clearInterval(timerRef.current);
- timerRef.current = null;
- }
- setLeftTime(0);
- };
- useEffect(() => {
- loadData();
- loadBox();
- if (poolId) poolIn(poolId);
- return () => {
- if (poolId) poolOut(poolId);
- lockTimeEnd();
- };
- }, [poolId]);
- const handlePay = async (num: number) => {
- if (!poolId || !data || !box) return;
- try {
- const preview = await previewOrder(poolId, num, box.number);
- if (preview) checkoutRef.current?.show(num, preview, box.number);
- } catch (error) {
- console.error('预览订单失败:', error);
- }
- };
- const handleSuccess = () => {
- setTimeout(() => {
- loadData();
- loadBox(boxNum);
- }, 500);
- };
- // 处理多盒购买(号码选择后的回调)
- const handleNumPay = async (params: { preview: any; seatNumbers: number[]; boxNumber: string }) => {
- checkoutRef.current?.show(params.seatNumbers.length, params.preview, params.boxNumber, params.seatNumbers);
- };
- // 打开号码选择弹窗
- const handleShowNumChoose = () => {
- if (!box) return;
- numChooseRef.current?.show({
- number: box.number,
- quantity: box.quantity || box.leftQuantity,
- lastNumber: box.lastNumber,
- });
- };
- // 打开换盒弹窗
- const handleShowBoxChoose = () => {
- boxChooseRef.current?.show();
- };
- // 选择盒子后的回调
- const handleChooseBox = (boxNumber: string) => {
- loadBox(boxNumber);
- };
- const handlePreBox = async () => {
- if (!poolId || !boxNum || parseInt(boxNum) <= 1) return;
- try {
- const res = await getPreBox(poolId, boxNum);
- if (res) handleBoxResult(res);
- } catch (error) {
- console.error('获取上一个盒子失败:', error);
- }
- };
- const handleNextBox = async () => {
- if (!poolId || !box || parseInt(boxNum) >= box.lastNumber) return;
- try {
- const res = await getNextBox(poolId, boxNum);
- if (res) handleBoxResult(res);
- } catch (error) {
- console.error('获取下一个盒子失败:', error);
- }
- };
- const handleLock = async () => {
- if (!poolId || !boxNum) return;
- try {
- await lockBox(poolId, boxNum);
- loadBox(boxNum);
- } catch (error) {
- console.error('锁定失败:', error);
- }
- };
- const handleUnlock = async () => {
- if (!poolId || !boxNum) return;
- try {
- await unlockBox(poolId, boxNum);
- loadBox(boxNum);
- } catch (error) {
- console.error('解锁失败:', error);
- }
- };
- const handlePrev = () => {
- if (currentIndex > 0) setCurrentIndex(currentIndex - 1);
- };
- const handleNext = () => {
- if (currentIndex < products.length - 1) setCurrentIndex(currentIndex + 1);
- };
- const getLevelName = (level: string) => {
- const map: Record<string, string> = { A: '超神款', B: '欧皇款', C: '隐藏款', D: '普通款' };
- return map[level] || level;
- };
- const getLeftNum = (item: ProductItem) => {
- if (!box?.usedStat || !box.usedStat[item.id]?.quantity) {
- return item.quantity || 1;
- }
- return (item.quantity || 1) - box.usedStat[item.id].quantity;
- };
- const getProbability = (item: ProductItem) => {
- if (!box || box.leftQuantity <= 0) return '0';
- const leftNum = getLeftNum(item);
- return ((leftNum / box.leftQuantity) * 100).toFixed(2);
- };
- const leftNum = box?.lock ? (leftTime / box.lock.leftTime) * 100 : 0;
- const headerBg = scrollTop > 0 ? '#333' : 'transparent';
- if (loading) {
- return (
- <View style={styles.loadingContainer}>
- <ActivityIndicator size="large" color="#fff" />
- </View>
- );
- }
- if (!data) {
- return (
- <View style={styles.loadingContainer}>
- <Text style={styles.errorText}>奖池不存在</Text>
- <TouchableOpacity style={styles.backBtn2} onPress={() => router.back()}>
- <Text style={styles.backBtn2Text}>返回</Text>
- </TouchableOpacity>
- </View>
- );
- }
- const currentProduct = products[currentIndex];
- return (
- <View style={styles.container}>
- <StatusBar barStyle="light-content" />
- <ImageBackground source={{ uri: Images.common.indexBg }} style={styles.background} resizeMode="cover">
- {/* 顶部导航 */}
- <View style={[styles.header, { paddingTop: insets.top, backgroundColor: headerBg }]}>
- <TouchableOpacity style={styles.backBtn} onPress={() => router.back()}>
- <Text style={styles.backText}>{'<'}</Text>
- </TouchableOpacity>
- <Text style={styles.headerTitle} numberOfLines={1}>
- {data.name}
- </Text>
- <View style={styles.placeholder} />
- </View>
- <ScrollView
- style={styles.scrollView}
- showsVerticalScrollIndicator={false}
- onScroll={(e) => setScrollTop(e.nativeEvent.contentOffset.y)}
- scrollEventThrottle={16}
- >
- {/* 主商品展示区域 */}
- <ImageBackground source={{ uri: Images.box.detail.mainGoodsSection }} style={styles.mainGoodsSection} resizeMode="cover">
- <View style={{ height: 72 + insets.top }} />
- {/* 商品轮播区域 */}
- <View style={styles.mainSwiper}>
- {currentProduct && (
- <>
- <Animated.View style={[styles.productImageBox, { transform: [{ translateY: floatAnim }] }]}>
- <Image source={{ uri: currentProduct.cover }} style={styles.productImage} contentFit="contain" />
- </Animated.View>
- {/* 等级信息 */}
- <ImageBackground source={{ uri: Images.box.detail.detailsBut }} style={styles.detailsBut} resizeMode="contain">
- <View style={styles.detailsText}>
- <Text style={styles.levelText}>{getLevelName(currentProduct.level)}</Text>
- <Text style={styles.probabilityText}>({getProbability(currentProduct)}%)</Text>
- </View>
- </ImageBackground>
- {/* 商品名称 */}
- <ImageBackground source={{ uri: Images.box.detail.nameBg }} style={styles.goodsNameBg} resizeMode="contain">
- <Text style={styles.goodsNameText} numberOfLines={6}>
- {currentProduct.name}
- </Text>
- </ImageBackground>
- </>
- )}
- {/* 左右切换按钮 */}
- {currentIndex > 0 && (
- <TouchableOpacity style={styles.prevBtn} onPress={handlePrev}>
- <Image source={{ uri: Images.box.detail.left }} style={styles.arrowImg} contentFit="contain" />
- </TouchableOpacity>
- )}
- {currentIndex < products.length - 1 && (
- <TouchableOpacity style={styles.nextBtn} onPress={handleNext}>
- <Image source={{ uri: Images.box.detail.right }} style={styles.arrowImg} contentFit="contain" />
- </TouchableOpacity>
- )}
- </View>
- {/* 左侧装饰 */}
- <Image source={{ uri: Images.box.detail.positionBgleftBg }} style={styles.positionBgleftBg} contentFit="contain" />
- {/* 右侧装饰 */}
- <Image source={{ uri: Images.box.detail.positionBgRightBg }} style={styles.positionBgRightBg} contentFit="contain" />
- </ImageBackground>
- {/* 底部装饰文字 */}
- <Image source={{ uri: Images.box.detail.mainGoodsSectionBtext }} style={styles.mainGoodsSectionBtext} contentFit="cover" />
- {/* 侧边按钮 - 规则 */}
- <TouchableOpacity style={[styles.positionBut, styles.positionRule]} onPress={() => ruleRef.current?.show()}>
- <ImageBackground source={{ uri: Images.box.detail.positionBgLeft }} style={styles.positionButBg} resizeMode="contain">
- <Text style={styles.positionButText}>规则</Text>
- </ImageBackground>
- </TouchableOpacity>
- {/* 侧边按钮 - 记录 */}
- <TouchableOpacity style={[styles.positionBut, styles.positionRecord]} onPress={() => recordRef.current?.show()}>
- <ImageBackground source={{ uri: Images.box.detail.positionBgLeft }} style={styles.positionButBg} resizeMode="contain">
- <Text style={styles.positionButText}>记录</Text>
- </ImageBackground>
- </TouchableOpacity>
- {/* 侧边按钮 - 锁定/解锁 */}
- {box && !box.lock && (
- <TouchableOpacity style={[styles.positionBut, styles.positionLock]} onPress={handleLock}>
- <ImageBackground source={{ uri: Images.box.detail.positionBgLeft }} style={styles.positionButBg} resizeMode="contain">
- <Text style={styles.positionButText}>锁定</Text>
- </ImageBackground>
- </TouchableOpacity>
- )}
- {box?.lock && user && box.lock.locker === (user.userId || user.id) && (
- <TouchableOpacity style={[styles.positionBut, styles.positionLock]} onPress={handleUnlock}>
- <ImageBackground source={{ uri: Images.box.detail.positionBgLeft }} style={styles.positionButBg} resizeMode="contain">
- <Text style={styles.positionButText}>解锁</Text>
- </ImageBackground>
- </TouchableOpacity>
- )}
- {/* 侧边按钮 - 仓库 */}
- <TouchableOpacity style={[styles.positionBut, styles.positionStore]} onPress={() => router.push('/store' as any)}>
- <ImageBackground source={{ uri: Images.box.detail.positionBgRight }} style={styles.positionButBg} resizeMode="contain">
- <Text style={styles.positionButTextR}>仓库</Text>
- </ImageBackground>
- </TouchableOpacity>
- {/* 侧边按钮 - 刷新 */}
- <TouchableOpacity style={[styles.positionBut, styles.positionRefresh]} onPress={() => loadBox(boxNum)}>
- <ImageBackground source={{ uri: Images.box.detail.positionBgRight }} style={styles.positionButBg} resizeMode="contain">
- <Text style={styles.positionButTextR}>刷新</Text>
- </ImageBackground>
- </TouchableOpacity>
- {/* 锁定倒计时 */}
- {box?.lock && (
- <View style={styles.lockTimeBox}>
- <Text style={styles.lockTimeLabel}>剩余时间:</Text>
- <View style={styles.lockTimeBarBox}>
- <View style={styles.lockTimeBar}>
- <View style={[styles.processBar, { width: `${leftNum}%` }]} />
- </View>
- <Text style={[styles.lockTimeText, { left: `${leftNum}%` }]}>{leftTime}</Text>
- </View>
- </View>
- )}
- {/* 标题 */}
- <View style={styles.productTitleBox}>
- <Image source={{ uri: Images.box.detail.productTitle }} style={styles.productTitleImg} contentFit="contain" />
- </View>
- {/* 一番赏盒子信息区域 */}
- <ImageBackground source={{ uri: Images.box.detail.firstBoxBg }} style={styles.firstLastBox}>
- {/* 当前盒子剩余数量 */}
- {box && (
- <View style={styles.boxSizeRow}>
- <Text style={styles.boxSizeText}>当前盒子剩余:</Text>
- <Text style={styles.boxSizeText}>
- <Text style={styles.boxSizeNum}>{box.leftQuantity}</Text>
- /{box.quantity || '-'}发
- </Text>
- </View>
- )}
- {/* 抢先赏/最终赏/全局赏展示 */}
- {box?.prizeList && box.prizeList.length > 0 && (
- <View style={styles.prizeListRow}>
- {box.prizeList.map((item: any, index: number) => (
- <ImageBackground key={index} source={{ uri: Images.box.detail.firstItemBg }} style={styles.prizeItem}>
- <Image source={{ uri: item.cover }} style={styles.prizeImage} contentFit="contain" />
- <View style={[styles.prizeLevelTag, {
- backgroundColor: item.level === 'FIRST' ? 'rgba(91, 189, 208, 0.8)' :
- item.level === 'LAST' ? 'rgba(246, 44, 113, 0.8)' : 'rgba(44, 246, 74, 0.8)'
- }]}>
- <Text style={styles.prizeLevelText}>
- {item.level === 'FIRST' ? '抢先赏' : item.level === 'LAST' ? '最终赏' : '全局赏'}
- </Text>
- </View>
- </ImageBackground>
- ))}
- </View>
- )}
- {/* 换盒控制区 */}
- <ImageBackground source={{ uri: Images.box.detail.funBoxBg }} style={styles.funBox}>
- <TouchableOpacity style={styles.preBoxBtn} onPress={handlePreBox} disabled={!boxNum || parseInt(boxNum) <= 1}>
- <Text style={[styles.funBoxText, (!boxNum || parseInt(boxNum) <= 1) && styles.disabled]}>上一盒</Text>
- </TouchableOpacity>
- <TouchableOpacity style={styles.changeBoxBtn} onPress={handleShowBoxChoose}>
- <Text style={styles.changeBoxText}>换盒({boxNum || '-'}/{box?.lastNumber || '-'})</Text>
- </TouchableOpacity>
- <TouchableOpacity style={styles.nextBoxBtn} onPress={handleNextBox} disabled={!box || parseInt(boxNum) >= box.lastNumber}>
- <Text style={[styles.funBoxText, (!box || parseInt(boxNum) >= box.lastNumber) && styles.disabled]}>下一盒</Text>
- </TouchableOpacity>
- </ImageBackground>
- </ImageBackground>
- {/* 商品列表 */}
- <ProductListYfs products={products} levelList={probability} poolId={poolId!} price={data.price} box={box} />
- <View style={{ height: 150 }} />
- </ScrollView>
- {/* 底部购买栏 */}
- <ImageBackground source={{ uri: Images.box.detail.boxDetailBott }} style={[styles.bottomBar, { paddingBottom: insets.bottom + 10 }]} resizeMode="cover">
- <View style={styles.bottomBtns}>
- <TouchableOpacity style={styles.btnItem} onPress={() => handlePay(1)} activeOpacity={0.8}>
- <ImageBackground source={{ uri: Images.common.butBgV }} style={styles.btnBg} resizeMode="contain">
- <Text style={styles.btnText}>购买一盒</Text>
- <Text style={styles.btnPrice}>(¥{data.specialPrice || data.price})</Text>
- </ImageBackground>
- </TouchableOpacity>
- <TouchableOpacity style={styles.btnItem} onPress={() => handlePay(5)} activeOpacity={0.8}>
- <ImageBackground source={{ uri: Images.common.butBgL }} style={styles.btnBg} resizeMode="contain">
- <Text style={styles.btnText}>购买五盒</Text>
- <Text style={styles.btnPrice}>(¥{data.specialPriceFive || data.price * 5})</Text>
- </ImageBackground>
- </TouchableOpacity>
- <TouchableOpacity style={styles.btnItem} onPress={handleShowNumChoose} activeOpacity={0.8}>
- <ImageBackground source={{ uri: Images.common.butBgH }} style={styles.btnBg} resizeMode="contain">
- <Text style={styles.btnText}>购买多盒</Text>
- </ImageBackground>
- </TouchableOpacity>
- </View>
- </ImageBackground>
- </ImageBackground>
- <CheckoutModal ref={checkoutRef} data={data} poolId={poolId!} boxNumber={boxNum} onSuccess={handleSuccess} />
- <RecordModal ref={recordRef} poolId={poolId!} />
- <RuleModal ref={ruleRef} />
- <NumChooseModal ref={numChooseRef} poolId={poolId!} onPay={handleNumPay} />
- <BoxChooseModal ref={boxChooseRef} poolId={poolId!} onChoose={handleChooseBox} />
- </View>
- );
- }
- const styles = StyleSheet.create({
- container: { flex: 1, backgroundColor: '#1a1a2e' },
- background: { flex: 1 },
- loadingContainer: { flex: 1, backgroundColor: '#1a1a2e', justifyContent: 'center', alignItems: 'center' },
- errorText: { color: '#999', fontSize: 16 },
- backBtn2: { marginTop: 20, backgroundColor: '#ff6600', paddingHorizontal: 20, paddingVertical: 10, borderRadius: 8 },
- backBtn2Text: { color: '#fff', fontSize: 14 },
- header: {
- flexDirection: 'row',
- alignItems: 'center',
- justifyContent: 'space-between',
- paddingHorizontal: 10,
- paddingBottom: 10,
- position: 'absolute',
- top: 0,
- left: 0,
- right: 0,
- zIndex: 100,
- },
- backBtn: { width: 40, height: 40, justifyContent: 'center', alignItems: 'center' },
- backText: { color: '#fff', fontSize: 16, fontWeight: 'bold' },
- headerTitle: { color: '#fff', fontSize: 15, fontWeight: 'bold', flex: 1, textAlign: 'center', width: 250 },
- placeholder: { width: 40 },
- scrollView: { flex: 1 },
- mainGoodsSection: { width: SCREEN_WIDTH, height: 504, position: 'relative' },
- mainSwiper: { position: 'relative', width: '100%', height: 375, alignItems: 'center', justifyContent: 'center', marginTop: -50 },
- productImageBox: { width: 200, height: 300, justifyContent: 'center', alignItems: 'center' },
- productImage: { width: 200, height: 300 },
- detailsBut: { width: 120, height: 45, justifyContent: 'center', alignItems: 'center', marginTop: -30 },
- detailsText: { flexDirection: 'row', alignItems: 'center' },
- levelText: { fontSize: 14, color: '#FBC400', fontWeight: 'bold' },
- probabilityText: { fontSize: 10, color: '#FBC400', marginLeft: 3 },
- goodsNameBg: { position: 'absolute', left: 47, top: 53, width: 43, height: 100, paddingTop: 8, justifyContent: 'flex-start', alignItems: 'center' },
- goodsNameText: { fontSize: 12, fontWeight: 'bold', color: '#000', width: 20, textAlign: 'center' },
- prevBtn: { position: 'absolute', left: 35, top: '40%' },
- nextBtn: { position: 'absolute', right: 35, top: '40%' },
- arrowImg: { width: 33, height: 38 },
- positionBgleftBg: { position: 'absolute', left: 0, top: 225, width: 32, height: 188 },
- positionBgRightBg: { position: 'absolute', right: 0, top: 225, width: 32, height: 188 },
- mainGoodsSectionBtext: { width: SCREEN_WIDTH, height: 74, marginTop: -10 },
- positionBut: { position: 'absolute', zIndex: 10, width: 35, height: 34 },
- positionButBg: { width: 35, height: 34, justifyContent: 'center', alignItems: 'center' },
- positionButText: { fontSize: 12, fontWeight: 'bold', color: '#fff', transform: [{ rotate: '14deg' }], textShadowColor: '#000', textShadowOffset: { width: 1, height: 1 }, textShadowRadius: 1 },
- positionButTextR: { fontSize: 12, fontWeight: 'bold', color: '#fff', transform: [{ rotate: '-16deg' }], textShadowColor: '#000', textShadowOffset: { width: 1, height: 1 }, textShadowRadius: 1 },
- positionRule: { top: 256, left: 0 },
- positionRecord: { top: 300, left: 0 },
- positionLock: { top: 345, left: 0 },
- positionStore: { top: 256, right: 0 },
- positionRefresh: { top: 300, right: 0 },
- lockTimeBox: { flexDirection: 'row', alignItems: 'center', backgroundColor: '#71ccff', padding: 10, marginHorizontal: 10, borderRadius: 8, marginTop: -60 },
- lockTimeLabel: { color: '#000', fontSize: 12 },
- lockTimeBarBox: { flex: 1, height: 30, position: 'relative', justifyContent: 'center' },
- lockTimeBar: { height: 8, backgroundColor: 'rgba(255,255,255,0.6)', borderRadius: 4, overflow: 'hidden' },
- processBar: { height: '100%', backgroundColor: '#209ae5', borderRadius: 4 },
- lockTimeText: { position: 'absolute', top: -5, fontSize: 10, backgroundColor: '#000', color: '#fff', paddingHorizontal: 4, borderRadius: 2, marginLeft: -13 },
- productTitleBox: { alignItems: 'center', marginTop: -20, marginBottom: 10 },
- productTitleImg: { width: 121, height: 29 },
- // 一番赏盒子信息区域
- firstLastBox: {
- marginHorizontal: 10,
- height: 193,
- marginBottom: 10,
- paddingTop: 20,
- },
- boxSizeRow: {
- flexDirection: 'row',
- alignItems: 'center',
- paddingLeft: 10,
- paddingTop: 12,
- },
- boxSizeText: {
- fontSize: 12,
- color: '#fff',
- textShadowColor: '#000',
- textShadowOffset: { width: 1, height: 1 },
- textShadowRadius: 2,
- },
- boxSizeNum: {
- fontSize: 16,
- fontWeight: 'bold',
- },
- prizeListRow: {
- flexDirection: 'row',
- justifyContent: 'center',
- alignItems: 'center',
- paddingTop: 20,
- minHeight: 66,
- },
- prizeItem: {
- width: 63,
- height: 65,
- marginHorizontal: 5,
- position: 'relative',
- },
- prizeImage: {
- width: 60,
- height: 50,
- },
- prizeLevelTag: {
- position: 'absolute',
- left: 0,
- bottom: -8,
- width: '100%',
- height: 22,
- justifyContent: 'center',
- alignItems: 'center',
- },
- prizeLevelText: {
- fontSize: 10,
- color: '#fff',
- fontWeight: 'bold',
- },
- funBox: {
- width: 270,
- height: 38,
- flexDirection: 'row',
- alignItems: 'center',
- justifyContent: 'center',
- alignSelf: 'center',
- marginTop: 15,
- },
- preBoxBtn: {
- width: 90,
- height: 50,
- justifyContent: 'center',
- alignItems: 'center',
- },
- nextBoxBtn: {
- width: 90,
- height: 50,
- justifyContent: 'center',
- alignItems: 'center',
- },
- changeBoxBtn: {
- width: 110,
- height: 60,
- justifyContent: 'center',
- alignItems: 'center',
- },
- funBoxText: {
- fontSize: 12,
- color: '#fff',
- fontWeight: '500',
- },
- changeBoxText: {
- fontSize: 12,
- color: '#000',
- fontWeight: '500',
- },
- disabled: { opacity: 0.3 },
- bottomBar: { position: 'absolute', bottom: 0, left: 0, right: 0, height: 69, paddingHorizontal: 5 },
- bottomBtns: { flexDirection: 'row', height: 64, alignItems: 'center', justifyContent: 'space-around' },
- btnItem: { flex: 1, marginHorizontal: 6 },
- btnBg: { width: '100%', height: 54, justifyContent: 'center', alignItems: 'center' },
- btnText: { fontSize: 14, fontWeight: 'bold', color: '#fff' },
- btnPrice: { fontSize: 9, color: '#fff' },
- });
|