diff --git a/api/.vscode/launch.json b/api/.vscode/launch.json
index 69a9028..f9f2031 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/control/analysis.js b/api/app/lib/controllers/control/analysis.js
index e097bfb..5d26317 100644
--- a/api/app/lib/controllers/control/analysis.js
+++ b/api/app/lib/controllers/control/analysis.js
@@ -1,86 +1,6 @@
'use strict';
const moment = require('moment');
-async function dataList (ctx) {
- try {
- const { models } = ctx.fs.dc;
- const { userId, pepUserId, userInfo = {}, pepUserInfo } = ctx.fs.api
- const { clickHouse } = ctx.app.fs
- const { utils: { judgeSuper, anxinStrucIdRange, pomsProjectRange } } = ctx.app.fs
- const { database: anxinyun } = clickHouse.anxinyun.opts.config
- const { pepProjectId } = ctx.request.query
-
-
- let anxinStruc = await anxinStrucIdRange({
- ctx, pepProjectId
- })
- let pomsProject = await pomsProjectRange({
- ctx, pepProjectId,
- })
- const pomsProjectIds = pomsProject.map(p => p.id)
-
- if (anxinStruc.length) {
-
- const anxinStrucIds = anxinStruc.map(a => a.strucId) || []
-
- const dataAlarm = await clickHouse.dataAlarm.query(`
- SELECT
- formatDateTime(alarmData.StartTime,'%F %H') hours, count(AlarmId) count
- FROM
- ( SELECT
- AlarmId,State,StartTime
- FROM
- alarms
- WHERE
- alarms.StructureId IN (${anxinStrucIds.join(",")})
- AND
- AlarmGroup = 3) AS alarmData
- GROUP BY hours
- `).toPromise();
-
- // const confirmedAlarm = dataAlarm
- // // TODO: 开发临时注释
- // .filter(ar => ar.State && ar.State > 2)
- // .map(ar => "'" + ar.AlarmId + "'")
-
- // // formatDateTime(Time,'%F %H') hours, count(AlarmId) count
-
- // const dataConfirme = confirmedAlarm.length ?
- // await clickHouse.dataAlarm.query(`
- // SELECT
- // max(Time) AS Time, AlarmId
- // FROM
- // alarm_details
- // WHERE
- // AlarmId IN (${confirmedAlarm.join(',')})
- // GROUP BY AlarmId
- // `).toPromise() :
- // [];
-
-
- // dataAlarm.forEach(ar => {
- // ar.confirme =
- // dataConfirme.find(as => as.AlarmId == ar.AlarmId) || {}
-
- // })
- ctx.status = 200
- ctx.body = dataAlarm
- } else {
- ctx.status = 200
- ctx.body = {
- dataAlarm: 0,
- }
- }
-
- } catch (error) {
- ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
- ctx.status = 400;
- ctx.body = {
- message: typeof error == 'string' ? error : undefined
- }
- }
-}
-
async function personnelApp (ctx) {
try {
const models = ctx.fs.dc.models;
@@ -219,7 +139,7 @@ async function personnelApp (ctx) {
findOptions.where.id = { $in: userInfo.correlationProject }
}
if (pepId) {
- findOption.where.id = pepId
+ findOptions.where.id = pepId
}
const proRes = await models.ProjectCorrelation.findAndCountAll(findOptions)
@@ -267,7 +187,7 @@ async function personnelApp (ctx) {
let appproRes = proRes.rows.filter(v => v.dataValues.pepProjectIsDelete != 1).map(r => {
if (r.dataValues.apps.length > 0) {
r.dataValues.apps.map(vv => {
- if (webApp.map(n => n.name).indexOf(vv.dataValues.name)) {
+ if (!webApp.map(n => n.name).includes(vv.dataValues.name)) {
webApp.push({ name: vv.dataValues.name, url: vv.dataValues.url })
}
})
@@ -283,7 +203,7 @@ async function personnelApp (ctx) {
ctx.status = 200
ctx.body = {
- personnel: personnel.map(v => v.dataValues.name),
+ personnel: personnel.map(v => ({ name: v.dataValues.name, department: v.dataValues.departments.map(r => r.name) })),
webApp: webApp
}
} catch (error) {
@@ -471,7 +391,7 @@ async function problem (ctx) {
ctx.status = 200;
ctx.body = sum
} else {
- ctx.body =[]
+ ctx.body = []
}
ctx.status = 200;
} catch (error) {
@@ -485,7 +405,6 @@ async function problem (ctx) {
module.exports = {
- dataList,
personnelApp,
problem
}
\ 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 a129002..be4e73c 100644
--- a/api/app/lib/routes/control/index.js
+++ b/api/app/lib/routes/control/index.js
@@ -14,12 +14,9 @@ module.exports = function (app, router, opts) {
app.fs.api.logAttr['DEL/console/toollink'] = { content: '删除常用工具', visible: true };
router.del('/console/toollink/:linkId', toolLink.del);
- app.fs.api.logAttr['GET/console/count'] = { content: '查询告警数量', visible: true };
+ app.fs.api.logAttr['GET/console/count'] = { content: '工作台查询告警数量', visible: true };
router.get('/console/count', toolLink.count);
- app.fs.api.logAttr['GET/analysis/dataList'] = { content: '查询数据告警产生,确认数量', visible: true };
- router.get('/analysis/dataList', analysis.dataList);
-
app.fs.api.logAttr['GET/analysis/userlist'] = { content: '查询关联人员,web应用', visible: true };
router.get('/analysis/userlist', analysis.personnelApp);
diff --git a/web/client/src/sections/control/actions/control.js b/web/client/src/sections/control/actions/control.js
index edcf54f..310021e 100644
--- a/web/client/src/sections/control/actions/control.js
+++ b/web/client/src/sections/control/actions/control.js
@@ -47,6 +47,18 @@ export function getConsoleCount (query) { //工作台数量查询
});
}
+export function getConsoleUser (query) { //查询关联人员,web应用
+ return dispatch => basicAction({
+ type: 'get',
+ dispatch: dispatch,
+ query,
+ actionType: 'GET_CONSLE_USER',
+ url: `${ApiTable.getConsoleUser}`,
+ msg: { option: '查询关联人员,web应用' },
+ reducer: { name: '' }
+ });
+}
+
export function getConsoleAbnormal (query) { //项目概览异常查询
return dispatch => basicAction({
type: 'get',
@@ -57,4 +69,40 @@ export function getConsoleAbnormal (query) { //项目概览异常查询
msg: { option: '项目概览异常查询' },
reducer: { name: '' }
});
+}
+
+export function getDataAlarmsAggDay (query) { //查询BI分析数据-数据
+ return dispatch => basicAction({
+ type: 'get',
+ dispatch: dispatch,
+ query,
+ actionType: 'GET_DATA_ALARMS_AGG_DAY',
+ url: `${ApiTable.getDataAlarmsAggDay}`,
+ msg: { option: '查询BI分析数据' },
+ reducer: { name: '' }
+ });
+}
+
+export function getVideoAlarmsAggDay (query) { //查询BI分析数据-视频异常
+ return dispatch => basicAction({
+ type: 'get',
+ dispatch: dispatch,
+ query,
+ actionType: 'GET_VIDEO_ALARMS_AGG_DAY',
+ url: `${ApiTable.getVideoAlarmsAggDay}`,
+ msg: { option: '查询BI分析视频数据' },
+ reducer: { name: '' }
+ });
+}
+
+export function getAppAlarmsAggDay (query) { //查询BI分析数据-应用
+ return dispatch => basicAction({
+ type: 'get',
+ dispatch: dispatch,
+ query,
+ actionType: 'GET_APP_ALARMS_AGG_DAY',
+ url: `${ApiTable.getAppAlarmsAggDay}`,
+ msg: { option: '查询BI分析应用数据' },
+ reducer: { name: '' }
+ });
}
\ No newline at end of file
diff --git a/web/client/src/sections/control/containers/control.jsx b/web/client/src/sections/control/containers/control.jsx
index 801caad..950ae75 100644
--- a/web/client/src/sections/control/containers/control.jsx
+++ b/web/client/src/sections/control/containers/control.jsx
@@ -7,7 +7,7 @@ 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;
+import moment from "moment";
let newScrollbar;
let overviewScrollbar;
@@ -21,21 +21,15 @@ let alarmScrollbar;
const Control = (props) => {
const { dispatch, actions, user, loading, socket, pepProjectId } = props
const { control } = actions
- 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 [memberList, setMemberList] = useState([])//相关成员列表
const [equipmentList, setEquipmentList] = useState(['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''])//平台设备接入列表
- const [webList, setWebList] = useState(['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''])//关联web应用列表
+ const [webList, setWebList] = useState([])//关联web应用列表
- const [problemsList, setProblemsList] = useState(['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''])//异常&问题列表
+ const [problemsList, setProblemsList] = useState([])//异常&问题列表
const [setup, setSetup] = useState(false); //设置是否显现
const [tableType, setTableType] = useState(''); //localStorage存储名
const [tool, setTool] = useState(false); //工具添加修改弹窗
@@ -43,7 +37,10 @@ const Control = (props) => {
const [compile, setCompile] = useState({}); //工具编辑的内容
const [toolShow, setToolShow] = useState([]); //工具展示
const [tableSetup, setTableSetup] = useState([]); //单一表格设置信息
- const [workData, setWorkData] = useState(); //我的工作台数据
+ const [workData, setWorkData] = useState({}); //我的工作台数据
+ const [dataBI, setDataBI] = useState({}); //查询BI分析数据-数据
+ const [videoBI, setVideoBI] = useState([]); //查询BI分析数据-视频
+ const [appBI, setAppBI] = useState([]); //查询BI分析数据-应用
const exhibition = useRef({ workbench: [], statistical: [] }) //页面结构
const FormApi = useRef()
@@ -56,22 +53,60 @@ const Control = (props) => {
data.map(v => {
localStorage.getItem(v) == null
? localStorage.setItem(v, JSON.stringify(show[v]))
- : "";
+ : ""
attribute(v)
})
}, [])
useEffect(() => {
+ // 工作台数据请求
dispatch(control.getConsoleCount({ pepProjectId: pepProjectId })).then(res => {
if (res.success) setWorkData(res.payload.data)
})
+ // 统计概览--异常&问题
dispatch(control.getConsoleAbnormal({ pepProjectId: pepProjectId })).then(res => {
- console.log(res.payload.data);
- if (res.success) setProblemsList([...res.payload.data,...res.payload.data])
+ if (res.success) {
+ if (res.payload.data?.length > 4) {
+ setProblemsList([...res.payload.data, ...res.payload.data])
+ startmarquee(500, 2000, 'problems')
+ } else {
+ setProblemsList(res.payload.data)
+ }
+ }
+ })
+ // 统计概览--相关成员与web应用
+ dispatch(control.getConsoleUser({ pepId: pepProjectId })).then(res => {
+ if (res.success) {
+ if (res.payload.data?.personnel?.length > 5) {
+ setMemberList([...res.payload.data?.personnel, ...res.payload.data?.personnel])
+ startmarquee(600, 2000, 'member')
+ } else {
+ setMemberList(res.payload.data?.personnel)
+ }
+ if (res.payload.data?.webApp?.length > 3) {
+ setWebList([...res.payload.data?.webApp, ...res.payload.data?.webApp])
+ startmarquee(600, 2000, 'web')
+ } else {
+ setWebList(res.payload.data?.webApp)
+ }
+ }
+ })
+ // 查询BI分析数据-数据
+ dispatch(control.getDataAlarmsAggDay({ pepProjectId: pepProjectId })).then(res => {
+ if (res.success) setDataBI(res.payload.data)
+ })
+ //查询BI分析数据-视频异常
+ dispatch(control.getVideoAlarmsAggDay({ pepProjectId: pepProjectId })).then(res => {
+ if (res.success) setVideoBI(res.payload.data)
+ })
+ //查询BI分析数据-应用
+ dispatch(control.getAppAlarmsAggDay({ pepProjectId: pepProjectId })).then(res => {
+ // console.log(res.payload.data);
+ if (res.success) setAppBI(res.payload.data)
})
- }, [pepProjectId])
+ }, [pepProjectId])
useEffect(() => {
const domProject = document.getElementById("news");
@@ -154,25 +189,55 @@ const Control = (props) => {
if (res.success) setToolShow(res.payload.data)
})
}
+ function startmarquee (speed, delay, name) {
+ /*
+ 函数startmarquee的参数:
+ lh:文字一次向上滚动的距离或高度;
+ speed:滚动速度;
+ delay:滚动停顿的时间间隔;
+ index:可以使封装后的函数应用于页面当中不同的元素;
+ */
+ var t;
+ var p = false;
+ let top = 0
+ var o = document.getElementById(name);
+ if (o) {
+ o.onmouseover = () => p = true
+ o.onmouseout = () => p = false
+ o.scrollTop = 0;
+ const start = () => {
+ t = setInterval(() => {
+ if (!p) (top += 10, o.scrollTop = top)
+ if (p) (clearInterval(t), setTimeout(start, delay))
+ if (o.scrollTop >= o.scrollHeight / 2) (top = 0, o.scrollTop = 0)
+ }, speed);
+ }
+ setTimeout(start, 1000);
+ }
+ }
+
+
+
+
let Select = {
workbench: ['project', 'data', 'app', 'device'],
statistical: ['milestone', 'personnel', 'DeviceAccess', 'web', 'problem'],
- analyse: ['dataInterrupt', 'dataAnomaly', 'strategyHit', 'videoException', 'appAbnormal', 'unitException', 'problemAnalysis'],
+ analyse: ['dataInterrupt', 'dataAbnormal', 'policyHit', 'videoException', 'appAbnormal', 'deviceAbnormal', 'problemAnalysis'],
dynamic: [],
}
let show = {
workbench: ['project', 'data', 'app', 'device'],
statistical: ['milestone', 'personnel', 'DeviceAccess', 'web', 'problem'],
- analyse: ['dataInterrupt', 'dataAnomaly', 'strategyHit', 'videoException', 'appAbnormal', 'unitException', 'problemAnalysis'],
+ analyse: ['dataInterrupt', 'dataAbnormal', 'policyHit', 'videoException', 'appAbnormal', 'deviceAbnormal', 'problemAnalysis'],
dynamic: [],
}
let listAll = [
{ 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: 2, key: 'data', data: workData?.dataSurplus || 0, img: 'url(/assets/images/console/lv_1.png)', url: '/problem/dataAlarm/dataLnterrupt' },
+ { name: '应用告警', sort: 2, key: 'app', data: workData?.appSurplus || 0, img: 'url(/assets/images/console/hong_1.png)', url: '/problem/useAlarm/useAbnormal' },
+ { name: '设备告警', sort: 2, key: 'device', data: workData?.toolSurplus || 0, img: 'url(/assets/images/console/hong_1.png)', url: '/problem/deviceAlarm/deviceAbnormal' },
{ name: '项目里程碑', sort: 1, key: 'milestone', },
{ name: '相关成员', sort: 2, key: 'personnel', },
@@ -181,11 +246,11 @@ const Control = (props) => {
{ name: '异常&问题', sort: 5, key: 'problem', },
{ name: '数据中断', sort: 1, key: 'dataInterrupt', },
- { name: '数据异常', sort: 2, key: 'dataAnomaly', },
- { name: '策略命中', sort: 3, key: 'strategyHit', },
+ { name: '数据异常', sort: 2, key: 'dataAbnormal', },
+ { name: '策略命中', sort: 3, key: 'policyHit', },
{ name: '视频异常', sort: 4, key: 'videoException', },
{ name: '应用异常', sort: 5, key: 'appAbnormal', },
- { name: '设备异常', sort: 6, key: 'unitException', },
+ { name: '设备异常', sort: 6, key: 'deviceAbnormal', },
{ name: '问题处置效率分析', sort: 7, key: 'problemAnalysis', },
]
@@ -209,7 +274,6 @@ const Control = (props) => {
return (
- // 11 ? :
<>