wenlele 1 year ago
parent
commit
f126437794
  1. 4
      web/client/assets/files/backups/iota20220523--20230625-080107.dump
  2. BIN
      web/client/assets/images/homePage/bigscreen/1.png
  3. BIN
      web/client/assets/images/homePage/bigscreen/2(1).png
  4. BIN
      web/client/assets/images/homePage/bigscreen/2.png
  5. BIN
      web/client/assets/images/homePage/bigscreen/3(1).png
  6. BIN
      web/client/assets/images/homePage/bigscreen/3.png
  7. BIN
      web/client/assets/images/homePage/bigscreen/4(1).png
  8. BIN
      web/client/assets/images/homePage/bigscreen/4.png
  9. BIN
      web/client/assets/images/homePage/bigscreen/6.png
  10. BIN
      web/client/assets/images/homePage/bigscreen/bg.png
  11. BIN
      web/client/assets/images/homePage/bigscreen/button(1).png
  12. BIN
      web/client/assets/images/homePage/bigscreen/button(2).png
  13. BIN
      web/client/assets/images/homePage/bigscreen/button.png
  14. BIN
      web/client/assets/images/homePage/bigscreen/center-left.png
  15. BIN
      web/client/assets/images/homePage/bigscreen/center-right.png
  16. BIN
      web/client/assets/images/homePage/bigscreen/cpu.png
  17. BIN
      web/client/assets/images/homePage/bigscreen/exit.png
  18. BIN
      web/client/assets/images/homePage/bigscreen/header-title-bg.png
  19. BIN
      web/client/assets/images/homePage/bigscreen/sorrow.png
  20. BIN
      web/client/assets/images/homePage/bigscreen/top.png
  21. BIN
      web/client/assets/images/homePage/bigscreen/内存.png
  22. BIN
      web/client/assets/images/homePage/bigscreen/分组 13 copy(1).png
  23. BIN
      web/client/assets/images/homePage/bigscreen/分组 13 copy(2).png
  24. BIN
      web/client/assets/images/homePage/bigscreen/分组 13 copy.png
  25. BIN
      web/client/assets/images/homePage/bigscreen/图.png
  26. BIN
      web/client/assets/images/homePage/bigscreen/整图.png
  27. BIN
      web/client/assets/images/homePage/bigscreen/硬盘.png
  28. BIN
      web/client/assets/images/homePage/bigscreen/组 1444.png
  29. 2
      web/client/index.html
  30. 5
      web/client/src/sections/backups/containers/backupTask.js
  31. 47
      web/client/src/sections/homePage/components/abnormalMonitoring.js
  32. 19
      web/client/src/sections/homePage/components/accessData.js
  33. 27
      web/client/src/sections/homePage/components/alarmList.js
  34. 19
      web/client/src/sections/homePage/components/dataShare.js
  35. 19
      web/client/src/sections/homePage/components/dataTop5.js
  36. 19
      web/client/src/sections/homePage/components/hotspotData.js
  37. 19
      web/client/src/sections/homePage/components/nodeResource.js
  38. 35
      web/client/src/sections/homePage/components/public/carousel-list.js
  39. 80
      web/client/src/sections/homePage/components/public/index.less
  40. 469
      web/client/src/sections/homePage/components/public/scrollBoard/index.js
  41. 44
      web/client/src/sections/homePage/components/public/scrollBoard/style.less
  42. 44
      web/client/src/sections/homePage/components/public/table-card.js
  43. 52
      web/client/src/sections/homePage/containers/homePage.js
  44. 222
      web/client/src/sections/homePage/containers/style.less
  45. 2
      web/client/src/sections/homePage/routes.js
  46. 1
      web/package.json

4
web/client/assets/files/backups/iota20220523--20230625-080107.dump

@ -0,0 +1,4 @@
alter table t_resource_consumption
add resource_id int;
comment on column t_resource_consumption.resource_id is '元数据id';

BIN
web/client/assets/images/homePage/bigscreen/1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

BIN
web/client/assets/images/homePage/bigscreen/2(1).png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

BIN
web/client/assets/images/homePage/bigscreen/2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

BIN
web/client/assets/images/homePage/bigscreen/3(1).png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

BIN
web/client/assets/images/homePage/bigscreen/3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

BIN
web/client/assets/images/homePage/bigscreen/4(1).png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

BIN
web/client/assets/images/homePage/bigscreen/4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

BIN
web/client/assets/images/homePage/bigscreen/6.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
web/client/assets/images/homePage/bigscreen/bg.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 945 KiB

BIN
web/client/assets/images/homePage/bigscreen/button(1).png

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

BIN
web/client/assets/images/homePage/bigscreen/button(2).png

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

BIN
web/client/assets/images/homePage/bigscreen/button.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

BIN
web/client/assets/images/homePage/bigscreen/center-left.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 826 B

BIN
web/client/assets/images/homePage/bigscreen/center-right.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 775 B

BIN
web/client/assets/images/homePage/bigscreen/cpu.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

BIN
web/client/assets/images/homePage/bigscreen/exit.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 745 B

