Browse Source

(*)社区大屏提交

master
peng.peng 1 year ago
parent
commit
eeef737c72
  1. BIN
      super-screen/client/assets/images/homepage/bigscreen/exit.png
  2. BIN
      super-screen/client/assets/images/homepage/bigscreen/headertitlebg.png
  3. BIN
      super-screen/client/assets/images/homepage/communtity/basicimg.png
  4. BIN
      super-screen/client/assets/images/homepage/communtity/basicinterval.png
  5. BIN
      super-screen/client/assets/images/homepage/communtity/basictextbg.png
  6. BIN
      super-screen/client/assets/images/homepage/communtity/basictitlebg.png
  7. BIN
      super-screen/client/assets/images/homepage/communtity/bg.png
  8. BIN
      super-screen/client/assets/images/homepage/communtity/lift.png
  9. BIN
      super-screen/client/assets/images/homepage/communtity/person.png
  10. BIN
      super-screen/client/assets/images/homepage/communtity/personbg.png
  11. BIN
      super-screen/client/assets/images/homepage/communtity/smoke.png
  12. BIN
      super-screen/client/assets/images/homepage/communtity/special1.png
  13. BIN
      super-screen/client/assets/images/homepage/communtity/special2.png
  14. BIN
      super-screen/client/assets/images/homepage/communtity/temp.png
  15. BIN
      super-screen/client/assets/images/homepage/communtity/video.png
  16. BIN
      super-screen/client/assets/images/homepage/enter/bg.png
  17. BIN
      super-screen/client/assets/images/homepage/enter/row1-select.png
  18. BIN
      super-screen/client/assets/images/homepage/enter/row1.png
  19. BIN
      super-screen/client/assets/images/homepage/enter/row2-1-select.png
  20. BIN
      super-screen/client/assets/images/homepage/enter/row2-1.png
  21. BIN
      super-screen/client/assets/images/homepage/enter/row2-2-select.png
  22. BIN
      super-screen/client/assets/images/homepage/enter/row2-2.png
  23. BIN
      super-screen/client/assets/images/homepage/enter/row2-3-select.png
  24. BIN
      super-screen/client/assets/images/homepage/enter/row2-3.png
  25. BIN
      super-screen/client/assets/images/homepage/enter/title.png
  26. 14
      super-screen/client/index.ejs
  27. 18
      super-screen/client/index.html
  28. 7
      super-screen/client/src/app.js
  29. 15
      super-screen/client/src/layout/components/header/index.js
  30. 2
      super-screen/client/src/layout/containers/layout/index.js
  31. 15
      super-screen/client/src/sections/community-safty/actions/example.js
  32. 7
      super-screen/client/src/sections/community-safty/actions/index.js
  33. 45
      super-screen/client/src/sections/community-safty/components/basic-info.js
  34. 14
      super-screen/client/src/sections/community-safty/components/city-safty.js
  35. 32
      super-screen/client/src/sections/community-safty/components/infrastructure.js
  36. 35
      super-screen/client/src/sections/community-safty/components/population-dynamics.js
  37. 33
      super-screen/client/src/sections/community-safty/components/public/carousel-list.js
  38. 77
      super-screen/client/src/sections/community-safty/components/public/index.less
  39. 18
      super-screen/client/src/sections/community-safty/components/public/noData.js
  40. 469
      super-screen/client/src/sections/community-safty/components/public/scrollBoard/index.js
  41. 44
      super-screen/client/src/sections/community-safty/components/public/scrollBoard/style.less
  42. 35
      super-screen/client/src/sections/community-safty/components/public/table-card.js
  43. 31
      super-screen/client/src/sections/community-safty/components/special-person.js
  44. 286
      super-screen/client/src/sections/community-safty/components/style.less
  45. 15
      super-screen/client/src/sections/community-safty/components/traffic-ranking.js
  46. 3
      super-screen/client/src/sections/community-safty/components/util.js
  47. 48
      super-screen/client/src/sections/community-safty/containers/gis.js
  48. 77
      super-screen/client/src/sections/community-safty/containers/homePage.js
  49. 6
      super-screen/client/src/sections/community-safty/containers/index.js
  50. 260
      super-screen/client/src/sections/community-safty/containers/style.less
  51. 15
      super-screen/client/src/sections/community-safty/index.js
  52. 11
      super-screen/client/src/sections/community-safty/nav-item.js
  53. 5
      super-screen/client/src/sections/community-safty/reducers/index.js
  54. 13
      super-screen/client/src/sections/community-safty/routes.js
  55. 0
      super-screen/client/src/sections/community-safty/style.less
  56. 74
      super-screen/client/src/sections/homePage/containers/homePage copy.js
  57. 50
      super-screen/client/src/sections/homePage/containers/homePage.js
  58. 102
      super-screen/client/src/sections/homePage/containers/style.less
  59. 15
      super-screen/client/src/sections/water-prevention/actions/example.js
  60. 7
      super-screen/client/src/sections/water-prevention/actions/index.js
  61. 49
      super-screen/client/src/sections/water-prevention/components/abnormalMonitoring.js
  62. 36
      super-screen/client/src/sections/water-prevention/components/accessData.js
  63. 52
      super-screen/client/src/sections/water-prevention/components/alarmList.js
  64. 19
      super-screen/client/src/sections/water-prevention/components/centerTop.js
  65. 54
      super-screen/client/src/sections/water-prevention/components/dataShare.js
  66. 262
      super-screen/client/src/sections/water-prevention/components/dataTop5.js
  67. 42
      super-screen/client/src/sections/water-prevention/components/hotspotData.js
  68. 39
      super-screen/client/src/sections/water-prevention/components/nodeResource.js
  69. 33
      super-screen/client/src/sections/water-prevention/components/public/carousel-list.js
  70. 80
      super-screen/client/src/sections/water-prevention/components/public/index.less
  71. 18
      super-screen/client/src/sections/water-prevention/components/public/noData.js
  72. 469
      super-screen/client/src/sections/water-prevention/components/public/scrollBoard/index.js
  73. 44
      super-screen/client/src/sections/water-prevention/components/public/scrollBoard/style.less
  74. 34
      super-screen/client/src/sections/water-prevention/components/public/table-card.js
  75. 373
      super-screen/client/src/sections/water-prevention/components/style.less
  76. 3
      super-screen/client/src/sections/water-prevention/components/util.js
  77. 74
      super-screen/client/src/sections/water-prevention/containers/homePage.js
  78. 6
      super-screen/client/src/sections/water-prevention/containers/index.js
  79. 324
      super-screen/client/src/sections/water-prevention/containers/style.less
  80. 15
      super-screen/client/src/sections/water-prevention/index.js
  81. 11
      super-screen/client/src/sections/water-prevention/nav-item.js
  82. 5
      super-screen/client/src/sections/water-prevention/reducers/index.js
  83. 13
      super-screen/client/src/sections/water-prevention/routes.js
  84. 0
      super-screen/client/src/sections/water-prevention/style.less
  85. 2
      super-screen/middlewares/webpack-dev.js

BIN
super-screen/client/assets/images/homepage/bigscreen/exit.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

BIN
super-screen/client/assets/images/homepage/bigscreen/headertitlebg.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
super-screen/client/assets/images/homepage/communtity/basicimg.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

BIN
super-screen/client/assets/images/homepage/communtity/basicinterval.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 B

BIN
super-screen/client/assets/images/homepage/communtity/basictextbg.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
super-screen/client/assets/images/homepage/communtity/basictitlebg.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
super-screen/client/assets/images/homepage/communtity/bg.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 MiB

BIN
super-screen/client/assets/images/homepage/communtity/lift.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
super-screen/client/assets/images/homepage/communtity/person.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

BIN
super-screen/client/assets/images/homepage/communtity/personbg.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
super-screen/client/assets/images/homepage/communtity/smoke.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
super-screen/client/assets/images/homepage/communtity/special1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
super-screen/client/assets/images/homepage/communtity/special2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
super-screen/client/assets/images/homepage/communtity/temp.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
super-screen/client/assets/images/homepage/communtity/video.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
super-screen/client/assets/images/homepage/enter/bg.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

BIN
super-screen/client/assets/images/homepage/enter/row1-select.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 450 KiB

BIN
super-screen/client/assets/images/homepage/enter/row1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 353 KiB

BIN
super-screen/client/assets/images/homepage/enter/row2-1-select.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 257 KiB

BIN
super-screen/client/assets/images/homepage/enter/row2-1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

BIN
super-screen/client/assets/images/homepage/enter/row2-2-select.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 KiB

BIN
super-screen/client/assets/images/homepage/enter/row2-2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

BIN
super-screen/client/assets/images/homepage/enter/row2-3-select.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 251 KiB

BIN
super-screen/client/assets/images/homepage/enter/row2-3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 KiB

BIN
super-screen/client/assets/images/homepage/enter/title.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

14
super-screen/client/index.ejs

@ -5,6 +5,15 @@
<meta charset="UTF-8">
<link rel="shortcut icon" href="/assets/images/favicon.ico">
<link rel="stylesheet" type="text/css" href="/assets/font_sc/iconfont.css">
<script type="text/javascript">
window._AMapSecurityConfig = {
securityJsCode: "1321f0b6cd761e2f85496778dcb9bddb",
};
</script>
<script
src="https://webapi.amap.com/maps?v=2.0&key=173f32a9ff6f3a8c6b15aceb3353c715&plugin=AMap.Adaptor,AMap.Scale,AMap.ToolBar,AMap.DistrictSearch,AMap.Geocoder,AMap.CustomLayer,Map3D,ElasticMarker,AMap.Autocomplete,AMap.PlaceSearch,AMap.MarkerCluster"></script>
<script src="https://webapi.amap.com/loca?v=2.0.0&key=173f32a9ff6f3a8c6b15aceb3353c715"></script>
<script src="https://webapi.amap.com/ui/1.1/main.js?v=1.1.1"></script>
</head>
<style>
@font-face {
@ -16,6 +25,11 @@
font-family: D-DIN-Bold;
src: url("/assets/font_sc/D-DIN-Bold.ttf");
}
@font-face {
font-family: D-DIN-Italic;
src: url("/assets/font_sc/D-DIN.ttf");
}
</style>
<body style="background: transparent">

18
super-screen/client/index.html

@ -6,6 +6,15 @@
<title></title>
<link rel="shortcut icon" href="/assets/images/favicon.ico">
<link rel="stylesheet" type="text/css" href="/assets/font_sc/iconfont.css">
<script type="text/javascript">
window._AMapSecurityConfig = {
securityJsCode: "1321f0b6cd761e2f85496778dcb9bddb",
};
</script>
<script
src="https://webapi.amap.com/maps?v=2.0&key=173f32a9ff6f3a8c6b15aceb3353c715&plugin=AMap.Adaptor,AMap.Scale,AMap.ToolBar,AMap.DistrictSearch,AMap.Geocoder,AMap.CustomLayer,Map3D,ElasticMarker,AMap.Autocomplete,AMap.PlaceSearch,AMap.MarkerCluster"></script>
<script src="https://webapi.amap.com/loca?v=2.0.0&key=173f32a9ff6f3a8c6b15aceb3353c715"></script>
<script src="https://webapi.amap.com/ui/1.1/main.js?v=1.1.1"></script>
</head>
<style>
@font-face {
@ -17,12 +26,17 @@
font-family: D-DIN-Bold;
src: url("/assets/font_sc/D-DIN-Bold.ttf");
}
@font-face {
font-family: D-DIN-Italic;
src: url("/assets/font_sc/D-DIN.ttf");
}
</style>
<body style="background: #0F1C2A;">
<div id='App'></div>
<script type="text/javascript" src="http://localhost:5401/client/build/vendor.js"></script>
<script type="text/javascript" src="http://localhost:5401/client/build/app.js"></script>
<script type="text/javascript" src="http://localhost:5501/client/build/vendor.js"></script>
<script type="text/javascript" src="http://localhost:5501/client/build/app.js"></script>
</body>
</html>

7
super-screen/client/src/app.js

