@ -0,0 +1,4 @@ |
|||||
|
alter table t_resource_consumption |
||||
|
add resource_id int; |
||||
|
|
||||
|
comment on column t_resource_consumption.resource_id is '元数据id'; |
After Width: | Height: | Size: 5.5 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 4.9 KiB |
After Width: | Height: | Size: 4.9 KiB |
After Width: | Height: | Size: 5.7 KiB |
After Width: | Height: | Size: 5.7 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 945 KiB |
After Width: | Height: | Size: 7.1 KiB |
After Width: | Height: | Size: 7.1 KiB |
After Width: | Height: | Size: 7.2 KiB |
After Width: | Height: | Size: 826 B |
After Width: | Height: | Size: 775 B |
After Width: | Height: | Size: 8.5 KiB |
After Width: | Height: | Size: 745 B |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 699 B |
After Width: | Height: | Size: 116 KiB |
After Width: | Height: | Size: 8.7 KiB |
After Width: | Height: | Size: 7.8 KiB |
After Width: | Height: | Size: 7.5 KiB |
After Width: | Height: | Size: 6.3 KiB |
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 56 KiB |
After Width: | Height: | Size: 7.3 KiB |
After Width: | Height: | Size: 19 KiB |
@ -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; |
||||
|
|
||||
|
|
@ -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; |
||||
|
|
||||
|
|
@ -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; |
||||
|
|
||||
|
|
@ -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; |
||||
|
|
||||
|
|
@ -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; |
||||
|
|
||||
|
|
@ -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; |
||||
|
|
||||
|
|
@ -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; |
||||
|
|
||||
|
|
@ -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; |
@ -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; |
||||
|
} |
@ -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; |
@ -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; |
||||
|
} |
||||
|
} |
||||
|
} |
@ -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 |
||||
|
|
@ -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; |
||||
|
} |
||||
|
} |