BIN
web/client/assets/images/homePage/bigscreen/header-title-bg.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
web/client/assets/images/homePage/bigscreen/sorrow.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 699 B

BIN
web/client/assets/images/homePage/bigscreen/top.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

BIN
web/client/assets/images/homePage/bigscreen/内存.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

BIN
web/client/assets/images/homePage/bigscreen/分组 13 copy(1).png

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

BIN
web/client/assets/images/homePage/bigscreen/分组 13 copy(2).png

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

BIN
web/client/assets/images/homePage/bigscreen/分组 13 copy.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

BIN
web/client/assets/images/homePage/bigscreen/图.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
web/client/assets/images/homePage/bigscreen/整图.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

BIN
web/client/assets/images/homePage/bigscreen/硬盘.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

BIN
web/client/assets/images/homePage/bigscreen/组 1444.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

2
web/client/index.html

@ -14,7 +14,7 @@
} }
</style> </style>
<body> <body style="background: #0F1C2A;">
<div id='App'></div> <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/vendor.js"></script>
<script type="text/javascript" src="http://localhost:5401/client/build/app.js"></script> <script type="text/javascript" src="http://localhost:5401/client/build/app.js"></script>

5
web/client/src/sections/backups/containers/backupTask.js

@ -91,7 +91,10 @@ function Member(props) {
/> : <a style={{ color: 'gray' }}></a>) /> : <a style={{ color: 'gray' }}></a>)
options.push( options.push(
record?.source ? record?.source ?
<a a onClick={() => { window.open(record?.source) }}> 下载</a> : <a style={{ color: 'gray' }}></a> <a a onClick={() => {
const url = '/assets/files/backups/' + record?.source.replace('/app/dbFiles/', '')
window.open(url)
}}>下载</a> : <a style={{ color: 'gray' }}></a>
) )
if (record?.state != '备份中' && record?.state != '恢复中') { if (record?.state != '备份中' && record?.state != '恢复中') {

47
web/client/src/sections/homePage/components/abnormalMonitoring.js

@ -0,0 +1,47 @@
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
},
// pollingInterval: 10000
});
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
// columnWidth={[200, 170, 120, 120]}
/>
</div>
}
export default AbnormalMonitoring;

19
web/client/src/sections/homePage/components/accessData.js

@ -0,0 +1,19 @@
import React, { useEffect, useState } from 'react'
import TableCard from './public/table-card';
function AccessData(props) {
const renderBody = () => {
return '接入数据统计'
}
return <TableCard
renderBody={renderBody()}
height={'100%'}
title={"接入数据统计"}
bodyPaddingTop={1} />
}
export default AccessData;

27
web/client/src/sections/homePage/components/alarmList.js

@ -0,0 +1,27 @@
import React, { useEffect, useState } from 'react'
import TableCard from './public/table-card';
import CarouselList from './public/carousel-list';
function AlarmList(props) {
const { cardHeight } = props;
const renderBody = () => {
return <CarouselList
header={['任务名称', '采集时间', '耗时', '异常日志']}
data={[['任务名称', '采集时间', '耗时', '异常日志'], ['任务名称', '采集时间', '耗时', '异常日志'], ['任务名称', '采集时间', '耗时', '异常日志'], ['任务名称', '采集时间', '耗时', '异常日志'], ['任务名称', '采集时间', '耗时', '异常日志'], ['任务名称', '采集时间', '耗时', '异常日志'], ['任务名称', '采集时间', '耗时', '异常日志'], ['任务名称', '采集时间', '耗时', '异常日志']]}
rowNum={6}
height={cardHeight - 42 - 13}
multiellipsis
// columnWidth={[200, 170, 120, 120]}
/>
}
return <TableCard
renderBody={renderBody()}
height={'100%'}
title={"预警列表"}
bodyPaddingTop={1} />
}
export default AlarmList;

19
web/client/src/sections/homePage/components/dataShare.js

@ -0,0 +1,19 @@
import React, { useEffect, useState } from 'react'
import TableCard from './public/table-card';
function DataShare(props) {
const renderBody = () => {
return '数据共享'
}
return <TableCard
renderBody={renderBody()}
height={'100%'}
title={"数据共享"}
bodyPaddingTop={1} />
}
export default DataShare;

19
web/client/src/sections/homePage/components/dataTop5.js

@ -0,0 +1,19 @@
import React, { useEffect, useState } from 'react'
import TableCard from './public/table-card';
function DataTop5(props) {
const renderBody = () => {
return '数据量TOP5单位'
}
return <TableCard
renderBody={renderBody()}
height={'100%'}
title={"数据量TOP5单位"}
bodyPaddingTop={1} />
}
export default DataTop5;

19
web/client/src/sections/homePage/components/hotspotData.js

@ -0,0 +1,19 @@
import React, { useEffect, useState } from 'react'
import TableCard from './public/table-card';
function HotspotData(props) {
const renderBody = () => {
return '热点数据'
}
return <TableCard
renderBody={renderBody()}
height={'100%'}
title={"热点数据"}
bodyPaddingTop={1} />
}
export default HotspotData;

19
web/client/src/sections/homePage/components/nodeResource.js

