|
@@ -0,0 +1,489 @@
|
|
|
+"use client";
|
|
|
+
|
|
|
+import { lredPacketApi, receiveRedPacketApi, redPacketApi } from "@/api/promo";
|
|
|
+import { getToken } from "@/utils/Cookies";
|
|
|
+import { Mask } from "antd-mobile";
|
|
|
+import Image from "next/image";
|
|
|
+import { forwardRef, Fragment, useEffect, useImperativeHandle, useRef, useState } from "react";
|
|
|
+import styles from "./redpacked.module.scss";
|
|
|
+
|
|
|
+const randomX = (len: number) => {
|
|
|
+ return Math.floor(Math.random() * len);
|
|
|
+};
|
|
|
+const mockData = Array(500)
|
|
|
+ .fill(0)
|
|
|
+ .map((item) => {
|
|
|
+ return {
|
|
|
+ phone: `55****${(randomX(99) + "").padEnd(2, "0")}`,
|
|
|
+ num: `${(Math.random() * 20).toFixed(2)}`,
|
|
|
+ time: "11:00",
|
|
|
+ };
|
|
|
+ });
|
|
|
+function getRandom(min: number, max: number) {
|
|
|
+ const floatRandom = Math.random();
|
|
|
+
|
|
|
+ const difference = max - min;
|
|
|
+
|
|
|
+ // 介于 0 和差值之间的随机数
|
|
|
+ const random = Math.round(difference * floatRandom);
|
|
|
+
|
|
|
+ return random + min;
|
|
|
+}
|
|
|
+/**
|
|
|
+ * @description 描述
|
|
|
+ */
|
|
|
+type DescProps = {
|
|
|
+ onClose: () => void;
|
|
|
+};
|
|
|
+const Desc = (props: DescProps) => {
|
|
|
+ const { onClose } = props;
|
|
|
+ const [activeTab, setActiveTab] = useState(0);
|
|
|
+ const tabs = [{ text: "Vezes de evento participado" }, { text: "Consulta de registo levado" }];
|
|
|
+ return (
|
|
|
+ <div className={"absolute top-[30%] w-[100%]"}>
|
|
|
+ <div className={"absolute -top-[1.3rem] left-1/2 w-[3.3rem] -translate-x-1/2"}>
|
|
|
+ <img src="/9f/red-header.png" alt="" />
|
|
|
+ <div
|
|
|
+ className={
|
|
|
+ "h-[0.2rem] w-[0.2rem] " + " absolute bottom-[20px] right-[30px]" + " "
|
|
|
+ }
|
|
|
+ onClick={onClose}
|
|
|
+ >
|
|
|
+ <Image src={"/9f/close.png"} alt={"close"} width={25} height={25} />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ className={"mx-auto w-[2.9rem] bg-[#ff9417] px-[0.16rem] pb-[0.12rem] pt-[0.44rem]"}
|
|
|
+ >
|
|
|
+ <img src="/9f/red-title.png" alt="" className={"mx-auto w-[90%]"} />
|
|
|
+ <div className={"mt-[0.0694rem] rounded-[3px] bg-primary-color"}>
|
|
|
+ <div className={"flex h-[0.54rem] justify-between text-center text-[0.15rem]"}>
|
|
|
+ {tabs.map((item, index) => {
|
|
|
+ return (
|
|
|
+ <Fragment key={index}>
|
|
|
+ <span
|
|
|
+ onClick={() => setActiveTab(index)}
|
|
|
+ className={`flex h-[100%] items-center ${index === activeTab ? "bg-[#8b3500] text-[#5f2600]" : ""}`}
|
|
|
+ >
|
|
|
+ {item.text}
|
|
|
+ </span>
|
|
|
+ </Fragment>
|
|
|
+ );
|
|
|
+ })}
|
|
|
+ </div>
|
|
|
+ {/* 动态内容 */}
|
|
|
+ <div className={"h-[3rem] overflow-y-scroll p-[0.1rem]"}>
|
|
|
+ <div
|
|
|
+ className={
|
|
|
+ "flex items-center rounded-[0.1rem] bg-[#d45300] p-[10px] font-bold"
|
|
|
+ }
|
|
|
+ >
|
|
|
+ <Image
|
|
|
+ className={"h-[0.43rem] w-[0.7rem]"}
|
|
|
+ width={80}
|
|
|
+ height={40}
|
|
|
+ src="/9f/wallet.png"
|
|
|
+ alt=""
|
|
|
+ />
|
|
|
+ <div className={"text-center"}>
|
|
|
+ <h2> Tempo regressivo </h2>
|
|
|
+ <p className={"text-[#fe0]"}>Começa amanhã às 11:00</p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {!activeTab ? (
|
|
|
+ <>
|
|
|
+ <Image
|
|
|
+ src={"/9f/6xtime.png"}
|
|
|
+ className={"mt-[0.1rem] h-[0.7rem] w-[100%] rounded-[0.1rem]"}
|
|
|
+ width={600}
|
|
|
+ height={100}
|
|
|
+ alt={"time"}
|
|
|
+ ></Image>
|
|
|
+
|
|
|
+ <Image
|
|
|
+ src={"/9f/3xtime.png"}
|
|
|
+ className={"mt-[0.1rem] h-[0.55rem] w-[100%] rounded-[0.1rem]"}
|
|
|
+ width={600}
|
|
|
+ height={80}
|
|
|
+ alt={"time"}
|
|
|
+ ></Image>
|
|
|
+ </>
|
|
|
+ ) : (
|
|
|
+ <>
|
|
|
+ <div
|
|
|
+ className={"mt-[0.1rem] rounded-[0.1rem] bg-[#d45300] p-[10px]"}
|
|
|
+ >
|
|
|
+ <p className={"text-[#fe0]"}>Registro persoal</p>
|
|
|
+ <div
|
|
|
+ className={
|
|
|
+ "grid grid-cols-3 text-center" +
|
|
|
+ " items-center text-[0.1rem]"
|
|
|
+ }
|
|
|
+ >
|
|
|
+ <span>Nome do jogo</span>
|
|
|
+ <span>Coleta cumulativa</span>
|
|
|
+ <span>Participação total</span>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div
|
|
|
+ className={
|
|
|
+ "grid grid-cols-3 text-center" +
|
|
|
+ " items-center text-[0.12rem] font-bold"
|
|
|
+ }
|
|
|
+ >
|
|
|
+ <span>55****26</span>
|
|
|
+ <span>R$ 100.00</span>
|
|
|
+ <span>1</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ className={"mt-[0.1rem] rounded-[0.1rem] bg-[#d45300] p-[10px]"}
|
|
|
+ >
|
|
|
+ <p className={"text-[#fe0]"}>Lista dos vencedores</p>
|
|
|
+ <div
|
|
|
+ className={
|
|
|
+ "grid grid-cols-3 text-center" +
|
|
|
+ " items-center text-[0.1rem]"
|
|
|
+ }
|
|
|
+ >
|
|
|
+ <span>ID do papel</span>
|
|
|
+ <span>Valor obtido</span>
|
|
|
+ <span>Hora obtida</span>
|
|
|
+ </div>
|
|
|
+ <div className={`h-[1rem] overflow-hidden`}>
|
|
|
+ {mockData.map((item, index) => {
|
|
|
+ return (
|
|
|
+ <div
|
|
|
+ key={index}
|
|
|
+ className={`grid grid-cols-3 items-center text-center text-[0.12rem] font-bold ${styles.scrollAnimation}`}
|
|
|
+ >
|
|
|
+ <span>{item.phone}</span>
|
|
|
+ <span>R$ {item.num}</span>
|
|
|
+ <span>{item.time}</span>
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ })}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </>
|
|
|
+ )}
|
|
|
+
|
|
|
+ <ul className={"mt-[0.1rem] text-[0.1rem]"}>
|
|
|
+ <li>
|
|
|
+ ·Cada sessão de chuva de dinheiro é distribuída gratuitamente por
|
|
|
+ R$100.000.
|
|
|
+ </li>
|
|
|
+ <li>
|
|
|
+ ·Valor máximo de queda em dinheiro: Cada sessão de chuva de dinheiro
|
|
|
+ é distribuída gratuitamente.
|
|
|
+ </li>
|
|
|
+ <li>·Membros recarregados podem reivindicar gratuitamente.</li>
|
|
|
+ <li>
|
|
|
+ ·O dinheiro recebido pode ser utilizado para jogar ou sacar
|
|
|
+ diretamente.
|
|
|
+ </li>
|
|
|
+ <li>
|
|
|
+ ·Quanto for maior o nível de associação VIP, será maior o valor
|
|
|
+ recebido.
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+};
|
|
|
+
|
|
|
+const FallAnimation = (props: any) => {
|
|
|
+ const { onClose } = props;
|
|
|
+ const fallContentRef = useRef<HTMLDivElement>(null);
|
|
|
+
|
|
|
+ const totalPackets = 200;
|
|
|
+ const timer = useRef<NodeJS.Timer>(null);
|
|
|
+ const total = useRef(0);
|
|
|
+ const createPacket = (xPoint: number) => {
|
|
|
+ const packetWrapperEl = document.createElement("div");
|
|
|
+ packetWrapperEl.classList.add(styles.packetWrapper);
|
|
|
+ packetWrapperEl.style.left = xPoint + "px";
|
|
|
+ packetWrapperEl.style.width = `77px`;
|
|
|
+ packetWrapperEl.style.height = `44px`;
|
|
|
+ packetWrapperEl.style.transform = `scale(0.8) `;
|
|
|
+
|
|
|
+ const packetEl = document.createElement("img");
|
|
|
+ packetEl.classList.add(styles.packet);
|
|
|
+
|
|
|
+ packetEl.style.width = `${getRandom(44, 77)}`;
|
|
|
+ packetEl.style.height = `${getRandom(44, 77)}`;
|
|
|
+
|
|
|
+ packetEl.src = `/9f/money${Math.floor(Math.random() * 3) + 1}.png`;
|
|
|
+
|
|
|
+ setInterval(() => {
|
|
|
+ packetEl.style.transform = `rotate(${getRandom(0, 180)}deg) translateX(${Math.random() > 0.5 ? getRandom(0, 180) : -getRandom(0, 180)}px) scale(${getRandom(0.4, 1.2)}) `;
|
|
|
+ }, 1000);
|
|
|
+
|
|
|
+ packetWrapperEl.appendChild(packetEl);
|
|
|
+ fallContentRef.current?.appendChild(packetWrapperEl);
|
|
|
+ };
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ // @ts-ignore
|
|
|
+ timer.current = setInterval(() => {
|
|
|
+ if (total.current >= totalPackets - 1) {
|
|
|
+ clearInterval(Number(timer.current));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ total.current += 1;
|
|
|
+ createPacket(Math.random() * fallContentRef.current?.clientWidth! || 500);
|
|
|
+ }, 200);
|
|
|
+ return () => {
|
|
|
+ clearInterval(Number(timer.current));
|
|
|
+ };
|
|
|
+ }, []);
|
|
|
+ return (
|
|
|
+ <div
|
|
|
+ ref={fallContentRef}
|
|
|
+ style={{ height: "100dvh" }}
|
|
|
+ className={"h-dvh overflow-hidden"}
|
|
|
+ onClick={onClose}
|
|
|
+ ></div>
|
|
|
+ );
|
|
|
+};
|
|
|
+
|
|
|
+const HbyInfoDetail = (props: any) => {
|
|
|
+ const { iconImg, onCloseHby } = props;
|
|
|
+ return (
|
|
|
+ <div
|
|
|
+ className={`absolute left-1/2 top-[50%] w-[90%] -translate-x-1/2 -translate-y-1/2 ${styles.promoRules}`}
|
|
|
+ >
|
|
|
+ {/* <Image src={"/hby/close.png"} alt={"close"} width={25} height={25} onClick={onCloseHby} className={styles.closeIcon}/> */}
|
|
|
+ <div onClick={onCloseHby} className={styles.closeIcon}></div>
|
|
|
+ <Image src={iconImg} alt={"detail"} width={672} height={1044} />
|
|
|
+ {/* <div className={`h-[0.15rem] text-[#ffd800] text-[0.20rem] text-center ${styles.promoTitle}`}>Dinheiro como chuva</div>
|
|
|
+ <div className={styles.titleWrap}>
|
|
|
+ <span>R$200.00</span>
|
|
|
+ <span> por vez, </span>
|
|
|
+ <span>Máx queda </span>
|
|
|
+ <span>R$7.777</span>
|
|
|
+ </div>
|
|
|
+ <div className={styles.tips}>
|
|
|
+ <img src="/hby/tip-icon.png" alt="tips" className={styles.tipsIcon}/>
|
|
|
+ <div className={styles.tipsTime}>Começa às 23:00</div>
|
|
|
+ </div>
|
|
|
+ <div className={styles.times1}>
|
|
|
+ <img src="/hby/time1.png"/>
|
|
|
+ </div>
|
|
|
+ <div className={styles.times2}>
|
|
|
+ <img src="/hby/time2.png"/>
|
|
|
+ </div>
|
|
|
+ <ul className={styles.rulelist}>
|
|
|
+ <li className={styles.ruleItem}>
|
|
|
+ Cada sessão de chuva de dinheiro é distribuída gratuitamente com <span>R$200.000</span>
|
|
|
+ </li>
|
|
|
+ <li className={styles.ruleItem}>
|
|
|
+ Valor máximo de queda em dinheiro:Cada sessäo de chuva de dinheiro é distribuida gratuitamente com
|
|
|
+ </li>
|
|
|
+ <li className={styles.ruleItem}>
|
|
|
+ Membros recarregados podem reivindicar gratuitamente
|
|
|
+ </li>
|
|
|
+ <li className={styles.ruleItem}>
|
|
|
+ O dinheiro recebido pode ser utilizado para jogar ou sacado diretamente
|
|
|
+ </li>
|
|
|
+ <li className={styles.ruleItem}>
|
|
|
+ Quanto maior o nivel de associacäo VP, maior o valor recebido
|
|
|
+ </li>
|
|
|
+ </ul> */}
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+};
|
|
|
+
|
|
|
+const HbyInfo = (props: any) => {
|
|
|
+ const { iconImg, onCloseHby, onReciveRed } = props;
|
|
|
+ if (!iconImg) return;
|
|
|
+ return (
|
|
|
+ <div
|
|
|
+ className={`absolute left-1/2 top-[50%] -translate-x-1/2 -translate-y-1/2 ${styles.redclose}`}
|
|
|
+ >
|
|
|
+ {/* <Image src={"/hby/close.png"} alt={"close"} width={20} height={20} onClick={onCloseHby} className={styles.closeIcon}/> */}
|
|
|
+ <div onClick={onCloseHby} className={styles.closeIcon}></div>
|
|
|
+ <img
|
|
|
+ src={iconImg}
|
|
|
+ alt={"icon"}
|
|
|
+ width={559}
|
|
|
+ height={687}
|
|
|
+ onClick={onReciveRed}
|
|
|
+ className={styles.redIcon}
|
|
|
+ />
|
|
|
+ {/* <div className={styles.title}>Chuva de dinheiro</div>
|
|
|
+ <div className={styles.desc}>
|
|
|
+ <ul className={styles.desclist}>
|
|
|
+ <li className={styles.descitem}> Membros recarregados podem reivindicar gratuitamente. </li>
|
|
|
+ <div className={styles.line}></div>
|
|
|
+ <li className={styles.descitem}> Valor máximo de queda em dinheiro: R$7.777 </li>
|
|
|
+ </ul>
|
|
|
+ </div>
|
|
|
+ <div className={styles.openBtn} onClick={onReciveRed}>AGARRAR</div> */}
|
|
|
+ </div>
|
|
|
+ // <div data-v-f333135e="" className={`absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 ${styles.redopen}`}>
|
|
|
+ // <Image src={"/hby/close.png"} alt={"close"} width={20} height={20} onClick={onCloseHby} className={styles.closeIcon}/>
|
|
|
+ // <div className={styles.title}>Chuva de dinheiro</div>
|
|
|
+ // <div className={styles.cash}>1.96</div>
|
|
|
+ // <div className={styles.tips}>Valor máximo de queda em dinheiro:Cada sessäo de chuva de dinheiro é </div>
|
|
|
+ // </div>
|
|
|
+ );
|
|
|
+};
|
|
|
+
|
|
|
+const HbyInfo2 = (props: any) => {
|
|
|
+ const { iconImg, onCloseHby, redAmount } = props;
|
|
|
+ console.log(`🚀🚀🚀🚀🚀-> in PopupHby.tsx on 364`, iconImg);
|
|
|
+ return (
|
|
|
+ <div
|
|
|
+ className={`absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 ${styles.redopen}`}
|
|
|
+ >
|
|
|
+ <Image
|
|
|
+ src={"/hby/close.png"}
|
|
|
+ alt={"close"}
|
|
|
+ width={30}
|
|
|
+ height={30}
|
|
|
+ onClick={onCloseHby}
|
|
|
+ className={styles.closeIcon}
|
|
|
+ />
|
|
|
+ {/* <div onClick={onCloseHby} className={styles.closeIcon}></div> */}
|
|
|
+ <Image src={iconImg} alt={"icon"} width={559} height={687} />
|
|
|
+ <div className={styles.cash}>{redAmount}</div>
|
|
|
+ {/* <div className={styles.title}>Chuva de dinheiro</div>
|
|
|
+ <div className={styles.cash}>{redAmount}</div>
|
|
|
+ <div className={styles.tips}>Valor máximo de queda em dinheiro:Cada sessäo de chuva de dinheiro é </div> */}
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+};
|
|
|
+
|
|
|
+type Props = {};
|
|
|
+export type RedPacketModalProps = {
|
|
|
+ onClose: () => void;
|
|
|
+ onOpen: () => void;
|
|
|
+};
|
|
|
+const RedPacketModal = forwardRef<RedPacketModalProps, Props>(function RedPacketModal(props, ref) {
|
|
|
+ const [visible, setVisible] = useState(false);
|
|
|
+
|
|
|
+ const [iconLists, setIconLists] = useState<any>([]);
|
|
|
+ const [isShowRed, setIsShowRed] = useState(false);
|
|
|
+ const [isShowReciveRed, setIsShowReciveRed] = useState(false);
|
|
|
+ const [isShowRedDetail, setIsShowRedDetail] = useState(false);
|
|
|
+ const [redPacketInfo, setRedPacketInfo] = useState<any>({});
|
|
|
+ const [redAmount, setRedAmount] = useState<any>(0);
|
|
|
+ const token = getToken();
|
|
|
+ useImperativeHandle(ref, () => {
|
|
|
+ return {
|
|
|
+ onClose: () => setVisible(false),
|
|
|
+ onOpen: () => {
|
|
|
+ getRedPacketInfo().then((res) => {
|
|
|
+ setVisible(true);
|
|
|
+ });
|
|
|
+ },
|
|
|
+ };
|
|
|
+ });
|
|
|
+ useEffect(() => {
|
|
|
+ // getRedPacketInfo();
|
|
|
+ }, []);
|
|
|
+
|
|
|
+ const getRedPacketInfo = async () => {
|
|
|
+ try {
|
|
|
+ let actList: any = [];
|
|
|
+ if (token) {
|
|
|
+ let redPacketInfo = await lredPacketApi();
|
|
|
+ actList = redPacketInfo.data?.red_packets || [];
|
|
|
+ } else {
|
|
|
+ let redPacketInfo = await redPacketApi();
|
|
|
+ actList = redPacketInfo.data;
|
|
|
+ }
|
|
|
+ // 是否有已开始但是没领过的红包
|
|
|
+ let isHasStartAct = actList.filter((aItem: any) => {
|
|
|
+ return !!aItem.is_start && !aItem.is_receive;
|
|
|
+ });
|
|
|
+ console.log(`🚀🚀🚀🚀🚀-> in RedPacketModal.tsx on 427`, actList);
|
|
|
+
|
|
|
+ let isShowRed = isHasStartAct.length > 0;
|
|
|
+ let isShowRedDetail = isHasStartAct.length === 0;
|
|
|
+ let redInfo = isShowRed ? isHasStartAct[0] : {};
|
|
|
+ let curAct = !!isShowRedDetail ? findCurrentActivity(actList) : actList[0];
|
|
|
+ let iconList = JSON.parse(curAct.icon);
|
|
|
+
|
|
|
+ setIconLists(iconList);
|
|
|
+ setIsShowRed(isShowRed);
|
|
|
+ setIsShowRedDetail(isShowRedDetail);
|
|
|
+ setRedPacketInfo(redInfo);
|
|
|
+ } catch (error) {
|
|
|
+ console.log("redPacketInfo===>error:", error);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ // 筛选出离当前时间最近的活动
|
|
|
+ const findCurrentActivity = (activities: any) => {
|
|
|
+ const now = Math.floor(Date.now() / 1000); // 获取当前时间的时间戳(单位:秒)
|
|
|
+ let closestActivity = null;
|
|
|
+ let isInRange = false;
|
|
|
+
|
|
|
+ // 遍历活动数据
|
|
|
+ for (let i = 0; i < activities.length; i++) {
|
|
|
+ const activity = activities[i];
|
|
|
+
|
|
|
+ // 检查当前时间是否在活动的时间范围内
|
|
|
+ if (now >= activity.start_time && now <= activity.end_time) {
|
|
|
+ isInRange = true;
|
|
|
+ return activity; // 如果在范围内,直接返回当前活动
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果不在范围内,记录离当前时间最近的活动
|
|
|
+ if (
|
|
|
+ !closestActivity ||
|
|
|
+ Math.abs(now - activity.end_time) < Math.abs(now - closestActivity.end_time)
|
|
|
+ ) {
|
|
|
+ closestActivity = activity;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果不在任何活动范围内,返回离当前时间最近的活动
|
|
|
+ return closestActivity;
|
|
|
+ };
|
|
|
+
|
|
|
+ const onReciveRed = async () => {
|
|
|
+ try {
|
|
|
+ let paramsData = {
|
|
|
+ id: redPacketInfo?.id,
|
|
|
+ index: redPacketInfo?.index,
|
|
|
+ };
|
|
|
+ let receiveRedPacketInfo = await receiveRedPacketApi(paramsData);
|
|
|
+ let redNum = receiveRedPacketInfo.data;
|
|
|
+ setIsShowRed(false);
|
|
|
+ setIsShowReciveRed(true);
|
|
|
+ setRedAmount(redNum?.amount);
|
|
|
+ } catch (error) {
|
|
|
+ console.log("redPacketInfo===>error:", error);
|
|
|
+ }
|
|
|
+ };
|
|
|
+ return (
|
|
|
+ <Mask visible={visible} destroyOnClose={true}>
|
|
|
+ <FallAnimation onClose={() => setVisible(false)} />
|
|
|
+ {isShowRedDetail && (
|
|
|
+ <HbyInfoDetail onCloseHby={() => setVisible(false)} iconImg={iconLists[0]} />
|
|
|
+ )}
|
|
|
+ {isShowRed && (
|
|
|
+ <HbyInfo
|
|
|
+ onCloseHby={() => setVisible(false)}
|
|
|
+ onReciveRed={onReciveRed}
|
|
|
+ iconImg={iconLists[1]}
|
|
|
+ />
|
|
|
+ )}
|
|
|
+ {isShowReciveRed && (
|
|
|
+ <HbyInfo2
|
|
|
+ onCloseHby={() => setVisible(false)}
|
|
|
+ redAmount={redAmount}
|
|
|
+ iconImg={iconLists[2]}
|
|
|
+ />
|
|
|
+ )}
|
|
|
+ </Mask>
|
|
|
+ );
|
|
|
+});
|
|
|
+
|
|
|
+export default RedPacketModal;
|