Browse Source

数据在线率

dev
wenlele 1 year ago
parent
commit
32cc25f7d6
  1. 2
      api/config.js
  2. 7
      web/client/src/layout/components/header/index.jsx
  3. 12
      web/client/src/sections/projectGroup/actions/group.js
  4. 5
      web/client/src/sections/projectGroup/components/card.jsx
  5. 32
      web/client/src/sections/projectGroup/components/header.jsx
  6. 119
      web/client/src/sections/projectGroup/containers/bigscreen.jsx
  7. 23
      web/client/src/sections/projectGroup/containers/statistic.jsx
  8. 3
      web/client/src/utils/webapi.js

2
api/config.js

@ -41,6 +41,8 @@ args.option('qndmn', 'qiniuDomain');
// clickHouse
args.option('clickHouseUrl', 'clickHouse Url');
args.option('clickHousePort', 'clickHouse Port');
args.option('clickHouseUser', 'clickHouse user');
args.option('clickHousePassword', 'clickHouse password');
args.option('clickHouseAnxincloud', 'clickHouse 安心云数据库名称');
args.option('clickHousePepEmis', 'clickHouse 项企数据库名称');
args.option('clickHouseProjectManage', 'clickHouse 项目管理数据库名称');

7
web/client/src/layout/components/header/index.jsx

@ -108,7 +108,12 @@ const Header = (props) => {
src="/assets/images/install/long_logo.png"
style={{ display: "inline-block", width: 200, height: 40, marginLeft: -24, cursor: 'pointer' }}
onClick={() => {
window.open('/projectGroup/statistic', '_blank');
let projectGroup = JSON.parse(localStorage.getItem('project_group'))
if (projectGroup && projectGroup?.find(v => v.userId == user?.id)) {
window.open('/projectGroup/bigscreen', '_blank')
} else {
window.open('/projectGroup/statistic', '_blank')
}
}}
/>
),

12
web/client/src/sections/projectGroup/actions/group.js

@ -44,3 +44,15 @@ export function groupStatistic () {
reducer: { name: "groupStatistic", params: { noClear: true } },
});
}
export function groupStatisticOnline (query = {}) {
return (dispatch) => basicAction({
type: "get",
dispatch: dispatch,
query,
actionType: "GET_GROPUP_STATISTICS_ONLINE`",
url: `${ApiTable.groupStatisticOnline}`,
msg: { error: "获取项目分组在线率统计信息失败" },
reducer: { name: "groupStatisticOnline", params: { noClear: true } },
});
}

5
web/client/src/sections/projectGroup/components/card.jsx