@ -0,0 +1,19 @@
import React, { useEffect, useState } from 'react'
import TableCard from './public/table-card';
function NodeResource(props) {
const renderBody = () => {
return '节点资源'
}
return <TableCard
renderBody={renderBody()}
height={'100%'}
title={"节点资源"}
bodyPaddingTop={1} />
}
export default NodeResource;

35
web/client/src/sections/homePage/components/public/carousel-list.js

@ -0,0 +1,35 @@
/* 轮播列表组件 */
import React from 'react';
import ScrollBoard from './scrollBoard';
// import { ScrollBoard } from '@jiaminghi/data-view-react';
// import NoData from './no-data';
import './index.less';
function CarouselList(props) {
const {
header = [], data = [], rowNum = 4, height, columnWidth, multiellipsis, waitTime = 2000, ...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'}
// eslint-disable-next-line react/jsx-props-no-spreading
{...restProps}
/>
) : null;
}
export default CarouselList;

80
web/client/src/sections/homePage/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;
}

469
web/client/src/sections/homePage/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
web/client/src/sections/homePage/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;
}
}
}

44
web/client/src/sections/homePage/components/public/table-card.js

@ -0,0 +1,44 @@
'use strict'
import React from 'react'
import { Row, Col, Modal, Tooltip } from 'antd'
import './index.less'
class TableCard extends React.Component {
render() {
const { title, renderBody, height, width, bodyPaddingTop, subTitle, titlePaddingTop, margin, overflow, padding } = this.props
const headerbg = {
background: 'url(/assets/images/homepage/bigscreen/header-title-bg.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%)',
// ...bg
}}>
<Row style={{ height: 42, paddingLeft: 24, paddingTop: '4px', wordBreak: 'keep-all', whiteSpace: 'nowrap', width: '100%', ...headerbg }}>
<Col span={8}>
<span className='card-title'>{title}</span><div className='_sorrow'/>
</Col>
<Col span={16} style={{ textAlign: 'right' }}>
{subTitle}
</Col>
</Row>
<div
style={{
width: '100%', height: 2,
marginTop: titlePaddingTop || 10, marginBottom: bodyPaddingTop || 25,
}} />
{renderBody}
</div>
</div>
)
}
}
export default TableCard

52
web/client/src/sections/homePage/containers/homePage.js

@ -1,12 +1,58 @@
import React, { useEffect, useState } from 'react' import React, { useEffect, useState } from 'react'
import { connect } from 'react-redux'; 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 './style.less' import './style.less'
function homePage(props) { function homePage(props) {
const { clientHeight } = props; const { dispatch } = props;
return <div style={{ width: '100%', height: clientHeight, overflow: 'hidden' }}> const childStyle = { height: '32%', color: '#fff', marginBottom: 17 }
1 const cardHeight = document.body.clientHeight * 0.32
return <div className='homepage'>
<div className='_title'>
<div onClick={() => { dispatch(push('/metadataManagement/latestMetadata')) }} className='_exit' ><div className='_icon' />进入后台</div>
</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 cardHeight={cardHeight} />
</div>
</div>
</div>
<div className='homepage-center'>
<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 />
</div>
<div className='child-right' style={childStyle}>
<HotspotData />
</div>
</div>
</div>
</div>
} }
function mapStateToProps(state) { function mapStateToProps(state) {

222
web/client/src/sections/homePage/containers/style.less

@ -0,0 +1,222 @@
.homepage {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
background: url('/assets/images/homePage/bigscreen/bg.png');
background-repeat: no-repeat;
background-size: 100% 100%;
overflow: hidden;
._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;
// width: 16px;
// height: 16px;
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 {
// padding-top: 15px;
width: 21.8%;
height: 89.6%;
// background-color: red;
position: absolute;
top: 8.2%;
z-index: 300;
}
.homepage-center {
width: 49.16%;
height: 150px;
// background-color: blueviolet;
position: absolute;
bottom: 2.5%;
left: 25.5%;
padding-left: 16px;
padding-right: 16px;
z-index: 400;
// background-color: rebeccapurple;
}
.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;
// margin-bottom: 17px;
}
.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;
}
}

2
web/client/src/sections/homePage/routes.js

@ -2,7 +2,7 @@
import homePage from './containers/index'; import homePage from './containers/index';
export default [{ export default [{
type: 'inner', type: 'outer',
route: { route: {
path: '/homePage', path: '/homePage',
key: 'homePage', key: 'homePage',

1
web/package.json

@ -67,6 +67,7 @@
"@antv/g6": "^4.2.5", "@antv/g6": "^4.2.5",
"@douyinfe/semi-ui": "^2.28.1", "@douyinfe/semi-ui": "^2.28.1",
"@fs/attachment": "^1.0.0", "@fs/attachment": "^1.0.0",
"@jiaminghi/data-view-react": "^1.2.5",
"@peace/components": "0.0.35", "@peace/components": "0.0.35",
"@peace/utils": "0.0.37", "@peace/utils": "0.0.37",
"ahooks": "^3.7.4", "ahooks": "^3.7.4",

Loading…
Cancel
Save