123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444 |
- "use client";
- import { getWheelApi, WheelsType } from "@/api/cashWheel";
- import Progress from "@/app/[locale]/(navbar)/cashback/@cashbackInfo/components/Progress";
- import { useRouter } from "@/i18n/routing";
- import { getToken } from "@/utils/Cookies";
- import { percentage, timeFormat } from "@/utils/methods";
- import { LuckyWheel } from "@lucky-canvas/react";
- import { Mask } from "antd-mobile";
- import Image from "next/image";
- import { FC, forwardRef, useEffect, useImperativeHandle, useRef, useState } from "react";
- import styles from "./WheelModal.module.scss";
- type Props = {
- onAfterHandler?: () => void;
- };
- export type WheelModalProps = {
- onClose: () => void;
- onOpen: (value: WheelsType) => void;
- };
- /**
- * 轮盘组件
- */
- const blocks = [
- {
- padding: "0",
- imgs: [
- {
- src: "/wheels/wheel.png",
- width: "100%",
- height: "100%",
- rotate: true,
- },
- ],
- },
- ];
- const prizes = [
- {
- fonts: [
- {
- text: "5000",
- top: "20%",
- fontColor: "#a47716",
- fontWeight: "bold",
- type: "bonus",
- fontSize: "0.1528rem",
- },
- ],
- },
- {
- fonts: [{ text: "", top: "20%", fontColor: "#a47716", fontWeight: "bold", type: "empty" }],
- imgs: [
- {
- src: "/wheels/prizes-empty.png",
- top: "20%",
- width: "0.2778rem",
- },
- ],
- },
- {
- fonts: [
- {
- text: "50",
- top: "20%",
- fontColor: "#a47716",
- fontWeight: "bold",
- type: "bonus",
- fontSize: "0.1528rem",
- },
- ],
- },
- {
- fonts: [
- { text: "", top: "30%", fontColor: "#a47716", fontWeight: "bold", type: "balance" },
- ],
- imgs: [
- {
- src: "/wheels/prizes-money.png",
- top: "20%",
- width: "0.3472rem",
- },
- ],
- },
- {
- fonts: [
- {
- text: "1000",
- top: "20%",
- fontColor: "#a47716",
- fontWeight: "bold",
- type: "bonus",
- fontSize: "0.1528rem",
- },
- ],
- },
- {
- imgs: [
- {
- src: "/wheels/prizes-empty.png",
- top: "20%",
- width: "0.2778rem",
- height: "0.2778rem",
- },
- ],
- },
- {
- fonts: [
- {
- text: "1",
- top: "20%",
- fontColor: "#a47716",
- fontWeight: "bold",
- type: "bonus",
- fontSize: "0.1528rem",
- },
- ],
- },
- {
- fonts: [
- {
- text: "",
- top: "20%",
- fontColor: "#a47716",
- fontWeight: "bold",
- type: "balance",
- fontSize: "0.1528rem",
- },
- ],
- imgs: [
- {
- src: "/wheels/prizes-money.png",
- top: "20%",
- width: "0.3472rem",
- },
- ],
- },
- ];
- const defaultConfig = {
- offsetDegree: 20,
- };
- /**
- * type: isRotate 是否可旋转, 分享页面不需要旋转, 而是跳转
- */
- export interface WheelProps {
- isRotate: boolean;
- wheel: Partial<WheelsType>;
- onRotateEnd?: () => void;
- }
- export const WheelClient: FC<WheelProps> = (props) => {
- const { isRotate, wheel, onRotateEnd } = props;
- const wheelRef = useRef<any>();
- /*是否旋转*/
- const rotating = useRef<boolean>(false);
- const router = useRouter();
- const current = { ...(wheel?.activities?.[0] || {}), ...(wheel?.activate || {}) };
- const [buttonText, setButtonText] = useState<string>("0"); // 0 -> false 1:true
- // 当前中奖
- const currentWin = useRef<any>({});
- const startRotate = (key: string) => {
- if (!isRotate) {
- router.push("/register");
- return;
- }
- // 正在旋转中
- if (rotating.current) return;
- if (!current.can) return;
- // 如果包含还没领取的奖励
- if (wheel.not_receive && wheel.not_receive.length > 0) return;
- // 当前活动不存在
- if (!current.id) return;
- // 开始旋转中
- wheelRef.current?.play();
- // 点击抽奖按钮会触发star回调
- rotating.current = true;
- // getWheelRunApi({ activity_id: current.id })
- // .then((res) => {
- // setTimeout(() => {
- // wheelRef.current?.stop(res.data.index);
- //
- // currentWin.current = res.data;
- // }, 2000);
- // })
- // .catch(() => {
- // wheelRef.current?.init();
- // });
- };
- const endRotate = (prize: any) => {
- rotating.current = false;
- if (currentWin.current.amount > 0) {
- setButtonText(`+${currentWin.current.amount}`);
- } else {
- setButtonText(`${current.can || 0}`);
- }
- setTimeout(() => {
- onRotateEnd && onRotateEnd();
- }, 2000);
- };
- useEffect(() => {
- setButtonText(`${current.can || 0}`);
- }, [wheel]);
- return (
- <div className={"relative w-[100%]"}>
- <img src={"/wheels/wheel-bg.png"} className={"h-[5.5556rem] w-[100%] object-contain"} />
- <img
- src={"/wheels/title.png"}
- className={"absolute left-[17%] top-[52%] z-10 w-[63%] object-contain"}
- />
- {/*定位到中心圆*/}
- <div className={"absolute bottom-0 h-[2.5rem] w-[100%]"}>
- {/*光圈图片 */}
- <div className={"flex h-[100%] w-[100%] justify-center p-[0.0556rem]"}>
- <img src="/wheels/light-1.png" alt="" className={"mr-[0.0556rem] h-[100%]"} />
- </div>
- {/*转盘*/}
- <div
- className={
- "absolute bottom-[0] flex h-[100%] w-[100%] justify-center p-[0.1389rem]"
- }
- >
- <div
- className={
- "relative mr-[0.0694rem] mt-[0.05rem] h-[2.1rem] w-[2.1rem] rounded-[50%]"
- }
- >
- <div className={"absolute bottom-[50%] z-50 w-[100%] translate-y-1/2"}>
- <div
- className={"flex justify-center"}
- onClick={() => startRotate("desktop")}
- >
- <Image
- src={"/wheels/pointer.png"}
- className={"h-[0.6944rem] w-[0.625rem] object-contain"}
- width={90}
- height={120}
- alt={"start"}
- />
- <span
- className={
- "absolute bottom-[40%] translate-y-1/2 text-[#ffdb0e]"
- }
- >
- {buttonText}
- </span>
- </div>
- </div>
- <LuckyWheel
- ref={wheelRef}
- width="2.1rem"
- height="2.1rem"
- blocks={blocks}
- defaultConfig={defaultConfig}
- prizes={prizes}
- onEnd={(prize: any) => endRotate(prize)}
- />
- </div>
- </div>
- </div>
- </div>
- );
- };
- export const LeftListClient = () => {
- const allHistory: any[] = Array.from({ length: 100 }).map((item) => ({
- phone_number: `55****${Math.floor(Math.random() * 10000)
- .toString()
- .padStart(4, "0")}`,
- receive_time: Date.now(),
- }));
- return (
- <>
- <div className={`${styles.winList} ${styles.swipernoswiping} ${styles.type2}`}>
- {allHistory &&
- allHistory.length > 0 &&
- allHistory?.map((item, index) => {
- return (
- <div className={styles.item} key={index}>
- <span className={`${styles.name} ${styles.omitWrap}`}>
- {item.phone_number}
- </span>
- <span className={styles.tipText}>
- {timeFormat(item.receive_time, "br", undefined, true)}
- </span>
- <div className={styles.value}>
- <span className={styles.addCash}>+100</span>
- <span className={styles.unit}> R$</span>
- </div>
- </div>
- );
- })}
- </div>
- </>
- );
- };
- const DetailClient = (props: { wheel: Partial<WheelsType>; onUnload: () => void }) => {
- const { wheel, onUnload } = props;
- const router = useRouter();
- const goPage = () => {
- router.push("/cashWheel");
- onUnload();
- };
- return (
- <div className={`${styles.cashMain} ${styles.cashMain} ${styles.type1}`}>
- <div className={styles.haveCash}>
- <img src="/wheel/cash.png" alt="" className={styles.cashImg} />
- <div>
- {" "}
- R$ <span className={styles.cash}>{wheel.activate?.amount}</span>
- </div>
- <span className={styles.withdraw}>
- <img src="/wheel/pix.png" alt="" /> SACAR{" "}
- </span>
- </div>
- <div className={styles.progress}>
- <div className={styles.num}> {percentage(wheel.activate?.amount || 0, 100)}%</div>
- {/*<div className={styles.bar}>*/}
- {/* <span style={{ width: "calc(97.15% - 1rem)" }}></span>*/}
- {/*</div>*/}
- <Progress num={percentage(wheel.activate?.amount || 0, 100)} />
- </div>
- <div className={styles.needCash}>
- Ainda e necessário{" "}
- <span className={styles.needCashNum}>
- {(100 - (wheel.activate?.amount || 0)).toFixed(2)}
- </span>{" "}
- para realizar do saque{" "}
- </div>
- <div
- className={
- "h-[0.34rem] w-[100%] rounded-[0.0694rem] bg-[#fb8b05] text-[#fff]" +
- " flex items-center justify-center"
- }
- onClick={goPage}
- >
- Reivindique mais para sacar
- </div>
- <div className={"mt-[10px] h-[400px] w-[100%] overflow-hidden"}>
- <LeftListClient />
- </div>
- </div>
- );
- };
- const WheelModal = forwardRef<WheelModalProps, Props>(function RedPacketModal(props, ref) {
- const [visible, setVisible] = useState(false);
- const [detailsVisible, setDetailsVisible] = useState(false);
- const [wheel, setWheel] = useState<Partial<WheelsType>>({});
- useImperativeHandle(ref, () => {
- return {
- onClose: () => setVisible(false),
- onOpen: (wheelValue: WheelsType) => {
- setVisible(true);
- setWheel(wheelValue);
- },
- };
- });
- const getWheel = () => {
- if (!getToken()) return Promise.resolve(undefined);
- return getWheelApi().then((res) => {
- setWheel(res.data);
- return res.data;
- });
- };
- // useEffect(() => {
- // getWheel().then((res) => {
- // if (
- // res &&
- // res.activities &&
- // res.activities.length > 0 &&
- // res.activate.can &&
- // !res.not_receive?.length
- // ) {
- // setVisible(true);
- // }
- // });
- // }, []);
- const onRotateEnd = () => {
- setTimeout(() => {
- setVisible(false);
- setDetailsVisible(true);
- getWheel();
- }, 1000);
- };
- const onUnload = () => {
- setDetailsVisible(false);
- };
- return (
- <>
- <Mask visible={detailsVisible} getContainer={null}>
- <div className={"absolute top-[10%] z-50 w-[100%] p-[0.1389rem]"}>
- <div className={"rounded-[0.0694rem] bg-[#232327FF] p-[0.0694rem]"}>
- <div className={"flex items-center"}>
- <div className={"flex flex-1"}>
- <Image
- src={"/wheels/prizes-money.png"}
- width={40}
- height={40}
- alt={"moeny"}
- ></Image>
- <span className={"ml-[0.0694rem]"}>Receba R$ 100 de graca</span>
- </div>
- <span
- className={"iconfont icon-guanbi"}
- onClick={() => setDetailsVisible(false)}
- ></span>
- </div>
- <DetailClient wheel={wheel} onUnload={onUnload} />
- </div>
- </div>
- </Mask>
- <Mask visible={visible} destroyOnClose={true} getContainer={null}>
- <div
- className={"absolute right-[0.2083rem] top-[18%] z-50"}
- onClick={() => setVisible(false)}
- >
- <span className={"iconfont icon-guanbi"}></span>
- </div>
- <WheelClient isRotate={true} wheel={wheel} onRotateEnd={onRotateEnd} />
- </Mask>
- </>
- );
- });
- export default WheelModal;
|