import { Image } from "expo-image"; import { useLocalSearchParams, useRouter } from "expo-router"; import React, { useCallback, useEffect, useRef, useState } from "react"; import { ActivityIndicator, Alert, ImageBackground, Modal, ScrollView, Share, StatusBar, StyleSheet, Text, TextInput, TouchableOpacity, View, } from "react-native"; import { useSafeAreaInsets } from "react-native-safe-area-context"; import { Images } from "@/constants/images"; import { getWealDetail, getWinningRecord, joinWealRoom, } from "@/services/dimension"; const TYPE_MAP: any = { COMMON: { title: "福利房" }, PASSWORD: { title: "口令房" }, ACHIEVEMENT: { title: "成就房" }, EUROPEAN_GAS: { title: "欧气房" }, HONOR_ROLL: { title: "荣耀榜" }, }; export default function WealDetailScreen() { const { id } = useLocalSearchParams<{ id: string }>(); const router = useRouter(); const insets = useSafeAreaInsets(); const [loading, setLoading] = useState(true); const [data, setData] = useState(null); const [leftTime, setLeftTime] = useState(0); const [scrollTop, setScrollTop] = useState(0); const [winVisible, setWinVisible] = useState(false); const [winRecords, setWinRecords] = useState([]); const [joinVisible, setJoinVisible] = useState(false); const [password, setPassword] = useState(""); const timerRef = useRef(null); const loadData = useCallback( async (showLoading = false) => { if (showLoading) setLoading(true); try { const res = await getWealDetail(id as string); if (res) { setData(res); setLeftTime(res.leftTime); } } catch (error) { console.error("加载详情失败:", error); } setLoading(false); }, [id], ); useEffect(() => { loadData(true); return () => stopTimer(); }, [loadData]); useEffect(() => { if (data?.status === 1 && leftTime > 0) { startTimer(); } else { stopTimer(); } }, [data, leftTime]); const startTimer = () => { stopTimer(); timerRef.current = setInterval(() => { setLeftTime((prev) => { if (prev <= 0) { stopTimer(); loadData(); return 0; } return prev - 1000; }); }, 1000); }; const stopTimer = () => { if (timerRef.current) { clearInterval(timerRef.current); timerRef.current = null; } }; const formatLeftTime = () => { if (leftTime <= 0) return "00:00:00"; let second = Math.floor(leftTime / 1000); const d = Math.floor(second / (24 * 3600)); second %= 24 * 3600; const h = Math.floor(second / 3600); second %= 3600; const m = Math.floor(second / 60); const s = second % 60; let res = ""; if (d > 0) res += `${d}天`; res += `${h.toString().padStart(2, "0")}时${m.toString().padStart(2, "0")}分${s.toString().padStart(2, "0")}秒`; return res; }; const handleJoin = async () => { if (data.status !== 1 || data.myParticipatedFlag === 1) return; if (data.type === "PASSWORD") { setJoinVisible(true); } else { try { const res = await joinWealRoom(id as string, ""); if (res.success) { Alert.alert("提示", "加入成功"); loadData(); } else { if ( res.msg && (res.msg.includes("口令") || res.msg.includes("密码")) ) { setJoinVisible(true); } else { Alert.alert("错误", res.msg || "加入失败"); } } } catch (error) { Alert.alert("错误", "请求异常"); } } }; const handleJoinWithPassword = async () => { if (!password) return; try { const res = await joinWealRoom(id as string, password); if (res.success) { Alert.alert("提示", "加入成功"); setJoinVisible(false); setPassword(""); loadData(); } else { Alert.alert("错误", res.msg || "口令错误"); } } catch (error) { Alert.alert("错误", "请求异常"); } }; const handleShare = async () => { try { const result = await Share.share({ message: `快来参与福利房:${data?.name},房间ID:${id}`, title: "福利房分享", }); if (result.action === Share.sharedAction) { if (result.activityType) { // shared with activity type of result.activityType } else { // shared } } else if (result.action === Share.dismissedAction) { // dismissed } } catch (error: any) { Alert.alert(error.message); } }; const showWinRecords = async () => { try { const res = await getWinningRecord(id as string); setWinRecords(res || []); setWinVisible(true); } catch (error) { console.error("获取中奖记录失败:", error); } }; if (loading) { return ( ); } const headerBg = scrollTop > 50 ? "#333" : "transparent"; return ( {/* 导航 */} router.back()} style={styles.backBtn} > {TYPE_MAP[data.type]?.title || "详情"} setScrollTop(e.nativeEvent.contentOffset.y)} scrollEventThrottle={16} showsVerticalScrollIndicator={false} > {data.name} {TYPE_MAP[data.type]?.title} {data.description} {/* 中奖记录按钮 */} {data.prizeMode !== 1 && data.type !== "EUROPEAN_GAS" && ( 中奖记录 )} {/* 赠品池 */} 赠品池 {data.luckRoomGoodsList?.length}件赠品 {data.luckRoomGoodsList?.map((item: any, index: number) => ( {item.spu.name} 数量:{item.quantity} ))} {/* 参与度 */} 参与度 {data.participatingList?.length}个玩家 {data.participatingList?.map((user: any, index: number) => ( {user.nickname} ))} {/* 底部按钮栏 */} {data.status === 1 && ( 倒计时: {formatLeftTime()} )} {data.status !== 1 ? "已开奖" : data.myParticipatedFlag === 1 ? data.participateMode === 1 && data.myAuditStatus === 0 ? "待审核" : data.participateMode === 1 && data.myAuditStatus === 1 ? "审核不通过" : "等待开赏" : "加入房间,即可参与"} {/* 口令弹窗 */} 请输入房间口令 setJoinVisible(false)} > 取消 确认加入 {/* 中奖记录弹窗 */} 中奖记录 setWinVisible(false)} style={styles.winClose} > × {winRecords.length === 0 ? ( 暂无记录 ) : ( winRecords.map((item: any, index: number) => ( {item.nickname} 获得了 {item.spu.name} )) )} ); } const styles = StyleSheet.create({ container: { flex: 1 }, background: { flex: 1 }, loading: { flex: 1, backgroundColor: "#1a1a2e", justifyContent: "center", alignItems: "center", }, nav: { flexDirection: "row", alignItems: "center", justifyContent: "space-between", paddingHorizontal: 15, height: 90, zIndex: 100, }, backBtn: { width: 40 }, backText: { color: "#fff", fontSize: 24 }, navTitle: { color: "#fff", fontSize: 16, fontWeight: "bold" }, placeholder: { width: 40 }, scrollView: { flex: 1 }, headerBg: { width: "100%", height: 180, position: "absolute", top: 0 }, content: { paddingHorizontal: 15, marginTop: 90 }, roomInfo: { alignItems: "center", marginBottom: 20 }, roomName: { color: "#fff", fontSize: 22, fontWeight: "bold", textShadowColor: "#000", textShadowOffset: { width: 1, height: 1 }, textShadowRadius: 2, }, roomType: { marginTop: 8, paddingVertical: 4, paddingHorizontal: 12, backgroundColor: "rgba(255,255,255,0.2)", borderRadius: 10, }, roomTypeText: { color: "#fff", fontSize: 12 }, roomDesc: { marginTop: 10, color: "#BEBBB3", fontSize: 12 }, recordBtn: { position: "absolute", right: 0, top: 0, zIndex: 10 }, recordBtnBg: { width: 78, height: 26, justifyContent: "center", alignItems: "center", flexDirection: "row", }, recordIcon: { width: 16, height: 16, marginRight: 2 }, recordBtnText: { color: "#fff", fontSize: 12, fontWeight: "bold", textShadowColor: "#000", textShadowOffset: { width: 1, height: 1 }, textShadowRadius: 1, }, goodsCard: { marginTop: 25, backgroundColor: "rgba(255,255,255,0.1)", borderRadius: 15, padding: 15, }, cardHeader: { flexDirection: "row", alignItems: "center", marginBottom: 15 }, cardTitle: { color: "#fff", fontSize: 18, fontWeight: "bold" }, cardNum: { color: "#eee", fontSize: 12, marginLeft: 10 }, goodsList: { flexDirection: "row", flexWrap: "wrap", justifyContent: "space-between", }, goodsItem: { width: "31%", aspectRatio: 0.8, backgroundColor: "rgba(0,0,0,0.3)", borderRadius: 10, padding: 8, marginBottom: 10, alignItems: "center", }, goodsImg: { width: "80%", height: "60%" }, goodsName: { color: "#fff", fontSize: 10, marginTop: 5 }, goodsCountTag: { position: "absolute", left: 0, bottom: 10, backgroundColor: "#FFDD00", paddingHorizontal: 5, borderTopRightRadius: 5, borderBottomRightRadius: 5, }, goodsCountText: { color: "#000", fontSize: 8, fontWeight: "bold" }, participantSection: { marginTop: 20, backgroundColor: "rgba(255,255,255,0.1)", borderRadius: 15, padding: 15, }, userList: { flexDirection: "row" }, userItem: { alignItems: "center", marginRight: 15, width: 50 }, userAvatar: { width: 40, height: 40, borderRadius: 20, borderWidth: 1, borderColor: "#fff", }, userName: { color: "#fff", fontSize: 8, marginTop: 5, width: "100%", textAlign: "center", }, bottomBar: { position: "absolute", left: 0, right: 0, bottom: 0, backgroundColor: "rgba(0,0,0,0.8)", paddingHorizontal: 15, paddingTop: 10, }, timerRow: { flexDirection: "row", alignItems: "center", justifyContent: "center", marginBottom: 10, }, timerLabel: { color: "#fff", fontSize: 12 }, timerValue: { color: "#fdf685", fontSize: 12, fontWeight: "bold" }, joinBtn: { height: 45, borderRadius: 22.5, width: "100%", overflow: "hidden", }, joinBtnDisabled: { backgroundColor: "#666" }, joinBtnBg: { width: "100%", height: "100%", justifyContent: "center", alignItems: "center", }, joinBtnText: { color: "#fff", fontSize: 14, fontWeight: "bold" }, modalOverlay: { flex: 1, backgroundColor: "rgba(0,0,0,0.6)", justifyContent: "center", alignItems: "center", }, modalContent: { width: "80%", backgroundColor: "#fff", borderRadius: 15, padding: 20, alignItems: "center", }, modalTitle: { fontSize: 18, fontWeight: "bold", marginBottom: 20 }, modalInput: { width: "100%", height: 45, backgroundColor: "#f5f5f5", borderRadius: 8, paddingHorizontal: 15, marginBottom: 20, }, modalBtns: { flexDirection: "row", justifyContent: "space-between", width: "100%", }, modalBtn: { flex: 0.45, height: 40, justifyContent: "center", alignItems: "center", borderRadius: 20, backgroundColor: "#eee", }, modalBtnConfirm: { backgroundColor: "#e79018" }, modalBtnText: { fontWeight: "bold" }, winOverlay: { flex: 1, backgroundColor: "rgba(0,0,0,0.5)", justifyContent: "flex-end", }, winContent: { backgroundColor: "#fff", height: "60%", borderTopLeftRadius: 20, borderTopRightRadius: 20, padding: 20, }, winHeader: { flexDirection: "row", justifyContent: "space-between", alignItems: "center", marginBottom: 20, }, winTitle: { fontSize: 18, fontWeight: "bold" }, winClose: { width: 30, height: 30, backgroundColor: "#eee", borderRadius: 15, justifyContent: "center", alignItems: "center", }, winCloseText: { fontSize: 20, color: "#999" }, winList: { flex: 1 }, winItem: { flexDirection: "row", alignItems: "center", paddingVertical: 10, borderBottomWidth: 1, borderBottomColor: "#f5f5f5", }, winAvatar: { width: 30, height: 30, borderRadius: 15 }, winUser: { marginLeft: 10, fontSize: 12, width: 60 }, winGot: { fontSize: 12, color: "#999", marginHorizontal: 5 }, winGoods: { flex: 1, fontSize: 12 }, winGoodsImg: { width: 30, height: 30, marginLeft: 10 }, empty: { alignItems: "center", padding: 30 }, });