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 bda94bc..b380664 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 ? : <>