@ -4,7 +4,8 @@ import React, { useEffect } from 'react';
import Layout from './layout';
import Auth from './sections/auth';
import homePage from './sections/homePage';
import waterprevention from './sections/water-prevention'
import communitysafty from './sections/community-safty'
const App = props => {
const { projectName } = props
@ -17,7 +18,9 @@ const App = props => {
title={projectName}
sections={[
homePage,
Auth
Auth,
waterprevention,
communitysafty
]}
/>
)

15
super-screen/client/src/layout/components/header/index.js

@ -7,7 +7,6 @@ import styles from './style.css';
import {
MenuFoldOutlined, MenuUnfoldOutlined, UserOutlined, LogoutOutlined
} from '@ant-design/icons';
import ResetPasswordModal from '../../../sections/memberManagement/components/resetPassword';
const Header = props => {
const { dispatch, history, user, pathname, toggleCollapsed, collapsed, actions } = props
@ -27,7 +26,7 @@ const Header = props => {
const handelClick = item => {
if (item.key == 'logout') {
dispatch(actions.auth.logout(user));
history.push(`/signin`);
history.push(`/homepage`);
}
}
@ -67,17 +66,7 @@ const Header = props => {
key: "user",
icon: <img className={styles['header-nav-user-img']} src={`/assets/images/avatar/5.png`} />,
children: [
{
icon: <UserOutlined />,
label: <ResetPasswordModal
editData={user}
triggerRender={<a>修改密码</a>}
title="修改密码"
onFinish={onFinish}
key="resetPassword"
/>,
key: 'resetPassword'
},
{
label: '退出', key: 'logout', icon: <LogoutOutlined />
},

2
super-screen/client/src/layout/containers/layout/index.js

@ -49,7 +49,7 @@ const LayoutContainer = props => {
useEffect(() => {
NProgress.done();
if (!user || !user.authorized) {
history.push('/signin');
history.push('/homepage');
}
if (msg) {
message.destroy();

15
super-screen/client/src/sections/community-safty/actions/example.js

@ -0,0 +1,15 @@
'use strict';
import { basicAction } from '@peace/utils'
import { ApiTable } from '$utils'
// export function getMembers(orgId) {
// return dispatch => basicAction({
// type: 'get',
// dispatch: dispatch,
// actionType: 'GET_MEMBERS',
// url: `${ApiTable.getEnterprisesMembers.replace('{enterpriseId}', orgId)}`,
// msg: { error: '获取用户列表失败' },
// reducer: { name: 'members' }
// });
// }

7
super-screen/client/src/sections/community-safty/actions/index.js

@ -0,0 +1,7 @@
'use strict';
import * as example from './example'
export default {
...example,
}

45
super-screen/client/src/sections/community-safty/components/basic-info.js

@ -0,0 +1,45 @@
import React from 'react'
import Box from './public/table-card';
function BasicInfo() {
return <Box title={"基本信息"} >
<div className='_basic_info'>
<div className='_basic_row1'>
<div className='_item1' />
<div className='_item2'>
<div className='_basictitlebg'>
<div className='_basic_title'>南昌县</div>
<span className='_basic_sub_title'>Nanchang county</span>
</div>
<div className='_basic_text'>
<span>区域面积</span>
<span className='_text_number_color'>1742.3km³</span>
</div>
<div className='_basic_text'>
<span>人口</span>
<span className='_text_number_color'>14.43</span>
</div>
</div>
</div>
<div className='_basic_row2'>
<div className='_item1'>
<span>社区数量</span>
<span className='_number'>53</span>
</div>
<div className='basicinterval' />
<div className='_item2'>
<span>房屋数量</span>
<span className='_number'>630</span>
</div>
</div>
</div>
</Box>
}
export default BasicInfo;

14
super-screen/client/src/sections/community-safty/components/city-safty.js

@ -0,0 +1,14 @@
import React, { useEffect, useState } from 'react'
import Box from './public/table-card';
import './style.less';
function CitySafty(props) {
return <Box title={"城市安全"} >
城市安全
</Box>
}
export default CitySafty;

32
super-screen/client/src/sections/community-safty/components/infrastructure.js

@ -0,0 +1,32 @@
import React from 'react'
import Box from './public/table-card';
function Infrastructure(props) {
const data = [
{ name: '烟感设备', number: 32 },
{ name: '温度设备', number: 32 },
{ name: '摄像头设备', number: 32 },
{ name: '电梯设备', number: 32 },
]
return <Box title={"基础设施"} >
<div className='_basic_device'>
{
data.map((s, index) => {
return <div className='_device_item'>
<div className={'_device_img' + (index + 1)} />
<div className='_device_text'>
<div>{s.name}</div>
<div><span className='_device_number'>{s.number}</span> </div>
</div>
</div>
})
}
</div>
</Box>
}
export default Infrastructure;

35
super-screen/client/src/sections/community-safty/components/population-dynamics.js

@ -0,0 +1,35 @@
import React from 'react'
import Box from './public/table-card';
function PopulationDynamics() {
const data = [
{ title: '常驻人口', number: 447 },
{ title: '流动人口', number: 447 },
{ title: '境外人口', number: 447 },
{ title: '未落户人口', number: 447 },
{ title: '贫困人口', number: 447 },
{ title: '老龄人口', number: 447 },
]
return <Box title={"人口动态"} >
<div className='_person_trends'>
<div className='_person_tends_item1' />
<div className='_person_tends_item2'>
{
data.map(s => {
return <div className='_person_text'>
<div className='_person_title'>{s.title}</div>
<div className='_person_number'>{s.number}</div>
<span>万人</span>
</div>
})
}
</div>
</div>
</Box>
}
export default PopulationDynamics;

33
super-screen/client/src/sections/community-safty/components/public/carousel-list.js

@ -0,0 +1,33 @@
/* 轮播列表组件 */
import React from 'react';
import ScrollBoard from './scrollBoard';
import NoData from './noData';
import './index.less';
function CarouselList(props) {
const {
header = [], data = [], rowNum = 4, height, columnWidth, multiellipsis, waitTime = 2000, marginTop, ...restProps
} = props;
const config = {
header,
rowNum,
headerBGC: 'rgba(81, 200, 247, 0.2)',
oddRowBGC: 'transparent',
evenRowBGC: 'transparent',
headerHeight: 30,
data,
waitTime,
columnWidth: columnWidth || [],
};
return data.length > 0 ? (
<ScrollBoard
config={config}
style={{ height }}
className={multiellipsis ? 'scroll-board-multi' : 'scroll-board'}
{...restProps}
/>
) : <NoData marginTop={marginTop || 0} />;
}
export default CarouselList;

77
super-screen/client/src/sections/community-safty/components/public/index.less

@ -0,0 +1,77 @@
.opcityBackground {
background-color: rgba(8, 27, 55, 0.6);
}
.card-title {
height: 31px;
font-family: YouSheBiaoTiHei;
font-size: 24px;
color: #FFFFFF;
letter-spacing: 2px;
}
/* 滚动列表 */
.scroll-board {
width: 533px;
height: 220px;
margin-top: 10px;
margin-left: 6px;
.header {
height: 30px;
border-top: 1px solid #0047ba;
border-bottom: 1px solid #0047ba;
.header-item {
// background: rgba(12, 49, 110, 0.3);
margin-right: 10px;
}
}
.rows {
.row-item {
font-size: 16px;
}
.row-item:hover {
background: linear-gradient(270deg, rgba(17, 183, 247, 0) 0%, rgba(17, 183, 247, 0.85) 100%);
color: #9ac8fc;
}
}
}
.scroll-board-multi {
padding: 5px 0px 5px;
color: rgba(204, 228, 255, 1) !important;
.header {
display: flex;
flex-direction: row;
font-size: 12px !important;
color: rgba(204, 228, 255, 1) !important;
// border-bottom: 1px solid #124C79 !important;
}
.rows {
color: rgba(204, 228, 255, 1) !important;
.row-item {
border-bottom: 1px solid #124C79 !important;
}
.row-item:hover {
background: linear-gradient(270deg, rgba(17, 183, 247, 0) 0%, rgba(17, 183, 247, 0.85) 100%);
color: #9ac8fc;
}
}
}
._sorrow {
display: inline-block;
width: 15px;
height: 15px;
background: url('/assets/images/homePage/bigscreen/sorrow.png');
background-repeat: no-repeat;
background-size: 100% 100%;
margin-left: 13px;
}

18
super-screen/client/src/sections/community-safty/components/public/noData.js

@ -0,0 +1,18 @@
/* 公共模块暂无数据组件 */
import React from 'react';
import { Empty } from 'antd';
function NoData({ height = 180, marginTop = 0 }) {
return (
<Empty
image="/assets/images/homePage/bigscreen/empty.png"
imageStyle={{
height,
marginTop
}}
description={false}
/>
);
}
export default NoData;

469
super-screen/client/src/sections/community-safty/components/public/scrollBoard/index.js

@ -0,0 +1,469 @@
import React, {
useEffect, useState, useRef, useMemo, forwardRef,
} from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { deepMerge } from '@jiaminghi/charts/lib/util/index';
import { deepClone } from '@jiaminghi/c-render/lib/plugin/util';
import { useAutoResize, co } from '@jiaminghi/data-view-react';
import './style.less';
const defaultConfig = {
/**
* @description Board header
* @type {Array<String>}
* @default header = []
* @example header = ['column1', 'column2', 'column3']
*/
header: [],
/**
* @description Board data
* @type {Array<Array>}
* @default data = []
*/
data: [],
/**
* @description Row num
* @type {Number}
* @default rowNum = 5
*/
rowNum: 5,
/**
* @description Header background color
* @type {String}
* @default headerBGC = '#00BAFF'
*/
headerBGC: '#00BAFF',
/**
* @description Odd row background color
* @type {String}
* @default oddRowBGC = '#003B51'
*/
oddRowBGC: '#003B51',
/**
* @description Even row background color
* @type {String}
* @default evenRowBGC = '#003B51'
*/
evenRowBGC: '#0A2732',
/**
* @description Scroll wait time
* @type {Number}
* @default waitTime = 2000
*/
waitTime: 2000,
/**
* @description Header height
* @type {Number}
* @default headerHeight = 35
*/
headerHeight: 35,
/**
* @description Column width
* @type {Array<Number>}
* @default columnWidth = []
*/
columnWidth: [],
/**
* @description Column align
* @type {Array<String>}
* @default align = []
* @example align = ['left', 'center', 'right']
*/
align: [],
/**
* @description Show index
* @type {Boolean}
* @default index = false
*/
index: false,
/**
* @description index Header
* @type {String}
* @default indexHeader = '#'
*/
indexHeader: '#',
/**
* @description Carousel type
* @type {String}
* @default carousel = 'single'
* @example carousel = 'single' | 'page'
*/
carousel: 'single',
/**
* @description Pause scroll when mouse hovered
* @type {Boolean}
* @default hoverPause = true
* @example hoverPause = true | false
*/
hoverPause: true,
};
function calcHeaderData({ header, index, indexHeader }) {
if (!header.length) {
return [];
}
header = [...header];
if (index) header.unshift(indexHeader);
return header;
}
function calcRows({
data, index, headerBGC, rowNum,
}) {
if (index) {
data = data.map((row, i) => {
row = [...row];
const indexTag = `<span class="index" style="background-color: ${headerBGC};">${i
+ 1}</span>`;
row.unshift(indexTag);
return row;
});
}
data = data.map((ceils, i) => ({ ceils, rowIndex: i }));
const rowLength = data.length;
if (rowLength > rowNum && rowLength < 2 * rowNum) {
data = [...data, ...data];
}
return data.map((d, i) => ({ ...d, scroll: i }));
}
function calcAligns(mergedConfig, header) {
const columnNum = header.length;
const aligns = new Array(columnNum).fill('left');
const { align } = mergedConfig;
return deepMerge(aligns, align);
}
const ScrollBoard = forwardRef(({
onClick, config = {}, className, style, onMouseOver,
}, ref) => {
const { width, height, domRef } = useAutoResize(ref);
const [state, setState] = useState({
mergedConfig: null,
header: [],
rows: [],
rowsShow: [],
widths: [],
heights: [],
aligns: [],
});
const {
mergedConfig, header, rows, widths, heights, aligns, rowsShow,
} = state;
const stateRef = useRef({
...state,
rowsData: [],
avgHeight: 0,
animationIndex: 0,
});
Object.assign(stateRef.current, state);
function onResize() {
if (!mergedConfig) return;
const widths = calcWidths(mergedConfig, stateRef.current.rowsData);
const heights = calcHeights(mergedConfig, header);
const data = { widths, heights };
Object.assign(stateRef.current, data);
setState((state) => ({ ...state, ...data }));
}
const [init, setInit] = useState(true);
function calcData() {
// const mergedConfig = deepMerge(
// deepClone(defaultConfig, true),
// config || {},
// );
const mergedConfig = {
...defaultConfig,
...config,
};
const header = calcHeaderData(mergedConfig);
const rows = calcRows(mergedConfig);
const widths = calcWidths(mergedConfig, stateRef.current.rowsData);
const heights = calcHeights(mergedConfig, header);
const aligns = calcAligns(mergedConfig, header);
const data = {
mergedConfig,
header,
rows,
widths,
aligns,
heights: init ? heights : state.heights.concat(heights),
rowsShow: init ? rows : state.rowsShow,
};
setInit(false);
Object.assign(stateRef.current, data, {
rowsData: rows,
animationIndex: stateRef.current.animationIndex,
});
setState((state) => ({ ...state, ...data }));
}
function calcWidths({ columnWidth, header }, rowsData) {
const usedWidth = columnWidth.reduce((all, w) => all + w, 0);
let columnNum = 0;
if (rowsData[0]) {
columnNum = rowsData[0].ceils.length;
} else if (header.length) {
columnNum = header.length;
}
const avgWidth = (width - usedWidth) / (columnNum - columnWidth.length);
const widths = new Array(columnNum).fill(avgWidth);
return deepMerge(widths, columnWidth);
}
function calcHeights({ headerHeight, rowNum, data }, header) {
let allHeight = height;
if (header.length) allHeight -= headerHeight;
const avgHeight = allHeight / rowNum;
Object.assign(stateRef.current, { avgHeight });
return new Array(data.length).fill(avgHeight);
}
function* animation(start = false) {
let {
avgHeight,
animationIndex,
mergedConfig: { waitTime, carousel, rowNum },
rowsData,
} = stateRef.current;
const rowLength = rowsData.length;
if (start) yield new Promise((resolve) => setTimeout(resolve, waitTime));
const animationNum = carousel === 'single' ? 1 : rowNum;
let rows = rowsData.slice(animationIndex);
rows.push(...rowsData.slice(0, animationIndex));
rows = rows.slice(0, carousel === 'page' ? rowNum * 2 : rowNum + 1);
const heights = new Array(rowLength).fill(avgHeight);
setState((state) => ({
...state, rows, heights, rowsShow: rows,
}));
yield new Promise((resolve) => setTimeout(resolve, 300));
animationIndex += animationNum;
const back = animationIndex - rowLength;
if (back >= 0) animationIndex = back;
const newHeights = [...heights];
newHeights.splice(0, animationNum, ...new Array(animationNum).fill(0));
Object.assign(stateRef.current, { animationIndex });
setState((state) => ({ ...state, heights: newHeights }));
}
function emitEvent(handle, ri, ci, row, ceil) {
const { ceils, rowIndex } = row;
handle && handle({
row: ceils, ceil, rowIndex, columnIndex: ci,
});
}
function handleHover(enter, ri, ci, row, ceil) {
if (enter) emitEvent(onMouseOver, ri, ci, row, ceil);
if (!mergedConfig.hoverPause) return;
const { pause, resume } = task.current;
enter && pause && resume ? pause() : resume && resume();
}
// updateRows(rows, animationIndex) {
// const { mergedConfig, animationHandler, animation } = this
// this.mergedConfig = {
// ...mergedConfig,
// data: [...rows]
// }
// this.needCalc = true
// if (typeof animationIndex === 'number') this.animationIndex = animationIndex
// if (!animationHandler) animation(true)
// }
const getBackgroundColor = (rowIndex) => mergedConfig[rowIndex % 2 === 0 ? 'evenRowBGC' : 'oddRowBGC'];
const task = useRef({});
useEffect(() => {
calcData();
let start = true;
function* loop() {
while (true) {
yield* animation(start);
start = false;
const { waitTime } = stateRef.current.mergedConfig;
yield new Promise((resolve) => setTimeout(resolve, waitTime - 300));
}
}
const {
mergedConfig: { rowNum },
rows: rowsData,
} = stateRef.current;
const rowLength = rowsData.length;
if (rowNum >= rowLength) {
setState((prestate) => ({
...prestate, rowsShow: state.rows,
}));
return;
}
task.current = co(loop);
return task.current.end;
}, [config, domRef.current]);
useEffect(onResize, [width, height, domRef.current]);
const classNames = useMemo(() => classnames('dv-scroll-board', className), [
className,
]);
return (
<div className={classNames} style={style} ref={domRef}>
{!!header.length && !!mergedConfig && (
<div
className="header"
style={{ backgroundColor: `${mergedConfig.headerBGC}` }}
>
{header.map((headerItem, i) => (
<div
className="header-item"
key={`${headerItem}-${i}`}
style={{
height: `${mergedConfig.headerHeight}px`,
lineHeight: `${mergedConfig.headerHeight}px`,
width: `${widths[i]}px`,
}}
align={aligns[i]}
dangerouslySetInnerHTML={{ __html: headerItem }}
/>
))}
</div>
)}
{!!mergedConfig && (
<div
className="rows"
style={{
height: `${height
- (header.length ? mergedConfig.headerHeight : 0)}px`,
}}
>
{rowsShow.map((row, ri) => (
<div
className="row-item"
key={`${row.toString()}-${row.scroll}`}
style={{
height: `${heights[ri]}px`,
lineHeight: `${heights[ri]}px`,
backgroundColor: `${getBackgroundColor(row.rowIndex)}`,
}}
>
{row.ceils.map((ceil, ci) => {
if (typeof (ceil) === 'string') {
return (
<div
className="ceil"
key={`${ceil}-${ri}-${ci}`}
style={{ width: `${widths[ci]}px` }}
align={aligns[ci]}
dangerouslySetInnerHTML={{ __html: ceil }}
onClick={() => emitEvent(onClick, ri, ci, row, ceil)}
onMouseEnter={() => handleHover(true, ri, ci, row, ceil)}
onMouseLeave={() => handleHover(false)}
/>
);
}
return (
<div
className="ceil"
style={{ width: `${widths[ci]}px` }}
align={aligns[ci]}
key={`${ri}-${ci}`}
onMouseEnter={() => handleHover(true, ri, ci, row, ceil)}
onMouseLeave={() => handleHover(false)}
>
{ceil}
</div>
);
})}
</div>
))}
</div>
)}
</div>
);
});
ScrollBoard.propTypes = {
config: PropTypes.object,
onClick: PropTypes.func,
onMouseOver: PropTypes.func,
className: PropTypes.string,
style: PropTypes.object,
};
export default ScrollBoard;

44
super-screen/client/src/sections/community-safty/components/public/scrollBoard/style.less

@ -0,0 +1,44 @@
.dv-scroll-board {
position: relative;
width: 100%;
height: 100%;
color: #fff;
.text {
padding: 0 10px;
box-sizing: border-box;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.header {
display: flex;
flex-direction: row;
font-size: 15px;
.header-item {
.text;
transition: all 0.3s;
}
}
.rows {
overflow: hidden;
.row-item {
display: flex;
font-size: 14px;
transition: all 0.3s;
}
.ceil {
.text;
}
.index {
border-radius: 3px;
padding: 0px 3px;
}
}
}

35
super-screen/client/src/sections/community-safty/components/public/table-card.js

@ -0,0 +1,35 @@
'use strict'
import React from 'react'
import './index.less'
class Box extends React.Component {
render() {
const { title, height = '100%', children, bodyPaddingTop = 1, titlePaddingTop, margin, overflow } = this.props
const headerbg = {
background: 'url(/assets/images/homePage/bigscreen/headertitlebg.png) no-repeat',
backgroundSize: '100% 100%',
}
return (
<div style={{ height, width: '100%', margin: margin || "0px 0px 28px" }}>
<div style={{
height: height, listStyle: 'none', overflow: overflow || 'hidden',
}}>
<div style={{ height: 42, paddingTop: '4px', wordBreak: 'keep-all', whiteSpace: 'nowrap', width: '100%', ...headerbg, }}>
<span className='card-title'>{title}</span>
</div>
<div style={{
height: 'calc(100% - 42px)',
backgroundImage: 'linear-gradient(180deg, #04377ecc 1%, #001241 100%)',
}}>
{children}
</div>
</div>
</div>
)
}
}
export default Box

31
super-screen/client/src/sections/community-safty/components/special-person.js

@ -0,0 +1,31 @@
import React, { useEffect, useState } from 'react'
import Box from './public/table-card';
import './style.less';
function SpecialPerson(props) {
const data = [
{ name: '刑满释放', number: 447 },
{ name: '社区矫正', number: 447 },
{ name: '吸毒人员', number: 447 },
{ name: '重点青少年', number: 447 },
{ name: '艾滋病人', number: 447 },
]
return <Box title={"特殊人群统计"}>
<div className='_special'>
{
data.map((s, index) => {
return <div className={`_special_item _special_bg${index % 2 == 0 ? 1 : 2}`}>
<span>{s.name}</span>
<span><span className='_number'>{s.number}</span></span>
</div>
})
}
</div>
</Box>
}
export default SpecialPerson;

286
super-screen/client/src/sections/community-safty/components/style.less

@ -0,0 +1,286 @@
@card-height: calc(100% - 42px - 13px); //左右卡片内容高度定义 目前卡片为等高
//基本信息
._basic_info {
padding: 21px 7px 0px 12px;
//第一行
._basic_row1 {
display: flex;
width: 100%;
._item1 {
width: 128px;
height: 125px;
background: url('/assets/images/homePage/communtity/basicimg.png');
background-repeat: no-repeat;
background-size: 100% 100%;
}
._item2 {
width: calc(100% - 128px);
height: 125px;
padding-left: 20px;
._basictitlebg {
background: url('/assets/images/homePage/communtity/basictitlebg.png');
background-repeat: no-repeat;
background-size: 100% 100%;
width: 100%;
height: 17.5px;
display: flex;
flex-direction: row;
justify-content: space-around;
align-items: center;
._basic_title {
font-family: YouSheBiaoTiHei;
font-size: 21px;
color: #FFFFFF;
letter-spacing: 0.74px;
width: 70px;
margin-top: -13px;
}
._basic_sub_title {
font-family: YouSheBiaoTiHei;
font-size: 14px;
color: #C0E2FF;
letter-spacing: 0;
}
}
._basic_text {
display: flex;
flex-direction: row;
justify-content: space-between;
padding-bottom: 14px;
border-bottom: 1px solid #c3e6ff69;
font-size: 14px;
color: #C0E2FF;
margin-top: 14px;
padding-left: 5px;
padding-right: 5px;
._text_number_color {
font-family: D-DIN-Italic;
font-weight: DIN;
font-size: 16px;
color: #FFFFFF;
letter-spacing: 0.5px;
}
}
}
}
//第二行
._basic_row2 {
width: 100%;
display: flex;
font-family: SourceHanSansCN-Medium;
font-weight: 500;
font-size: 13px;
color: #C0E2FF;
letter-spacing: 0;
margin-top: 19px;
background: url('/assets/images/homePage/communtity/basictextbg.png');
background-repeat: no-repeat;
background-size: 100% 100%;
height: 43px;
align-items: center;
._item1 {
width: 50%;
display: flex;
justify-content: space-around;
}
._item2 {
width: calc(50% - 1px);
display: flex;
justify-content: space-around;
}
.basicinterval {
background: url('/assets/images/homePage/communtity/basicinterval.png');
background-repeat: no-repeat;
background-size: 100% 100%;
width: 1px;
height: 19px;
}
._number {
font-family: YouSheBiaoTiHei;
font-size: 16px;
color: #FFFFFF;
letter-spacing: 0;
text-align: right;
}
}
}
//人口动态
._person_trends {
display: flex;
padding: 10px 18px 0px 10px;
height: 100%;
._person_tends_item1 {
width: 123.5px;
height: 100%;
background: url('/assets/images/homePage/communtity/person.png');
background-repeat: no-repeat;
background-size: 100% 100%;
}
._person_tends_item2 {
width: calc(100% - 123.5px);
padding-left: 21px;
padding-top: 30px;
._person_text {
margin-bottom: 10%;
background: url('/assets/images/homePage/communtity/personbg.png');
background-repeat: no-repeat;
background-size: 100% 100%;
width: 100%;
height: 15px;
display: flex;
flex-direction: row;
justify-content: space-around;
align-items: center;
padding-left: 10px;
padding-right: 8px;
font-family: YouSheBiaoTiHei;
font-size: 12px;
color: #C0E2FF;
letter-spacing: 0;
._person_title {
width: 100px;
font-family: YouSheBiaoTiHei;
font-size: 16px;
color: #FFFFFF;
letter-spacing: 0.56px;
margin-top: -11px;
}
._person_number {
width: calc(100% - 150px);
height: 28px;
font-family: D-DIN-Italic;
font-weight: Italic;
font-size: 28px;
color: #24DCF7;
letter-spacing: 0.98px;
margin-top: -37px;
text-align: right;
}
}
}
}
//基础设施
._basic_device {
display: flex;
flex-wrap: wrap;
height: 100%;
align-items: center;
._device_item {
width: 50%;
height: 82px;
display: flex;
._device_img1 {
width: 93.12px;
height: 82px;
background: url('/assets/images/homePage/communtity/smoke.png');
background-repeat: no-repeat;
background-size: 100% 100%;
}
._device_img2 {
width: 93.12px;
height: 82px;
background: url('/assets/images/homePage/communtity/temp.png');
background-repeat: no-repeat;
background-size: 100% 100%;
}
._device_img3 {
width: 93.12px;
height: 82px;
background: url('/assets/images/homePage/communtity/video.png');
background-repeat: no-repeat;
background-size: 100% 100%;
}
._device_img4 {
width: 93.12px;
height: 82px;
background: url('/assets/images/homePage/communtity/lift.png');
background-repeat: no-repeat;
background-size: 100% 100%;
}
._device_text {
color: #ECF7FF;
width: calc(100% - 94px);
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
._device_number {
font-family: D-DIN-Italic;
font-weight: Italic;
font-size: 28px;
color: #29E4FF;
letter-spacing: 0;
}
}
}
}
._special {
height: 100%;
padding-left: 16px;
padding-right: 9px;
._special_item {
height: 19%;
margin-bottom: 0.6%;
display: flex;
font-family: YouSheBiaoTiHei;
font-size: 18px;
color: #ECF7FF;
letter-spacing: 0.4px;
display: flex;
justify-content: space-between;
align-items: center;
padding-right: 3%;
padding-left: 15%;
._number {
font-family: D-DIN-Italic;
font-weight: Italic;
font-size: 26px;
color: #24DCF7;
letter-spacing: 0;
}
}
._special_bg1 {
background: url('/assets/images/homePage/communtity/special1.png');
background-repeat: no-repeat;
background-size: 100% 100%;
}
._special_bg2 {
background: url('/assets/images/homePage/communtity/special2.png');
background-repeat: no-repeat;
background-size: 100% 100%;
}
}

15
super-screen/client/src/sections/community-safty/components/traffic-ranking.js

@ -0,0 +1,15 @@
import React, { useEffect, useState } from 'react'
import Box from './public/table-card';
import './style.less';
function DataTop5(props) {
return <Box title={"小区人流量排名"} bodyPaddingTop={1} >
小区人流量排名
</Box>
}
export default DataTop5;

3
super-screen/client/src/sections/community-safty/components/util.js

@ -0,0 +1,3 @@
export const mathRound = (number) => {
return number ? Math.round(number / 1000) / 10 : 0
}

48
super-screen/client/src/sections/community-safty/containers/gis.js

@ -0,0 +1,48 @@
import React, { useEffect, useState } from 'react';
import { connect } from 'react-redux';
const MAPDOMID = 'fs-amap-container';
let map = null;
let interval = null;
function Map(props) {
const [delay, setDelay] = useState(true)
// 地图初始化
const loadMap = () => {
map = new AMap.Map(MAPDOMID, {
center: [115.89, 28.68],
zoomEnable: true,
dragEnable: true,
viewMode: '3D',
pitch: 30,
labelzIndex: 130,
zoom: 18,
cursor: 'pointer',
mapStyle: 'amap://styles/4eb48d1ef0a024c73376fd2256d0b5a5',
});
map.on('complete', () => {
setTimeout(() => {
setDelay(false)
}, 1000);
});
};
// 初始化GIS 组件销毁清空定时器
useEffect(() => {
loadMap();
}, []);
return (
<>
{delay && <div style={{
width: '100%', height: '100%', left: 0, top: 0, zIndex: 1000, background: '#02152f', position: 'absolute',
display: 'flex', alignItems: 'center', justifyContent: 'center'
}}>
</div>}
<div className="gis" id={MAPDOMID} />
</>
);
}
export default connect()(Map);

77
super-screen/client/src/sections/community-safty/containers/homePage.js

@ -0,0 +1,77 @@
import React, { useEffect, useState } from 'react'
import { connect } from 'react-redux';
import { push } from 'react-router-redux';
import LeftTop from '../components/basic-info'
import LeftMiddle from '../components/population-dynamics'
import LeftBottom from '../components/infrastructure'
import RightTop from '../components/city-safty'
import RightMiddle from '../components/special-person'
import RightBottom from '../components/traffic-ranking'
import Gis from './gis';
import './style.less'
function homePage(props) {
const { dispatch } = props;
const childStyle = { height: '32%', color: '#fff', marginBottom: 17 }
const cardHeight = document.body.clientHeight * 0.896 * 0.32
const cardContentHeight = cardHeight - 42 - 13
return <>
<div className='homepage'>
<div className='_title'>
<div className='_title_text'>
<span>社区安全</span>
<div className='_title_dot'></div>
<span>流动人口</span>
</div>
<div onClick={() => { dispatch(push('/metadataManagement/latestMetadata')) }} className='_exit' >返回平台</div>
</div>
<div className='homepage-left homepage-left-left'>
<div className="list">
<div className='child' style={childStyle}>
<LeftTop />
</div>
<div className='child' style={childStyle}>
<LeftMiddle />
</div>
<div className='child' style={childStyle}>
<LeftBottom cardContentHeight={cardContentHeight} />
</div>
</div>
</div>
<div className='homepage-center'>
<Gis />
</div>
<div className='homepage-left homepage-left-right'>
<div className="list">
<div className='child-right' style={childStyle}>
<RightTop />
</div>
<div className='child-right' style={childStyle}>
<RightMiddle cardContentHeight={cardContentHeight} />
</div>
<div className='child-right' style={childStyle}>
<RightBottom />
</div>
</div>
</div>
</div>
</>
}
function mapStateToProps(state) {
const {
auth, global
} = state;
return {
clientHeight: global.clientHeight,
actions: global.actions,
};
}
export default connect(mapStateToProps)(homePage);

6
super-screen/client/src/sections/community-safty/containers/index.js

@ -0,0 +1,6 @@
'use strict';
import homePage from './homePage';
export default homePage ;

260
super-screen/client/src/sections/community-safty/containers/style.less

@ -0,0 +1,260 @@
.homepage {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
background: url('/assets/images/homePage/communtity/bg.png');
background-repeat: no-repeat;
background-size: 100% 100%;
overflow: hidden;
// display: flex;
// flex-direction: column;
// justify-content: center;
// align-items: center;
padding-top: 5%;
._title_text {
position: absolute;
top: 0%;
width: 100%;
height: 62px;
font-family: YouSheBiaoTiHei;
font-size: 48px;
color: #FFFFFF;
letter-spacing: 12px;
z-index: 300;
display: flex;
align-items: center;
justify-content: center;
._title_dot {
display: inline-block;
width: 8px;
height: 8px;
background-image: linear-gradient(180deg, #FFFFFF 0%, #0d71ef00 100%);
margin-left: 14px;
margin-right: 14px;
border-radius: 4px;
}
}
._exit {
position: absolute;
right: 60px;
top: 38px;
cursor: pointer;
color: #C8F0FF;
display: flex;
width: 102px;
height: 33px;
background: url('/assets/images/homePage/bigscreen/exit.png');
background-repeat: no-repeat;
background-size: 100% 100%;
padding-left: 35px;
align-items: center;
z-index: 400;
}
.homepage-left {
width: 21.8%;
height: 84.6%;
position: absolute;
top: 10.1%;
z-index: 300;
}
.homepage-center {
width: 93.9%;
height: 84%;
position: absolute;
top: 10.4%;
left: 58px;
padding-left: 16px;
padding-right: 16px;
z-index: 200;
._top {
margin-top: 5%;
height: calc(100% - 200px);
background: url('/assets/images/homePage/bigscreen/centerbg.png');
background-repeat: no-repeat;
background-size: 100% 100%;
position: relative;
}
}
.homepage-left-left {
left: 58px;
}
.homepage-left-right {
right: 58px;
}
}
.list {
list-style: none;
height: 100%;
}
.list .child {
box-sizing: border-box;
opacity: 0;
transform: translateX(-300px);
animation: show .5s forwards;
}
.list .child.show {
animation-delay: 0s !important;
}
.list .child.hide {
opacity: 1;
transform: translateX(0);
animation-name: hide;
animation-delay: 0s;
}
/*animation-delay*/
.list .child:not(.hide):nth-child(5n + 1) {
animation-delay: .3s;
}
.list .child:not(.hide):nth-child(5n + 2) {
animation-delay: .6s;
}
.list .child:not(.hide):nth-child(5n + 3) {
animation-delay: .9s;
}
.list .child:not(.hide):nth-child(5n + 4) {
animation-delay: 1.2s;
}
.list .child:not(.hide):nth-child(5n + 5) {
animation-delay: 1.5s;
}
.list .child-right {
box-sizing: border-box;
opacity: 0;
transform: translateX(300px);
animation: show .5s forwards;
}
.list .child-right.show {
animation-delay: 0s !important;
}
.list .child-right.hide {
opacity: 1;
transform: translateX(0);
animation-name: hide;
animation-delay: 0s;
}
/*animation-delay*/
.list .child-right:not(.hide):nth-child(5n + 1) {
animation-delay: .3s;
}
.list .child-right:not(.hide):nth-child(5n + 2) {
animation-delay: .6s;
}
.list .child-right:not(.hide):nth-child(5n + 3) {
animation-delay: .9s;
}
.list .child-right:not(.hide):nth-child(5n + 4) {
animation-delay: 1.2s;
}
.list .child-right:not(.hide):nth-child(5n + 5) {
animation-delay: 1.5s;
}
.list .child-top {
box-sizing: border-box;
opacity: 0;
transform: translateY(300px);
animation: show 1s forwards;
}
.list .child-top.show {
animation-delay: 0s !important;
}
.list .child-top.hide {
opacity: 1;
transform: translateY(0);
animation-name: hide;
animation-delay: 0s;
}
@keyframes show {
to {
opacity: 1;
transform: translateX(0);
}
}
@keyframes hide {
to {
opacity: 0;
transform: translateX(100px);
max-height: 0;
margin: 0;
}
}
.center-card-title {
height: 31px;
font-family: YouSheBiaoTiHei;
font-size: 24px;
color: #FFFFFF;
display: flex;
align-items: center;
margin-top: 5px;
._icon_left {
width: 32px;
height: 17px;
background: url('/assets/images/homePage/bigscreen/center-left.png');
background-repeat: no-repeat;
background-size: 100% 100%;
margin-right: 11px;
margin-left: 10px;
}
._icon_right {
width: 32px;
height: 17px;
background: url('/assets/images/homePage/bigscreen/center-right.png');
background-repeat: no-repeat;
background-size: 100% 100%;
margin-right: 11px;
margin-left: 10px;
}
}
.gis {
position: absolute;
width: 100vw;
height: calc(~"100% - 114px");
left: 0;
top: 114px;
z-index: 0;
display: flex;
justify-content: center;
top: 0;
left: 0;
width: 100%;
height: 100%;
}

15
super-screen/client/src/sections/community-safty/index.js

@ -0,0 +1,15 @@
'use strict';
import reducers from './reducers';
import routes from './routes';
import actions from './actions';
import { getNavItem } from './nav-item';
export default {
key: 'communitysafty',
name: '首页',
reducers: reducers,
routes: routes,
actions: actions,
getNavItem: getNavItem
};

11
super-screen/client/src/sections/community-safty/nav-item.js

@ -0,0 +1,11 @@
import React from 'react';
import { Link } from 'react-router-dom';
import { Menu } from 'antd';
import { HomeOutlined } from '@ant-design/icons';
export function getNavItem(user) {
return (
<Menu.Item key="communitysafty" icon={<HomeOutlined />}>
<Link to="/communitysafty">社区安全</Link>
</Menu.Item>
);
}

5
super-screen/client/src/sections/community-safty/reducers/index.js

@ -0,0 +1,5 @@
'use strict';
export default {
}

13
super-screen/client/src/sections/community-safty/routes.js

@ -0,0 +1,13 @@
'use strict';
import homePage from './containers/index';
export default [{
type: 'outer',
route: {
path: '/communitysafty',
key: 'communitysafty',
breadcrumb: '数据监控平台',
// 不设置 component 则面包屑禁止跳转
component: homePage
}
}];

0
super-screen/client/src/sections/community-safty/style.less

74
super-screen/client/src/sections/homePage/containers/homePage copy.js

@ -0,0 +1,74 @@
import React, { useEffect, useState } from 'react'
import { connect } from 'react-redux';
import { push } from 'react-router-redux';
import AccessData from '../components/accessData'
import AlarmList from '../components/alarmList'
import DataShare from '../components/dataShare'
import DataTop5 from '../components/dataTop5'
import HotspotData from '../components/hotspotData'
import NodeResource from '../components/nodeResource'
import AbnormalMonitoring from '../components/abnormalMonitoring'
import CenterTop from '../components/centerTop'
import './style.less'
function homePage(props) {
const { dispatch } = props;
const childStyle = { height: '32%', color: '#fff', marginBottom: 17 }
const cardHeight = document.body.clientHeight * 0.896 * 0.32
const cardContentHeight = cardHeight - 42 - 13
return <div className='homepage'>
<div className='_title'>
<div onClick={() => { dispatch(push('/metadataManagement/latestMetadata')) }} className='_exit' ><div className='_icon' />进入后台</div>
</div>
<div className='homepage-left homepage-left-left'>
<div className="list">
<div className='child' style={childStyle}>
<AccessData />
</div>
<div className='child' style={childStyle}>
<NodeResource />
</div>
<div className='child' style={childStyle}>
<AlarmList cardContentHeight={cardContentHeight} />
</div>
</div>
</div>
<div className='homepage-center'>
<CenterTop />
<div className="list">
<div className='child-top'>
<AbnormalMonitoring />
</div>
</div>
</div>
<div className='homepage-left homepage-left-right'>
<div className="list">
<div className='child-right' style={childStyle}>
<DataShare />
</div>
<div className='child-right' style={childStyle}>
<DataTop5 cardContentHeight={cardContentHeight} />
</div>
<div className='child-right' style={childStyle}>
<HotspotData />
</div>
</div>
</div>
</div>
}
function mapStateToProps(state) {
const {
auth, global
} = state;
return {
clientHeight: global.clientHeight,
actions: global.actions,
};
}
export default connect(mapStateToProps)(homePage);

50
super-screen/client/src/sections/homePage/containers/homePage.js

@ -1,14 +1,6 @@
import React, { useEffect, useState } from 'react'
import { connect } from 'react-redux';
import { push } from 'react-router-redux';
import AccessData from '../components/accessData'
import AlarmList from '../components/alarmList'
import DataShare from '../components/dataShare'
import DataTop5 from '../components/dataTop5'
import HotspotData from '../components/hotspotData'
import NodeResource from '../components/nodeResource'
import AbnormalMonitoring from '../components/abnormalMonitoring'
import CenterTop from '../components/centerTop'
import './style.less'
function homePage(props) {
@ -17,42 +9,14 @@ function homePage(props) {
const cardHeight = document.body.clientHeight * 0.896 * 0.32
const cardContentHeight = cardHeight - 42 - 13
return <div className='homepage'>
<div className='_title'>
<div onClick={() => { dispatch(push('/metadataManagement/latestMetadata')) }} className='_exit' ><div className='_icon' />进入后台</div>
<div className='_enter_title'></div>
<div className='_enter_row1'>
<div className='_row1_item'></div>
</div>
<div className='homepage-left homepage-left-left'>
<div className="list">
<div className='child' style={childStyle}>
<AccessData />
</div>
<div className='child' style={childStyle}>
<NodeResource />
</div>
<div className='child' style={childStyle}>
<AlarmList cardContentHeight={cardContentHeight} />
</div>
</div>
</div>
<div className='homepage-center'>
<CenterTop />
<div className="list">
<div className='child-top'>
<AbnormalMonitoring />
</div>
</div>
</div>
<div className='homepage-left homepage-left-right'>
<div className="list">
<div className='child-right' style={childStyle}>
<DataShare />
</div>
<div className='child-right' style={childStyle}>
<DataTop5 cardContentHeight={cardContentHeight} />
</div>
<div className='child-right' style={childStyle}>
<HotspotData />
</div>
</div>
<div className='_enter_row2'>
<div className='_row2_item1' onClick={() => { dispatch(push('/waterprevention')) }}></div>
<div className='_row2_item2' onClick={() => { dispatch(push('/communitysafty')) }}></div>
<div className='_row2_item3'></div>
</div>
</div>

102
super-screen/client/src/sections/homePage/containers/style.less

@ -4,10 +4,110 @@
position: absolute;
top: 0;
left: 0;
background: url('/assets/images/homePage/bigscreen/bg.png');
background: url('/assets/images/homePage/enter/bg.png');
background-repeat: no-repeat;
background-size: 100% 100%;
overflow: hidden;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding-top: 5%;
._enter_row1 {
height: 302px;
._row1_item {
width: 1434px;
height: 241px;
// opacity: 0.8;
background: url('/assets/images/homePage/enter/row1.png');
background-repeat: no-repeat;
background-size: 100% 100%;
cursor: pointer;
}
._row1_item:hover {
width: 1434px;
height: 302.6px;
background: url('/assets/images/homePage/enter/row1-select.png');
background-repeat: no-repeat;
background-size: 100% 100%;
cursor: pointer;
}
}
._enter_row2 {
height: 427px;
display: flex;
width: 100%;
padding-left: 4%;
._row2_item1 {
width: 454px;
height: 371px;
// opacity: 0.8;
background: url('/assets/images/homePage/enter/row2-1.png');
background-repeat: no-repeat;
background-size: 100% 100%;
cursor: pointer;
margin-left: 60px;
}
._row2_item1:hover {
background: url('/assets/images/homePage/enter/row2-1-select.png');
background-repeat: no-repeat;
background-size: 100% 100%;
cursor: pointer;
}
._row2_item2 {
margin-left: 60px;
width: 454px;
height: 371px;
// opacity: 0.8;
background: url('/assets/images/homePage/enter/row2-2.png');
background-repeat: no-repeat;
background-size: 100% 100%;
cursor: pointer;
}
._row2_item2:hover {
background: url('/assets/images/homePage/enter/row2-2-select.png');
background-repeat: no-repeat;
background-size: 100% 100%;
cursor: pointer;
}
._row2_item3 {
margin-left: 60px;
width: 454px;
height: 371px;
// opacity: 0.8;
background: url('/assets/images/homePage/enter/row2-3.png');
background-repeat: no-repeat;
background-size: 100% 100%;
cursor: pointer;
}
._row2_item3:hover {
background: url('/assets/images/homePage/enter/row2-3-select.png');
background-repeat: no-repeat;
background-size: 100% 100%;
cursor: pointer;
}
}
._enter_title {
position: absolute;
top: 4%;
left: 3%;
width: 575.35px;
height: 78px;
background: url('/assets/images/homePage/enter/title.png');
background-repeat: no-repeat;
background-size: 100% 100%;
}
._title {
width: 100%;

15
super-screen/client/src/sections/water-prevention/actions/example.js

@ -0,0 +1,15 @@
'use strict';
import { basicAction } from '@peace/utils'
import { ApiTable } from '$utils'
// export function getMembers(orgId) {
// return dispatch => basicAction({
// type: 'get',
// dispatch: dispatch,
// actionType: 'GET_MEMBERS',
// url: `${ApiTable.getEnterprisesMembers.replace('{enterpriseId}', orgId)}`,
// msg: { error: '获取用户列表失败' },
// reducer: { name: 'members' }
// });
// }

7
super-screen/client/src/sections/water-prevention/actions/index.js

@ -0,0 +1,7 @@
'use strict';
import * as example from './example'
export default {
...example,
}

49
super-screen/client/src/sections/water-prevention/components/abnormalMonitoring.js

@ -0,0 +1,49 @@
import React, { useEffect, useState } from 'react'
import CarouselList from './public/carousel-list';
import { Tooltip } from 'antd';
import { ApiTable, useFsRequest } from '$utils';
import moment from 'moment';
function AbnormalMonitoring(props) {
const { data: logs = {} } = useFsRequest({
url: ApiTable.getLogs,
query: {
logState: false,
startTime: moment().subtract(7, 'days').format('YYYY-MM-DD HH:mm:ss'),
endTime: moment().format('YYYY-MM-DD HH:mm:ss')
},
pollingInterval: 1000 * 60
});
const dataSource = logs?.rows ? logs?.rows?.map(s => {
return [
<div style={{ color: '#fff' }}>
<Tooltip placement="top" title={s?.acquisitionTask?.taskName}>
{s?.acquisitionTask?.taskName?.length > 20 ? s?.acquisitionTask?.taskNamesubstring(0, 20) + '...' : s?.acquisitionTask?.taskName}
</Tooltip>
</div>,
moment(s?.startTime).format('YYYY-MM-DD HH:mm:ss'),
moment(s?.endTime).valueOf() - moment(s?.startTime).valueOf() + '毫秒',
<div style={{ color: 'rgba(245, 27, 27, 1)' }}>
<Tooltip placement="top" title={s?.details}>
{s?.details?.length > 20 ? s?.details.substring(0, 20) + '...' : s?.details}
</Tooltip>
</div>
]
}) : []
return <div style={{ height: 149, border: '1px solid #50c9d74d', backgroundImage: 'linear-gradient(180deg, rgba(0, 32, 74, 0) 3%, rgba(80, 201, 247, 0.1) 100%)' }}>
<div className='center-card-title' style={{ marginBottom: 6 }}><div className='_icon_left' />异常监控<div className='_icon_right' /></div>
<CarouselList
header={['任务名称', '采集时间', '耗时', '异常日志']}
data={dataSource}
rowNum={2}
height={100}
multiellipsis
marginTop={-50}
/>
</div>
}
export default AbnormalMonitoring;

36
super-screen/client/src/sections/water-prevention/components/accessData.js

@ -0,0 +1,36 @@
import React from 'react'
import Box from './public/table-card';
import { useFsRequest } from '$utils';
import { mathRound } from './util'
function AccessData() {
const { data: accessdata = [] } = useFsRequest({
url: 'homepage/accessdata',
pollingInterval: 1000 * 60,
cacheKey: 'accessdata',
});
const renderBody = () => {
return <div className='access_data'>
<div className='_img'></div>
<div className='data_unit'>
数据单位<div className='data_number'>{!accessdata?.projects ? '-' : accessdata?.projects?.split(',')?.length}</div>
</div>
<div className='data_today'>
今日数据<div className='data_number'>{!accessdata?.res?.stat?.today ? '-' : accessdata?.res?.stat?.today > 1000 ? mathRound(accessdata?.res?.stat?.today) : accessdata?.res?.stat?.today}</div>{accessdata?.res?.stat?.today > 1000 ? '' : ''}
</div>
<div className='data_total'>
数据总量<div className='data_number'>{accessdata?.res?.stat?.datas ? Math.round(accessdata?.res?.stat?.datas / 10000) : '-'}</div>
</div>
</div>
}
return <Box title={"接入数据统计"} >
{renderBody()}
</Box>
}
export default AccessData;

52
super-screen/client/src/sections/water-prevention/components/alarmList.js

@ -0,0 +1,52 @@
import React from 'react'
import Box from './public/table-card';
import CarouselList from './public/carousel-list';
import { Tooltip } from 'antd';
import moment from 'moment';
import NoData from './public/noData';
import { useFsRequest } from '$utils';
function AlarmList(props) {
const { cardContentHeight } = props;
const { data: alarms = [] } = useFsRequest({
url: 'homepage/alarms',
pollingInterval: 1000 * 60,
cacheKey: 'alarms',
});
const data = alarms.map(s => {
return [
s.content,
s.level == 1 ? '一级' : s.level == 2 ? '二级' : s.level == 3 ? '三级' : '四级',
moment(s.time).format('YYYY-MM-DD HH:mm:ss')
]
})
const renderBody = () => {
return <CarouselList
header={['预警内容', '预警等级', '预警时间']}
data={data?.map(s => {
return [
<Tooltip placement="top" title={s[0]}>
{s[0].length > 20 ? s[0]?.substring(0, 20) + '...' : s[0]}
</Tooltip>,
<div style={{ color: s[1] == '一级' ? 'rgba(245, 27, 27, 1)' : s[1] == '二级' ? '#FF7900' : s[1] == '三级' ? '#FFCD00' : '#00DA9F' }}>{s[1]}</div>,
s[2]
]
})}
rowNum={6}
height={cardContentHeight}
multiellipsis
columnWidth={[180, 80, 150]}
/>
}
return <Box title={"预警列表"}>
{alarms?.length > 0 ? renderBody() : <NoData />}
</Box>
}
export default AlarmList;

19
super-screen/client/src/sections/water-prevention/components/centerTop.js

@ -0,0 +1,19 @@
import React from 'react'
import './style.less'
function CenterTop(props) {
return <div className='_top'>
<div className='center_top_data'>
<div className='_center_card1'>共享交换</div>
<div className='_center_card2'>数据监控</div>
<div className='_center_card3'>数据治理</div>
<div className='_center_card4'>数据采集</div>
</div>
</div>
}
export default CenterTop;

54
super-screen/client/src/sections/water-prevention/components/dataShare.js

@ -0,0 +1,54 @@
import React from 'react'
import Box from './public/table-card';
import { useFsRequest } from '$utils';
import { mathRound } from './util';
function DataShare(props) {
const { data: dataTotal = {} } = useFsRequest({
url: 'homepage/datatotal/top5',
pollingInterval: 1000 * 60,
cacheKey: 'datatotal',
});
const { data: restfulInfo = {} } = useFsRequest({
url: 'homepage/restful/info',
pollingInterval: 1000 * 60,
cacheKey: 'restfulInfo',
});
const renderItem = (s) => {
return <div className='_item_content'>
<div className={'_item_icon' + s.key} />
<div className='_item_text'>
{s.title}
<div className='number_container'>
<span className='_number'>{s.data}</span>{s.unit}
</div>
</div>
</div>
}
const leftData = [
{ key: '1', data: mathRound(dataTotal?.total), unit: '万条', title: '共享库数据总量' },
{ key: '2', data: restfulInfo?.total, unit: '次', title: '访问接口总次数' },
{ key: '3', data: restfulInfo?.totalUser, unit: '个', title: '访问接口用户总数' }]
const rightData = [
{ key: '2', data: restfulInfo?.todayTotal, unit: '次', title: '接口访问次数' },
{ key: '3', data: restfulInfo?.todayUser, unit: '个', title: '访问接口用户总数' }]
return <Box title={"数据共享"} >
<div className='data_share'>
<div className='_left_content'>
{leftData.map(s => renderItem(s))}
</div>
<div className='_right_content'>
<div className='_today_text'>今日</div>
{rightData.map(s => renderItem(s))}
</div>
</div>
</Box>
}
export default DataShare;

262
super-screen/client/src/sections/water-prevention/components/dataTop5.js

@ -0,0 +1,262 @@
import React, { useEffect, useState } from 'react'
import Box from './public/table-card';
import ReactEcharts from 'echarts-for-react';
import './style.less';
import { useFsRequest } from '$utils';
import { mathRound } from './util';
import NoData from './public/noData';
function DataTop5(props) {
const { cardContentHeight } = props;
const { data: dataTotal = {} } = useFsRequest({
url: 'homepage/datatotal/top5',
pollingInterval: 1000 * 60,
cacheKey: 'datatotal',
});
const renderBody = () => {
let chartData = dataTotal?.top5?.map(x => {
return {
name: x?.dataSource?.resourceCatalog?.name,
value: mathRound(x.dbRecordCount),
}
}) || []
let options = {
xAxis: {
splitLine: {
show: false,
},
axisLabel: {
show: false,
},
axisTick: {
show: false,
},
splitArea: { show: false },
axisLine: {
show: false,
},
},
tooltip: {
confine: true,
trigger: 'axis',
axisPointer: {
type: 'shadow',
},
backgroundColor: 'rgba(13,30,44, 0.7)',
borderColor: 'rgba(3, 65, 118, 0.8)',
textStyle: {
color: '#fff',
},
formatter: function (params) {
var name = params[0].name
if (name.length > 20) {
name = name.replace(/(.{20})/g, '$1<br>') // 每 30 个字符添加一个换行符
}
var content = name
return content + ' : <b>' + params[0].value + '</b>万条'
}
},
grid: {
top: 13,
bottom: -10,
left: '5%',
},
yAxis: {
inverse: true,
axisLine: {
show: false,
},
axisTick: {
show: false,
},
axisLabel: {
textStyle: {
color: '#fff',
padding: [-5, 0, 35, 18],
},
formatter(value, index) {
let str = '', num = 'TOP' + (index + 1)
let valueHandle = value.length > 10 ? value.substring(0, 10) + '...' : value
if (index === 0) {
str = '{a| ' + num + '}{title| ' + valueHandle + '}'
} else if (index === 1) {
str = '{b| ' + num + '}{title| ' + valueHandle + '}'
} else if (index === 2) {
str = '{c| ' + num + '}{title| ' + valueHandle + '}'
} else {
str = '{d| ' + num + '}{title| ' + valueHandle + '}'
}
return str
},
rich: {
a: {
borderColor: '#EE6F7C',
borderWidth: 1,
borderRadius: [0, 10, 10, 0],
padding: [3.5, 10, 1, -13],
backgroundColor: 'rgba(238, 111, 124, 0.8)',
},
b: {
borderColor: '#FFCF5F',
borderWidth: 1,
borderRadius: [0, 10, 10, 0],
padding: [3.5, 10, 1, -13],
backgroundColor: 'rgba(255, 207, 95, 0.7)',
},
c: {
borderColor: '#00E8FF',
borderWidth: 1,
borderRadius: [0, 10, 10, 0],
padding: [3.5, 10, 1, -13],
backgroundColor: 'rgba(0, 232, 255, 0.7)',
},
d: {
borderColor: '#1A90FF',
borderWidth: 1,
borderRadius: [0, 10, 10, 0],
padding: [3.5, 10, 1, -13],
backgroundColor: 'rgba(26, 144, 255, 0.7)',
},
title: {
padding: [0, 0, 0, 3],
},
},
align: 'left',
},
data: chartData.map((item) => item.name),
},
series: [
{
type: 'pictorialBar',
symbol: 'rect',
symbolRotate: 30,
symbolRepeat: 'fixed',
symbolClip: true,
symbolOffset: [0, -1.5],
symbolSize: [2, 12],
symbolMargin: '3',
itemStyle: {
normal: {
color: '#000726',
},
},
label: {
show: true,
color: '#C8F0FF',
fontFamily: 'Bebas',
fontSize: 12,
offset: [-9, 1],
position: 'right',
formatter(params) {
let result = ''
switch (params.dataIndex) {
case 0:
result = '{img|}{index0|' + params.value + '}{unit|}'
break
case 1:
result = '{img|}{index1|' + params.value + '}{unit|}'
break
case 2:
result = '{img|}{index2|' + params.value + '}{unit|}'
break
default:
result = '{img|}{index3|' + params.value + '}{unit|}'
break
}
return result
},
rich: {
img: {
height: 18,
width: 20,
// backgroundColor: { image: arrow },这个图片自己切,这里上传不了(加了一个尾巴的形状)
},
unit: {
color: '#C8F0FF',
fontSize: 11,
},
index0: {
color: '#FFF',
fontFamily: 'Bebas',
padding: [-2, 2, 0, 0],
fontWeight: 'bold',
fontSize: 16,
},
index1: {
color: '#FFF',
fontFamily: 'Bebas',
padding: [-2, 2, 0, 0],
fontWeight: 'bold',
fontSize: 16,
},
index2: {
color: '#FFF',
fontFamily: 'Bebas',
padding: [-2, 2, 0, 0],
fontWeight: 'bold',
fontSize: 16,
},
index3: {
color: '#FFF',
fontFamily: 'Bebas',
padding: [-2, 2, 0, 0],
fontWeight: 'bold',
fontSize: 16,
},
},
},
symbolBoundingData: Math.max(...chartData.map((item) => item.value)) * 1.3,
data: chartData.map((item) => item.value),
z: 2,
},
{
type: 'bar',
barWidth: 10,
data: chartData.map((item) => item.value),
itemStyle: {
normal: {
color: '#54DEFA',
},
},
z: 1,
},
{
type: 'bar',
barGap: '-125%', // 设置外框粗细
data: chartData.map((items) => Math.max(...chartData.map((item) => item.value)) * 1.3),
barWidth: 15,
itemStyle: {
color: 'none',
borderColor: '#979797',
},
z: 0,
},
],
};
return <ReactEcharts
option={options}
notMerge
lazyUpdate
style={{ height: cardContentHeight }}
/>
}
return <Box title={"数据量TOP5单位"} bodyPaddingTop={1} >
{
dataTotal?.top5?.length > 0 ?
<>
<div className='data_top5_unit'>数据量万条</div>
{renderBody()}
</>
: <NoData />
}
</Box>
}
export default DataTop5;

42
super-screen/client/src/sections/water-prevention/components/hotspotData.js

@ -0,0 +1,42 @@
import React, { useEffect, useState } from 'react'
import Box from './public/table-card';
import NoData from './public/noData';
import './style.less';
import { ApiTable, useFsRequest } from '$utils';
function HotspotData(props) {
const { data: restfulInfo = {} } = useFsRequest({
url: 'homepage/restful/info',
pollingInterval: 1000 * 60,
cacheKey: 'restfulInfo',
});
const top3 = restfulInfo?.top3
return <Box title={"热点数据"} bodyPaddingTop={25} >
{top3?.length > 0 ?
<div className='hotspot_data_container'>
<div className='_img'></div>
<div className='_top1'>
<span className='hotspot_title' title={top3[0].name}>{top3[0].name?.length > 8 ? top3[0].name.substring(0, 8) + '...' : top3[0].name}</span>
<div className='hotspot_data_number'>{top3[0].count}</div>
</div>
<div className='_top2'>
{top3?.length > 2 && <>
<span className='hotspot_title' title={top3[2].name}>{top3[2].name?.length > 8 ? top3[2].name.substring(0, 8) + '...' : top3[2].name}</span>
<div className='hotspot_data_number'>{top3[2].count}</div>
</>}
</div>
<div className='_top3'>
{top3?.length > 1 && <>
<span className='hotspot_title' title={top3[1].name}>{top3[1].name?.length > 8 ? top3[1].name.substring(0, 8) + '...' : top3[1].name}</span>
<div className='hotspot_data_number'>{top3[1].count}</div>
</>}
</div>
</div> : <NoData />
}
</Box>
}
export default HotspotData;

39
super-screen/client/src/sections/water-prevention/components/nodeResource.js

@ -0,0 +1,39 @@
import React, { useEffect, useState } from 'react'
import Box from './public/table-card';
import { ApiTable, useFsRequest } from '$utils';
import './style.less';
function NodeResource(props) {
const { data: cluters = {} } = useFsRequest({
url: 'homepage/datatotal/cluters',
pollingInterval: 1000 * 20,
});
const renderBody = () => {
return <div className='node-resource-container'>
<div className='_item'>
<div className='_noderesource_data'>{cluters?.disk}<span className='_percent'>%</span></div>
<div className='_noderesource_title'>硬盘</div>
<div className='disk_icon' />
</div>
<div className='_item'>
<div className='_noderesource_data'>{cluters?.memory}<span className='_percent'>%</span></div>
<div className='_noderesource_title'>内存</div>
<div className='memory_icon' />
</div>
<div className='_item'>
<div className='_noderesource_data'>{cluters?.cpu}<span className='_percent'>%</span></div>
<div className='_noderesource_title'>CPU</div>
<div className='cpu_icon' />
</div>
</div>
}
return <Box title={"节点资源"} >
{renderBody()}
</Box>
}
export default NodeResource;

33
super-screen/client/src/sections/water-prevention/components/public/carousel-list.js

@ -0,0 +1,33 @@
/* 轮播列表组件 */
import React from 'react';
import ScrollBoard from './scrollBoard';
import NoData from './noData';
import './index.less';
function CarouselList(props) {
const {
header = [], data = [], rowNum = 4, height, columnWidth, multiellipsis, waitTime = 2000, marginTop, ...restProps
} = props;
const config = {
header,
rowNum,
headerBGC: 'rgba(81, 200, 247, 0.2)',
oddRowBGC: 'transparent',
evenRowBGC: 'transparent',
headerHeight: 30,
data,
waitTime,
columnWidth: columnWidth || [],
};
return data.length > 0 ? (
<ScrollBoard
config={config}
style={{ height }}
className={multiellipsis ? 'scroll-board-multi' : 'scroll-board'}
{...restProps}
/>
) : <NoData marginTop={marginTop || 0} />;
}
export default CarouselList;

80
super-screen/client/src/sections/water-prevention/components/public/index.less

@ -0,0 +1,80 @@
.opcityBackground {
background-color: rgba(8, 27, 55, 0.6);
}
.card-title {
// background: linear-gradient(to bottom, #fafafb, #92cbff);
// background-clip: border-box;
// -webkit-background-clip: text;
color: #fff;
font-size: 22px;
font-family: YouSheBiaoTiHei;
padding-left: 20px;
// font-weight: 600;
}
/* 滚动列表 */
.scroll-board {
width: 533px;
height: 220px;
margin-top: 10px;
margin-left: 6px;
.header {
height: 30px;
border-top: 1px solid #0047ba;
border-bottom: 1px solid #0047ba;
.header-item {
// background: rgba(12, 49, 110, 0.3);
margin-right: 10px;
}
}
.rows {
.row-item {
font-size: 16px;
}
.row-item:hover {
background: linear-gradient(270deg, rgba(17, 183, 247, 0) 0%, rgba(17, 183, 247, 0.85) 100%);
color: #9ac8fc;
}
}
}
.scroll-board-multi {
padding: 5px 0px 5px;
color: rgba(204, 228, 255, 1) !important;
.header {
display: flex;
flex-direction: row;
font-size: 12px !important;
color: rgba(204, 228, 255, 1) !important;
// border-bottom: 1px solid #124C79 !important;
}
.rows {
color: rgba(204, 228, 255, 1) !important;
.row-item {
border-bottom: 1px solid #124C79 !important;
}
.row-item:hover {
background: linear-gradient(270deg, rgba(17, 183, 247, 0) 0%, rgba(17, 183, 247, 0.85) 100%);
color: #9ac8fc;
}
}
}
._sorrow {
display: inline-block;
width: 15px;
height: 15px;
background: url('/assets/images/homePage/bigscreen/sorrow.png');
background-repeat: no-repeat;
background-size: 100% 100%;
margin-left: 13px;
}

18
super-screen/client/src/sections/water-prevention/components/public/noData.js

@ -0,0 +1,18 @@
/* 公共模块暂无数据组件 */
import React from 'react';
import { Empty } from 'antd';
function NoData({ height = 180, marginTop = 0 }) {
return (
<Empty
image="/assets/images/homePage/bigscreen/empty.png"
imageStyle={{
height,
marginTop
}}
description={false}
/>
);
}
export default NoData;

469
super-screen/client/src/sections/water-prevention/components/public/scrollBoard/index.js

@ -0,0 +1,469 @@
import React, {
useEffect, useState, useRef, useMemo, forwardRef,
} from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { deepMerge } from '@jiaminghi/charts/lib/util/index';
import { deepClone } from '@jiaminghi/c-render/lib/plugin/util';
import { useAutoResize, co } from '@jiaminghi/data-view-react';
import './style.less';
const defaultConfig = {
/**
* @description Board header
* @type {Array<String>}
* @default header = []
* @example header = ['column1', 'column2', 'column3']
*/
header: [],
/**
* @description Board data
* @type {Array<Array>}
* @default data = []
*/
data: [],
/**
* @description Row num
* @type {Number}
* @default rowNum = 5
*/
rowNum: 5,
/**
* @description Header background color
* @type {String}
* @default headerBGC = '#00BAFF'
*/
headerBGC: '#00BAFF',
/**
* @description Odd row background color
* @type {String}
* @default oddRowBGC = '#003B51'
*/
oddRowBGC: '#003B51',
/**
* @description Even row background color
* @type {String}
* @default evenRowBGC = '#003B51'
*/
evenRowBGC: '#0A2732',
/**
* @description Scroll wait time
* @type {Number}
* @default waitTime = 2000
*/
waitTime: 2000,
/**
* @description Header height
* @type {Number}
* @default headerHeight = 35
*/
headerHeight: 35,
/**
* @description Column width
* @type {Array<Number>}
* @default columnWidth = []
*/
columnWidth: [],
/**
* @description Column align
* @type {Array<String>}
* @default align = []
* @example align = ['left', 'center', 'right']
*/
align: [],
/**
* @description Show index
* @type {Boolean}
* @default index = false
*/
index: false,
/**
* @description index Header
* @type {String}
* @default indexHeader = '#'
*/
indexHeader: '#',
/**
* @description Carousel type
* @type {String}
* @default carousel = 'single'
* @example carousel = 'single' | 'page'
*/
carousel: 'single',
/**
* @description Pause scroll when mouse hovered
* @type {Boolean}
* @default hoverPause = true
* @example hoverPause = true | false
*/
hoverPause: true,
};
function calcHeaderData({ header, index, indexHeader }) {
if (!header.length) {
return [];
}
header = [...header];
if (index) header.unshift(indexHeader);
return header;
}
function calcRows({
data, index, headerBGC, rowNum,
}) {
if (index) {
data = data.map((row, i) => {
row = [...row];
const indexTag = `<span class="index" style="background-color: ${headerBGC};">${i
+ 1}</span>`;
row.unshift(indexTag);
return row;
});
}
data = data.map((ceils, i) => ({ ceils, rowIndex: i }));
const rowLength = data.length;
if (rowLength > rowNum && rowLength < 2 * rowNum) {
data = [...data, ...data];
}
return data.map((d, i) => ({ ...d, scroll: i }));
}
function calcAligns(mergedConfig, header) {
const columnNum = header.length;
const aligns = new Array(columnNum).fill('left');
const { align } = mergedConfig;
return deepMerge(aligns, align);
}
const ScrollBoard = forwardRef(({
onClick, config = {}, className, style, onMouseOver,
}, ref) => {
const { width, height, domRef } = useAutoResize(ref);
const [state, setState] = useState({
mergedConfig: null,
header: [],
rows: [],
rowsShow: [],
widths: [],
heights: [],
aligns: [],
});
const {
mergedConfig, header, rows, widths, heights, aligns, rowsShow,
} = state;
const stateRef = useRef({
...state,
rowsData: [],
avgHeight: 0,
animationIndex: 0,
});
Object.assign(stateRef.current, state);
function onResize() {
if (!mergedConfig) return;
const widths = calcWidths(mergedConfig, stateRef.current.rowsData);
const heights = calcHeights(mergedConfig, header);
const data = { widths, heights };
Object.assign(stateRef.current, data);
setState((state) => ({ ...state, ...data }));
}
const [init, setInit] = useState(true);
function calcData() {
// const mergedConfig = deepMerge(
// deepClone(defaultConfig, true),
// config || {},
// );
const mergedConfig = {
...defaultConfig,
...config,
};
const header = calcHeaderData(mergedConfig);
const rows = calcRows(mergedConfig);
const widths = calcWidths(mergedConfig, stateRef.current.rowsData);
const heights = calcHeights(mergedConfig, header);
const aligns = calcAligns(mergedConfig, header);
const data = {
mergedConfig,
header,
rows,
widths,
aligns,
heights: init ? heights : state.heights.concat(heights),
rowsShow: init ? rows : state.rowsShow,
};
setInit(false);
Object.assign(stateRef.current, data, {
rowsData: rows,
animationIndex: stateRef.current.animationIndex,
});
setState((state) => ({ ...state, ...data }));
}
function calcWidths({ columnWidth, header }, rowsData) {
const usedWidth = columnWidth.reduce((all, w) => all + w, 0);
let columnNum = 0;
if (rowsData[0]) {
columnNum = rowsData[0].ceils.length;
} else if (header.length) {
columnNum = header.length;
}
const avgWidth = (width - usedWidth) / (columnNum - columnWidth.length);
const widths = new Array(columnNum).fill(avgWidth);
return deepMerge(widths, columnWidth);
}
function calcHeights({ headerHeight, rowNum, data }, header) {
let allHeight = height;
if (header.length) allHeight -= headerHeight;
const avgHeight = allHeight / rowNum;
Object.assign(stateRef.current, { avgHeight });
return new Array(data.length).fill(avgHeight);
}
function* animation(start = false) {
let {
avgHeight,
animationIndex,
mergedConfig: { waitTime, carousel, rowNum },
rowsData,
} = stateRef.current;
const rowLength = rowsData.length;
if (start) yield new Promise((resolve) => setTimeout(resolve, waitTime));
const animationNum = carousel === 'single' ? 1 : rowNum;
let rows = rowsData.slice(animationIndex);
rows.push(...rowsData.slice(0, animationIndex));
rows = rows.slice(0, carousel === 'page' ? rowNum * 2 : rowNum + 1);
const heights = new Array(rowLength).fill(avgHeight);
setState((state) => ({
...state, rows, heights, rowsShow: rows,
}));
yield new Promise((resolve) => setTimeout(resolve, 300));
animationIndex += animationNum;
const back = animationIndex - rowLength;
if (back >= 0) animationIndex = back;
const newHeights = [...heights];
newHeights.splice(0, animationNum, ...new Array(animationNum).fill(0));
Object.assign(stateRef.current, { animationIndex });
setState((state) => ({ ...state, heights: newHeights }));
}
function emitEvent(handle, ri, ci, row, ceil) {
const { ceils, rowIndex } = row;
handle && handle({
row: ceils, ceil, rowIndex, columnIndex: ci,
});
}
function handleHover(enter, ri, ci, row, ceil) {
if (enter) emitEvent(onMouseOver, ri, ci, row, ceil);
if (!mergedConfig.hoverPause) return;
const { pause, resume } = task.current;
enter && pause && resume ? pause() : resume && resume();
}
// updateRows(rows, animationIndex) {
// const { mergedConfig, animationHandler, animation } = this
// this.mergedConfig = {
// ...mergedConfig,
// data: [...rows]
// }
// this.needCalc = true
// if (typeof animationIndex === 'number') this.animationIndex = animationIndex
// if (!animationHandler) animation(true)
// }
const getBackgroundColor = (rowIndex) => mergedConfig[rowIndex % 2 === 0 ? 'evenRowBGC' : 'oddRowBGC'];
const task = useRef({});
useEffect(() => {
calcData();
let start = true;
function* loop() {
while (true) {
yield* animation(start);
start = false;
const { waitTime } = stateRef.current.mergedConfig;
yield new Promise((resolve) => setTimeout(resolve, waitTime - 300));
}
}
const {
mergedConfig: { rowNum },
rows: rowsData,
} = stateRef.current;
const rowLength = rowsData.length;
if (rowNum >= rowLength) {
setState((prestate) => ({
...prestate, rowsShow: state.rows,
}));
return;
}
task.current = co(loop);
return task.current.end;
}, [config, domRef.current]);
useEffect(onResize, [width, height, domRef.current]);
const classNames = useMemo(() => classnames('dv-scroll-board', className), [
className,
]);
return (
<div className={classNames} style={style} ref={domRef}>
{!!header.length && !!mergedConfig && (
<div
className="header"
style={{ backgroundColor: `${mergedConfig.headerBGC}` }}
>
{header.map((headerItem, i) => (
<div
className="header-item"
key={`${headerItem}-${i}`}
style={{
height: `${mergedConfig.headerHeight}px`,
lineHeight: `${mergedConfig.headerHeight}px`,
width: `${widths[i]}px`,
}}
align={aligns[i]}
dangerouslySetInnerHTML={{ __html: headerItem }}
/>
))}
</div>
)}
{!!mergedConfig && (
<div
className="rows"
style={{
height: `${height
- (header.length ? mergedConfig.headerHeight : 0)}px`,
}}
>
{rowsShow.map((row, ri) => (
<div
className="row-item"
key={`${row.toString()}-${row.scroll}`}
style={{
height: `${heights[ri]}px`,
lineHeight: `${heights[ri]}px`,
backgroundColor: `${getBackgroundColor(row.rowIndex)}`,
}}
>
{row.ceils.map((ceil, ci) => {
if (typeof (ceil) === 'string') {
return (
<div
className="ceil"
key={`${ceil}-${ri}-${ci}`}
style={{ width: `${widths[ci]}px` }}
align={aligns[ci]}
dangerouslySetInnerHTML={{ __html: ceil }}
onClick={() => emitEvent(onClick, ri, ci, row, ceil)}
onMouseEnter={() => handleHover(true, ri, ci, row, ceil)}
onMouseLeave={() => handleHover(false)}
/>
);
}
return (
<div
className="ceil"
style={{ width: `${widths[ci]}px` }}
align={aligns[ci]}
key={`${ri}-${ci}`}
onMouseEnter={() => handleHover(true, ri, ci, row, ceil)}
onMouseLeave={() => handleHover(false)}
>
{ceil}
</div>
);
})}
</div>
))}
</div>
)}
</div>
);
});
ScrollBoard.propTypes = {
config: PropTypes.object,
onClick: PropTypes.func,
onMouseOver: PropTypes.func,
className: PropTypes.string,
style: PropTypes.object,
};
export default ScrollBoard;

44
super-screen/client/src/sections/water-prevention/components/public/scrollBoard/style.less

@ -0,0 +1,44 @@
.dv-scroll-board {
position: relative;
width: 100%;
height: 100%;
color: #fff;
.text {
padding: 0 10px;
box-sizing: border-box;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.header {
display: flex;
flex-direction: row;
font-size: 15px;
.header-item {
.text;
transition: all 0.3s;
}
}
.rows {
overflow: hidden;
.row-item {
display: flex;
font-size: 14px;
transition: all 0.3s;
}
.ceil {
.text;
}
.index {
border-radius: 3px;
padding: 0px 3px;
}
}
}

34
super-screen/client/src/sections/water-prevention/components/public/table-card.js

@ -0,0 +1,34 @@
'use strict'
import React from 'react'
import './index.less'
class Box extends React.Component {
render() {
const { title, height = '100%', children, bodyPaddingTop = 1, titlePaddingTop, margin, overflow } = this.props
const headerbg = {
background: 'url(/assets/images/homePage/bigscreen/headertitlebg.png) no-repeat',
backgroundSize: '100% 100%',
}
return (
<div style={{ height, width: '100%', margin: margin || "0px 0px 28px" }}>
<div style={{
height: height, listStyle: 'none', overflow: overflow || 'hidden',
backgroundImage: 'linear-gradient(180deg, #00204a00 3%, #50c9f71a 100%)',
}}>
<div style={{ height: 42, paddingLeft: 24, paddingTop: '4px', wordBreak: 'keep-all', whiteSpace: 'nowrap', width: '100%', ...headerbg }}>
<span className='card-title'>{title}</span><div className='_sorrow' />
</div>
<div
style={{
width: '100%', height: 2,
marginTop: titlePaddingTop || 10, marginBottom: bodyPaddingTop || 25,
}} />
{children}
</div>
</div>
)
}
}
export default Box

373
super-screen/client/src/sections/water-prevention/components/style.less

@ -0,0 +1,373 @@
@card-height: calc(100% - 42px - 13px); //左右卡片内容高度定义 目前卡片为等高
//节点资源
.node-resource-container {
display: flex;
height: @card-height;
width: 100%;
align-items: center;
._item {
width: 33%;
display: flex;
flex-direction: column;
align-items: center;
._noderesource_data {
font-family: D-DINExp-Bold;
font-weight: 600;
font-size: 24px;
color: #FFFFFF;
line-height: 43.2px;
display: flex;
align-items: center;
._percent {
opacity: 0.8;
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 12px;
color: #C8F0FF;
text-align: left;
line-height: 24px;
}
}
._noderesource_title {
font-family: YouSheBiaoTiHei;
font-size: 20px;
color: #D8F0FF;
letter-spacing: 1.54px;
text-align: center;
text-shadow: 0 0 10px rgba(0, 145, 255, 0.5);
margin-bottom: 17px;
}
.disk_icon {
width: 68.73px;
height: 62.77px;
background: url('/assets/images/homePage/bigscreen/disk.png');
background-repeat: no-repeat;
background-size: 100% 100%;
}
.cpu_icon {
width: 68.73px;
height: 62.77px;
background: url('/assets/images/homePage/bigscreen/cpu.png');
background-repeat: no-repeat;
background-size: 100% 100%;
}
.memory_icon {
width: 68.73px;
height: 62.77px;
background: url('/assets/images/homePage/bigscreen/memory.png');
background-repeat: no-repeat;
background-size: 100% 100%;
}
}
}
//接入数据统计
.access_data {
display: flex;
height: @card-height;
width: 100%;
justify-content: center;
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 14px;
color: #FFFFFF;
._img {
width: 230px;
height: 95%;
background: url('/assets/images/homePage/bigscreen/accessdata.png');
background-repeat: no-repeat;
background-size: 100% 100%;
}
.data_unit {
position: absolute;
top: 27%;
right: 21%;
.data_number {
line-height: 25px;
font-family: D-DINExp-Bold;
font-weight: 700;
font-size: 20px;
color: #3E86FF;
letter-spacing: 0;
}
}
.data_today {
position: absolute;
bottom: 13%;
right: 79%;
text-align: right;
.data_number {
line-height: 25px;
font-family: D-DINExp-Bold;
font-weight: 700;
font-size: 20px;
color: #00F6E4;
letter-spacing: 0;
}
}
.data_total {
position: absolute;
bottom: 13%;
left: 79%;
.data_number {
line-height: 25px;
font-family: D-DINExp-Bold;
font-weight: 700;
font-size: 20px;
color: #FFDC4E;
letter-spacing: 0;
}
}
}
.data_top5_unit {
position: absolute;
right: 4%;
top: 18%;
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 12px;
color: #C8F0FF;
}
.hotspot_data_container {
display: flex;
height: @card-height;
width: 100%;
justify-content: center;
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 14px;
color: #FFFFFF;
._img {
width: 203px;
height: 80%;
background: url('/assets/images/homePage/bigscreen/hotspotdatabg.png');
background-repeat: no-repeat;
background-size: 100% 100%;
}
.hotspot_title {
padding: 2px;
padding-left: 6px;
padding-right: 6px;
background: rgba(77, 241, 227, 0.08);
border: 1px solid rgba(77, 241, 227, 0.1);
box-shadow: inset 0 0 20px 0 rgba(28, 185, 196, 0.23);
}
.hotspot_data_number {
font-family: D-DINExp-Bold;
font-weight: 700;
font-size: 18px;
color: #FFFFFF;
}
._top1 {
position: absolute;
top: 25%;
right: 63%;
text-align: right;
}
._top2 {
position: absolute;
bottom: 22%;
right: 67%;
text-align: center;
}
._top3 {
position: absolute;
bottom: 34%;
left: 73%;
}
}
//数据共享
.data_share {
display: flex;
height: @card-height;
._left_content {
width: 50%;
height: 90%;
padding-left: 30px;
display: flex;
flex-direction: column;
justify-content: space-between;
}
._right_content {
._today_text {
font-family: YouSheBiaoTiHei;
font-size: 24px;
color: #FFFFFF;
letter-spacing: 0.5px;
position: absolute;
right: 6%;
top: 21%;
}
padding-top: 23px;
display: flex;
flex-direction: column;
width: 47%;
height: 95%;
background: url(/assets/images/homePage/bigscreen/todaybg.png);
background-repeat: no-repeat;
background-size: 100% 100%;
justify-content: space-evenly;
align-items: center;
}
._item_content {
display: flex;
._item_icon1 {
width: 52px;
height: 52px;
background: url('/assets/images/homePage/bigscreen/1.png');
background-repeat: no-repeat;
background-size: 100% 100%;
}
._item_icon2 {
width: 52px;
height: 52px;
background: url('/assets/images/homePage/bigscreen/2.png');
background-repeat: no-repeat;
background-size: 100% 100%;
}
._item_icon3 {
width: 52px;
height: 52px;
background: url('/assets/images/homePage/bigscreen/3.png');
background-repeat: no-repeat;
background-size: 100% 100%;
}
._item_text {
color: #C8F0FF;
padding-left: 6px;
.number_container {
._number {
font-family: D-DINExp-Bold;
font-weight: 700;
font-size: 22px;
color: #FFFFFF;
}
display: flex;
align-items: center;
justify-content: space-evenly;
width: 112px;
height: 28px;
background-image: linear-gradient(227deg, #3196AB 0%, #2091cd00 100%);
}
}
}
}
//大屏中间上部分
.center_top_data {
._center_card1 {
width: 353px;
height: 74px;
font-family: YouSheBiaoTiHei;
font-size: 22px;
color: #FFFFFF;
letter-spacing: 0.46px;
text-align: center;
position: absolute;
top: -3%;
left: 32%;
background: url(/assets/images/homePage/bigscreen/centerdatabg1.png);
background-repeat: no-repeat;
background-size: 100% 100%;
display: flex;
align-items: center;
justify-content: center;
}
._center_card2 {
width: 146px;
height: 35px;
font-family: YouSheBiaoTiHei;
font-size: 16px;
color: #35D0FF;
letter-spacing: 0.46px;
text-align: center;
position: absolute;
top: 26%;
left: 42%;
background: url(/assets/images/homePage/bigscreen/centerdatabg2.png);
background-repeat: no-repeat;
background-size: 100% 100%;
display: flex;
align-items: center;
justify-content: center;
}
._center_card3 {
width: 146px;
height: 35px;
font-family: YouSheBiaoTiHei;
font-size: 16px;
color: #35D0FF;
letter-spacing: 0.46px;
text-align: center;
position: absolute;
top: 52%;
left: 42%;
background: url(/assets/images/homePage/bigscreen/centerdatabg2.png);
background-repeat: no-repeat;
background-size: 100% 100%;
display: flex;
align-items: center;
justify-content: center;
}
._center_card4 {
width: 146px;
height: 35px;
font-family: YouSheBiaoTiHei;
font-size: 16px;
color: #35D0FF;
letter-spacing: 0.46px;
text-align: center;
position: absolute;
top: 74%;
left: 42%;
background: url(/assets/images/homePage/bigscreen/centerdatabg2.png);
background-repeat: no-repeat;
background-size: 100% 100%;
display: flex;
align-items: center;
justify-content: center;
}
}

3
super-screen/client/src/sections/water-prevention/components/util.js

@ -0,0 +1,3 @@
export const mathRound = (number) => {
return number ? Math.round(number / 1000) / 10 : 0
}

74
super-screen/client/src/sections/water-prevention/containers/homePage.js

@ -0,0 +1,74 @@
import React, { useEffect, useState } from 'react'
import { connect } from 'react-redux';
import { push } from 'react-router-redux';
import AccessData from '../components/accessData'
import AlarmList from '../components/alarmList'
import DataShare from '../components/dataShare'
import DataTop5 from '../components/dataTop5'
import HotspotData from '../components/hotspotData'
import NodeResource from '../components/nodeResource'
import AbnormalMonitoring from '../components/abnormalMonitoring'
import CenterTop from '../components/centerTop'
import './style.less'
function homePage(props) {
const { dispatch } = props;
const childStyle = { height: '32%', color: '#fff', marginBottom: 17 }
const cardHeight = document.body.clientHeight * 0.896 * 0.32
const cardContentHeight = cardHeight - 42 - 13
return <div className='homepage'>
<div className='_title'>
<div onClick={() => { dispatch(push('/metadataManagement/latestMetadata')) }} className='_exit' ><div className='_icon' />进入后台</div>
</div>
<div className='homepage-left homepage-left-left'>
<div className="list">
<div className='child' style={childStyle}>
<AccessData />
</div>
<div className='child' style={childStyle}>
<NodeResource />
</div>
<div className='child' style={childStyle}>
<AlarmList cardContentHeight={cardContentHeight} />
</div>
</div>
</div>
<div className='homepage-center'>
<CenterTop />
<div className="list">
<div className='child-top'>
<AbnormalMonitoring />
</div>
</div>
</div>
<div className='homepage-left homepage-left-right'>
<div className="list">
<div className='child-right' style={childStyle}>
<DataShare />
</div>
<div className='child-right' style={childStyle}>
<DataTop5 cardContentHeight={cardContentHeight} />
</div>
<div className='child-right' style={childStyle}>
<HotspotData />
</div>
</div>
</div>
</div>
}
function mapStateToProps(state) {
const {
auth, global
} = state;
return {
clientHeight: global.clientHeight,
actions: global.actions,
};
}
export default connect(mapStateToProps)(homePage);

6
super-screen/client/src/sections/water-prevention/containers/index.js

@ -0,0 +1,6 @@
'use strict';
import homePage from './homePage';
export default homePage ;

324
super-screen/client/src/sections/water-prevention/containers/style.less

@ -0,0 +1,324 @@
.homepage {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
background: url('/assets/images/homePage/enter/bg.png');
background-repeat: no-repeat;
background-size: 100% 100%;
overflow: hidden;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding-top: 5%;
._enter_row1 {
height: 302px;
._row1_item {
width: 1434px;
height: 241px;
// opacity: 0.8;
background: url('/assets/images/homePage/enter/row1.png');
background-repeat: no-repeat;
background-size: 100% 100%;
cursor: pointer;
}
._row1_item:hover {
width: 1434px;
height: 302.6px;
background: url('/assets/images/homePage/enter/row1-select.png');
background-repeat: no-repeat;
background-size: 100% 100%;
cursor: pointer;
}
}
._enter_row2 {
height: 427px;
display: flex;
width: 100%;
padding-left: 4%;
._row2_item1 {
width: 454px;
height: 371px;
// opacity: 0.8;
background: url('/assets/images/homePage/enter/row2-1.png');
background-repeat: no-repeat;
background-size: 100% 100%;
cursor: pointer;
margin-left: 60px;
}
._row2_item1:hover {
background: url('/assets/images/homePage/enter/row2-1-select.png');
background-repeat: no-repeat;
background-size: 100% 100%;
cursor: pointer;
}
._row2_item2 {
margin-left: 60px;
width: 454px;
height: 371px;
// opacity: 0.8;
background: url('/assets/images/homePage/enter/row2-2.png');
background-repeat: no-repeat;
background-size: 100% 100%;
cursor: pointer;
}
._row2_item2:hover {
background: url('/assets/images/homePage/enter/row2-2-select.png');
background-repeat: no-repeat;
background-size: 100% 100%;
cursor: pointer;
}
._row2_item3 {
margin-left: 60px;
width: 454px;
height: 371px;
// opacity: 0.8;
background: url('/assets/images/homePage/enter/row2-3.png');
background-repeat: no-repeat;
background-size: 100% 100%;
cursor: pointer;
}
._row2_item3:hover {
background: url('/assets/images/homePage/enter/row2-3-select.png');
background-repeat: no-repeat;
background-size: 100% 100%;
cursor: pointer;
}
}
._enter_title {
position: absolute;
top: 4%;
left: 3%;
width: 575.35px;
height: 78px;
background: url('/assets/images/homePage/enter/title.png');
background-repeat: no-repeat;
background-size: 100% 100%;
}
._title {
width: 100%;
height: 88px;
background: url('/assets/images/homePage/bigscreen/top.png');
background-repeat: no-repeat;
background-size: 100% 100%;
}
._exit {
position: absolute;
right: 60px;
top: 38px;
cursor: pointer;
color: #C8F0FF;
display: flex;
._icon {
display: inline-block;
width: 28px;
height: 28px;
background: url('/assets/images/homePage/bigscreen/exit.png');
background-repeat: no-repeat;
background-size: 100% 100%;
margin-right: 3px;
}
}
.homepage-left {
width: 21.8%;
height: 89.6%;
position: absolute;
top: 8.2%;
z-index: 300;
}
.homepage-center {
width: 49.16%;
height: 89.6%;
position: absolute;
bottom: 2.4%;
left: 25.5%;
padding-left: 16px;
padding-right: 16px;
z-index: 400;
._top {
margin-top: 5%;
height: calc(100% - 200px);
background: url('/assets/images/homePage/bigscreen/centerbg.png');
background-repeat: no-repeat;
background-size: 100% 100%;
position: relative;
}
}
.homepage-left-left {
left: 48px;
}
.homepage-left-right {
right: 48px;
}
}
.list {
list-style: none;
height: 100%;
}
.list .child {
box-sizing: border-box;
opacity: 0;
transform: translateX(-300px);
animation: show .5s forwards;
}
.list .child.show {
animation-delay: 0s !important;
}
.list .child.hide {
opacity: 1;
transform: translateX(0);
animation-name: hide;
animation-delay: 0s;
}
/*animation-delay*/
.list .child:not(.hide):nth-child(5n + 1) {
animation-delay: .3s;
}
.list .child:not(.hide):nth-child(5n + 2) {
animation-delay: .6s;
}
.list .child:not(.hide):nth-child(5n + 3) {
animation-delay: .9s;
}
.list .child:not(.hide):nth-child(5n + 4) {
animation-delay: 1.2s;
}
.list .child:not(.hide):nth-child(5n + 5) {
animation-delay: 1.5s;
}
.list .child-right {
box-sizing: border-box;
opacity: 0;
transform: translateX(300px);
animation: show .5s forwards;
}
.list .child-right.show {
animation-delay: 0s !important;
}
.list .child-right.hide {
opacity: 1;
transform: translateX(0);
animation-name: hide;
animation-delay: 0s;
}
/*animation-delay*/
.list .child-right:not(.hide):nth-child(5n + 1) {
animation-delay: .3s;
}
.list .child-right:not(.hide):nth-child(5n + 2) {
animation-delay: .6s;
}
.list .child-right:not(.hide):nth-child(5n + 3) {
animation-delay: .9s;
}
.list .child-right:not(.hide):nth-child(5n + 4) {
animation-delay: 1.2s;
}
.list .child-right:not(.hide):nth-child(5n + 5) {
animation-delay: 1.5s;
}
.list .child-top {
box-sizing: border-box;
opacity: 0;
transform: translateY(300px);
animation: show 1s forwards;
}
.list .child-top.show {
animation-delay: 0s !important;
}
.list .child-top.hide {
opacity: 1;
transform: translateY(0);
animation-name: hide;
animation-delay: 0s;
}
@keyframes show {
to {
opacity: 1;
transform: translateX(0);
}
}
@keyframes hide {
to {
opacity: 0;
transform: translateX(100px);
max-height: 0;
margin: 0;
}
}
.center-card-title {
height: 31px;
font-family: YouSheBiaoTiHei;
font-size: 24px;
color: #FFFFFF;
display: flex;
align-items: center;
margin-top: 5px;
._icon_left {
width: 32px;
height: 17px;
background: url('/assets/images/homePage/bigscreen/center-left.png');
background-repeat: no-repeat;
background-size: 100% 100%;
margin-right: 11px;
margin-left: 10px;
}
._icon_right {
width: 32px;
height: 17px;
background: url('/assets/images/homePage/bigscreen/center-right.png');
background-repeat: no-repeat;
background-size: 100% 100%;
margin-right: 11px;
margin-left: 10px;
}
}

15
super-screen/client/src/sections/water-prevention/index.js

@ -0,0 +1,15 @@
'use strict';
import reducers from './reducers';
import routes from './routes';
import actions from './actions';
import { getNavItem } from './nav-item';
export default {
key: 'waterprevention',
name: '首页',
reducers: reducers,
routes: routes,
actions: actions,
getNavItem: getNavItem
};

11
super-screen/client/src/sections/water-prevention/nav-item.js

@ -0,0 +1,11 @@
import React from 'react';
import { Link } from 'react-router-dom';
import { Menu } from 'antd';
import { HomeOutlined } from '@ant-design/icons';
export function getNavItem(user) {
return (
<Menu.Item key="waterprevention" icon={<HomeOutlined />}>
<Link to="/waterprevention">数据监控平台</Link>
</Menu.Item>
);
}

5
super-screen/client/src/sections/water-prevention/reducers/index.js

@ -0,0 +1,5 @@
'use strict';
export default {
}

13
super-screen/client/src/sections/water-prevention/routes.js

@ -0,0 +1,13 @@
'use strict';
import homePage from './containers/index';
export default [{
type: 'outer',
route: {
path: '/waterprevention',
key: 'waterprevention',
breadcrumb: '数据监控平台',
// 不设置 component 则面包屑禁止跳转
component: homePage
}
}];

0
super-screen/client/src/sections/water-prevention/style.less

2
super-screen/middlewares/webpack-dev.js

@ -44,7 +44,7 @@ module.exports = {
const server = express();
server.use(middleware(compiler));
//server.use(require("webpack-hot-middleware")(compiler));
server.listen('5401', function (err) {
server.listen('5501', function (err) {
if (err) {
console.log(err);
}

Loading…
Cancel
Save