diff --git a/api/.vscode/launch.json b/api/.vscode/launch.json
index 5d040f2..42d30dc 100644
--- a/api/.vscode/launch.json
+++ b/api/.vscode/launch.json
@@ -56,7 +56,7 @@
// "--clickHouseDataAlarm default",
// 测试
- "--clickHouseAnxincloud Anxinyun20",
+ "--clickHouseAnxincloud Anxinyun21",
"--clickHousePepEmis pepca8",
"--clickHouseProjectManage peppm8",
"--clickHouseVcmp video_access_dev",
diff --git a/api/app/lib/controllers/control/toolLink.js b/api/app/lib/controllers/control/toolLink.js
index 685b2f6..c61abbc 100644
--- a/api/app/lib/controllers/control/toolLink.js
+++ b/api/app/lib/controllers/control/toolLink.js
@@ -114,105 +114,235 @@ async function del (ctx) {
-
-
async function count (ctx) {
try {
const { models } = ctx.fs.dc;
const { userId, pepUserId, userInfo = {}, pepUserInfo } = ctx.fs.api
const { clickHouse } = ctx.app.fs
- const { utils: { judgeSuper, anxinStrucIdRange } } = ctx.app.fs
+ const { utils: { judgeSuper, anxinStrucIdRange, pomsProjectRange } } = ctx.app.fs
const { database: anxinyun } = clickHouse.anxinyun.opts.config
- const { pepProjectId } = ctx.request.body
+ 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
- AlarmId,State,StartTime
+ AlarmId,State,StartTime,AlarmGroup
FROM
alarms
WHERE
alarms.StructureId IN (${anxinStrucIds.join(",")})
`).toPromise();
- //数据告警总数
- const alarm = await clickHouse.dataAlarm.query(`
- SELECT
- count(alarms.AlarmId) AS count
- FROM
- alarms
- WHERE
- alarms.StructureId IN (${anxinStrucIds.join(",")})
- `).toPromise();
-
-
const confirmedAlarm = dataAlarm
// TODO: 开发临时注释
.filter(ar => ar.State && ar.State > 2)
.map(ar => "'" + ar.AlarmId + "'")
//剩余数据告警
- const alarmSurplus = dataAlarm.filter(ar => ar.State && ar.State < 3).length || 0
+ const dataSurplus = dataAlarm.filter(ar => ar.State && ar.State < 3 && ar.AlarmGroup < 4).length || 0
+ //剩余设备告警
+ const toolSurplus = dataAlarm.filter(ar => ar.State && ar.State < 3 && ar.AlarmGroup > 3).length || 0
//今日新增数据告警
- const alarmNewAdd = await clickHouse.dataAlarm.query(`
- SELECT
- count(alarms.StartTime) AS count
- FROM
- alarms
- WHERE
- alarms.StructureId IN (${anxinStrucIds.join(",")})
- AND
- alarms.StartTime >= '${moment().startOf('day').format('YYYY-MM-DD HH:mm:ss')}'
- AND
- alarms.StartTime <= '${moment().endOf('day').format('YYYY-MM-DD HH:mm:ss')}'
-
- `).toPromise();
+ const dataNewAdd = dataAlarm.filter(r => moment(moment().startOf('day').format('YYYY-MM-DD HH:mm:ss')).isBefore(r.StartTime) && moment(r.createTime).isBefore(moment().endOf('day').format('YYYY-MM-DD HH:mm:ss')) && r.AlarmGroup < 4).length || 0
+ const toolNewAdd = dataAlarm.filter(r => moment(moment().startOf('day').format('YYYY-MM-DD HH:mm:ss')).isBefore(r.StartTime) && moment(r.createTime).isBefore(moment().endOf('day').format('YYYY-MM-DD HH:mm:ss')) && r.AlarmGroup > 3).length || 0
//今日确认数据告警
- const confirmedAlarmDetailMax = confirmedAlarm.length ?
+ const dataConfirme = confirmedAlarm.length ?
await clickHouse.dataAlarm.query(`
SELECT
- max(Time) AS Time, AlarmId , max(Content) AS Content
+ max(Time) AS Time, AlarmId , max(Content) AS Content,
+ alarms.AlarmGroup AS AlarmGroup
FROM
alarm_details
+ LEFT JOIN alarms
+ ON alarm_details.AlarmId=alarms.AlarmId
WHERE
AlarmId IN (${confirmedAlarm.join(',')})
AND
alarm_details.Time >= '${moment().startOf('day').format('YYYY-MM-DD HH:mm:ss')}'
AND
alarm_details.Time <= '${moment().endOf('day').format('YYYY-MM-DD HH:mm:ss')}'
- GROUP BY AlarmId
+ GROUP BY AlarmId,AlarmGroup
`).toPromise() :
[];
+ let findOption = {
+ where: {
+ '$app->projectCorrelations.id$': {
+ $in: pomsProjectIds
+ }
+ },
+ attributes: ['createTime', 'confirmTime'],
+ include: [{
+ model: models.App,
+ where: {
+
+ },
+ attributes: ['id', 'name'],
+ include: [{
+ model: models.ProjectCorrelation,
+ where: {
+
+ },
+ attributes: ['id'],
+ }]
+ }]
+ }
+
+ //应用总告警
+ const listRes = await models.AppAlarm.findAndCountAll(findOption)
+ //剩余应用告警
+ const appSurplus = listRes.rows.filter(r => !r.confirmTime).length || 0
+ //今日新增应用告警
+ const appNewAdd = listRes.rows.filter(r => moment(moment().startOf('day').format('YYYY-MM-DD HH:mm:ss')).isBefore(r.createTime) && moment(r.createTime).isBefore(moment().endOf('day').format('YYYY-MM-DD HH:mm:ss'))).length || 0
+ //今日确认应用告警
+ const appConfirme = listRes.rows.filter(r => moment(moment().startOf('day').format('YYYY-MM-DD HH:mm:ss')).isBefore(r.confirmTime) && moment(r.confirmTime).isBefore(moment().endOf('day').format('YYYY-MM-DD HH:mm:ss'))).length || 0
+
+ const alarmRes = anxinStrucIds.length ? await clickHouse.vcmp.query(
+ `
+ SELECT
+ cameraAlarm.cameraId AS cameraId,
+ cameraAlarm.cameraName AS cameraName,
+ cameraAlarm.cameraSerialNo AS cameraSerialNo,
+ cameraAlarm.cameraChannelNo AS cameraChannelNo,
+ cameraAlarm.alarmId AS alarmId,
+ cameraAlarm.createTime AS createTime,
+ cameraAlarm.platform AS platform,
+ cameraAlarm.confirmTime AS confirmTime,
+ camera_status_resolve.id AS resolveId,
+ camera_status.describe AS statusDescribe,
+ camera_status_resolve.resolve AS resolve,
+ "gbCamera".online AS cameraOnline,
+ anxinIpc.t_video_ipc.name AS anxinIpcPosition,
+ anxinStation.id AS anxinStationId,
+ anxinStation.name AS anxinStationName,
+ anxinStruc.name AS strucName,
+ anxinStruc.id AS strucId
+ FROM
+ (
+ SELECT
+ camera.id AS cameraId,
+ camera.gb_id AS gbId,
+ camera.name AS cameraName,
+ camera_status_alarm.id AS alarmId,
+ camera_status_alarm.create_time AS createTime,
+ camera_status_alarm.platform AS platform,
+ camera_status_alarm.status_id AS statusId,
+ camera_status_alarm.serial_no AS cameraSerialNo,
+ camera_status_alarm.channel_no AS cameraChannelNo,
+ camera_status_alarm.confirm_time AS confirmTime
+ FROM camera_status_alarm
+ INNER JOIN camera
+ ON camera.serial_no = camera_status_alarm.serial_no
+ AND camera.channel_no = camera_status_alarm.channel_no
+ LEFT JOIN vender
+ ON vender.id = camera.vender_id
+ WHERE
+ camera.delete = false
+ AND camera.recycle_time is null
+ AND alarmId IN (
+ SELECT camera_status_alarm.id AS alarmId
+ FROM camera_status_alarm
+ RIGHT JOIN ${anxinyun}.t_video_ipc
+ ON toString(${anxinyun}.t_video_ipc.channel_no) = camera_status_alarm.channel_no
+ AND ${anxinyun}.t_video_ipc.serial_no = camera_status_alarm.serial_no
+ ${`WHERE ${anxinyun}.t_video_ipc.structure IN (${anxinStrucIds.join(',')})`
+ }
+ )
+ ) AS cameraAlarm
+ LEFT JOIN camera_status
+ ON cameraAlarm.platform = camera_status.platform
+ AND cameraAlarm.statusId = camera_status.id
+ LEFT JOIN camera_status_resolve
+ ON camera_status_resolve.status_id = camera_status.id
+ LEFT JOIN "gbCamera"
+ ON "gbCamera".id = cameraAlarm.gbId
+ LEFT JOIN ${anxinyun}.t_video_ipc AS anxinIpc
+ ON toString(anxinIpc.channel_no) = cameraAlarm.cameraChannelNo
+ AND anxinIpc.serial_no = cameraAlarm.cameraSerialNo
+ LEFT JOIN ${anxinyun}.t_structure AS anxinStruc
+ ON anxinStruc.id = anxinIpc.structure
+ AND anxinStruc.id IN (${anxinStrucIds.join(',')})
+ LEFT JOIN ${anxinyun}.t_video_ipc_station AS anxinIpcStation
+ ON anxinIpcStation.ipc = anxinIpc.id
+ LEFT JOIN ${anxinyun}.t_sensor AS anxinStation
+ ON anxinStation.id = anxinIpcStation.station
+ `
+ ).toPromise() : []
+
+ let returnD = []
+ let positionD = {}
+ // 每个设备一个告警
+ for (let a of alarmRes) {
+ if (positionD[a.cameraId]) {
+ let curD = returnD[positionD[a.cameraId].positionReturnD]
+
+ } else {
+ let d = {
+ cameraId: a.cameraId,
+ cameraName: a.cameraName,
+ createTime: a.createTime,
+ alarmId: a.alarmId,
+ confirmTime: a.confirmTime,
+ }
+
+ returnD.push(d)
+ positionD[a.cameraId] = {
+ positionReturnD: returnD.length - 1
+ }
+ }
+ }
+
+ //剩余视频告警
+ const videoSurplus = returnD.filter(r => !r.confirmTime).length || 0
+ //今日新增视频告警
+ const videoNewAdd = returnD.filter(r => moment(moment().startOf('day').format('YYYY-MM-DD HH:mm:ss')).isBefore(r.createTime) && moment(r.createTime).isBefore(moment().endOf('day').format('YYYY-MM-DD HH:mm:ss'))).length || 0
+ //今日确认视频告警
+ const videoConfirme = returnD.filter(r => moment(moment().startOf('day').format('YYYY-MM-DD HH:mm:ss')).isBefore(r.confirmTime) && moment(r.confirmTime).isBefore(moment().endOf('day').format('YYYY-MM-DD HH:mm:ss'))).length || 0
+ let findOptions = {
+ where: {
+ del: false
+ },
+ attributes: []
+ }
+ if (!userInfo.role.includes('SuperAdmin') && !userInfo.role.includes('admin')) {
+ findOptions.where.id = { $in: userInfo.correlationProject }
+ }
+ const projects = await models.ProjectCorrelation.findAndCountAll(findOptions)
+ ctx.status = 200;
+ ctx.body = {
+ dataSurplus: dataSurplus + videoSurplus,
+ dataNewAdd: dataNewAdd + videoNewAdd,
+ dataConfirme: appConfirme + dataConfirme.filter(r => r.AlarmGroup < 4).length,
+ toolSurplus: toolSurplus,
+ toolNewAdd: toolNewAdd,
+ toolConfirme: dataConfirme.filter(r => r.AlarmGroup > 3).length,
- ctx.status = 200;
- ctx.body = {
- dataAlarm: {
- alarm: alarm[0].count || 0,
- alarmSurplus: alarmSurplus,
- alarmNewAdd: alarmNewAdd[0].count || 0,
- confirmedAlarmDetailMax: confirmedAlarmDetailMax.length || 0,
- },
- videoAlarm:{
-
- }
+ appSurplus: appSurplus,
+ appNewAdd: appNewAdd,
+ appConfirme: appConfirme,
+ projects: projects.count,
}
} else {
diff --git a/web/client/src/sections/control/actions/control.js b/web/client/src/sections/control/actions/control.js
index 822c0a7..83db79c 100644
--- a/web/client/src/sections/control/actions/control.js
+++ b/web/client/src/sections/control/actions/control.js
@@ -1,37 +1,48 @@
'use strict';
-import { ApiTable ,basicAction} from '$utils'
+import { ApiTable, basicAction } from '$utils'
export function getConsoleToollink () { //获取常用工具
- return dispatch => basicAction({
- type: 'get',
- dispatch: dispatch,
- actionType: 'GET_CONSLE_TOOLLINK',
- url: `${ApiTable.consoleToollink}`,
- msg: { option: '获取常用工具' },
- reducer: { name: '' }
- });
+ return dispatch => basicAction({
+ type: 'get',
+ dispatch: dispatch,
+ actionType: 'GET_CONSLE_TOOLLINK',
+ url: `${ApiTable.consoleToollink}`,
+ msg: { option: '获取常用工具' },
+ reducer: { name: '' }
+ });
}
export function putConsoleToollink (data) { //编辑常用工具
return dispatch => basicAction({
- type: 'put',
- dispatch: dispatch,
- data,
- actionType: 'PUT_CONSLE_TOOLLINK',
- url: `${ApiTable.consoleToollink}`,
- msg: { option: '编辑常用工具' },
- reducer: { name: '' }
+ type: 'put',
+ dispatch: dispatch,
+ data,
+ actionType: 'PUT_CONSLE_TOOLLINK',
+ url: `${ApiTable.consoleToollink}`,
+ msg: { option: '编辑常用工具' },
+ reducer: { name: '' }
});
}
export function deleteConsoleToollink (orgId) { //删除常用工具
- console.log(orgId);
return dispatch => basicAction({
- type: 'delete',
- dispatch: dispatch,
- actionType: 'DELETE_CONSLE_TOOLLINK',
- url: `${ApiTable.deleteConsoleToollink.replace('{linkId}', orgId)}`,
- msg: { option: '删除常用工具' },
- reducer: { name: '' }
+ type: 'delete',
+ dispatch: dispatch,
+ actionType: 'DELETE_CONSLE_TOOLLINK',
+ url: `${ApiTable.deleteConsoleToollink.replace('{linkId}', orgId)}`,
+ msg: { option: '删除常用工具' },
+ reducer: { name: '' }
});
}
+
+export function geteteConsoleCount (query) { //工作台数量查询
+ return dispatch => basicAction({
+ type: 'get',
+ dispatch: dispatch,
+ query,
+ actionType: 'GET_CONSLE_COUNT',
+ url: `${ApiTable.geteteConsoleCount}`,
+ msg: { option: '工作台数量查询' },
+ 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 9a7d175..ed5b649 100644
--- a/web/client/src/sections/control/containers/control.jsx
+++ b/web/client/src/sections/control/containers/control.jsx
@@ -18,7 +18,7 @@ let alarmScrollbar;
const Control = (props) => {
- const { dispatch, actions, user, loading, socket } = props
+ const { dispatch, actions, user, loading, socket ,pepProjectId} = props
const { control } = actions
const stationList = [
'url(/assets/images/console/lan_1.png)',
@@ -43,6 +43,7 @@ const Control = (props) => {
const [toolShow, setToolShow] = useState([]); //工具展示
const [tableSetup, setTableSetup] = useState([]); //单一表格设置信息
const [exhibition, setExhibition] = useState({ workbench: [] }); //页面结构
+ const [workData, setWorkData] = useState({}); //我的工作台数据
const FormApi = useRef()
@@ -50,7 +51,6 @@ const Control = (props) => {
useEffect(() => {
consoleToollink()
-
//初始化表格显示设置
let data = ['workbench']
data.map(v => {
@@ -63,55 +63,61 @@ const Control = (props) => {
}, [])
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();
- // }
- // alarmScrollbar = new PerfectScrollbar("#alarm", {
- // suppressScrollY: true,
- // });
- // const domProject6 = document.getElementById("alarm");
- // if (domProject6 && alarmScrollbar) {
- // alarmScrollbar.update();
- // }
+ 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();
+ }
+ 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();
+ }
+ alarmScrollbar = new PerfectScrollbar("#alarm", {
+ suppressScrollY: true,
+ });
+ const domProject6 = document.getElementById("alarm");
+ if (domProject6 && alarmScrollbar) {
+ alarmScrollbar.update();
+ }
// ACTION 示例
// dispatch(actions.example.getMembers(user.orgId))
@@ -138,13 +144,17 @@ const Control = (props) => {
}
let listAll = [
- { name: '关注的项目', sort: 1, key: 'project', data: 1, img: 'url(/assets/images/console/lan_1.png)' },
- { name: '数据告警', sort: 2, key: 'data', data: 2, img: 'url(/assets/images/console/lv_1.png)' },
- { name: '应用告警', sort: 2, key: 'app', data: 3, img: 'url(/assets/images/console/hong_1.png)' },
- { name: '设备告警', sort: 2, key: 'device', data: 225, img: 'url(/assets/images/console/hong_1.png)' },
+ { 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)' },
]
+ console.log(workData);
+ console.log(listAll);
-
+ useEffect(() => {
+ attribute('workbench')
+ }, [workData])
const attribute = (title) => {
let take = localStorage.getItem(title)
@@ -152,10 +162,8 @@ const Control = (props) => {
: [];
let data = Select[title].map(v => {
let dataTitle = listAll.find(vv => v == vv.key) || {}
- console.log(dataTitle);
return { name: dataTitle.name, value: dataTitle.key }
})
- console.log(data);
let TableDisplay = take?.map(v => listAll?.find(vv => v == vv.key))
TableDisplay.sort((a, b) => a.sort - b.sort)
setExhibition({ ...exhibition, [title]: TableDisplay })
@@ -165,7 +173,7 @@ const Control = (props) => {
return (
- 11 ? :
+ // 11 ?
:
<>