|
|
@ -1,6 +1,6 @@ |
|
|
|
import React, { useEffect, useState } from 'react'; |
|
|
|
import React, { useEffect, useState, useRef } from 'react'; |
|
|
|
import { connect } from 'react-redux'; |
|
|
|
import { Timeline, Card, Button } from '@douyinfe/semi-ui'; |
|
|
|
import { Timeline, Card, Button, Modal, Form } from '@douyinfe/semi-ui'; |
|
|
|
import { push } from 'react-router-redux'; |
|
|
|
import '../style.less' |
|
|
|
import PerfectScrollbar from "perfect-scrollbar"; |
|
|
@ -17,8 +17,9 @@ let problemsScrollbar; |
|
|
|
let alarmScrollbar; |
|
|
|
|
|
|
|
|
|
|
|
const Console = (props) => { |
|
|
|
const Control = (props) => { |
|
|
|
const { dispatch, actions, user, loading, socket } = props |
|
|
|
const { control } = actions |
|
|
|
const stationList = [ |
|
|
|
'url(/assets/images/console/lan_1.png)', |
|
|
|
'url(/assets/images/console/lv_1.png)', |
|
|
@ -36,67 +37,93 @@ const Console = (props) => { |
|
|
|
const [problemsList, setProblemsList] = useState(['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''])//异常&问题列表 |
|
|
|
const [setup, setSetup] = useState(false); //设置是否显现 |
|
|
|
const [tableType, setTableType] = useState(''); //localStorage存储名 |
|
|
|
const [tool, setTool] = useState(false); //工具添加修改弹窗 |
|
|
|
const [alter, setAlter] = useState(false); //工具添加或编辑 |
|
|
|
const [compile, setCompile] = useState({}); //工具编辑的内容 |
|
|
|
const [toolShow, setToolShow] = useState([]); //工具展示 |
|
|
|
const [tableSetup, setTableSetup] = useState([]); //单一表格设置信息 |
|
|
|
const [exhibition, setExhibition] = useState({ workbench: [] }); //页面结构 |
|
|
|
|
|
|
|
|
|
|
|
const FormApi = useRef() |
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
consoleToollink() |
|
|
|
|
|
|
|
|
|
|
|
//初始化表格显示设置 |
|
|
|
let data = ['workbench'] |
|
|
|
data.map(v => { |
|
|
|
localStorage.getItem(v) == null |
|
|
|
? localStorage.setItem(v, JSON.stringify(show[v])) |
|
|
|
: ""; |
|
|
|
attribute(v) |
|
|
|
}) |
|
|
|
|
|
|
|
}, []) |
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
newScrollbar = new PerfectScrollbar("#news", { |
|
|
|
suppressScrollX: true, |
|
|
|
}); |
|
|
|
const domProject = document.getElementById("news"); |
|
|
|
if (domProject && newScrollbar) { |
|
|
|
newScrollbar.update(); |
|
|
|
} |
|
|
|
overviewScrollbar = new PerfectScrollbar("#overview", { |
|
|
|
suppressScrollY: true, |
|
|
|
}); |
|
|
|
const domProject1 = document.getElementById("overview"); |
|
|
|
if (domProject1 && overviewScrollbar) { |
|
|
|
overviewScrollbar.update(); |
|
|
|
} |
|
|
|
memberScrollbar = new PerfectScrollbar("#member", { |
|
|
|
suppressScrollX: true, |
|
|
|
}); |
|
|
|
const domProject2 = document.getElementById("member"); |
|
|
|
if (domProject2 && memberScrollbar) { |
|
|
|
memberScrollbar.update(); |
|
|
|
} |
|
|
|
equipmentScrollbar = new PerfectScrollbar("#equipment", { |
|
|
|
suppressScrollX: true, |
|
|
|
}); |
|
|
|
const domProject3 = document.getElementById("equipment"); |
|
|
|
if (domProject3 && equipmentScrollbar) { |
|
|
|
equipmentScrollbar.update(); |
|
|
|
} |
|
|
|
webScrollbar = new PerfectScrollbar("#web", { |
|
|
|
suppressScrollX: true, |
|
|
|
}); |
|
|
|
const domProject4 = document.getElementById("web"); |
|
|
|
if (domProject4 && webScrollbar) { |
|
|
|
webScrollbar.update(); |
|
|
|
} |
|
|
|
problemsScrollbar = new PerfectScrollbar("#problems", { |
|
|
|
suppressScrollX: true, |
|
|
|
}); |
|
|
|
const domProject5 = document.getElementById("problems"); |
|
|
|
if (domProject5 && problemsScrollbar) { |
|
|
|
problemsScrollbar.update(); |
|
|
|
} |
|
|
|
alarmScrollbar = new PerfectScrollbar("#alarm", { |
|
|
|
suppressScrollY: true, |
|
|
|
}); |
|
|
|
const domProject6 = document.getElementById("alarm"); |
|
|
|
if (domProject6 && alarmScrollbar) { |
|
|
|
alarmScrollbar.update(); |
|
|
|
} |
|
|
|
// newScrollbar = new PerfectScrollbar("#news", { |
|
|
|
// suppressScrollX: true, |
|
|
|
// }); |
|
|
|
// const domProject = document.getElementById("news"); |
|
|
|
// if (domProject && newScrollbar) { |
|
|
|
// newScrollbar.update(); |
|
|
|
// } |
|
|
|
// overviewScrollbar = new PerfectScrollbar("#overview", { |
|
|
|
// suppressScrollY: true, |
|
|
|
// }); |
|
|
|
// const domProject1 = document.getElementById("overview"); |
|
|
|
// if (domProject1 && overviewScrollbar) { |
|
|
|
// overviewScrollbar.update(); |
|
|
|
// } |
|
|
|
// memberScrollbar = new PerfectScrollbar("#member", { |
|
|
|
// suppressScrollX: true, |
|
|
|
// }); |
|
|
|
// const domProject2 = document.getElementById("member"); |
|
|
|
// if (domProject2 && memberScrollbar) { |
|
|
|
// memberScrollbar.update(); |
|
|
|
// } |
|
|
|
// equipmentScrollbar = new PerfectScrollbar("#equipment", { |
|
|
|
// suppressScrollX: true, |
|
|
|
// }); |
|
|
|
// const domProject3 = document.getElementById("equipment"); |
|
|
|
// if (domProject3 && equipmentScrollbar) { |
|
|
|
// equipmentScrollbar.update(); |
|
|
|
// } |
|
|
|
// webScrollbar = new PerfectScrollbar("#web", { |
|
|
|
// suppressScrollX: true, |
|
|
|
// }); |
|
|
|
// const domProject4 = document.getElementById("web"); |
|
|
|
// if (domProject4 && webScrollbar) { |
|
|
|
// webScrollbar.update(); |
|
|
|
// } |
|
|
|
// problemsScrollbar = new PerfectScrollbar("#problems", { |
|
|
|
// suppressScrollX: true, |
|
|
|
// }); |
|
|
|
// const domProject5 = document.getElementById("problems"); |
|
|
|
// if (domProject5 && problemsScrollbar) { |
|
|
|
// problemsScrollbar.update(); |
|
|
|
// } |
|
|
|
// alarmScrollbar = new PerfectScrollbar("#alarm", { |
|
|
|
// suppressScrollY: true, |
|
|
|
// }); |
|
|
|
// const domProject6 = document.getElementById("alarm"); |
|
|
|
// if (domProject6 && alarmScrollbar) { |
|
|
|
// alarmScrollbar.update(); |
|
|
|
// } |
|
|
|
|
|
|
|
// ACTION 示例 |
|
|
|
// dispatch(actions.example.getMembers(user.orgId)) |
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
const consoleToollink = () => { |
|
|
|
dispatch(control.getConsoleToollink()).then(res => { |
|
|
|
if (res.success) setToolShow(res.payload.data) |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
let Select = { |
|
|
|
workbench: ['project', 'data', 'app', 'device'], |
|
|
|
statistical: [], |
|
|
@ -111,40 +138,33 @@ const Console = (props) => { |
|
|
|
} |
|
|
|
|
|
|
|
let listAll = [ |
|
|
|
{ name: '关注的项目', sort: 1, key: 'project', data: [], img: 'url(/assets/images/console/lan_1.png)' }, |
|
|
|
{ name: '数据告警', sort: 2, key: 'data', data: [], img: 'url(/assets/images/console/lv_1.png)' }, |
|
|
|
{ name: '应用告警', sort: 2, key: 'app', data: [], img: 'url(/assets/images/console/hong_1.png)' }, |
|
|
|
{ name: '设备告警', sort: 2, key: 'device', data: [], img: 'url(/assets/images/console/hong_1.png)' }, |
|
|
|
{ name: '关注的项目', sort: 1, key: 'project', data: 1, img: 'url(/assets/images/console/lan_1.png)' }, |
|
|
|
{ name: '数据告警', sort: 2, key: 'data', data: 2, img: 'url(/assets/images/console/lv_1.png)' }, |
|
|
|
{ name: '应用告警', sort: 2, key: 'app', data: 3, img: 'url(/assets/images/console/hong_1.png)' }, |
|
|
|
{ name: '设备告警', sort: 2, key: 'device', data: 225, img: 'url(/assets/images/console/hong_1.png)' }, |
|
|
|
] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// const attribute = (name, route) => { |
|
|
|
// let arr = localStorage.getItem(name) |
|
|
|
// ? JSON.parse(localStorage.getItem(name)) |
|
|
|
// : []; |
|
|
|
// // console.log(arr); |
|
|
|
// if (route) { |
|
|
|
// let setup = tableList[route].map(v => columnAll.find(vv => v == vv.value)) |
|
|
|
const attribute = (title) => { |
|
|
|
let take = localStorage.getItem(title) |
|
|
|
? JSON.parse(localStorage.getItem(title)) |
|
|
|
: []; |
|
|
|
let data = Select[title].map(v => { |
|
|
|
let dataTitle = listAll.find(vv => v == vv.key) || {} |
|
|
|
console.log(dataTitle); |
|
|
|
return { name: dataTitle.name, value: dataTitle.key } |
|
|
|
}) |
|
|
|
console.log(data); |
|
|
|
let TableDisplay = take?.map(v => listAll?.find(vv => v == vv.key)) |
|
|
|
TableDisplay.sort((a, b) => a.sort - b.sort) |
|
|
|
setExhibition({ ...exhibition, [title]: TableDisplay }) |
|
|
|
setTableSetup([{ list: data }]) |
|
|
|
|
|
|
|
// let data = [] |
|
|
|
// data.splice(1, 0, ...arr, 'text') |
|
|
|
|
|
|
|
// let TableDisplay = data?.map(v => { |
|
|
|
// let datas = columnAll?.find(vv => v == vv.value) |
|
|
|
// if (datas) { |
|
|
|
// return { title: datas.name, sort: datas.sort, dataIndex: datas.value, rowKey: datas.value, render: datas.render } |
|
|
|
// } |
|
|
|
|
|
|
|
// }) |
|
|
|
// TableDisplay.sort((a, b) => a.sort - b.sort) |
|
|
|
// setExhibition(TableDisplay) |
|
|
|
// setTableSetup([{ list: setup }]) |
|
|
|
// } |
|
|
|
// } |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
return (11 ? <img src="/assets/images/install/watting.png" alt="" style={{ width: 'calc(100% + 16px)', position: "relative", top: -12, left: -8, }} /> : |
|
|
|
<> |
|
|
|
<div style={{ padding: '0px 40px', width: '100%' }} className='console'> |
|
|
|
{/* 头部 */} |
|
|
@ -215,17 +235,17 @@ const Console = (props) => { |
|
|
|
</div> |
|
|
|
{/* 循环类型 */} |
|
|
|
<div id='alarm' style={{ width: 'calc(100% - 200px)', position: 'relative', whiteSpace: 'nowrap', }}> |
|
|
|
{stationList.map((item, index) => { |
|
|
|
{exhibition['workbench'].map((item, index) => { |
|
|
|
return ( |
|
|
|
<div key={item} style={{ background: item, backgroundSize: "100% 100%", display: "inline-block", width: 270, height: 135, marginRight: 26 }}> |
|
|
|
<div key={item.name} style={{ background: item.img, backgroundSize: "100% 100%", display: "inline-block", width: 270, height: 135, marginRight: 26 }}> |
|
|
|
<div style={{ margin: '35px 0px 0px 134px' }}> |
|
|
|
<div> |
|
|
|
<span style={{ fontSize: 14, color: '#4A4A4A' }}>关注的项目</span> |
|
|
|
<span style={{ fontSize: 12, color: '#4A4A4A' }}>(个)</span> |
|
|
|
<span style={{ fontSize: 14, color: '#4A4A4A', fontWeight: 500, fontFamily: 'PingFangSC-Medium, PingFang SC' }}>{item.name}</span> |
|
|
|
<span style={{ fontSize: 12, color: '#4A4A4A' }}>{item.name == '关注的项目' ? ' ( 个 )' : ' ( 条 )'}</span> |
|
|
|
</div> |
|
|
|
<div style={{ marginTop: 15, display: 'flex', alignItems: 'center' }}> |
|
|
|
<div style={{ fontSize: 32, color: index == 0 ? '#0F7EFB' : index == 1 ? '#0091A1' : index == 2 ? '#FE9812' : '#FF7575', fontFamily: 'YouSheBiaoTiHei' }}>112</div> |
|
|
|
<div style={{ fontSize: 12, color: '#969799', marginLeft: 4 }}>进行中</div> |
|
|
|
<div style={{ fontSize: 32, color: index == 0 ? '#0F7EFB' : index == 1 ? '#0091A1' : index == 2 ? '#FE9812' : '#FF7575', fontFamily: 'YouSheBiaoTiHei' }}>{item.data}</div> |
|
|
|
{item.name == '关注的项目' ? '' : <div style={{ fontSize: 12, color: '#969799', marginLeft: 4 }}>待处理</div>} |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
@ -461,7 +481,7 @@ const Console = (props) => { |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
{/* 我常用的工具 */} |
|
|
|
<div style={{ marginTop: 20, background: '#FFFFFF', boxShadow: '0px 0px 12px 2px rgba(220,222,224,0.2)', borderRadius: 2, paddingTop: 20, paddingLeft: 21, height: 303 }}> |
|
|
|
<div style={{ marginTop: 20, background: '#FFFFFF', boxShadow: '0px 0px 12px 2px rgba(220,222,224,0.2)', borderRadius: 2, padding: 20 }}> |
|
|
|
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}> |
|
|
|
<div style={{ display: 'flex', alignItems: 'center' }}> |
|
|
|
<div style={{ width: 0, height: 20, borderLeft: '3px solid #005ABD', borderTop: '3px solid transparent', borderBottom: '3px solid transparent' }}></div> |
|
|
@ -469,66 +489,140 @@ const Console = (props) => { |
|
|
|
<div style={{ marginLeft: 6, fontSize: 12, color: '#969799', fontFamily: "DINExp", }}>MY USUAL TOOLS</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div |
|
|
|
onMouseLeave={() => { |
|
|
|
console.log(111111); |
|
|
|
document.getElementById('aa').style.display = 'none' |
|
|
|
}} |
|
|
|
style={{ marginTop: 24, position: 'relative', display: "inline-block" }}> |
|
|
|
<Button |
|
|
|
theme="solid" |
|
|
|
type="primary" |
|
|
|
style={{ |
|
|
|
width: 94, height: 29, borderRadius: 2, marginRight: 10, marginBottom: 15, |
|
|
|
background: '#0F7EFB', color: '#FFFFFF', border: '1px solid #0F7EFB', |
|
|
|
}} |
|
|
|
onContextMenu={(e) => { |
|
|
|
e.preventDefault(); |
|
|
|
document.getElementById('aa').style.display = 'block' |
|
|
|
}} |
|
|
|
onClick={(e) => { |
|
|
|
// console.log(e); |
|
|
|
|
|
|
|
}} |
|
|
|
|
|
|
|
> |
|
|
|
工单管理 |
|
|
|
</Button> |
|
|
|
<div id='aa' |
|
|
|
style={{ |
|
|
|
position: 'absolute', top: 12, right: -10, background: 'rgb(208 208 223 / 100%)', fontSize: 13, |
|
|
|
width: 50, textAlign: "center", borderRadius: 4, padding: '0 10px', display: "none" |
|
|
|
}}> |
|
|
|
<div style={{ lineHeight: '30px' }} |
|
|
|
onClick={() => { |
|
|
|
|
|
|
|
{toolShow.length > 0 ? |
|
|
|
toolShow?.map(v => |
|
|
|
<div |
|
|
|
onMouseLeave={() => { |
|
|
|
document.getElementById(v.id + 'name').style.display = 'none' |
|
|
|
}} |
|
|
|
>编辑</div> |
|
|
|
<div style={{ lineHeight: '30px' }} |
|
|
|
onClick={() => { |
|
|
|
id={v.id + v.name} |
|
|
|
style={{ marginTop: 24, position: 'relative', display: "inline-block", cursor: 'pointer' }}> |
|
|
|
<a href={v.link} target="_blank"> |
|
|
|
<Button |
|
|
|
theme="solid" |
|
|
|
type="primary" |
|
|
|
style={{ |
|
|
|
height: 29, borderRadius: 2, marginRight: 10, marginBottom: 15, |
|
|
|
background: '#0F7EFB', color: '#FFFFFF', border: '1px solid #0F7EFB', |
|
|
|
}} |
|
|
|
onContextMenu={(e) => { |
|
|
|
e.preventDefault(); |
|
|
|
document.getElementById(v.id + 'name').style.display = 'block' |
|
|
|
}} |
|
|
|
> |
|
|
|
{v.name} |
|
|
|
</Button> |
|
|
|
</a> |
|
|
|
<div id={v.id + 'name'} |
|
|
|
style={{ |
|
|
|
position: 'absolute', top: 12, right: -10, background: 'rgb(208 208 223 / 100%)', fontSize: 13, |
|
|
|
width: 50, textAlign: "center", borderRadius: 4, padding: '0 10px', display: "none" |
|
|
|
}}> |
|
|
|
<div style={{ lineHeight: '30px' }} |
|
|
|
onClick={() => { |
|
|
|
setTool(true) |
|
|
|
setAlter(true) |
|
|
|
setCompile({ id: v.id, name: v.name, link: v.link, }) |
|
|
|
}} |
|
|
|
>编辑</div> |
|
|
|
<div style={{ lineHeight: '30px' }} |
|
|
|
onClick={() => { |
|
|
|
dispatch(control.deleteConsoleToollink(v.id)).then(res => { |
|
|
|
if (res.success) consoleToollink() |
|
|
|
}) |
|
|
|
}} |
|
|
|
>删除</div> |
|
|
|
</div> |
|
|
|
</div>) : ""} |
|
|
|
|
|
|
|
}} |
|
|
|
>删除</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<Button |
|
|
|
theme="solid" |
|
|
|
type="primary" |
|
|
|
style={{ |
|
|
|
width: '100%', |
|
|
|
height: 40, |
|
|
|
borderRadius: 2, |
|
|
|
marginTop: 20, |
|
|
|
background: '#F2F3F5', |
|
|
|
color: '#0F7EFB', |
|
|
|
border: '1px solid #F2F3F5' |
|
|
|
}} |
|
|
|
onClick={() => { |
|
|
|
setTool(true) |
|
|
|
}} |
|
|
|
> |
|
|
|
添加 |
|
|
|
</Button> |
|
|
|
|
|
|
|
</div> |
|
|
|
</div>75 |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
{setup ? ( |
|
|
|
<Setup |
|
|
|
tableType={tableType} |
|
|
|
tableList={tableSetup} |
|
|
|
close={() => { |
|
|
|
setSetup(false); |
|
|
|
attribute(tableType[route], route); |
|
|
|
setTableType('') |
|
|
|
}} |
|
|
|
/> |
|
|
|
) : ( |
|
|
|
"" |
|
|
|
)} |
|
|
|
{/* 页面各个设置弹窗 */} |
|
|
|
{ |
|
|
|
setup ? ( |
|
|
|
<Setup |
|
|
|
tableType={tableType} |
|
|
|
tableList={tableSetup} |
|
|
|
close={() => { |
|
|
|
setSetup(false); |
|
|
|
attribute(tableType); |
|
|
|
setTableType('') |
|
|
|
}} |
|
|
|
/> |
|
|
|
) : ( |
|
|
|
"" |
|
|
|
) |
|
|
|
} |
|
|
|
{/* 工具添加修改弹窗 */} |
|
|
|
{tool ? <Modal |
|
|
|
title={alter ? '编辑' : "添加"} |
|
|
|
visible={true} |
|
|
|
width={600} |
|
|
|
onCancel={() => { |
|
|
|
setTool(false) |
|
|
|
setAlter(false) |
|
|
|
setCompile({}) |
|
|
|
}} |
|
|
|
onOk={() => { |
|
|
|
FormApi.current.validate().then((v) => { |
|
|
|
console.log(v); |
|
|
|
dispatch(control.putConsoleToollink({ id: compile?.id, name: v.name, link: v.link })).then(res => { |
|
|
|
if (res.success) { |
|
|
|
setTool(false) |
|
|
|
setAlter(false) |
|
|
|
setCompile({}) |
|
|
|
consoleToollink() |
|
|
|
} |
|
|
|
}) |
|
|
|
}) |
|
|
|
}} |
|
|
|
> |
|
|
|
<div style={{ paddingLeft: 20 }}> |
|
|
|
<Form |
|
|
|
onSubmit={(values) => console.log(values)} |
|
|
|
getFormApi={(formApi) => (FormApi.current = formApi)} |
|
|
|
> |
|
|
|
<Form.Input |
|
|
|
label='工具名称' |
|
|
|
labelPosition="left" |
|
|
|
rules={[{ required: true, message: "请输入工具名称,1~10个字符,支持中英文,数字及常见符号-_ /." }]} |
|
|
|
field='name' |
|
|
|
initValue={compile?.name || ''} |
|
|
|
placeholder='请输入工具名称' |
|
|
|
/> |
|
|
|
<Form.TextArea maxCount={50} showClear |
|
|
|
label='地址链接' |
|
|
|
labelPosition="left" |
|
|
|
placeholder='请输入URL' |
|
|
|
initValue={compile?.link || ''} |
|
|
|
rules={[{ required: true, message: "请输入地址链接" }]} |
|
|
|
field='link' |
|
|
|
/> |
|
|
|
</Form> |
|
|
|
</div> |
|
|
|
</Modal> : "" |
|
|
|
} |
|
|
|
</> |
|
|
|
) |
|
|
|
} |
|
|
@ -538,10 +632,10 @@ function mapStateToProps (state) { |
|
|
|
return { |
|
|
|
// loading: members.isRequesting, |
|
|
|
user: auth.user, |
|
|
|
// actions: global.actions, |
|
|
|
actions: global.actions, |
|
|
|
// members: members.data, |
|
|
|
// socket: webSocket.socket |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
export default connect(mapStateToProps)(Console); |
|
|
|
export default connect(mapStateToProps)(Control); |