diff --git a/web/client/assets/images/console/hong_1.png b/web/client/assets/images/console/hong_1.png new file mode 100644 index 0000000..29e8703 Binary files /dev/null and b/web/client/assets/images/console/hong_1.png differ diff --git a/web/client/assets/images/console/huang_1.png b/web/client/assets/images/console/huang_1.png new file mode 100644 index 0000000..da0b063 Binary files /dev/null and b/web/client/assets/images/console/huang_1.png differ diff --git a/web/client/assets/images/console/icon_all.png b/web/client/assets/images/console/icon_all.png new file mode 100644 index 0000000..22fe3fd Binary files /dev/null and b/web/client/assets/images/console/icon_all.png differ diff --git a/web/client/assets/images/console/icon_offline.png b/web/client/assets/images/console/icon_offline.png new file mode 100644 index 0000000..addf367 Binary files /dev/null and b/web/client/assets/images/console/icon_offline.png differ diff --git a/web/client/assets/images/console/icon_online.png b/web/client/assets/images/console/icon_online.png new file mode 100644 index 0000000..31cdf11 Binary files /dev/null and b/web/client/assets/images/console/icon_online.png differ diff --git a/web/client/assets/images/console/icon_up.png b/web/client/assets/images/console/icon_up.png new file mode 100644 index 0000000..9400de5 Binary files /dev/null and b/web/client/assets/images/console/icon_up.png differ diff --git a/web/client/assets/images/console/icon_webpage.png b/web/client/assets/images/console/icon_webpage.png new file mode 100644 index 0000000..5127238 Binary files /dev/null and b/web/client/assets/images/console/icon_webpage.png differ diff --git a/web/client/assets/images/console/lan_1.png b/web/client/assets/images/console/lan_1.png new file mode 100644 index 0000000..c6e7b3d Binary files /dev/null and b/web/client/assets/images/console/lan_1.png differ diff --git a/web/client/assets/images/console/lv_1.png b/web/client/assets/images/console/lv_1.png new file mode 100644 index 0000000..d37eb5b Binary files /dev/null and b/web/client/assets/images/console/lv_1.png differ diff --git a/web/client/assets/images/console/member.png b/web/client/assets/images/console/member.png new file mode 100644 index 0000000..37a3347 Binary files /dev/null and b/web/client/assets/images/console/member.png differ diff --git a/web/client/assets/images/console/onGoing.png b/web/client/assets/images/console/onGoing.png new file mode 100644 index 0000000..c124829 Binary files /dev/null and b/web/client/assets/images/console/onGoing.png differ diff --git a/web/client/assets/images/console/suo.png b/web/client/assets/images/console/suo.png new file mode 100644 index 0000000..92e3599 Binary files /dev/null and b/web/client/assets/images/console/suo.png differ diff --git a/web/client/assets/images/console/yonghu.png b/web/client/assets/images/console/yonghu.png new file mode 100644 index 0000000..e67e296 Binary files /dev/null and b/web/client/assets/images/console/yonghu.png differ diff --git a/web/client/assets/images/problem/banner.gif b/web/client/assets/images/problem/banner.gif new file mode 100644 index 0000000..37cc8f6 Binary files /dev/null and b/web/client/assets/images/problem/banner.gif differ diff --git a/web/client/src/layout/components/header/index.jsx b/web/client/src/layout/components/header/index.jsx index ca80918..d338a87 100644 --- a/web/client/src/layout/components/header/index.jsx +++ b/web/client/src/layout/components/header/index.jsx @@ -6,133 +6,160 @@ import { IconTreeTriangleDown } from '@douyinfe/semi-icons'; import "./index.less"; const Header = (props) => { - const { dispatch, history, user, actions, socket, headerItems, tochange } = props; + const { dispatch, history, user, actions, socket, headerItems, tochange } = props; - return ( - <> -
-
+ } + > +
+
+ + {user?.name?.substr(0, 1)} + +
+ {user.name} +
v.name + '、')} style={{ width: 60, overflow: 'hidden', whiteSpace: 'nowrap', textOverflow: 'ellipsis', color: '#969799', fontSize: 12 }}>{user?.department?.map(v => v.name + '、')}
+
+
+
+
{ + history.push(`/userCenter`); + }}> +
+ +
+
+ 用户中心 +
+
+
+
+ +
+
+ 安全认证 +
+
+
{ + dispatch(actions.auth.logout(user)); + if (socket) { + socket.disconnect(); + } + history.push(`/signin`); + }}> + 退出 + {/* */} +
- {/* collapseButton collapseText */} + {/* collapseButton collapseText */} - - - } - /> - - - ); + + + } + /> + + + ); }; function mapStateToProps (state) { - const { global, auth, webSocket } = state; - return { - actions: global.actions, - user: auth.user, - socket: webSocket.socket, - }; + const { global, auth, webSocket } = state; + return { + actions: global.actions, + user: auth.user, + socket: webSocket.socket, + }; } export default connect(mapStateToProps)(Header); diff --git a/web/client/src/layout/containers/layout/index.jsx b/web/client/src/layout/containers/layout/index.jsx index 495636a..28a7f90 100644 --- a/web/client/src/layout/containers/layout/index.jsx +++ b/web/client/src/layout/containers/layout/index.jsx @@ -9,6 +9,7 @@ import Footer from '../../components/footer'; import { resize } from '../../actions/global'; import * as NProgress from 'nprogress'; import PerfectScrollbar from 'perfect-scrollbar'; +import { useLocation } from "react-router"; NProgress.configure({ template: ` @@ -22,7 +23,7 @@ NProgress.configure({ }); let scrollbar - +// const location111 = useLocation(); const LayoutContainer = props => { const { dispatch, msg, user, copyright, children, sections, clientWidth, clientHeight, @@ -116,7 +117,7 @@ const LayoutContainer = props => { if (lastSelectedKeys) {//如果有缓存 for (let i = 0; i < nextItems.length; i++) { if (JSON.parse(lastSelectedKeys)[0] == nextItems[i].itemKey) { - + let openArr = [] for (let j = 0; j < nextItems[i].items.length; j++) { openArr.push(nextItems[i].items[j].itemKey) @@ -137,6 +138,30 @@ const LayoutContainer = props => { } }, []) + useEffect(() => { + let pathnameArr = location.pathname.split('/') + let openArr = [] + for (let i = 0; i < allItems.length; i++) { + if (allItems[i].items) { + for (let j = 0; j < allItems[i].items.length; j++) { + if (allItems[i].items[j].items) { + for (let k = 0; k < allItems[i].items[j].items.length; k++) { + if (allItems[i].items[j].items[k].to == location.pathname) { + for (let o = 0; o < allItems[i].items.length; o++) { + openArr.push(allItems[i].items[o].itemKey) + } + localStorage.setItem('poms_selected_sider', JSON.stringify([pathnameArr[1]])) + localStorage.setItem('poms_open_sider', JSON.stringify(openArr)) + setLeftItems(allItems[i].items) + setLeftShow(true) + } + } + } + } + } + } + }, [location]) + useEffect(() => { NProgress.done(); if ((!user || !user.authorized)) { @@ -173,7 +198,7 @@ const LayoutContainer = props => { // websocket 使用测试 useEffect(() => { - // console.log(socket) + // console.log(socket) if (socket) { socket.on('CAMERA_ONLINE', function (msg) { console.info(msg); diff --git a/web/client/src/sections/console/containers/console.jsx b/web/client/src/sections/console/containers/console.jsx index f3bb34d..c976973 100644 --- a/web/client/src/sections/console/containers/console.jsx +++ b/web/client/src/sections/console/containers/console.jsx @@ -1,16 +1,87 @@ -import React, { useEffect } from 'react'; +import React, { useEffect, useState } from 'react'; import { connect } from 'react-redux'; -import { Spin, Card } from '@douyinfe/semi-ui'; +import { Timeline, Card, Button } from '@douyinfe/semi-ui'; +import { push } from 'react-router-redux'; import '../style.less' +import PerfectScrollbar from "perfect-scrollbar"; const { Meta } = Card; +let newScrollbar; +let overviewScrollbar; +let memberScrollbar; +let equipmentScrollbar; +let webScrollbar; +let problemsScrollbar; + + const Console = (props) => { const { dispatch, actions, user, loading, socket } = props + const stationList = [ + 'url(/assets/images/console/lan_1.png)', + 'url(/assets/images/console/lv_1.png)', + 'url(/assets/images/console/huang_1.png)', + 'url(/assets/images/console/hong_1.png)' + ] + const [timelineList, setTimelineList] = useState(['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''])//最新动态列表 + + const [memberList, setMemberList] = useState(['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''])//相关成员列表 + + const [equipmentList, setEquipmentList] = useState(['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''])//平台设备接入列表 + + const [webList, setWebList] = useState(['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''])//关联web应用列表 + const [problemsList, setProblemsList] = useState(['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''])//异常&问题列表 useEffect(() => { // ACTION 示例 // dispatch(actions.example.getMembers(user.orgId)) }, []) + 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(); + } + + // ACTION 示例 + // dispatch(actions.example.getMembers(user.orgId)) + }) // websocket 使用测试 // useEffect(() => { @@ -28,8 +99,418 @@ const Console = (props) => { return ( <> -
- +
+ {/* 头部 */} +
+
+
+ HI,欢迎回来,行业服务部 +
+
+ 刘昊然! +
+
+
+ +
+
+ {/* 主体 */} +
+ {/* 左边 */} +
+ {/* 工作台和统计概览 */} +
+ {/* 我的工作台 */} +
+
+
+
我的工作台
+
MY WORK STATION
+
+
+ setSetup(true)} /> +
+
+
+
+
+
+ 剩余问题: +
+
+ 122 +
+
+
+
+ 今日新增问题: +
+
+
+ 12223 +
+
+ +
+
+
+
+
+ 今日处理: +
+
+ 3 +
+
+
+ {/* 循环类型 */} + { + stationList.map((item, index) => { + return ( +
+
+
+ 关注的项目 + (个) +
+
+
112
+
进行中
+
+
+
+ ) + }) + } +
+ {/* 统计概览 */} +
+
+
+
统计概览
+
STATISTICAL OVERVIEW
+
+
+ setSetup(true)} /> +
+
+
+
+ {/* 项目里程碑 */} +
+
+ 项目里程碑 +
+
+
+
+ 立项时间: +
+
+ 2022-5-12 +
+
+
+
+ 施工时间: +
+
+ 2022-5-12至2022-12-12 +
+
+
+
+
+
+ 内验时间: +
+
+ 2023-1-18 +
+
+
+
+ 外验时间: +
+
+ 2023-3-18 +
+
+
+
+
+ 工程维保时间: +
+
+ 2022-11-11 +
+
+
+
+
+ 售后维修时间: +
+
+ 2022-11-11至2023-12-14 +
+
+ 进行中 +
+
+ {/* 相关成员 */} +
+
+ 相关成员 +
+
+ {memberList.map((item, index) => { + return ( +
+
+
+ 成员 +
+
+ 刘昊然 +
+
+ (负责人) +
+
+
+ 行业服务部 +
+
+ ) + })} +
+
+ {/* 平台设备接入 */} +
+
+ 平台设备接入 +
+
+ { + equipmentList.map((item, index) => { + return ( +
+
+ 5阶ZK1高清摄球机 +
+
+ 视频 +
+
+ 网络 + {/* 网络 */} +
+
+ 在线 +
+ {/*
+ 掉线 +
*/} +
+ ) + }) + } +
+
+ {/* 关联web应用 */} +
+
+ 关联web应用 +
+
+ { + webList.map((item, index) => { + return ( +
+
+
+ web应用 +
+
+ superchangnan.anxiny +
+
+
+ 第三方 +
+
+ ) + }) + } +
+
+ {/* 异常&问题 */} +
+
+ 异常&问题 +
+
+ { + problemsList.map((item, index) => { + return ( +
+
+ 【告警源A】数据信息中断,诊断为 服务异常,请前往确认 +
+
+ 2022-05-21 15:23:41 +
+
+ ) + }) + } +
+
+
+
+
+
+ {/* BI分析模块 */} +
+
+
+
我的工作台
+
MY WORK STATION
+
+
+ setSetup(true)} /> +
+
+
+
+ {/* 右边 */} +
+ {/* 最新动态 */} +
+
+
+
+
最新动态
+
RECENT NEWS
+
+
+ setSetup(true)} /> +
+
+
+ + {timelineList.map((item, index) => { + return ( + + A项目DTU设备状态异常,诊断为离线 + + ) + })} + +
+
+ {/* 我常用的工具 */} +
+
+
+
+
我常用的工具
+
MY USUAL TOOLS
+
+
+
+ + + + +
+
+ +
+
+
+
) diff --git a/web/client/src/sections/console/containers/index.js b/web/client/src/sections/console/containers/index.js index c8d0fe8..d290d54 100644 --- a/web/client/src/sections/console/containers/index.js +++ b/web/client/src/sections/console/containers/index.js @@ -1,5 +1,6 @@ 'use strict'; import Console from './console'; +import UserCenter from './userCenter'; -export { Console }; \ No newline at end of file +export { Console, UserCenter }; \ No newline at end of file diff --git a/web/client/src/sections/console/containers/userCenter.jsx b/web/client/src/sections/console/containers/userCenter.jsx new file mode 100644 index 0000000..4eb4b8c --- /dev/null +++ b/web/client/src/sections/console/containers/userCenter.jsx @@ -0,0 +1,82 @@ +import React, { useEffect, useState } from 'react'; +import { connect } from 'react-redux'; +import { Avatar, Card, Button } from '@douyinfe/semi-ui'; +import { push } from 'react-router-redux'; +import '../style.less' +import PerfectScrollbar from "perfect-scrollbar"; +const { Meta } = Card; + +const UserCenter = (props) => { + const { dispatch, actions, user, loading, socket } = props + useEffect(() => { + console.log('user',user); + // ACTION 示例 + // dispatch(actions.example.getMembers(user.orgId)) + }, []) + useEffect(() => { + + // ACTION 示例 + // dispatch(actions.example.getMembers(user.orgId)) + }) + + // websocket 使用测试 + // useEffect(() => { + // console.log(socket) + // if (socket) { + // socket.on('TEST', function (msg) { + // console.info(msg); + // }); + // return () => { + // socket.off("TEST"); + // } + // } + + // }, [socket]) + + return ( + <> +
+ {/* 头部 */} +
+
+
+ HI,欢迎回来,行业服务部 +
+
+ 刘昊然! +
+
+
+ {/* 主体 */} +
+
+
+
+
用户中心
+
USER CENTER
+
+
+
+ + {user.name.split('')[0]} + +
+
+ {/* moment(row.createTime).format("YYYY-MM-DD HH:mm:ss") */} +
+ + ) +} + +function mapStateToProps (state) { + const { auth, global, members, webSocket } = state; + return { + // loading: members.isRequesting, + user: auth.user, + // actions: global.actions, + // members: members.data, + // socket: webSocket.socket + }; +} + +export default connect(mapStateToProps)(UserCenter); diff --git a/web/client/src/sections/console/routes.js b/web/client/src/sections/console/routes.js index 9900cb1..7a9c027 100644 --- a/web/client/src/sections/console/routes.js +++ b/web/client/src/sections/console/routes.js @@ -1,5 +1,5 @@ 'use strict'; -import { Console, } from './containers'; +import { Console,UserCenter } from './containers'; export default [{ type: 'inner', @@ -10,4 +10,12 @@ export default [{ component: Console, // 不设置 component 则面包屑禁止跳转 } +}, { + type: 'inner', + route: { + path: "/userCenter", + key: 'userCenter', + breadcrumb: '用户中心', + component: UserCenter + } }]; \ No newline at end of file diff --git a/web/client/src/sections/console/style.less b/web/client/src/sections/console/style.less index 75ecdb6..d57914b 100644 --- a/web/client/src/sections/console/style.less +++ b/web/client/src/sections/console/style.less @@ -1,7 +1,18 @@ -#example { - box-shadow: 3px 3px 2px black; +.even{ + .semi-timeline-item-head-default{ + background-color: #005ABD; + } } - -#example:hover { - color: yellowgreen; +.odd{ + .semi-timeline-item-head-default{ + background-color: #FFFFFF; + border: 1px solid #A4CFFF; + } +} +.semi-timeline-item-content-time{ + font-size: 14px; +} +.semi-timeline-item-content{ + font-size: 12px; + width: calc(59% - 14px) !important; } \ No newline at end of file diff --git a/web/client/src/sections/problem/components/inspection.jsx b/web/client/src/sections/problem/components/inspection.jsx index 9d567e5..18d2d8a 100644 --- a/web/client/src/sections/problem/components/inspection.jsx +++ b/web/client/src/sections/problem/components/inspection.jsx @@ -48,28 +48,31 @@ const Inspection = ({ dispatch, actions, user, route, statistic }) => { useEffect(() => { if (projectScrollbar) projectScrollbar.destroy() const domEquipment = document.getElementById("inspection"); - if (unfold) { - projectScrollbar = new PerfectScrollbar("#inspection", { - suppressScrollY: true, - }); - if (domEquipment && projectScrollbar) projectScrollbar.update() - } else { - projectScrollbar = new PerfectScrollbar("#inspection", { - suppressScrollX: true, - }) - if (domEquipment && projectScrollbar) projectScrollbar.update() + if (domEquipment) { + if (unfold) { + projectScrollbar = new PerfectScrollbar("#inspection", { + suppressScrollY: true, + }); + if (domEquipment && projectScrollbar) projectScrollbar.update() + } else { + projectScrollbar = new PerfectScrollbar("#inspection", { + suppressScrollX: true, + }) + if (domEquipment && projectScrollbar) projectScrollbar.update() + } } + }) useEffect(() => { dispatch(problem.getAlarmLnspection(checkPatrol)).then((res) => { - // console.log(res.payload.data); + // console.log(res.payload.data) if (res.success) { setPatrolAbnormal(res.payload.data) setNotRead(res.payload.data.filter(v => !v.notedTime).length) } }) - }, [checkPatrol]); + }, [checkPatrol]) useEffect(() => { @@ -91,7 +94,7 @@ const Inspection = ({ dispatch, actions, user, route, statistic }) => { return ( -
+
@@ -192,118 +195,132 @@ const Inspection = ({ dispatch, actions, user, route, statistic }) => {
-
document.getElementById('unfold').style.display = 'none'} - onMouseOut={() => document.getElementById('unfold').style.display = 'block'} - id="inspection" style={{ width: 'calc(100% - 20px)', marginLeft: 10, height: unfold ? 280 : 600, whiteSpace: unfold ? 'nowrap' : '', position: "relative", }}> - {patrolAbnormal?.map((v, i) => -
{ - setPicturePop(true) - setPictureId(i); - setPictureData(patrolAbnormal[i]) - }} - > - -
- 获取时间:{moment(v.createTime).format("YYYY-MM-DD HH:mm:ss")} - {v.app?.name} -
- {v.notedPepUser ? : ""} -
)} + {patrolAbnormal?.length > 0 ? +
document.getElementById('unfold').style.display = 'none'} + onMouseOut={() => document.getElementById('unfold').style.display = 'block'} + id="inspection" style={{ width: 'calc(100% - 20px)', marginLeft: 10, height: unfold ? 280 : 600, whiteSpace: unfold ? 'nowrap' : '', position: "relative", }}> + {patrolAbnormal?.map((v, i) => +
{ + setPicturePop(true) + setPictureId(i); + setPictureData(patrolAbnormal[i]) + }} + > + +
+ 获取时间:{moment(v.createTime).format("YYYY-MM-DD HH:mm:ss")} + {v.app?.name} +
+ {v.notedPepUser ? : ""} +
)} -
-
e.stopPropagation()} - onMouseOut={(e) => e.stopPropagation()} - onClick={() => setUnfold(!unfold)} - style={{ - width: 'calc(100% - 20px)', marginLeft: 10, height: 24, - background: unfold ? 'linear-gradient(180deg, rgba(36,139,255,0) 0%, rgba(36,139,255,0.09) 100%)' : 'linear-gradient(180deg, rgba(218,218,218,0) 0%, rgba(212,212,212,0.38) 100%)', - borderRadius: 3, - lineHeight: '24px', - fontSize: 12, - zIndex: 100, - position: 'relative', - top: unfold ? -20 : 6, - left: 0, - textAlign: 'center', - color: unfold ? 'rgba(0,90,189,0.7)' : '#969799', - cursor: 'pointer', - }}>{unfold ? '展开更多' : '收起'} -
- {picturePop ? {pictureData?.app?.name} - - 未阅 {notRead}/{patrolAbnormal.length} - -
} - hasCancel={false} - footer={
- - 图片下载 - - - - - -
} - visible={true} - onOk={() => { +
+ :
+ 当前应用暂无自动巡检计划 +
+ } + {patrolAbnormal?.length > 0 ? +
e.stopPropagation()} + onMouseOut={(e) => e.stopPropagation()} + onClick={() => setUnfold(!unfold)} + style={{ + width: 'calc(100% - 20px)', marginLeft: 10, height: 24, + background: unfold ? 'linear-gradient(180deg, rgba(36,139,255,0) 0%, rgba(36,139,255,0.09) 100%)' : 'linear-gradient(180deg, rgba(218,218,218,0) 0%, rgba(212,212,212,0.38) 100%)', + borderRadius: 3, + lineHeight: '24px', + fontSize: 12, + zIndex: 100, + position: 'relative', + top: unfold ? -20 : 14, + left: 0, + textAlign: 'center', + color: unfold ? 'rgba(0,90,189,0.7)' : '#969799', + cursor: 'pointer', + }}>{unfold ? '展开更多' : '收起'} +
: ""} + { + picturePop ? {pictureData?.app?.name} + + 未阅 {notRead}/{patrolAbnormal.length} + +
} + hasCancel={false} + footer={
+ + 图片下载 + + + + + +
} + visible={true} + onOk={() => { - }} - width={837} - onCancel={() => { - setPicturePop(false) - setPictureId('') - if (timer) clearTimeout(timer) - }} - > -
- {pictureData.notedTime ? 核验信息:{pictureData.notedPepUser} {moment(pictureData.notedTime).format("YYYY-MM-DD HH:mm:ss")} : ""} - 截取时间:{moment(pictureData.createTime).format("YYYY-MM-DD HH:mm:ss")} - { - console.log(pictureData); - copy(pictureData?.router || "无相关地址"); - Notification.success({ - content: "复制成功", - duration: 2, - }) - }} + }} + width={837} + onCancel={() => { + setPicturePop(false) + setPictureId('') + if (timer) clearTimeout(timer) + }} + > +
+ {pictureData.notedTime ? 核验信息:{pictureData.notedPepUser} {moment(pictureData.notedTime).format("YYYY-MM-DD HH:mm:ss")} : ""} + 截取时间:{moment(pictureData.createTime).format("YYYY-MM-DD HH:mm:ss")} + { + console.log(pictureData); + copy(pictureData?.router || "无相关地址"); + Notification.success({ + content: "复制成功", + duration: 2, + }) + }} + /> +
+ -
- - - : "" + + : "" }
diff --git a/web/client/src/sections/problem/components/tableData.jsx b/web/client/src/sections/problem/components/tableData.jsx index a9652ee..8ec8f7c 100644 --- a/web/client/src/sections/problem/components/tableData.jsx +++ b/web/client/src/sections/problem/components/tableData.jsx @@ -48,6 +48,14 @@ const TableData = ({ route, dispatch, actions, collectData, setSetup, exhibition }) break; case 'videoAbnormal': + let cameraKind = [] + dispatch(problem.getAlarmVideoDeviceKind()).then((res) => { + if (res.success) { + cameraKind = res.payload.data.map(v => ({ name: v.kind, value: v.id })) + setGenre(res.payload.data.map(v => ({ name: v.kind, value: v.id }))) + } + }) + dispatch(problem.getAlarmVideoList({ ...search, pepProjectId: '' })).then((res) => { if (res.success) { // console.log(res); @@ -64,11 +72,11 @@ const TableData = ({ route, dispatch, actions, collectData, setSetup, exhibition yingshiToken: v.yingshiToken, AlarmContent: v.statusDescribe, // State: v.State, - station: v.station, - resolve: v.resolve, + station: v.station || [], + resolve: v.resolve || [], cameraChannelNo: v.cameraChannelNo, cameraSerialNo: v.cameraSerialNo, - cameraKindId: v.cameraKindId, + cameraKindId: v.cameraKindId ? cameraKind?.find(v => v.value == v.cameraKindId)?.name : "", venderName: v.venderName, platform: v.platform, confirm: v.confirmedContent, @@ -79,11 +87,6 @@ const TableData = ({ route, dispatch, actions, collectData, setSetup, exhibition setTableData(tableDatas) } }) - dispatch(problem.getAlarmVideoDeviceKind()).then((res) => { - if (res.success) { - setGenre(res.payload.data.map(v => ({ name: v.kind, value: v.id }))) - } - }) break; default: dispatch(problem.getAlarmDataGroup()).then((res) => { @@ -106,7 +109,7 @@ const TableData = ({ route, dispatch, actions, collectData, setSetup, exhibition setGenre(genreData) if (data && data[0]?.id) { dispatch(problem.getAlarmDataList({ ...query, ...search, groupId: data.map(v => v.id).join(), pepProjectId: '' })).then((res) => { - // console.log(res); + console.log(res); if (res.success) { setCount(res.payload.data?.count || 0) let tableDatas = res.payload.data?.rows?.map(v => ({ @@ -122,6 +125,7 @@ const TableData = ({ route, dispatch, actions, collectData, setSetup, exhibition AlarmGroupUnit: v.AlarmGroupUnit ? genreData.find(r => r.value == v.AlarmGroupUnit)?.name : "", Strategy: v.AlarmGroupUnit ? genreData.find(r => r.value == v.AlarmGroupUnit)?.name : "", type: v.AlarmGroupUnit ? genreData.find(r => r.value == v.AlarmGroupUnit)?.name : "", + cameraKindId: v.AlarmGroupUnit ? genreData.find(r => r.value == v.AlarmGroupUnit)?.name : "", AlarmCodeName: v.AlarmCodeName, CurrentLevel: v.CurrentLevel, detailCount: v.detailCount, @@ -129,6 +133,7 @@ const TableData = ({ route, dispatch, actions, collectData, setSetup, exhibition State: v.State, alarmType: v.alarmType, confirm: v.confirmedContent, + station: v.StructureLongitude && v.StructureLatitude ? v.StructureLongitude + '. ' + v.StructureLatitude : "", })) // console.log(tableDatas); setTableData(tableDatas) @@ -254,7 +259,7 @@ const TableData = ({ route, dispatch, actions, collectData, setSetup, exhibition state: v.state, keywordTarget: v.keywordTarget, keyword: v.keyword, - kindId:v.kindId, + kindId: v.kindId, groupUnitId: v.groupUnitId, errType: v.errType, confirmState: v.confirmState, diff --git a/web/client/src/sections/problem/containers/dataAlarm.jsx b/web/client/src/sections/problem/containers/dataAlarm.jsx index e4699fb..59cb6a5 100644 --- a/web/client/src/sections/problem/containers/dataAlarm.jsx +++ b/web/client/src/sections/problem/containers/dataAlarm.jsx @@ -165,7 +165,7 @@ const DataAlarm = ({ match, dispatch, actions, user, loading, socket, iotVcmpWeb strategyHit: ['index', 'projectName', 'StructureName', 'SourceName', 'Strategy', 'State', 'createTime', 'sustainTime', 'AlarmContent', 'CurrentLevel', 'updateTime', 'detailCount', 'confirm', 'confirmTime'], videoAbnormal: ['index', 'projectName', 'StructureName', 'SourceName', 'station', 'cameraKindId', 'venderName', 'point', 'cameraSerialNo', 'cameraChannelNo', 'platform', 'AlarmContent', 'resolve', 'createTime', 'updateTime', 'confirm', 'confirmTime', 'camerOnline'], useAbnormal: ['index', 'projectName', 'appName', 'url', 'type', 'alarmContent', 'createTime', 'updateTime', 'confirm', 'confirmTime'], - deviceAbnormal: ['index', 'projectName', 'StructureName', 'SourceName', 'station', 'alarmContent', 'venderName', 'AlarmContent', 'AlarmCodeName', 'createTime', 'updateTime', 'confirm', 'confirmTime'], + deviceAbnormal: ['index', 'projectName', 'StructureName', 'SourceName', 'station', 'alarmContent', 'cameraKindId', 'venderName', 'AlarmContent', 'AlarmCodeName', 'createTime', 'updateTime', 'confirm', 'confirmTime'], } //表格默认配置信息 const columns = { @@ -250,7 +250,7 @@ const DataAlarm = ({ match, dispatch, actions, user, loading, socket, iotVcmpWeb { name: '产生次数', sort: 19, value: 'detailCount', render: (_, r, index) => r.detailCount + '次' }, { name: '确认信息', sort: 20, value: 'confirm', render: (_, r, index) => { - return r.State == 3 ? '无' : r.State == 4 ? r.confirm : r.confirm || '未确认' + return r.State == 3 ? '无' : r.State == 4 ? r.confirm || '无' : r.confirm || '未确认' } }, { name: '确认/恢复时间', sort: 21, value: 'confirmTime', render: (_, r, index) =>
{r.confirmTime ? r.confirmTime : "无"}
}, @@ -279,11 +279,9 @@ const DataAlarm = ({ match, dispatch, actions, user, loading, socket, iotVcmpWeb return '当前' } }, - { name: '位置信息', sort: 11, value: 'station', render: (_, r, index) => r.station?.map(v =>
{v.position}
) }, + { name: '位置信息', sort: 11, value: 'station', render: (_, r, index) => route == 'deviceAbnormal' ? r.station : r.station?.map(v =>
{v.position}
) }, { - name: '设备类型', sort: 6, value: 'cameraKindId', render: (_, r, index) => { - - } + name: '设备类型', sort: 6, value: 'cameraKindId', }, { name: '设备厂家', sort: 10, value: 'venderName', render: (_, r, index) => r.platform ? '未知' : r.venderName }, { name: '通道号', sort: 10.1, value: 'cameraChannelNo' }, @@ -307,7 +305,7 @@ const DataAlarm = ({ match, dispatch, actions, user, loading, socket, iotVcmpWeb { name: '操作', sort: 25, value: 'text', render: (_, r, index) => { return
- {r.State && r.State >= 0 && r.State < 3 || route && ['videoAbnormal', 'useAbnormal'].includes(route) && !r.confirmTime ? + {r.State < 3 || route && ['videoAbnormal', 'useAbnormal'].includes(route) && !r.confirmTime ? : } - {route && ['dataLnterrupt', 'dataAbnormal', 'strategyHit'].includes(route) ? <> + {route && ['dataLnterrupt', 'dataAbnormal', 'strategyHit', 'deviceAbnormal'].includes(route) ? <> - + }}>查看} : route == 'videoAbnormal' ? <> @@ -501,7 +499,7 @@ const DataAlarm = ({ match, dispatch, actions, user, loading, socket, iotVcmpWeb field='textData' onChange={(e) => setContent(e)} /> - {(() => { + {route == 'videoAbnormal' ? (() => { let data if (selected.length == 1) { data = tableData.find(v => v.key == selected[0]) @@ -514,7 +512,7 @@ const DataAlarm = ({ match, dispatch, actions, user, loading, socket, iotVcmpWeb return v.name } })}中被多次绑定(可能拥有不同的名称),确认后,该设备的同类型告警也会被一同确认。
: "" - })()} + })() : ""} : ""} diff --git a/web/client/src/sections/service/actions/emPush.jsx b/web/client/src/sections/service/actions/emPush.jsx new file mode 100644 index 0000000..d4dcd9e --- /dev/null +++ b/web/client/src/sections/service/actions/emPush.jsx @@ -0,0 +1,14 @@ +'use strict'; + +import { ApiTable, basicAction } from '$utils' + +export function getPush () { //获取推送配置列表 + return dispatch => basicAction({ + type: 'get', + dispatch: dispatch, + actionType: 'GET_PUSH', + url: `${ApiTable.getPush}`, + msg: { error: '获取推送配置列表失败' }, + reducer: { name: '' } + }); +} diff --git a/web/client/src/sections/service/actions/index.js b/web/client/src/sections/service/actions/index.js index eb109ab..1014015 100644 --- a/web/client/src/sections/service/actions/index.js +++ b/web/client/src/sections/service/actions/index.js @@ -1,2 +1,7 @@ 'use strict'; +import * as emPush from './emPush' + +export default { + ...emPush +} \ No newline at end of file diff --git a/web/client/src/sections/service/components/pushModal.jsx b/web/client/src/sections/service/components/pushModal.jsx new file mode 100644 index 0000000..b2c73cd --- /dev/null +++ b/web/client/src/sections/service/components/pushModal.jsx @@ -0,0 +1,171 @@ +import React, { useState, useRef, useEffect } from "react"; +import { connect } from "react-redux"; +import { Modal, Form } from "@douyinfe/semi-ui"; +import { IconAlertCircle } from '@douyinfe/semi-icons'; + + +function pushModal (props) { + const { + close, + cancel, + visible, + dispatch, + pepList, + actions, + adminEdit,//是否是编辑 + editObj, + } = props; + const { install } = actions; + const form = useRef();//表单 + const [disablePeople, setDisablePeople] = useState(true); //页码信息 + const [peopleList, setPeopleList] = useState([]); //人员List + const [departmentId, setDepartmentId] = useState(); //部门id + const [peopleId, setPeopleId] = useState(); //人员id + //初始化 + useEffect(() => { + if (editObj.id) { + let departmentList = [] + for (let i = 0; i < pepList.length; i++) { + if (pepList[i].id == editObj.departments[0].id) { + departmentList = pepList[i].users + } + } + setPeopleList(departmentList) + setDepartmentId(editObj.departments[0].id) + setPeopleId(editObj.pepUserId) + setDisablePeople(false) + } + }, []); + + function handleOk () { + //点击弹框确定 右边按钮 + form.current + .validate() + .then((values) => { + if (adminEdit) { + dispatch(install.deteleOrganizationAdmin({id:editObj.id,msg:''})).then( + dispatch(install.postOrganizationUser({ role: ['admin'], pepUserId: values.pepUserId, msg: '修改管理员' })).then((res) => {//获取项企(PEP)全部部门及其下用户 + if (res.success) { + close(); + } + }) + ) + } + else { + dispatch(install.postOrganizationUser({ role: ['admin'], pepUserId: values.pepUserId, msg: '新增管理员' })).then((res) => {//获取项企(PEP)全部部门及其下用户 + if (res.success) { + close(); + } + }) + } + }) + } + function handleCancel () { + cancel(); + //点击弹框取消 左边按钮 + } + return ( + <> + +
+
+
+
成员成为管理员后,拥有平台所有权限和项目,成员的普通角色会被禁用。
+
+
{ + for (var key in field) { + if (key == 'department') { + if (values.department >= 0) { + let departmentList = [] + for (let i = 0; i < pepList.length; i++) { + if (pepList[i].id == values.department) { + departmentList = pepList[i].users + } + } + setPeopleList(departmentList) + setDisablePeople(false) + form.current.setValue('pepUserId', undefined); + } + else { + setPeopleList([]) + setDisablePeople(true) + form.current.setValue('pepUserId', undefined); + } + } + } + }} + getFormApi={(formApi) => (form.current = formApi)} + > +
+ + { + pepList.map((item, index) => { + return ( + + {item.name} + + ) + }) + } + +
+
+ + { + peopleList.map((item, index) => { + return ( + + {item.name} + + ) + }) + } + +
+
+
+
+ + ); +} +function mapStateToProps (state) { + const { auth, global, members } = state; + return { + // loading: members.isRequesting, + user: auth.user, + actions: global.actions, + // members: members.data, + }; +} + +export default connect(mapStateToProps)(pushModal); diff --git a/web/client/src/sections/service/containers/emPush.jsx b/web/client/src/sections/service/containers/emPush.jsx index 8abf95c..d91c9b6 100644 --- a/web/client/src/sections/service/containers/emPush.jsx +++ b/web/client/src/sections/service/containers/emPush.jsx @@ -1,34 +1,498 @@ -import React, { useEffect } from 'react'; +import React, { useEffect, useRef, useState } from 'react'; import { connect } from 'react-redux'; +import { Skeleton, Button, Pagination, Form, Popconfirm, Table } from '@douyinfe/semi-ui'; +import { SkeletonScreen, } from "$components"; +import moment from "moment"; +import pushModal from '../components/pushModal' +import '../style.less' +import { Setup } from "$components"; +// import { set } from 'nprogress'; +const EmPush = (props) => { + const form = useRef();//表单 + const { dispatch, actions, user, loading, socket } = props + const { service } = actions; + const [setup, setSetup] = useState(false); //表格设置是否显现 + const [setupp, setSetupp] = useState([]);//实际显示的表格列表 + const [tableSetup, setTableSetup] = useState([]); //单一表格设置信息 + const [query, setQuery] = useState({ limit: 10, page: 0 }); //页码信息 + const [limits, setLimits] = useState()//每页实际条数 + const mylimits = useRef(); //每页实际条数 + const [selected, setSelected] = useState([]) //表格被勾选项 + const [pushModal, setPushModal] = useState(false) //信鸽弹框 + const [systemEdit, setSystemEdit] = useState(false) //是否是修改 + const [anxincloudList, setAnxincloudList] = useState([]) //安心云列表 + const [peplist, setPeplist] = useState([]) //PEP项目管理项目列表 + const [appList, setAppList] = useState([]) //应用列表 + const [pepProjectId, setPepProjectId] = useState() //修改时项企id + const [anxincloudArr, setAnxincloudArr] = useState([]) //修改时已经选择的安心云列表 + const [pepname, setPepname] = useState() //修改时自定义项目名称 + const [anxinDelete, setAnxinDelete] = useState([]) //修改时安心云项目有删除,显示提示信息 + const [appArr, setAppArr] = useState([]) //修改时添加应用 + const [bindId, setBindId] = useState() //修改时绑定的id + const [tableKey, setTableKey] = useState([]) //修改时绑定的id + const page = useRef(query.page);//哪一页 + const EMPUSH = "empush"; + const tableList = [//表格属性 + { + title: '推送信息', + list: [ + { name: "策略类型", value: "pushWay" }, + { name: "推送机制", value: "noticeWay" }, + { name: "监听设备数量", value: "monitorCount" }, + { name: "累计推送次数", value: "logCount" }, + ] + }, +]; -const Server = (props) => { - const { dispatch, actions, user, loading, socket } = props - useEffect(() => { + function handleRow (record, index) {//斑马条纹 + // 给偶数行设置斑马纹 + if (index % 2 === 0) { + return { + style: { + background: '#FAFCFF', + } + }; + } else { + return {}; + } + } - }, []) + const [tableData, setTableData] = useState([]) //表格数据 + useEffect(() => { + attribute(); + dispatch(service.getPush(query)).then((res) => {//获取推送配置列表 + console.log('res.payload.datares.payload.data',res.payload.data); + // setAnxincloudList(res.payload.data) + }) + // dispatch(install.getProjectPmanage(query)).then((res) => {//获取PEP项目管理项目 + // setPeplist(res.payload.data) + // }) + // dispatch(install.getProjectAppList(query)).then((res) => {//获取应用列表 + // setAppList(res.payload.data) + // }) + localStorage.getItem(EMPUSH) == null + ? localStorage.setItem( + EMPUSH, + JSON.stringify(['pushWay','noticeWay','logCount','monitorCount']) + ) + : ""; + }, []) + useEffect(() => { + // getProjectPomsList(); + }, [query]); - return ( - <> -
- -
- - ) + function getProjectPomsList () { + // dispatch(install.getProjectPoms(query)).then((res) => {//获取已绑定项目 + // if (res.success) { + // let mytableData = JSON.parse(JSON.stringify(res.payload.data.rows)); + // let mytableKey = [] + // for (let index = 0; index < mytableData.length; index++) { + // mytableData[index].key = mytableData[index].id + // mytableKey.push(mytableData[index].id) + // } + // setTableKey(mytableKey) + // setTableData(mytableData) + // setLimits(res.payload.data.count) + // mylimits.current = res.payload.data.rows.length + // } + // }) + } + const [columns, setColumns] = useState([//表格属性 + { + title: "策略编号", + dataIndex: "index", + key: 'index', + render: (text, r, index) => { + return index + 1; + }, + }, + { + title: '策略名称', + dataIndex: "pepProjectName", + key: 'pepProjectName', + render: (_, row) => { + return row.pepProjectName + } + }, + { + title: "操作", + width: "20%", + dataIndex: "text", + key: 'text', + render: (_, row) => { + return ( +
+ + + { + // dispatch(install.deleteProjectBind({ bindId: row?.id, msg: '删除安心云、项目管理项目绑定关系' })).then(() => { + // if (page.current > 0 && mylimits.current < 2) { + // setQuery({ limit: 10, page: page.current - 1 }) + // } else { + // setQuery({ limit: 10, page: page.current }) + // } + // }) + }} + > + + +
+ ); + }, + }, + ]) + const rowSelection = { + selectedRowKeys: selected, + onChange: (selectedRowKeys, selectedRows) => { + setSelected(selectedRows.map(v => v.key)) + }, + } + //获取表格属性设置 + function attribute () { + const arr = localStorage.getItem(EMPUSH) + ? JSON.parse(localStorage.getItem(EMPUSH)) + : []; + + const column = [ + { + title: "关联项目", + dataIndex: "noticeWay", + key: "noticeWay", + render: (_, r, index) => { + return r.noticeWay; + }, + }, + { + title: "创建时间", + dataIndex: "logCount", + key: "logCount", + render: (_, r, index) => { + return (r.logCount + '次') + }, + }, + { + title: "接收人", + dataIndex: "monitorCount", + key: "monitorCount", + render: (_, r, index) => { + return r.monitorCount + }, + }, + { + title: "监听问题", + dataIndex: "pushWay", + key: "pushWay", + render: (_, r, index) => { + return r.pushWay=='email' ? '邮件通知' : '短信通知'; + }, + }, + { + title: "通知时效", + dataIndex: "text1", + key: "text1", + render: (_, r, index) => { + return r.text1 + }, + }, + { + title: "启用状态", + dataIndex: "text2", + key: "text2", + render: (_, r, index) => { + return r.text2 + }, + }, + { + title: "推送次数", + dataIndex: "time", + key: "time", + render: (_, r, index) => { + return r.time + }, + }, + ]; + for (let i = 0; i < arr.length; i++) { + let colum = column.filter((item) => { + return item.key === arr[i]; + }); + columns.splice(i + 2, 0, colum[0]); + } + setSetupp(columns); + } + return ( + <> +
+
+
+
+
EM推送
+
Em push
+
+
+
console.log(values)} + // onValueChange={values=>console.log(values)} + getFormApi={(formApi) => (form.current = formApi)} + layout="horizontal" + style={{ position: "relative", width: "100%", flex: 1 }} + > + + + {/* {.map((item) => { + return ( + + {item.name} + + ); + })} */} + + + {/* {.map((item) => { + return ( + + {item.name} + + ); + })} */} + + + +
+ setSetup(true)} /> +
+ +
+
+
+
预留预留预留预留预留预留预留预留预留预留预留预留预留预留预留预留预留预留预留预留预留预留
+
+
+ + s)} + dataSource={tableData} + bordered={false} + empty="暂无数据" + pagination={false} + onRow={handleRow} + rowSelection={rowSelection} + /> + +
+
+
勾选 {selected.length}条 信息
+ + { + // dispatch(install.deleteProjectBind({ bindId: selected.join(','), msg: '删除安心云、项目管理项目绑定关系' })).then(() => { + // if (page.current > 0 && mylimits.current == selected.length) { + // setQuery({ limit: 10, page: page.current - 1 }) + // } else { + // setQuery({ limit: 10, page: page.current }) + // } + // setSelected([]) + // }) + }} + > + + +
+
+ + 共{limits}条信息 + + { + setQuery({ limit: pageSize, page: currentPage - 1 }); + page.current = currentPage - 1 + setSelected([]) + }} + /> +
+
+ + + {/* {//映射关系弹框 + pushModal ? + { + setPushModal(false); + }} + close={() => { + setPushModal(false); + getProjectPomsList() + }} > + : '' + } */} + {setup ? ( + { + setSetup(false); + attribute(); + // setcameraSetup(false); + }} + /> + ) : ( + "" + )} + + ) } function mapStateToProps (state) { - const { auth, global, members, webSocket } = state; - return { - // loading: members.isRequesting, - // user: auth.user, - // actions: global.actions, - // members: members.data, - // socket: webSocket.socket - }; + const { auth, global, ProjectPoms } = state; + return { + // loading: ProjectPoms.isRequesting, + user: auth.user, + actions: global.actions, + // members: members.data, + }; } -export default connect(mapStateToProps)(Server); +export default connect(mapStateToProps)(EmPush); diff --git a/web/client/src/sections/service/style.less b/web/client/src/sections/service/style.less index 75ecdb6..b98d242 100644 --- a/web/client/src/sections/service/style.less +++ b/web/client/src/sections/service/style.less @@ -1,7 +1,5 @@ -#example { - box-shadow: 3px 3px 2px black; -} - -#example:hover { - color: yellowgreen; +.empush{ + .semi-input-wrapper{ + margin-bottom: 0px !important; + } } \ No newline at end of file diff --git a/web/client/src/utils/webapi.js b/web/client/src/utils/webapi.js index 784a070..7ed808c 100644 --- a/web/client/src/utils/webapi.js +++ b/web/client/src/utils/webapi.js @@ -48,6 +48,8 @@ export const ApiTable = { putAlarmVideoConfirm: 'alarm/video/confirm', //确认视频告警信息 getVcmpAuth: 'vcmp/auth', // 获取视频平台应用鉴权token + //服务-信鸽服务 + getPush: "push", //获取推送配置列表 }; export const RouteTable = {