diff --git a/api/app/lib/controllers/project/group.js b/api/app/lib/controllers/project/group.js index c9f0fbb..63a12ee 100644 --- a/api/app/lib/controllers/project/group.js +++ b/api/app/lib/controllers/project/group.js @@ -409,6 +409,56 @@ async function groupStatisticAlarm (ctx) { } } +async function groupProject (ctx) { + try { + const { models } = ctx.fs.dc; + + const { groupId } = ctx.query + const { clickHouse } = ctx.app.fs + const findOne = await models.ProjectGroup.findOne({ where: { id: groupId } }) + const proRes = await models.ProjectCorrelation.findAll({ where: { id: { $in: findOne.pomsProjectIds } } }) + let pepProjectIds = new Set() + + for (let p of proRes) { + if (p.pepProjectId) { + pepProjectIds.add(p.pepProjectId) + } + } + + const pepProjectRes = pepProjectIds.size ? + await clickHouse.projectManage.query( + ` + SELECT + t_pim_project.id AS id, + t_pim_project.project_name AS project_name, + t_pim_project.isdelete AS isdelete, + t_pim_project_construction.construction_status_id AS construction_status_id, + t_pim_project_state.construction_status AS construction_status + FROM t_pim_project + LEFT JOIN t_pim_project_construction + ON t_pim_project.id = t_pim_project_construction.project_id + LEFT JOIN t_pim_project_state + ON t_pim_project_construction.construction_status_id = t_pim_project_state.id + WHERE id IN (${[...pepProjectIds].join(',')}, -1) + ` + ).toPromise() : + [] + + for (let p of proRes) { + const corPro = pepProjectRes.find(pp => pp.id == p.pepProjectId) || {} + p.dataValues.pepProjectName = corPro.project_name + } + ctx.status = 200; + ctx.body = proRes; + } catch (error) { + ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); + ctx.status = 400; + ctx.body = { + message: typeof error == 'string' ? error : undefined + } + } +} + module.exports = { groupList, editGroup, @@ -416,4 +466,5 @@ module.exports = { groupStatistic, groupStatisticOnline, groupStatisticAlarm, + groupProject, }; \ No newline at end of file diff --git a/api/app/lib/routes/project/index.js b/api/app/lib/routes/project/index.js index 545d829..bb0ffa6 100644 --- a/api/app/lib/routes/project/index.js +++ b/api/app/lib/routes/project/index.js @@ -48,4 +48,7 @@ module.exports = function (app, router, opts) { app.fs.api.logAttr['GET/project/group/statistic/alarm'] = { content: '获取项目分组告警统计信息', visible: true }; router.get('/project/group/statistic/alarm', projectGroup.groupStatisticAlarm); + + app.fs.api.logAttr['GET/project/group/list'] = { content: '获取分组项目信息', visible: true }; + router.get('/project/group/list', projectGroup.groupProject); }; \ No newline at end of file diff --git a/web/client/assets/images/projectGroup/chart.png b/web/client/assets/images/projectGroup/chart.png new file mode 100644 index 0000000..b575c3c Binary files /dev/null and b/web/client/assets/images/projectGroup/chart.png differ diff --git a/web/client/src/sections/projectGroup/actions/group.js b/web/client/src/sections/projectGroup/actions/group.js index aa351e8..72e47b5 100644 --- a/web/client/src/sections/projectGroup/actions/group.js +++ b/web/client/src/sections/projectGroup/actions/group.js @@ -65,8 +65,22 @@ export function groupStatisticAlarm (query = {}) { query, actionType: "GET_STATISTICALARM", url: `${ApiTable.groupStatisticAlarm}`, - msg: { error: "获获取项目分组告警统计信息失败" }, + msg: { error: "获取项目分组告警统计信息失败" }, reducer: { name: "groupStatisticAlarm", params: { noClear: true } }, }); -} \ No newline at end of file +} + +export function groupProject (query = {}) { + return (dispatch) => basicAction({ + type: "get", + dispatch: dispatch, + query, + actionType: "GET_GROUP_PROJECT", + url: `${ApiTable.groupProject}`, + msg: { error: "获取分组项目信息失败" }, + reducer: { name: "groupProject", + params: { noClear: true } }, + }); +} + diff --git a/web/client/src/sections/projectGroup/containers/bigscreen.jsx b/web/client/src/sections/projectGroup/containers/bigscreen.jsx index 8cb4e29..14d5e4b 100644 --- a/web/client/src/sections/projectGroup/containers/bigscreen.jsx +++ b/web/client/src/sections/projectGroup/containers/bigscreen.jsx @@ -11,6 +11,7 @@ import PerfectScrollbar from "perfect-scrollbar"; let interrupt +let repair let overviewScrollbar; const Bigscreen = ({ dispatch, actions, user, match, history, clientHeight, groupStatisticOnline }) => { @@ -18,13 +19,17 @@ const Bigscreen = ({ dispatch, actions, user, match, history, clientHeight, grou const [online, setOnline] = useState([]) const [value, setValue] = useState([]) const [time, setTime] = useState([]) + const [groupProject, setGroupProject] = useState([]) + const [proportion, setProportion] = useState([]) + const [formatter, setFormatter] = useState({}) + const [alarmData, setAlarmData] = useState()//第三项之后的数据 const [biggest, setBiggest] = useState()//最大的刻度值 const [mockData, setMockData] = useState()//所有的告警数据 const [xData, setXData] = useState([])//横坐标 - + const self = useRef({ myChart: null }); useEffect(() => { @@ -32,7 +37,15 @@ const Bigscreen = ({ dispatch, actions, user, match, history, clientHeight, grou statisticOnline(groupId) dispatch(actions.projectGroup.groupStatisticAlarm({ groupId })).then(res => { if (res.success) { - setMockData(res.data) + setMockData(res.payload.data) + } + }) + + + dispatch(actions.projectGroup.groupProject({ groupId })).then(res => { + if (res.success) { + setGroupProject(res.payload.data?.map(v => ({ ...v, value: (Math.random() * 20).toFixed(0) })) || []) + setProportion([...res.payload.data?.slice(0, 3)?.map(v => ({ name: v.name || v.pepProjectName, value: (Math.random() * 20).toFixed(0) })), { value: 20, name: '其它' }]) } }) @@ -43,6 +56,12 @@ const Bigscreen = ({ dispatch, actions, user, match, history, clientHeight, grou suppressScrollX: true, }); } + const repairDom = document.getElementById("repair"); + if (repairDom) { + repair = new PerfectScrollbar("#repair", { + suppressScrollX: true, + }); + } }, []) @@ -63,6 +82,10 @@ const Bigscreen = ({ dispatch, actions, user, match, history, clientHeight, grou interrupt.update(); } + const repairDom = document.getElementById("repair"); + if (repair && repairDom) { + interrupt.update(); + } }) useEffect(() => { const maxCombinedValue = mockData?.reduce((max, item) => { @@ -119,7 +142,6 @@ const Bigscreen = ({ dispatch, actions, user, match, history, clientHeight, grou let statisticOnline = (groupId) => { dispatch(actions.projectGroup.groupStatisticOnline({ groupId })).then(res => { - console.log(res); if (res.success) { let Interrupt = [] res.payload.data?.forEach(v => { @@ -182,6 +204,43 @@ const Bigscreen = ({ dispatch, actions, user, match, history, clientHeight, grou } + useEffect(() => { + let count = 0; + let currentIndex = -1; + if (!self.current.cityChart) return; + const timer = setInterval(() => { + count++; + if (count == 8) { + count = 1; + } + // 取消之前高亮的图形 + self.current.cityChart.dispatchAction({ + type: "downplay", + seriesIndex: 0, + dataIndex: currentIndex, + }); + currentIndex = + (currentIndex + 1) % proportion?.length + // 高亮当前图形 + self.current.cityChart.dispatchAction({ + type: "highlight", + seriesIndex: 0, + dataIndex: currentIndex, + }); + // 显示 label + self.current.cityChart.dispatchAction({ + type: "showTip", + seriesIndex: 0, + dataIndex: currentIndex, + }); + }, 3000); + + return () => { + clearInterval(timer); + }; + }, [proportion]); + + return (