index.tsx 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. import { AccountBookOutlined, AppstoreOutlined, BuildOutlined, LeftOutlined, MoneyCollectOutlined, RightOutlined, TransactionOutlined, UsergroupAddOutlined } from "@ant-design/icons";
  2. import { useHover, useScroll, useSize } from "ahooks";
  3. import { Button, Card, Space, Spin, Statistic } from "antd"
  4. import React, { useEffect, useRef, useState } from "react"
  5. import style from './index.less'
  6. import LineC from "./lineC";
  7. import { AllSurveyTotalDataProps, getAllSurveyTotalDataApi } from "@/services/gameData/allSurvey";
  8. import { useAjax } from "@/Hook/useAjax";
  9. import QueryForm from "@/components/QueryForm";
  10. import moment from "moment";
  11. const AllSurvey: React.FC = () => {
  12. /* ==================== */
  13. const ref = useRef(null);
  14. const ref1 = useRef(null);
  15. const ref2 = useRef(null);
  16. const ref3 = useRef(null);
  17. const isHovering = useHover(ref); // 是否hover
  18. const isHovering1 = useHover(ref1); // 是否hover
  19. const isHovering2 = useHover(ref2); // 是否hover
  20. const size = useSize(ref); // div大小
  21. const size3 = useSize(ref3); // div大小
  22. const scroll = useScroll(ref);
  23. const [scrollDivWidth, setScrollDivWidth] = useState<number>(2000)
  24. const [badWidth, setBadWidth] = useState<number>(0)
  25. const [leftShow, setLeftShow] = useState<boolean>(false)
  26. const [rightShow, setRightShow] = useState<boolean>(false)
  27. const [queryForm, setQueryForm] = useState<AllSurveyTotalDataProps>({ sourceSystem: 'ZX_ONE' })
  28. const [totalData, setTotalData] = useState<any>({})
  29. /* ==================== */
  30. const getAllSurveyTotalData = useAjax((params) => getAllSurveyTotalDataApi(params))
  31. useEffect(() => {
  32. if (size?.width) {
  33. let buguWidth = 0
  34. if (queryForm?.sourceSystem && (queryForm?.sourceSystem === 'BG_OLD' || queryForm?.sourceSystem === 'BG_NEW')) {
  35. buguWidth = 200
  36. }
  37. let width = 2042
  38. let b = 6
  39. if (queryForm?.gameId) {
  40. b = 5
  41. width = 1712
  42. } else {
  43. b = 6
  44. width = 2042
  45. }
  46. let w = size?.width || 0
  47. if (w > width) {
  48. let badW = w - width
  49. width = w
  50. setBadWidth(badW / b)
  51. }
  52. setScrollDivWidth(width + buguWidth)
  53. }
  54. }, [queryForm?.gameId, size, queryForm?.sourceSystem])
  55. // 处理左右按钮隐藏 显示
  56. useEffect(() => {
  57. // console.log('isHovering---->', isHovering, 'size---->', size, 'scroll--->', scroll);
  58. if (isHovering || isHovering1 || isHovering2) {
  59. let width = size.width || 0
  60. let left = scroll.left || 0
  61. if (width >= scrollDivWidth) { // 容器大于内容宽度 兼容
  62. setLeftShow(false)
  63. setRightShow(false)
  64. } else {
  65. if (left === 0) {
  66. setLeftShow(false)
  67. } else {
  68. setLeftShow(true)
  69. }
  70. if (width < scrollDivWidth) {
  71. setRightShow(true)
  72. }
  73. if (width + left === scrollDivWidth) {
  74. setRightShow(false)
  75. }
  76. }
  77. } else {
  78. setLeftShow(false)
  79. setRightShow(false)
  80. }
  81. }, [isHovering, isHovering1, isHovering2, size, scroll, ref, scrollDivWidth])
  82. // 左右移动
  83. const aboutHandle = (about: 'left' | 'right') => {
  84. let left = scroll.left || 0
  85. if (about === 'left') {
  86. (ref?.current as any)?.scrollTo(left - 100, 0)
  87. } else {
  88. (ref?.current as any)?.scrollTo(left + 100, 0)
  89. }
  90. }
  91. useEffect(() => {
  92. getAllSurveyTotalData.run(queryForm).then((res) => {
  93. setTotalData(res)
  94. })
  95. }, [queryForm])
  96. const isBg = () => {
  97. return queryForm?.sourceSystem && (queryForm?.sourceSystem === 'BG_OLD' || queryForm?.sourceSystem === 'BG_NEW')
  98. }
  99. return <div className={style.allSurver}>
  100. <Space direction="vertical" style={{ width: '100%' }}>
  101. <div ref={ref3}>
  102. <Card bordered={false} bodyStyle={{ padding: '12px 24px' }} style={{ borderRadius: 8 }}>
  103. <QueryForm
  104. initialValues={{ sourceSystem: 'ZX_ONE' }}
  105. onChange={(data: any) => {
  106. console.log(data)
  107. const { beginDay, ...par } = data
  108. let newQueryForm = JSON.parse(JSON.stringify(queryForm))
  109. if (beginDay && beginDay?.length === 2) {
  110. newQueryForm['beginDate'] = moment(beginDay[0]).format('YYYY-MM-DD')
  111. newQueryForm['endDate'] = moment(beginDay[1]).format('YYYY-MM-DD')
  112. } else {
  113. delete newQueryForm['beginDate']
  114. delete newQueryForm['endDate']
  115. }
  116. setQueryForm({ ...newQueryForm, ...par })
  117. }}
  118. isSource
  119. isAccountId
  120. isGameId
  121. isSysUserId
  122. isAgentId
  123. />
  124. </Card>
  125. </div>
  126. <Spin spinning={getAllSurveyTotalData.loading}>
  127. <div className={style.overviewC}>
  128. <div className={style.left}><Button type="primary" ref={ref1} style={{ opacity: leftShow ? 1 : 0 }} onClick={() => aboutHandle('left')} shape="circle" icon={<LeftOutlined />} /></div>
  129. <div className={style.right}><Button type="primary" ref={ref2} style={{ opacity: rightShow ? 1 : 0 }} onClick={() => aboutHandle('right')} shape="circle" icon={<RightOutlined />} /></div>
  130. <div className={style.overviews} ref={ref}>
  131. <div style={{ width: scrollDivWidth }}>
  132. <Card bordered={false} style={{ borderRadius: 8 }} bodyStyle={{ width: 320 + badWidth }}>
  133. <div className={style.overview}>
  134. <div className={style.left}>
  135. <UsergroupAddOutlined style={{ fontSize: 24 }} />
  136. <div>玩家</div>
  137. </div>
  138. <div className={style.right}>
  139. <div className={style.top}>
  140. 总计:<Statistic value={totalData?.totalPlayers || 0} valueStyle={{ fontSize: 20, fontWeight: 600 }} />
  141. </div>
  142. <div className={style.bottom}>
  143. <div>昨日:<Statistic value={totalData?.yesterdayPlayerCount || 0} /></div>
  144. <div><span style={{ color: 'red' }}>今日:</span><Statistic value={totalData?.todayPlayerCount || 0} /></div>
  145. </div>
  146. </div>
  147. </div>
  148. </Card>
  149. <Card bordered={false} style={{ borderRadius: 8 }} bodyStyle={{ width: 320 + badWidth }}>
  150. <div className={style.overview}>
  151. <div className={style.left} style={{ backgroundColor: '#36a3f7' }}>
  152. <TransactionOutlined style={{ fontSize: 24 }} />
  153. <div>消耗</div>
  154. </div>
  155. <div className={style.right}>
  156. <div className={style.top} style={{ borderColor: '#36a3f7' }}>
  157. 总计:<Statistic value={totalData?.totalCost || 0} valueStyle={{ fontSize: 20, fontWeight: 600 }} />
  158. </div>
  159. <div className={style.bottom}>
  160. <div>昨日:<Statistic value={totalData?.yesterdayTotalCost || 0} /></div>
  161. <div><span style={{ color: 'red' }}>今日:</span><Statistic value={totalData?.todayTotalCost || 0} /></div>
  162. </div>
  163. </div>
  164. </div>
  165. </Card>
  166. <Card bordered={false} style={{ borderRadius: 8 }} bodyStyle={{ width: isBg() ? 320 + 200 + badWidth : 320 + 40 + badWidth }}>
  167. <div className={style.overview}>
  168. <div className={style.left} style={{ backgroundColor: '#f4516c' }}>
  169. <MoneyCollectOutlined style={{ fontSize: 24 }} />
  170. <div>充值</div>
  171. </div>
  172. <div className={style.right}>
  173. <div className={style.top} style={{ borderColor: '#f4516c' }}>
  174. 总计:<Statistic value={totalData?.totalAmount || 0} valueStyle={{ fontSize: 20, fontWeight: 600 }} />
  175. </div>
  176. <div className={style.bottom}>
  177. <div style={{ justifyContent: 'space-between' }}>
  178. <div style={{ width: isBg() ? '30%' : '50%' }}>昨账:<Statistic value={totalData?.yesterdayAmount || 0} /></div>
  179. <div style={{ width: isBg() ? '27%' : '50%' }}>昨新:<Statistic value={totalData?.yesterdayNewPlayerAmount || 0} /></div>
  180. {isBg() && <div style={{ width: '43%' }}>BG自累充:<Statistic value={totalData?.totalAmountForBG || 0} /></div>}
  181. </div>
  182. <div style={{ justifyContent: 'space-between', flex: 1 }}>
  183. <div style={{ width: isBg() ? '30%' : '50%' }}>今账:<Statistic value={totalData?.todayAmount || 0} /></div>
  184. <div style={{ width: isBg() ? '27%' : '50%' }}><span style={{ color: 'red' }}>今新:</span><Statistic value={totalData?.todayNewPlayerAmount || 0} /></div>
  185. {isBg() && <div style={{ width: '43%' }}>BG自今账:<Statistic value={totalData?.todayAmountForBG || 0} /></div>}
  186. </div>
  187. {isBg() && <div style={{ justifyContent: 'space-between' }}>
  188. <div style={{ width: '30%' }}></div>
  189. <div style={{ width: '27%' }}></div>
  190. <div style={{ width: '43%' }}>BG自昨账:<Statistic value={totalData?.yesterdayAmountForBG || 0} /></div>
  191. </div>}
  192. </div>
  193. </div>
  194. </div>
  195. </Card>
  196. <Card bordered={false} style={{ borderRadius: 8 }} bodyStyle={{ width: 320 + badWidth }}>
  197. <div className={style.overview}>
  198. <div className={style.left} style={{ backgroundColor: '#52c41a' }}>
  199. <AppstoreOutlined style={{ fontSize: 24 }} />
  200. <div>渠道</div>
  201. </div>
  202. <div className={style.right}>
  203. <div className={style.top} style={{ borderColor: '#52c41a' }}>
  204. 总计:<Statistic value={totalData?.totalAgentCount || 0} valueStyle={{ fontSize: 20, fontWeight: 600 }} />
  205. </div>
  206. <div className={style.bottom}>
  207. <div>昨日:<Statistic value={totalData?.yesterdayAgentCount || 0} /></div>
  208. <div><span style={{ color: 'red' }}>今日:</span><Statistic value={totalData?.todayAgentCount || 0} /></div>
  209. </div>
  210. </div>
  211. </div>
  212. </Card>
  213. {!queryForm?.gameId && <Card bordered={false} style={{ borderRadius: 8 }} bodyStyle={{ width: 320 + badWidth }}>
  214. <div className={style.overview}>
  215. <div className={style.left} style={{ backgroundColor: '#597ef7' }}>
  216. <BuildOutlined style={{ fontSize: 24 }} />
  217. <div>游戏</div>
  218. </div>
  219. <div className={style.right}>
  220. <div className={style.top} style={{ borderColor: '#597ef7' }}>
  221. 总投游戏数:<Statistic value={totalData?.totalGameCount || 0} valueStyle={{ fontSize: 20, fontWeight: 600 }} />
  222. </div>
  223. <div className={style.bottom}>
  224. <div>昨日在投:<Statistic value={totalData?.yesterdayGameCount || 0} /></div>
  225. <div><span style={{ color: 'red' }}>今日在投:</span><Statistic value={totalData?.todayGameCount || 0} /></div>
  226. </div>
  227. </div>
  228. </div>
  229. </Card>}
  230. <Card bordered={false} style={{ borderRadius: 8 }} bodyStyle={{ width: 400 + badWidth }}>
  231. <div className={style.overview}>
  232. <div className={style.left} style={{ backgroundColor: '#9254de' }}>
  233. <AccountBookOutlined style={{ fontSize: 24 }} />
  234. <div>回本</div>
  235. </div>
  236. <div className={style.right}>
  237. <div className={style.top} style={{ borderColor: '#9254de' }}>
  238. 总回:<Statistic value={totalData?.totalRoi || 0} valueStyle={{ fontSize: 20, fontWeight: 600, color: 'red' }} precision={2} suffix="%" />
  239. </div>
  240. <div className={style.bottom}>
  241. <div style={{ justifyContent: 'space-between' }}>
  242. <div>首日:<Statistic value={totalData?.totalFirstRoi || 0} suffix="%" precision={2} /></div>
  243. <div><span style={{ color: 'red' }}>今日:</span><Statistic value={totalData?.firstRoi || 0} suffix="%" precision={2} /></div>
  244. </div>
  245. {/* <div style={{ justifyContent: 'space-between', flex: 1 }}>
  246. <div>近7天:<Statistic value={totalData?.d7TotalRoi || 0} suffix="%" precision={2} /></div>
  247. <div>近30天:<Statistic value={totalData?.d30TotalRoi || 0} suffix="%" precision={2} /></div>
  248. </div> */}
  249. </div>
  250. </div>
  251. </div>
  252. </Card>
  253. </div>
  254. </div>
  255. </div>
  256. </Spin>
  257. </Space>
  258. <LineC width={size3.width || 0} height={size3.height || 0} queryForm={queryForm} />
  259. </div>
  260. }
  261. export default AllSurvey