realtime.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. import { connect } from 'dva/index';
  2. import React, { Component, Fragment } from 'react';
  3. import { Form, Spin, Tooltip } from 'antd';
  4. import {
  5. sldLlineRtextAddGoodsAddMargin,
  6. sldComLanguage,
  7. formatNum,
  8. } from '@/utils/utils';
  9. import global from '@/global.less';
  10. import styles from './realtime.less';
  11. import RealtimeOther from './realtime_other';
  12. import stat from '@/assets/css/stat.less';
  13. import SldScrollbars from '@/components/SldScrollbars';
  14. import TweenOne from 'rc-tween-one';
  15. import Children from 'rc-tween-one/lib/plugin/ChildrenPlugin';
  16. import defaultSettings from '@/defaultSettings';
  17. TweenOne.plugins.push(Children);
  18. @connect(({ statistics, global }) => ({
  19. statistics, global,
  20. }))
  21. @Form.create()
  22. export default class StatisticsRealtime extends Component {
  23. constructor(props) {
  24. super(props);
  25. this.state = {
  26. loadedFlag: false,//顶部数据是否加载完成
  27. screenW: document.body.clientWidth,//屏幕宽度
  28. refreshTime: '',//更新时间
  29. initLoading: false,
  30. detailData: {},//页面数据
  31. currentSiteName: props.global.currentSiteName,
  32. realTimeData1: {
  33. icon: require('@/assets/real_icon_1.png'),
  34. title: `${sldComLanguage('平台汇总')}`,
  35. list: [
  36. // {
  37. // name: `${sldComLanguage('销售总额(元)')}`,
  38. // value: '',
  39. // isHelpIcon: false,
  40. // tip: `${sldComLanguage('截止至当前时间,全平台累计销售额')}`,
  41. // mapKey: 'orderPayAmountTotal',
  42. // isMoney: true,
  43. // },
  44. {
  45. name: `${sldComLanguage('会员总数')}`,
  46. value: '',
  47. isHelpIcon: true,
  48. tip: `${sldComLanguage('截止至当前时间,全平台注册会员数')}`,
  49. mapKey: 'memberNum',
  50. },
  51. {
  52. name: `${sldComLanguage('店铺总数')}`,
  53. value: '',
  54. isHelpIcon: true,
  55. tip: `${sldComLanguage('截止至当前时间,全平台商家总数,包括自营商家和入驻商家')}`,
  56. mapKey: 'storeNum',
  57. },
  58. {
  59. name: `${sldComLanguage('在售商品数')}`,
  60. value: '',
  61. isHelpIcon: true,
  62. tip: `${sldComLanguage('截止至当前时间,状态为在售的商品数量')}`,
  63. mapKey: 'saleGoodsNum',
  64. },
  65. ],
  66. },
  67. siteRealTimeData: {
  68. icon: require('@/assets/real_icon_1.png'),
  69. title: `${sldComLanguage('平台汇总')}`,
  70. list: [
  71. // {
  72. // name: `${sldComLanguage('销售总额(元)')}`,
  73. // value: '',
  74. // isHelpIcon: false,
  75. // tip: `${sldComLanguage('截止至当前时间,全平台累计销售额')}`,
  76. // mapKey: 'orderPayAmountTotal',
  77. // isMoney: true,
  78. // },
  79. {
  80. name: `${sldComLanguage('会员总数')}`,
  81. value: '',
  82. isHelpIcon: true,
  83. tip: `${sldComLanguage('截止至当前时间,全平台注册会员数')}`,
  84. mapKey: 'webSiteMemberNum',
  85. },
  86. {
  87. name: `${sldComLanguage('店铺总数')}`,
  88. value: '',
  89. isHelpIcon: true,
  90. tip: `${sldComLanguage('截止至当前时间,全平台商家总数,包括自营商家和入驻商家')}`,
  91. mapKey: 'webSiteStoreNum',
  92. },
  93. {
  94. name: `${sldComLanguage('在售商品数')}`,
  95. value: '',
  96. isHelpIcon: true,
  97. tip: `${sldComLanguage('截止至当前时间,状态为在售的商品数量')}`,
  98. mapKey: 'webSiteSaleGoodsNum',
  99. },
  100. ],
  101. },
  102. realTimeData2: {
  103. icon: require('@/assets/real_icon_2.png'),
  104. title: `${sldComLanguage('今日实时')}`,
  105. list: [
  106. // {
  107. // name: `${sldComLanguage('今日销售额(元)')}`,
  108. // value: '',
  109. // isHelpIcon: false,
  110. // tip: `${sldComLanguage('今日0时至当前时间的销售额')}`,
  111. // mapKey: 'orderPayAmount',
  112. // isMoney: true,
  113. // },
  114. {
  115. name: `${sldComLanguage('新增会员数')}`,
  116. value: '',
  117. isHelpIcon: true,
  118. tip: `${sldComLanguage('统计时间内,全平台注册的人数总和')}`,
  119. mapKey: 'newMemberNum',
  120. },
  121. {
  122. name: `${sldComLanguage('新增店铺数')}`,
  123. value: '',
  124. isHelpIcon: true,
  125. tip: `${sldComLanguage('统计时间内,全平台新增商家数')}`,
  126. mapKey: 'newStoreNum',
  127. },
  128. {
  129. name: `${sldComLanguage('新增商品')}`,
  130. value: '',
  131. isHelpIcon: true,
  132. tip: `${sldComLanguage('统计时间内,全平台新增商品spu数')}`,
  133. mapKey: 'newGoodsNum',
  134. },
  135. {
  136. isBr: true,
  137. },
  138. {
  139. name: `${sldComLanguage('访客数')}`,
  140. value: '',
  141. isHelpIcon: true,
  142. tip: `${sldComLanguage('统计时间内,全平台所有页面的去重人数总和')}`,
  143. mapKey: 'visitorNum',
  144. },
  145. {
  146. name: `${sldComLanguage('浏览量')}`,
  147. value: '',
  148. isHelpIcon: true,
  149. tip: `${sldComLanguage('统计时间内,全平台所有页面被访问的次数总和')}`,
  150. mapKey: 'viewNum',
  151. },
  152. {
  153. name: `${sldComLanguage('商品访客数')}`,
  154. value: '',
  155. isHelpIcon: true,
  156. tip: `${sldComLanguage('统计时间内,访问商品详情页的去重人数')}`,
  157. mapKey: 'goodsVisitorNum',
  158. },
  159. {
  160. name: `${sldComLanguage('商品浏览量')}`,
  161. value: '',
  162. isHelpIcon: true,
  163. tip: `${sldComLanguage('统计时间内,访问商品详情页的人次数')}`,
  164. mapKey: 'goodsViewNum',
  165. },
  166. {
  167. isBr: true,
  168. },
  169. // {
  170. // name: `${sldComLanguage('下单数')}`,
  171. // value: '',
  172. // isHelpIcon: true,
  173. // tip: `${sldComLanguage('统计时间内,全平台用户成功提交订单的笔数总和')}`,
  174. // mapKey: 'orderSubmitNum',
  175. // },
  176. // {
  177. // name: `${sldComLanguage('下单人数')}`,
  178. // value: '',
  179. // isHelpIcon: true,
  180. // tip: `${sldComLanguage('统计时间内,全平台成功提交订单的去重人数总和')}`,
  181. // mapKey: 'orderSubmitMemberNum',
  182. // },
  183. // {
  184. // name: `${sldComLanguage('下单金额(元)')}`,
  185. // value: '',
  186. // isHelpIcon: true,
  187. // tip: `${sldComLanguage('统计时间内,全平台用户成功提交订单的金额总和')}`,
  188. // mapKey: 'orderSubmitAmount',
  189. // isMoney: true,
  190. //
  191. // },
  192. // {
  193. // name: `${sldComLanguage('下单客单价(元)')}`,
  194. // value: '',
  195. // isHelpIcon: true,
  196. // tip: `${sldComLanguage('统计时间内,全平台下单金额/下单人数')}`,
  197. // mapKey: 'orderSubmitAtv',
  198. // isMoney: true,
  199. //
  200. // },
  201. // {
  202. // name: `${sldComLanguage('访问-下单转化率')}`,
  203. // value: '',
  204. // isHelpIcon: true,
  205. // tip: `${sldComLanguage('统计时间内,全平台下单人数/平台访客数')}`,
  206. // mapKey: 'pvSubmitRate',
  207. // },
  208. // {
  209. // isBr: true,
  210. // },
  211. // {
  212. // name: `${sldComLanguage('支付订单数')}`,
  213. // value: '',
  214. // isHelpIcon: true,
  215. // tip: `${sldComLanguage('统计时间内,全平台用户成功支付的订单数量总和')}`,
  216. // mapKey: 'orderPayNum',
  217. // },
  218. // {
  219. // name: `${sldComLanguage('支付人数')}`,
  220. // value: '',
  221. // isHelpIcon: true,
  222. // tip: `${sldComLanguage('统计时间内,全平台成功付款的去重人数总和')}`,
  223. // mapKey: 'orderPayMemberNum',
  224. // },
  225. // {
  226. // name: `${sldComLanguage('支付金额(元)')}`,
  227. // value: '',
  228. // isHelpIcon: true,
  229. // tip: `${sldComLanguage('统计时间内,全平台用户成功支付的金额总和')}`,
  230. // mapKey: 'orderPayAmount',
  231. // isMoney: true,
  232. //
  233. // },
  234. // {
  235. // name: `${sldComLanguage('支付客单价(元)')}`,
  236. // value: '',
  237. // isHelpIcon: true,
  238. // tip: `${sldComLanguage('统计时间内,全平台下单金额/下单人数')}`,
  239. // mapKey: 'orderPayAtv',
  240. // isMoney: true,
  241. //
  242. // },
  243. // {
  244. // name: `${sldComLanguage('访问-支付转化率')}`,
  245. // value: '',
  246. // isHelpIcon: true,
  247. // tip: `${sldComLanguage('统计时间内,全平台支付人数/平台访客数')}`,
  248. // mapKey: 'pvPayRate',
  249. // },
  250. ],
  251. },
  252. };
  253. }
  254. componentDidMount() {
  255. this.resize();
  256. this.props.dispatch({
  257. type: 'global/getLayoutCollapsed',
  258. });
  259. window.addEventListener('resize', this.resize, { passive: true });
  260. this.initData();
  261. }
  262. resize = () => {
  263. this.setState({ screenW: document.body.clientWidth });
  264. };
  265. //获取页面数据
  266. initData = (type = '') => {
  267. this.setState({ initLoading: true });
  268. const { dispatch } = this.props;
  269. let { detailData, realTimeData2, realTimeData1, refreshTime } = this.state;
  270. let params = {};
  271. if (type) {
  272. params.refresh = type;
  273. }
  274. dispatch({
  275. type: 'statistics/get_realtime_data',
  276. payload: params,
  277. callback: (res) => {
  278. if (res.state == 200) {
  279. detailData = res.data;
  280. //渲染头部实时分析的数据
  281. const { realTimeData1, realTimeData2, siteRealTimeData } = this.state;
  282. const tempArray = [...realTimeData1.list, ...realTimeData2.list, ...siteRealTimeData.list];
  283. const tempActionData = { ...res.data.platformSummary, ...res.data.platformTodaySummary,orderPayAmountTotal:res.data.platformSummary.orderPayAmount };
  284. tempArray.forEach((item, index) => {
  285. tempArray[index]['value'] = tempActionData[item.mapKey];
  286. });
  287. refreshTime = res.data.statsTime;
  288. this.setState({
  289. detailData,
  290. realTimeData2,
  291. realTimeData1,
  292. siteRealTimeData,
  293. refreshTime,
  294. });
  295. }
  296. this.setState({ loadedFlag: true, initLoading: false });
  297. },
  298. });
  299. };
  300. realtimeAnalysis = () => {
  301. const { refreshTime } = this.state;
  302. return (
  303. <>
  304. <div className={`${stat.label_panel} ${global.flex_row_start_center}`}>
  305. {sldLlineRtextAddGoodsAddMargin(defaultSettings.primaryColor, `${sldComLanguage('实时分析')}`, 10, 0, 0)}
  306. <Tooltip placement="right" title={`${sldComLanguage('今日实时数据的统计时间均为今日零时至当前更新时间。点击刷新按钮可强制更新。')}`}>
  307. <img style={{ display: 'inline-block', marginLeft: '10px' }}
  308. src={require('@/assets/home_basic/help_icon.png')}></img>
  309. </Tooltip>
  310. <div className={`${stat.update_time_panel} ${global.flex_row_start_center}`}>
  311. <span>{`${sldComLanguage('更新时间:')}`}{refreshTime}</span>
  312. <i onClick={() => this.initData(true)} className={`${stat.reload_icon}`}></i>
  313. </div>
  314. </div>
  315. </>
  316. )
  317. }
  318. platformSummary = (type) => {
  319. const { currentSiteName, realTimeData2, siteRealTimeData, realTimeData1, initLoading, refreshTime, screenW, loadedFlag, detailData } = this.state;
  320. const renderRealTimeData = type ? siteRealTimeData : realTimeData1
  321. const leftW = this.props.global != undefined && this.props.global.collapsed != undefined && this.props.global.collapsed ? 90 : 150;
  322. let itemW = (screenW * 1 - leftW - 20 - 100 - 30 - 80) / 5;
  323. return (
  324. <>
  325. {this.realtimeAnalysis()}
  326. <div className={`${stat.num_stat_item} ${global.flex_row_start_center} ${global.no_border}`}>
  327. <div className={`${stat.left_slide} ${global.flex_column_center_center}`}>
  328. <img src={renderRealTimeData.icon} className={`${stat.slide_icon}`}></img>
  329. <span className={`${stat.slide_title}`}>{renderRealTimeData.title}</span>
  330. </div>
  331. <div className={`${stat.right_main}`}>
  332. <ul className={`${global.flex_row_start_center}`}>
  333. {renderRealTimeData.list.map((item, index) => (
  334. <li key={index} className={`${global.flex_column_center_start}`} style={{ width: itemW }}>
  335. <div className={`${stat.up_desc}`}>
  336. <span>{item.name}</span>
  337. {item.isHelpIcon ? <Tooltip placement="right" title={item.tip}>
  338. <img src={require('@/assets/home_basic/help_icon.png')}></img>
  339. </Tooltip> : ''}
  340. </div>
  341. <div className={`${stat.down_num}`} title={item.value}>
  342. <span>
  343. {loadedFlag && (
  344. item.value > 10000
  345. ? formatNum(item.value, item.isMoney ? 2 : 0)
  346. : <TweenOne animation={{
  347. Children: {
  348. value: item.value, floatLength: item.isMoney ? 2 : 0,
  349. formatMoney: true,
  350. },
  351. duration: 1000,
  352. }}/>
  353. )}
  354. </span>
  355. </div>
  356. </li>
  357. ))}
  358. </ul>
  359. </div>
  360. </div>
  361. </>
  362. )
  363. }
  364. render() {
  365. const { currentSiteName, realTimeData2, realTimeData1, initLoading, refreshTime, screenW, loadedFlag, detailData } = this.state;
  366. const leftW = this.props.global != undefined && this.props.global.collapsed != undefined && this.props.global.collapsed ? 90 : 150;
  367. let itemW = (screenW * 1 - leftW - 20 - 100 - 30 - 80) / 5;
  368. return (
  369. <div className={`${stat.real_stat} ${stat.stat_part}`}
  370. style={{ flex: 1 }}>
  371. <SldScrollbars
  372. autoHeight
  373. autoHeightMin={100}
  374. autoHeightMax={document.body.clientHeight - 60}
  375. >
  376. <Spin spinning={initLoading}>
  377. <div className={`${stat.module_item}`}>
  378. {this.platformSummary()}
  379. {<div className={ styles.current_site }>{ currentSiteName }</div> }
  380. <div className={`${stat.real_num_panel} ${styles.current_site_stat}`}>
  381. {this.platformSummary('site')}
  382. <div>
  383. <div className={`${stat.num_stat_item} ${global.flex_row_start_start} ${styles.no_border}`}>
  384. <div
  385. className={`${stat.left_slide} ${global.flex_column_center_center}`}>
  386. <img src={realTimeData2.icon} className={`${stat.slide_icon}`}></img>
  387. <span className={`${stat.slide_title}`}>{realTimeData2.title}</span>
  388. </div>
  389. <div className={`${stat.right_main}`}>
  390. <ul style={{ flexWrap: 'wrap' }} className={`${global.flex_row_start_center}`}>
  391. {realTimeData2.list.map((item, index) => (
  392. item.isBr ?
  393. <li key={index} style={{ height: '15px', width: '100%', backgroundColor: '#ffffff' }}></li>
  394. :
  395. <li key={index} className={`${global.flex_column_center_start}`} style={{ width: itemW }}>
  396. <div className={`${stat.up_desc}`}>
  397. <span>{item.name}</span>
  398. {item.isHelpIcon ? <Tooltip placement="right" title={item.tip}>
  399. <img src={require('@/assets/home_basic/help_icon.png')}></img>
  400. </Tooltip> : ''}
  401. </div>
  402. <div className={`${stat.down_num}`} title={item.value}>
  403. <span>
  404. {loadedFlag && (item.mapKey != 'pvSubmitRate') && (item.mapKey != 'pvPayRate') && (
  405. item.value > 10000
  406. ? formatNum(item.value, item.isMoney ? 2 : 0)
  407. : <TweenOne animation={{
  408. Children: {
  409. value: item.value, floatLength: item.isMoney ? 2 : 0,
  410. formatMoney: true,
  411. },
  412. duration: 1000,
  413. }}/>
  414. )}
  415. {loadedFlag && (item.mapKey == 'pvSubmitRate' || item.mapKey == 'pvPayRate') &&
  416. <Fragment>
  417. {item.value}
  418. </Fragment>
  419. }
  420. </span>
  421. </div>
  422. </li>
  423. ))}
  424. </ul>
  425. </div>
  426. </div>
  427. </div>
  428. </div>
  429. </div>
  430. <RealtimeOther detailData={detailData}/>
  431. </Spin>
  432. </SldScrollbars>
  433. </div>
  434. );
  435. }
  436. }