"use client";
import { receiveRedPacketApi } from "@/api/promo";
import { useRouter } from "@/i18n/routing";
import { getToken } from "@/utils/Cookies";
import { Mask } from "antd-mobile";
import clsx from "clsx";
import { useTranslations } from "next-intl";
import { FC, forwardRef, memo, useEffect, useImperativeHandle, useRef, useState } from "react";
import styles from "./style.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 HbyInfoDetail = (props: any) => {
const { iconImg, onCloseHby } = props;
const router = useRouter();
const token = getToken();
const handler = () => {
if (!token) {
router.push("/login");
}
onCloseHby();
};
const str = "12:00".split("");
return (

{/* 下一场开始时间*/}
{str[0]}
{str[1]}
{str[2]}
{str[3]}
{str[4]}
);
};
const HbyInfo = (props: any) => {
const { iconImg, onCloseHby, onReciveRed } = props;
if (!iconImg) return;
return (
{/*
*/}
{/* Chuva de dinheiro
- Membros recarregados podem reivindicar gratuitamente.
- Valor máximo de queda em dinheiro: R$7.777
AGARRAR
*/}
//
//
// Chuva de dinheiro
// 1.96
// Valor máximo de queda em dinheiro:Cada sessäo de chuva de dinheiro é
//
);
};
const HbyInfo2 = (props: any) => {
const { iconImg, onCloseHby, redAmount } = props;
const hbyInfoClass = clsx(
`${styles.redopen} absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 bg-no-repeat bg-cover`
);
const t = useTranslations("packetsPopup");
return (
{t("title")}
{redAmount}
{redAmount > 0 ? t("receiveSuccess") : t("receiveWarring")}
);
};
/**
* @description 动画背景 - 下雨动效
*/
type Props = {
onAfterHandler?: () => void;
};
export type RedPacketModalProps = {
onClose: () => void;
onOpen: (source: any[], index?: number) => void;
};
/**
* @description 红包的三种状态
* is_start 可领取 展示红包领取组件
* is_receive 已领取 展示领取详情组件
* is_end 可展示 展示说明页
*/
enum Status {
is_start,
is_receive,
is_end,
}
interface Snowflake {
x: number; // 水平位置
y: number; // 垂直位置
scale: number; // 缩放比例
speedX: number; // 水平移动速度
speedY: number; // 垂直下落速度
rotate: number; // 当前旋转角度
rotateSpeed: number; // 旋转速度
image: HTMLImageElement; // 图片路径
}
interface SnowfallProps {
images: string[]; // 图片数组
snowflakeCount?: number; // 雪花数量
onClose: () => void;
}
const Snowfall: FC = ({ images, snowflakeCount = 80, onClose = () => {} }) => {
// canvas
const canvasRef = useRef(null);
// 预加载图片
const imageElements = useRef([]);
// 父元素
const containerRef = useRef(null);
const createSnowflakes = (count: number, width: number, height: number): Snowflake[] => {
return Array.from({ length: count }, () => ({
x: Math.random() * width,
y: Math.random() * height - height,
scale: Math.random() * (1.2 - 0.5) + 0.5,
speedX: Math.random() * 1.5 - 0.75,
speedY: Math.random() * 5 + 1,
rotate: Math.random() * 180,
rotateSpeed: Math.random() * 2 - 1,
image: imageElements.current[Math.floor(Math.random() * imageElements.current.length)],
}));
};
useEffect(() => {
// 预加载图片
imageElements.current = images.map((src) => {
const img = new Image();
img.src = src;
return img;
});
const canvas = canvasRef.current;
if (!canvas) return;
const ctx = canvas.getContext("2d");
if (!ctx) return;
const parentWidth = containerRef.current?.clientWidth || 0;
const parentHeight = (canvas.height = containerRef.current?.clientHeight || 0);
const width = (canvas.width = parentWidth);
const height = (canvas.height = parentHeight);
let snowflakes: Snowflake[] = createSnowflakes(snowflakeCount, width, height);
const imgHeight = 80;
const imgWidth = 80;
const animate = () => {
ctx.clearRect(0, 0, width, height);
snowflakes.forEach((flake) => {
flake.y += flake.speedY;
flake.x += flake.speedX;
flake.rotate += flake.rotateSpeed;
if (flake.y > height) {
flake.y = -44;
flake.x = Math.random() * width;
flake.rotate = Math.random() * 360;
}
if (flake.x < 0 || flake.x > width) {
flake.speedX *= -1;
}
ctx.save();
ctx.globalAlpha = 1;
ctx.translate(
flake.x + (imgHeight * flake.scale) / 2,
flake.y + (imgWidth * flake.scale) / 2
);
ctx.rotate((flake.rotate * Math.PI) / 180);
ctx.drawImage(
flake.image,
(-imgHeight * flake.scale) / 2,
(-imgWidth * flake.scale) / 2,
imgHeight * flake.scale,
imgWidth * flake.scale
);
ctx.restore();
});
requestAnimationFrame(animate);
};
animate();
const handleResize = () => {
canvas.width = parentWidth;
canvas.height = parentHeight;
snowflakes = createSnowflakes(snowflakeCount, canvas.width, canvas.height);
};
window.addEventListener("resize", handleResize);
return () => {
window.removeEventListener("resize", handleResize);
};
}, []);
return (
;
);
};
const RedPacketModal = forwardRef(function RedPacketModal(props, ref) {
const { onAfterHandler } = props;
const [visible, setVisible] = useState(false);
const [iconLists, setIconLists] = useState([]);
// 初始状态为is_end, 展示活动详情页
const [status, setStatus] = useState(Status.is_end);
const packetCurrent = useRef({});
const packets = useRef([]);
const [redAmount, setRedAmount] = useState(1);
const activeIndex = useRef(0);
const token = getToken();
const element = useRef(null);
useImperativeHandle(ref, () => {
return {
onClose: () => setVisible(false),
onOpen: (source, index?: number) => {
packets.current = source;
if (index !== null && index !== undefined) {
activeIndex.current = index;
}
getRedPacketInfo().then((res) => {
setVisible(true);
});
},
};
});
const getRedPacketInfo = async () => {
try {
let actList = packets.current;
// 是否有已开始但是没领过的红包
let packetsFilter = actList
.filter((aItem: any) => {
return aItem.can_receive && aItem.is_start && !aItem.is_receive;
})
.sort((pre: any, next: any) => pre.end_time - next.end_time);
// 有可领取红包
if (packetsFilter.length > 0) {
let current = packetsFilter[activeIndex.current];
let iconList = JSON.parse(current.icon);
// 红包
packetCurrent.current = current;
// 有可领取红包
setIconLists(iconList);
if (!token) {
setStatus(Status.is_end);
} else {
setStatus(Status.is_start);
}
} else {
// 无可领取红包
// 展示最近可领红包详情
let packets = actList.sort((pre: any, next: any) => pre.end_time - next.end_time);
packetCurrent.current = packets[0];
setIconLists(JSON.parse(packets[0].icon));
// 无可领取红包展示详情
setStatus(Status.is_end);
}
} catch (error) {
console.log("redPacketInfo===>error:", error);
}
};
const onReciveRed = async () => {
try {
let paramsData = {
id: packetCurrent.current?.id,
index: packetCurrent.current?.index,
};
let receiveRedPacketInfo = await receiveRedPacketApi(paramsData);
let redNum = receiveRedPacketInfo.data;
if (onAfterHandler) {
onAfterHandler();
}
setStatus(Status.is_receive);
setRedAmount(redNum?.amount);
} catch (error) {
console.log("redPacketInfo===>error:", error);
}
};
useEffect(() => {
element.current = document.getElementById("app");
}, []);
const ImagesData = Array.from({ length: 6 }).map((_, index) => {
return `/9f/money${index + 1}.png`;
});
return (
setVisible(false)} />
{status === Status.is_start ? (
setVisible(false)}
onReciveRed={onReciveRed}
iconImg={iconLists[1]}
/>
) : status === Status.is_receive ? (
setVisible(false)}
redAmount={redAmount}
iconImg={iconLists[2]}
/>
) : (
setVisible(false)} iconImg={iconLists[0]} />
)}
);
});
export default memo(RedPacketModal);