App.tsx 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. import { useEffect, useRef, useState } from 'react';
  2. import { eventBus } from './lib/EventBus';
  3. import { pmBridge } from './lib/PostMessageBridge';
  4. import { useSetAtom, useAtomValue } from 'jotai'
  5. import { openModalAction } from './store';
  6. import { LoginIndex } from './components/login';
  7. import { RealNameIndex } from './components/real-name';
  8. import { PaymentIndex } from './components/payment';
  9. import { report } from './components/report';
  10. import { getH5GameLinkApi } from './api';
  11. import { getURLparams } from './utils';
  12. import { init } from './components/init';
  13. import { nativeInit, nativeLogin, nativePay, nativeReport, nativeLogout, nativeOnLogout } from './native';
  14. import SlideBarIndex from './components/slide-bar';
  15. import { FloatingButton } from './components/FloatingButton';
  16. import { userStateAtom } from './store/user-atom';
  17. import { logoutApi } from './api/login';
  18. function App() {
  19. const iframeRef = useRef<HTMLIFrameElement>(null);
  20. const [iframeUrl, setIframeUrl] = useState<string>('');
  21. const [isSlideBarOpen, setIsSlideBarOpen] = useState(false);
  22. const openModal = useSetAtom(openModalAction);
  23. const userState = useAtomValue(userStateAtom);
  24. const getGameUrl = async () => {
  25. const res = await getH5GameLinkApi({ game_id: getURLparams('game_id') || '' })
  26. setIframeUrl(`${res.game_url}?game_id=${getURLparams('game_id') || ''}&time=${Math.round(new Date().getTime() / 1000)}`)
  27. }
  28. // 初始化通信桥
  29. useEffect(() => {
  30. if (iframeRef.current) {
  31. pmBridge.init(iframeRef.current);
  32. }
  33. return () => pmBridge.destroy();
  34. }, []);
  35. // EventBus 事件订阅
  36. useEffect(() => {
  37. // 处理登录请求
  38. const handleLoginReq = (payload: any) => {
  39. if (getURLparams('is_native') === 'true') {
  40. openModal({ name: 'login', item: { isOpen: false, requestId: payload.requestId, data: payload.data } })
  41. nativeLogin(payload)
  42. } else {
  43. openModal({ name: 'login', item: { isOpen: true, requestId: payload.requestId, data: payload.data } })
  44. console.log("登录")
  45. }
  46. };
  47. // 处理支付请求
  48. const handlePayReq = (payload: any) => {
  49. if (getURLparams('is_native') === 'true') {
  50. openModal({ name: 'payment', item: { isOpen: false, requestId: payload.requestId, data: payload.data } })
  51. nativePay(payload)
  52. } else {
  53. openModal({ name: 'payment', item: { isOpen: true, requestId: payload.requestId, data: payload.data } })
  54. }
  55. };
  56. // 处理上报请求
  57. const handleReportReq = (payload: any) => {
  58. openModal({ name: 'report', item: { isOpen: true, requestId: payload.requestId, data: payload.data } })
  59. if (getURLparams('is_native') === 'true') {
  60. nativeReport(payload)
  61. } else {
  62. report(payload)
  63. }
  64. };
  65. // 处理初始化请求
  66. const handleInitReq = (payload: any) => {
  67. openModal({ name: 'init', item: { isOpen: true, requestId: payload.requestId, data: payload.data } })
  68. // 微端是真
  69. if (getURLparams('is_native') === 'true') {
  70. nativeInit(payload)
  71. } else {
  72. init(payload)
  73. }
  74. }
  75. // 处理退出登录请求
  76. const handleLogoutReq = async (payload: any) => {
  77. openModal({ name: 'logout', item: { isOpen: true, requestId: payload.requestId, data: payload.data } })
  78. if (getURLparams('is_native') === 'true') {
  79. nativeLogout(payload)
  80. } else {
  81. await logoutApi()
  82. pmBridge.sendToIframe('LOGOUT_REQUEST', { success: true, message: "退出登录成功" }, payload.requestId);
  83. }
  84. }
  85. // 处理退出登录回调
  86. const handleOnLogoutReq = (payload: any) => {
  87. openModal({ name: 'onLogout', item: { isOpen: false, requestId: payload.requestId, data: payload.data } })
  88. if (getURLparams('is_native') === 'true') {
  89. nativeOnLogout(payload)
  90. }
  91. }
  92. eventBus.on('LOGIN_REQUEST', handleLoginReq);
  93. eventBus.on('PAY_REQUEST', handlePayReq);
  94. eventBus.on('REPORT_REQUEST', handleReportReq);
  95. eventBus.on('INIT_REQUEST', handleInitReq);
  96. eventBus.on('LOGOUT_REQUEST', handleLogoutReq);
  97. eventBus.on('ONLOGOUT', handleOnLogoutReq);
  98. return () => {
  99. eventBus.off('LOGIN_REQUEST', handleLoginReq);
  100. eventBus.off('PAY_REQUEST', handlePayReq);
  101. eventBus.off('REPORT_REQUEST', handleReportReq);
  102. eventBus.off('INIT_REQUEST', handleInitReq);
  103. };
  104. }, []);
  105. // 请求记载游戏链接
  106. useEffect(() => {
  107. getGameUrl()
  108. }, []);
  109. return (
  110. <div className="w-full h-screen relative bg-white font-sans overflow-hidden">
  111. {/* Iframe 游戏容器 */}
  112. <iframe
  113. ref={iframeRef}
  114. src={iframeUrl}
  115. title="Game Container"
  116. className="w-full h-full border-none"
  117. sandbox="allow-scripts allow-same-origin allow-forms"
  118. />
  119. {userState.token}
  120. {/* 渲染弹窗 */}
  121. <LoginIndex />
  122. <RealNameIndex />
  123. <PaymentIndex />
  124. {/* 登录后显示浮标球 */}
  125. {userState.token && (
  126. <FloatingButton onClick={() => setIsSlideBarOpen(true)} />
  127. )}
  128. {/* 侧边栏 */}
  129. {isSlideBarOpen && (
  130. <SlideBarIndex onClose={() => setIsSlideBarOpen(false)} />
  131. )}
  132. </div>
  133. );
  134. }
  135. export default App;