From bb8342d1e3158c3c5fe56f64e95680558c11a0cc Mon Sep 17 00:00:00 2001 From: wenlele Date: Wed, 26 Oct 2022 14:56:31 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/.vscode/launch.json | 4 +- api/app/lib/controllers/alarm/app.js | 6 +- api/app/lib/controllers/control/analysis.js | 140 +++++ api/app/lib/routes/control/index.js | 3 + .../sections/control/containers/control.jsx | 511 +++++++++++------- .../sections/problem/components/sideSheet.jsx | 2 +- .../sections/problem/components/tableData.jsx | 1 + 7 files changed, 468 insertions(+), 199 deletions(-) diff --git a/api/.vscode/launch.json b/api/.vscode/launch.json index 5018623..3388416 100644 --- a/api/.vscode/launch.json +++ b/api/.vscode/launch.json @@ -16,9 +16,9 @@ "-p 4600", "-f http://localhost:4600", // 研发 - "-g postgres://postgres:123@10.8.30.32:5432/orational_service", + // "-g postgres://postgres:123@10.8.30.32:5432/orational_service", // 测试 - //"-g postgres://FashionAdmin:123456@10.8.30.156:5432/POMS", + "-g postgres://FashionAdmin:123456@10.8.30.156:5432/POMS", "-k node35:6667,node36:6667,node37:6667", "--iotaProxy http://10.8.30.157:17007", "--redisHost 10.8.30.112", diff --git a/api/app/lib/controllers/alarm/app.js b/api/app/lib/controllers/alarm/app.js index 5279241..723435e 100644 --- a/api/app/lib/controllers/alarm/app.js +++ b/api/app/lib/controllers/alarm/app.js @@ -78,9 +78,9 @@ async function inspectionList(ctx) { } }] } - if (timeStart && timeEnd) { - findOption.where.createTime = { $between: [moment(timeStart).format(), moment(timeEnd).format()] } - } + // if (timeStart && timeEnd) { + // findOption.where.createTime = { $between: [moment(timeStart).format(), moment(timeEnd).format()] } + // } if (noted) { if (noted == 'noted') { findOption.where.notedTime = { $ne: null } diff --git a/api/app/lib/controllers/control/analysis.js b/api/app/lib/controllers/control/analysis.js index e6e741f..b83048d 100644 --- a/api/app/lib/controllers/control/analysis.js +++ b/api/app/lib/controllers/control/analysis.js @@ -1,6 +1,7 @@ 'use strict'; const moment = require('moment'); + async function dataList (ctx) { try { const { models } = ctx.fs.dc; @@ -81,10 +82,149 @@ async function dataList (ctx) { } } +async function userlist (ctx) { + try { + const models = ctx.fs.dc.models; + const { clickHouse } = ctx.app.fs + const sequelize = ctx.fs.dc.orm; + + const { pepId } = ctx.query + + const excludeField = ['lastInTime', 'inTimes', 'onlineDuration', 'lastInAddress', 'deleted', 'updateTime'] + + let findOption = { + attributes: { + exclude: excludeField, + // include: [[sequelize.fn('array_length', sequelize.col('role')), 'roleCount']] + }, + where: { + deleted: false, + $or: [{ + $not: { + role: { $contained: ['SuperAdmin', 'admin'] } + } + }, + sequelize.where(sequelize.fn('cardinality', sequelize.col('role')), 0)], + // $not: { + // role: { $contained: ['SuperAdmin', 'admin'] } + // } + }, + order: [['updateTime', 'DESC']] + } + + const userRes = await models.User.findAndCountAll(findOption) + + const adminRes = await models.User.findAll({ + where: { + role: { $contains: ['admin'] } + }, + attributes: { + exclude: excludeField, + }, + order: [['updateTime', 'DESC']] + }) + + let userIds = new Set() + let pomsProjectIds = new Set() + for (let u of userRes.rows.concat(adminRes)) { + userIds.add(u.pepUserId) + for (let pid of u.correlationProject) { + pomsProjectIds.add(pid) + } + } + // 查用户所属的项企pep的部门、人员信息 + let userPepRes = userIds.size ? + await clickHouse.pepEmis.query(` + SELECT DISTINCT + user.id AS id, "user"."name" AS name, department.name AS depName, department.id AS depId + FROM department_user + LEFT JOIN user + ON department_user.user=user.id + LEFT JOIN department + ON department.id=department_user.department + WHERE + user.id IN (${[...userIds].join(',')}) + AND department.delete=false` + ).toPromise() : + [] + + // 查用户绑定的当前系统的项目 id + let pomsProjectRes = await models.ProjectCorrelation.findAll({ + where: { + id: { $in: [...pomsProjectIds] }, + // del: false + } + }) + // 获取响应的绑定的 项企项目的 id + let pepPojectIds = new Set() + for (let p of pomsProjectRes) { + if (p.pepProjectId) { + pepPojectIds.add(p.pepProjectId) + } + } + // 查对应的项企项目信息 + let pepProjectRes = pepPojectIds.size ? + await clickHouse.projectManage.query(` + SELECT id, project_name, isdelete FROM t_pim_project WHERE id IN (${[...pepPojectIds]}) + `).toPromise() : + [] + + // 遍历用户并将查到的信息拼合 + for (let u of userRes.rows.concat(adminRes)) { + // 用户信息 + const corUsers = userPepRes.filter(up => up.id == u.pepUserId) + u.dataValues.name = corUsers.length ? corUsers[0].name : '' + u.dataValues.departments = corUsers.length ? corUsers.map(cu => { + return { + name: cu.depName, + id: cu.depId + } + }) : [] + // pep项目信息 + u.dataValues.correlationProject = u.dataValues.correlationProject.map(cpid => { + let returnData = { + id: cpid, + } + const corPomsProject = pomsProjectRes.find(ppr => ppr.id == cpid) + if (corPomsProject) { + returnData.name = corPomsProject.name + returnData.del = corPomsProject.del + if (corPomsProject.pepProjectId) { + returnData.pepProjectId = corPomsProject.pepProjectId + const corPepProject = pepProjectRes.find(ppr => ppr.id == corPomsProject.pepProjectId) + if (corPepProject) { + returnData.pepProjectName = corPepProject.project_name + returnData.pepIsdelete = corPepProject.isdelete + } + } + } + return returnData + }) + } + + let personnel = userRes.rows.filter(r => r.correlationProject.length > 0) + + if (pepId) { + personnel = personnel.filter(r => r.dataValues.correlationProject.map(v => v.id).includes(Number(pepId))) + } + + ctx.status = 200 + ctx.body = { + personnel: personnel.map(v => v.dataValues.name) + } + } catch (error) { + ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); + ctx.status = 400; + ctx.body = { + + } + } +} module.exports = { dataList, + userlist }; \ No newline at end of file diff --git a/api/app/lib/routes/control/index.js b/api/app/lib/routes/control/index.js index 95aa8e5..39f71f4 100644 --- a/api/app/lib/routes/control/index.js +++ b/api/app/lib/routes/control/index.js @@ -20,6 +20,9 @@ module.exports = function (app, router, opts) { app.fs.api.logAttr['GET/analysis/dataList'] = { content: '查询数据告警产生,确认数量', visible: true }; router.get('/analysis/dataList', analysis.dataList); + app.fs.api.logAttr['GET/analysis/userlist'] = { content: '查询关联人员', visible: true }; + router.get('/analysis/userlist', analysis.userlist); + //项目概览 diff --git a/web/client/src/sections/control/containers/control.jsx b/web/client/src/sections/control/containers/control.jsx index ed5b649..3f14e79 100644 --- a/web/client/src/sections/control/containers/control.jsx +++ b/web/client/src/sections/control/containers/control.jsx @@ -6,6 +6,7 @@ import '../style.less' import PerfectScrollbar from "perfect-scrollbar"; import repairFQA from '../../means/containers/repairFQA'; import { Setup, OutHidden } from "$components"; +import ReactECharts from 'echarts-for-react'; const { Meta } = Card; let newScrollbar; @@ -18,7 +19,7 @@ let alarmScrollbar; const Control = (props) => { - const { dispatch, actions, user, loading, socket ,pepProjectId} = props + const { dispatch, actions, user, loading, socket, pepProjectId } = props const { control } = actions const stationList = [ 'url(/assets/images/console/lan_1.png)', @@ -42,17 +43,16 @@ const Control = (props) => { const [compile, setCompile] = useState({}); //工具编辑的内容 const [toolShow, setToolShow] = useState([]); //工具展示 const [tableSetup, setTableSetup] = useState([]); //单一表格设置信息 - const [exhibition, setExhibition] = useState({ workbench: [] }); //页面结构 - const [workData, setWorkData] = useState({}); //我的工作台数据 - + const [workData, setWorkData] = useState(); //我的工作台数据 + const exhibition = useRef({ workbench: [], statistical: [] }) //页面结构 const FormApi = useRef() useEffect(() => { consoleToollink() //初始化表格显示设置 - let data = ['workbench'] + let data = ['workbench', 'statistical', 'analyse'] data.map(v => { localStorage.getItem(v) == null ? localStorage.setItem(v, JSON.stringify(show[v])) @@ -63,62 +63,84 @@ const Control = (props) => { }, []) useEffect(() => { - dispatch(control.geteteConsoleCount({pepProjectId:pepProjectId})).then(res => { + dispatch(control.geteteConsoleCount({ pepProjectId: pepProjectId })).then(res => { if (res.success) setWorkData(res.payload.data) }) }, [pepProjectId]) useEffect(() => { - newScrollbar = new PerfectScrollbar("#news", { - suppressScrollX: true, - }); + const domProject = document.getElementById("news"); - if (domProject && newScrollbar) { - newScrollbar.update(); + if (domProject) { + newScrollbar = new PerfectScrollbar("#news", { + suppressScrollX: true, + }); + if (domProject && newScrollbar) { + newScrollbar.update(); + } } - overviewScrollbar = new PerfectScrollbar("#overview", { - suppressScrollY: true, - }); + const domProject1 = document.getElementById("overview"); - if (domProject1 && overviewScrollbar) { - overviewScrollbar.update(); + if (domProject1) { + overviewScrollbar = new PerfectScrollbar("#overview", { + suppressScrollY: true, + }); + if (domProject1 && overviewScrollbar) { + overviewScrollbar.update(); + } } - memberScrollbar = new PerfectScrollbar("#member", { - suppressScrollX: true, - }); + const domProject2 = document.getElementById("member"); - if (domProject2 && memberScrollbar) { - memberScrollbar.update(); + if (domProject2) { + memberScrollbar = new PerfectScrollbar("#member", { + suppressScrollX: true, + }); + if (domProject2 && memberScrollbar) { + memberScrollbar.update(); + } } - equipmentScrollbar = new PerfectScrollbar("#equipment", { - suppressScrollX: true, - }); + const domProject3 = document.getElementById("equipment"); - if (domProject3 && equipmentScrollbar) { - equipmentScrollbar.update(); + if (domProject3) { + equipmentScrollbar = new PerfectScrollbar("#equipment", { + suppressScrollX: true, + }); + if (domProject3 && equipmentScrollbar) { + equipmentScrollbar.update(); + } } - webScrollbar = new PerfectScrollbar("#web", { - suppressScrollX: true, - }); + const domProject4 = document.getElementById("web"); - if (domProject4 && webScrollbar) { - webScrollbar.update(); + if (domProject4) { + webScrollbar = new PerfectScrollbar("#web", { + suppressScrollX: true, + }) + if (domProject4 && webScrollbar) { + webScrollbar.update(); + } } - problemsScrollbar = new PerfectScrollbar("#problems", { - suppressScrollX: true, - }); + const domProject5 = document.getElementById("problems"); - if (domProject5 && problemsScrollbar) { - problemsScrollbar.update(); + if (domProject5) { + problemsScrollbar = new PerfectScrollbar("#problems", { + suppressScrollX: true, + }); + if (domProject5 && problemsScrollbar) { + problemsScrollbar.update(); + } } - alarmScrollbar = new PerfectScrollbar("#alarm", { - suppressScrollY: true, - }); + const domProject6 = document.getElementById("alarm"); - if (domProject6 && alarmScrollbar) { - alarmScrollbar.update(); + if (domProject6) { + alarmScrollbar = new PerfectScrollbar("#alarm", { + suppressScrollY: true, + }); + if (domProject6 && alarmScrollbar) { + alarmScrollbar.update(); + } } + // ACTION 示例 // dispatch(actions.example.getMembers(user.orgId)) }) @@ -132,25 +154,37 @@ const Control = (props) => { let Select = { workbench: ['project', 'data', 'app', 'device'], - statistical: [], - analyse: [], + statistical: ['milestone', 'personnel', 'DeviceAccess', 'web', 'problem'], + analyse: ['dataInterrupt', 'dataAnomaly', 'strategyHit', 'videoException', 'appAbnormal', 'unitException', 'problemAnalysis'], dynamic: [], } let show = { workbench: ['project', 'data', 'app', 'device'], - statistical: [], - analyse: [], + statistical: ['milestone', 'personnel', 'DeviceAccess', 'web', 'problem'], + analyse: ['dataInterrupt', 'dataAnomaly', 'strategyHit', 'videoException', 'appAbnormal', 'unitException', 'problemAnalysis'], dynamic: [], } let listAll = [ - { name: '关注的项目', sort: 1, key: 'project', data: workData?.projects, img: 'url(/assets/images/console/lan_1.png)' }, - { name: '数据告警', sort: 2, key: 'data', data: workData?.dataSurplus, img: 'url(/assets/images/console/lv_1.png)' }, - { name: '应用告警', sort: 2, key: 'app', data: workData?.appSurplus, img: 'url(/assets/images/console/hong_1.png)' }, - { name: '设备告警', sort: 2, key: 'device', data: workData?.toolSurplus, img: 'url(/assets/images/console/hong_1.png)' }, + { name: '关注的项目', sort: 1, key: 'project', data: workData?.projects || 0, img: 'url(/assets/images/console/lan_1.png)' }, + { name: '数据告警', sort: 2, key: 'data', data: workData?.dataSurplus || 0, img: 'url(/assets/images/console/lv_1.png)' }, + { name: '应用告警', sort: 2, key: 'app', data: workData?.appSurplus || 0, img: 'url(/assets/images/console/hong_1.png)' }, + { name: '设备告警', sort: 2, key: 'device', data: workData?.toolSurplus || 0, img: 'url(/assets/images/console/hong_1.png)' }, + + { name: '项目里程碑', sort: 1, key: 'milestone', }, + { name: '相关成员', sort: 2, key: 'personnel', }, + { name: '平台设备接入', sort: 3, key: 'DeviceAccess', }, + { name: '关联web应用', sort: 4, key: 'web', }, + { name: '异常&问题', sort: 5, key: 'problem', }, + + { name: '数据中断', sort: 5, key: 'dataInterrupt', }, + { name: '数据异常', sort: 5, key: 'dataAnomaly', }, + { name: '策略命中', sort: 5, key: 'strategyHit', }, + { name: '视频异常', sort: 5, key: 'videoException', }, + { name: '应用异常', sort: 5, key: 'appAbnormal', }, + { name: '设备异常', sort: 5, key: 'unitException', }, + { name: '问题处置效率分析', sort: 5, key: 'problemAnalysis', }, ] - console.log(workData); - console.log(listAll); useEffect(() => { attribute('workbench') @@ -166,14 +200,14 @@ const Control = (props) => { }) let TableDisplay = take?.map(v => listAll?.find(vv => v == vv.key)) TableDisplay.sort((a, b) => a.sort - b.sort) - setExhibition({ ...exhibition, [title]: TableDisplay }) + exhibition.current = { ...exhibition.current, [title]: TableDisplay } setTableSetup([{ list: data }]) } return ( - // 11 ? : + 11 ? : <>
{/* 头部 */} @@ -207,6 +241,7 @@ const Control = (props) => { { setSetup(true) setTableType('workbench') + attribute('workbench') }} />
@@ -244,7 +279,7 @@ const Control = (props) => { {/* 循环类型 */}
- {exhibition['workbench']?.map((item, index) => { + {exhibition.current['workbench']?.map((item, index) => { return (
@@ -271,181 +306,195 @@ const Control = (props) => {
STATISTICAL OVERVIEW
- setSetup(true)} /> + { + setSetup(true) + setTableType('statistical') + attribute('statistical') + }} />
{/* 项目里程碑 */} -
-
- 项目里程碑 -
-
-
-
- 立项时间: -
-
- 2022-5-12 -
+ {exhibition.current?.statistical?.find(v => v.key == 'milestone') ? +
+
+ 项目里程碑
-
-
- 施工时间: +
+
+
+ 立项时间: +
+
+ 2022-5-12 +
-
- 2022-5-12至2022-12-12 +
+
+ 施工时间: +
+
+ 2022-5-12至2022-12-12 +
-
-
-
-
- 内验时间: +
+
+
+ 内验时间: +
+
+ 2023-1-18 +
-
- 2023-1-18 +
+
+ 外验时间: +
+
+ 2023-3-18 +
-
+
- 外验时间: + 工程维保时间:
- 2023-3-18 + 2022-11-11
-
-
-
- 工程维保时间: -
-
- 2022-11-11 -
-
-
-
-
- 售后维修时间: -
-
- 2022-11-11至2023-12-14 +
+
+
+ 售后维修时间: +
+
+ 2022-11-11至2023-12-14 +
+ 进行中
- 进行中
-
+ : ""} {/* 相关成员 */} -
-
- 相关成员 -
-
- {memberList.map((item, index) => { - return ( -
-
-
- 成员 -
-
- 刘昊然 + {exhibition.current?.statistical?.find(v => v.key == 'personnel') ? +
+
+ 相关成员 +
+
+ {memberList.map((item, index) => { + return ( +
+
+
+ 成员 +
+
+ 刘昊然 +
+
+ (负责人) +
-
- (负责人) +
+ 行业服务部
-
- 行业服务部 -
-
- ) - })} + ) + })} +
-
+ : ""} {/* 平台设备接入 */} -
-
- 平台设备接入 -
-
- { - equipmentList.map((item, index) => { - return ( -
-
- 5阶ZK1高清摄球机 -
-
- 视频 -
-
- 网络 - {/* 网络 */} -
-
- 在线 -
- {/*
+ {exhibition.current?.statistical?.find(v => v.key == 'DeviceAccess') ? +
+
+ 平台设备接入 +
+
+ { + equipmentList.map((item, index) => { + return ( +
+
+ 5阶ZK1高清摄球机 +
+
+ 视频 +
+
+ 网络 + {/* 网络 */} +
+
+ 在线 +
+ {/*
掉线
*/} -
- ) - }) - } +
+ ) + }) + } +
-
+ : ""} {/* 关联web应用 */} -
-
- 关联web应用 -
-
- { - webList.map((item, index) => { - return ( -
-
-
- web应用 + {exhibition.current?.statistical?.find(v => v.key == 'web') ? +
+
+ 关联web应用 +
+
+ { + webList.map((item, index) => { + return ( +
+
+
+ web应用 +
+
+ superchangnan.anxiny +
-
- superchangnan.anxiny +
+ 第三方
-
- 第三方 -
-
- ) - }) - } + ) + }) + } +
-
+ : ""} {/* 异常&问题 */} -
-
- 异常&问题 -
-
- { - problemsList.map((item, index) => { - return ( -
-
- 【告警源A】数据信息中断,诊断为 服务异常,请前往确认 -
-
- 2022-05-21 15:23:41 + {exhibition.current?.statistical?.find(v => v.key == 'problem') ? +
+
+ 异常&问题 +
+
+ { + problemsList.map((item, index) => { + return ( +
+
+ 【告警源A】数据信息中断,诊断为 服务异常,请前往确认 +
+
+ 2022-05-21 15:23:41 +
-
- ) - }) - } + ) + }) + } +
-
+ : ""}
@@ -458,9 +507,85 @@ const Control = (props) => {
BI ANAL YSIS MODEL
- setSetup(true)} /> + { + setSetup(true) + setTableType('analyse') + attribute('analyse') + }} />
+
+ {exhibition.current?.analyse?.map((v, index) => { + console.log(exhibition.current?.analyse); + return
+ +
+ })} +
+
{/* 右边 */} diff --git a/web/client/src/sections/problem/components/sideSheet.jsx b/web/client/src/sections/problem/components/sideSheet.jsx index d4a320f..1d7740c 100644 --- a/web/client/src/sections/problem/components/sideSheet.jsx +++ b/web/client/src/sections/problem/components/sideSheet.jsx @@ -5,7 +5,7 @@ import copy from "copy-to-clipboard"; import moment from "moment"; import PerfectScrollbar from "perfect-scrollbar"; import ReactECharts from 'echarts-for-react'; -import * as echarts from 'echarts'; + let projectScrollbar; diff --git a/web/client/src/sections/problem/components/tableData.jsx b/web/client/src/sections/problem/components/tableData.jsx index 1f4fa02..4ad5e92 100644 --- a/web/client/src/sections/problem/components/tableData.jsx +++ b/web/client/src/sections/problem/components/tableData.jsx @@ -139,6 +139,7 @@ const TableData = ({ route, dispatch, actions, collectData, setSetup, exhibition }, [query, search, pepProjectId]) + console.log(exhibition); return ( <> From 236b4eb4095d9b7a65994fec0f8bd908961814d3 Mon Sep 17 00:00:00 2001 From: wenlele Date: Wed, 26 Oct 2022 15:02:07 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E5=95=86=E7=94=A8=E8=B0=83=E8=AF=95BUG?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/client/src/sections/problem/components/tableData.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/web/client/src/sections/problem/components/tableData.jsx b/web/client/src/sections/problem/components/tableData.jsx index 4ad5e92..8b226b0 100644 --- a/web/client/src/sections/problem/components/tableData.jsx +++ b/web/client/src/sections/problem/components/tableData.jsx @@ -140,6 +140,7 @@ const TableData = ({ route, dispatch, actions, collectData, setSetup, exhibition }, [query, search, pepProjectId]) console.log(exhibition); + console.log(tableData); return ( <>