@ -2,7 +2,7 @@ import React, { useEffect, useRef, useState } from 'react';
import { connect } from 'react-redux';
const Card = (props) => {
const { title } = props
const { title, style = {} } = props
return (
<div style={{
@ -11,6 +11,7 @@ const Card = (props) => {
borderRadius: 4,
// filter: 'blur(5px)',
padding: '6px 4px',
...style
}}>
<div style={{
height: 34, lineHeight: '34px',
@ -27,7 +28,7 @@ const Card = (props) => {
boxShadow: '0 0 4px 1px #2C66F3'
}} />
</div>
<div style={{ minHeight: 24, padding: '12px 18px' }}>
<div style={{ height:'calc(100% - 34px)', padding: '12px 18px' }}>
{props?.children}
</div>
</div>

32
web/client/src/sections/projectGroup/components/header.jsx

@ -4,7 +4,8 @@ import { Skeleton, Button, Pagination, Form, Popconfirm, Table, Toast } from '@d
import moment from "moment";
const Header = (props) => {
const { dispatch, actions, weatherRealtime } = props
const { dispatch, actions, user,match, weatherRealtime, history } = props
const [date, setDate] = useState(moment());
const dayMap = { 0: '日', 1: '一', 2: '二', 3: '三', 4: '四', 5: '五', 6: '六' }
const weatherMap = {
@ -71,7 +72,9 @@ const Header = (props) => {
padding: '0 24px',
display: 'flex', alignItems: 'center', justifyContent: 'space-between'
}}>
<span style={{ fontSize: 'xx-large', fontWeight: 'bolder' }}>运维中台大屏</span>
<span style={{ fontSize: 'xx-large', fontWeight: 'bolder' }}>
{match?.path == '/projectGroup/bigscreen' ? `${JSON.parse(localStorage.getItem('project_group'))?.find(v => v.userId == user?.id)?.name}数据统计大屏` : '运维中台大屏'}
</span>
<span style={{
display: 'flex', alignItems: 'center', flexDirection: 'row'
}}>
@ -110,19 +113,26 @@ const Header = (props) => {
{weatherMap[weatherRealtime?.skycon]}
</span>
</div>
<div style={lineBetweenStyle} />
<div style={{
display: "flex", alignItems: 'center', justifyContent: "space-around", width: 90,
color: 'color: #5A6685'
}}>
<img src="/assets/images/projectGroup/backend.png" style={{ width: 14, height: 14 }} alt="" />
返回后台
</div>
{match?.path == '/projectGroup/bigscreen' ? <>
<div style={lineBetweenStyle} />
<div style={{
display: "flex", alignItems: 'center', justifyContent: "space-around", width: 90,
color: 'color: #5A6685', fontSize: 14, fontFamily: "SourceHanSansCN-Regular", cursor: 'pointer'
}} onClick={() => {
history.push({ pathname: `/projectGroup/statistic`, })
}}>
<img src="/assets/images/projectGroup/backend.png" style={{ width: 14, height: 14 }} alt="" />
返回后台
</div>
</>
: <></>
}
</span>
</div>
)
}
function mapStateToProps (state) {
const { auth, global, weatherRealtime } = state;
return {

119
web/client/src/sections/projectGroup/containers/bigscreen.jsx

@ -4,33 +4,134 @@ import Header from '../components/header';
import Body from '../components/body'
import Card from '../components/card'
import '../style.less'
import ReactECharts from 'echarts-for-react';
import moment from 'moment'
const Bigscreen = ({ dispatch, actions, user, history, clientHeight }) => {
const Bigscreen = ({ dispatch, actions, user, match, history, clientHeight, groupStatisticOnline }) => {
useEffect(() => {
let projectGroupId = localStorage.getItem('project_group_id')
console.log(projectGroupId);
})
let groupId = JSON.parse(localStorage.getItem('project_group'))?.find(v => user?.id == v.userId)?.projectGroupId
console.log();
dispatch(actions.projectGroup.groupStatisticOnline({ groupId }))
}, [])
console.log(groupStatisticOnline);
return (
<div className='project-group'>
<Header />
<Header match={match} history={history} />
<Body>
<Card>
123
</Card>
<div style={{ width: "100%", height: '100%' }}>
<div style={{ width: '100%', height: "45%", display: 'flex' }}>
<div style={{ width: "calc(50% - 8px)", height: "100%", marginRight: 16, display: 'flex' }}>
<Card title='项目工单占比' style={{ width: "calc(50% - 8px)", height: "100%", marginRight: 16 }}>
<div style={{ height: '100%' }}>
</div>
</Card>
<Card title='修复排名' style={{ width: "calc(50% - 8px)", height: "100%" }}>
<div style={{ height: '100%' }}>
</div>
</Card>
</div>
<Card title='数据在线率' style={{ width: "calc(50% - 8px)", height: "100%", }}>
<div style={{ height: '100%' }}>
<ReactECharts
option={{
title: {
// text: v.name,
},
grid: {
// width: 300,
// height: 200
},
// dataZoom: [
// {
// type: 'slider',
// showDetail: false
// },
// {
// type: 'inside',
// },
// ],
tooltip: {
trigger: 'axis'
},
legend: {
data: groupStatisticOnline?.map(v => v.name) || [],
right: '10%',
textStyle: {
color: '#FFF',
},
},
xAxis: {
type: 'time',
// name: "",
boundaryGap: false,
minInterval: 1000 * 60,
},
yAxis: {
type: 'value',
name: "单位:A",
areaStyle: {
color: '#FFF',
},
},
series: groupStatisticOnline?.map(v => ({
type: 'line',
name: v.name,
smooth: true,
areaStyle: {
color: '#0e9cff26',
},
data: v.online?.map(f => [moment(f.collect_time).format('YYYY-MM-DD HH'), f.rate]) || []
})) || []
}}
notMerge={true}
lazyUpdate={true}
style={{ width: "100%", height: "100%" }}
theme={'ReactEChart'}
/>
</div>
</Card>
</div>
<div style={{ width: '100%', height: "calc(55% - 24px)", display: 'flex', marginTop: 24 }}>
<Card title='告警排名TOP20' style={{ width: "calc(50% - 8px)", height: "100%", marginRight: 16, }}>
<div style={{ height: '100%' }}>
</div>
</Card>
<Card title='中断排名' style={{ width: "calc(50% - 8px)", height: "100%", }}>
<div style={{ height: '100%' }}>
</div>
</Card>
</div>
</div>
</Body>
</div>
)
}
function mapStateToProps (state) {
const { auth, global, } = state;
const { auth, global, groupStatisticOnline } = state;
return {
user: auth.user,
actions: global.actions,
clientHeight: global.clientHeight,
groupStatisticOnline: groupStatisticOnline?.data
};
}

23
web/client/src/sections/projectGroup/containers/statistic.jsx

@ -26,10 +26,25 @@ const Statistic = ({ dispatch, actions, user, history, loading, groupStatistic,
key: 'name',
width: "30%",
render: (text, row) => <div style={{ cursor: 'pointer' }} onClick={() => {
localStorage.setItem('project_group_id', row.id)
history.push({
pathname: `/projectGroup/bigscreen`,
})
//id便
let projectGroup = JSON.parse(localStorage.getItem('project_group'))
if (!projectGroup) {
localStorage.setItem('project_group', JSON.stringify([{ userId: user?.id, projectGroupId: row?.id, name: row?.name }]))
} else {
let findOne = projectGroup?.find(v => v.userId == user?.id)
if (findOne) {
projectGroup?.forEach(v => {
if (v.userId == user?.id) {
v.projectGroupId = row?.id
v.name = row?.name
}
})
} else {
projectGroup.push({ userId: user?.id, projectGroupId: row?.id, name: row?.name })
}
localStorage.setItem('project_group', JSON.stringify(projectGroup))
}
history.push({ pathname: `/projectGroup/bigscreen`, })
}}>{text}</div>
}, {
title: '项目集类型',

3
web/client/src/utils/webapi.js

@ -38,7 +38,8 @@ export const ApiTable = {
//项目分组
projectGroup: 'project/group',
groupStatistic:'project/group/statistic',
groupStatistic: 'project/group/statistic',
groupStatisticOnline: 'project/group/statistic/online',
//告警
getProjectPoms: 'project/poms', //获取已绑定项目

Loading…
Cancel
Save