index.tsx 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. "use client";
  2. import { getGlobalNoticeApi, getGlobalUserNoticeApi } from "@/api/home";
  3. import { Link, usePathname, useRouter } from "@/i18n/routing";
  4. import { getToken } from "@/utils/Cookies";
  5. import { Badge } from "antd-mobile";
  6. import clsx from "clsx";
  7. import { useTranslations } from "next-intl";
  8. import { ChangeEvent, FC, ReactNode, useEffect } from "react";
  9. import "./style.scss";
  10. import { getUserDepositApi, getUserMoneyApi } from "@/api/user";
  11. import { useEventPoint } from "@/hooks/useEventPoint";
  12. import { useGlobalNoticeStore } from "@/stores/useGlobalNoticeStore";
  13. import { useWalletStore } from "@/stores/useWalletStore";
  14. import { useRequest } from "ahooks";
  15. /**
  16. * @description 底部Tab组件
  17. * @param children 插槽内容
  18. *
  19. */
  20. export interface FooterProps {
  21. children?: ReactNode;
  22. }
  23. const whitRouter = ["/deposit", "/profile"];
  24. const tabList = [
  25. {
  26. iconSpanName: "icon-zhuye",
  27. label: "start",
  28. path: "/",
  29. },
  30. {
  31. iconSpanName: "icon-qianbao3",
  32. label: "deposit",
  33. path: "/deposit",
  34. },
  35. {
  36. iconSpanName: "icon-afiliado",
  37. label: "affiliated",
  38. path: "/affiliate/summary",
  39. },
  40. {
  41. iconSpanName: "icon-lihe",
  42. label: "promocoes",
  43. path: "/promo",
  44. },
  45. {
  46. iconSpanName: "icon-yonghu",
  47. label: "profile",
  48. path: "/profile",
  49. },
  50. ];
  51. const Footer: FC = () => {
  52. const token = getToken();
  53. const t = useTranslations("navBar");
  54. const { eventPurchase, eventFirstDeposit } = useEventPoint();
  55. const pathname = usePathname();
  56. const router = useRouter();
  57. const goPage = (event: ChangeEvent<any>, path = "/") => {
  58. event.preventDefault();
  59. if (!token && (path == "/deposit" || path == "/profile" || path == "/sports")) {
  60. router.push(`/login?redirect=${path}`);
  61. return;
  62. }
  63. router.push(path);
  64. };
  65. const { unread, userUnred, setNotices, setUserUnread, promotion_count, setPromotionCount } =
  66. useGlobalNoticeStore((state) => ({
  67. unread: state.unread,
  68. setNotices: state.setNotices,
  69. setUserUnread: state.setUserUnread,
  70. setPromotionCount: state.setPromotionCount,
  71. userUnred: state.userUnred,
  72. promotion_count: state.promotion_count,
  73. }));
  74. const setWallet = useWalletStore((state) => state.setWallet);
  75. const { run } = useRequest(getGlobalNoticeApi, {
  76. pollingInterval: 10000,
  77. manual: true,
  78. pollingErrorRetryCount: 3,
  79. pollingWhenHidden: false,
  80. onSuccess: (data) => {
  81. setNotices(data?.data || [], data?.summery.unread || 0);
  82. setPromotionCount(data.summery.promotion_count || 0);
  83. },
  84. });
  85. const { run: userRun } = useRequest(getGlobalUserNoticeApi, {
  86. pollingInterval: 10000,
  87. manual: true,
  88. pollingErrorRetryCount: 3,
  89. pollingWhenHidden: false,
  90. onSuccess: (data) => {
  91. setUserUnread(data.summery.unread || 0);
  92. },
  93. });
  94. const { run: walletRun } = useRequest(getUserMoneyApi, {
  95. pollingInterval: 5000,
  96. pollingWhenHidden: true,
  97. pollingErrorRetryCount: 3,
  98. staleTime: 5000,
  99. manual: true,
  100. refreshDeps: [token],
  101. onError: (error) => {},
  102. onSuccess: (res) => {
  103. setWallet(res.data);
  104. },
  105. });
  106. const { run: depositRun } = useRequest(getUserDepositApi, {
  107. pollingInterval: 10000,
  108. pollingWhenHidden: true,
  109. pollingErrorRetryCount: 3,
  110. staleTime: 5000,
  111. manual: true,
  112. refreshDeps: [token],
  113. onError: (error) => {},
  114. onSuccess: (res) => {
  115. if (Object.keys(res.data).length < 0) return;
  116. if (res.data.is_first_pay === 1) {
  117. eventFirstDeposit();
  118. return;
  119. }
  120. if (res.data.is_success === 1) {
  121. eventPurchase();
  122. }
  123. },
  124. });
  125. useEffect(() => {
  126. if (getToken()) {
  127. run();
  128. walletRun();
  129. userRun();
  130. depositRun();
  131. }
  132. }, []);
  133. return (
  134. <footer className={"footer-placeholder"}>
  135. <div className="footer-box">
  136. <div className={"footer-item"}>
  137. {tabList.map((item, index) => {
  138. return (
  139. <Link
  140. href={item.path}
  141. onClick={(event) => goPage(event, item.path)}
  142. key={index}
  143. className={`footer-item-column ${item.path === pathname ? "active" : ""}`}
  144. >
  145. <div className="icon-box">
  146. {index == 2 ? (
  147. <div className="relative top-[-.08rem] flex h-[.64rem] w-[.64rem] items-center justify-center overflow-hidden rounded-[50%]">
  148. {/* <Image src="/home/game.png" width={84} height={84} alt='middle'></Image> */}
  149. <img
  150. src={"/home/game.png"}
  151. style={{
  152. width: ".5rem",
  153. maxWidth: "1000%",
  154. position: "relative",
  155. }}
  156. alt=""
  157. />
  158. </div>
  159. ) : (
  160. <Badge
  161. content={
  162. (index === 4 && unread) ||
  163. (index === 4 && userUnred)
  164. ? Badge.dot
  165. : null
  166. }
  167. >
  168. <span
  169. className={clsx("iconfont", item.iconSpanName)}
  170. ></span>
  171. </Badge>
  172. )}
  173. {index == 3 && !!promotion_count && (
  174. <div className="absolute -top-[0px] right-[18px] flex h-[.16rem] w-[.16rem] items-center justify-center rounded-[50%] bg-[#ff0000] text-[.1rem] text-[#fff]">
  175. {promotion_count > 99 ? `99+` : promotion_count}
  176. </div>
  177. )}
  178. </div>
  179. <label>{t(item.label)}</label>
  180. </Link>
  181. );
  182. })}
  183. </div>
  184. </div>
  185. </footer>
  186. );
  187. };
  188. export default Footer;