Browse Source

工作台接口 80%

dev
wenlele 2 years ago
parent
commit
7c31489e8e
  1. 2
      api/.vscode/launch.json
  2. 167
      api/app/lib/controllers/control/toolLink.js
  3. 57
      web/client/src/sections/control/actions/control.js
  4. 123
      web/client/src/sections/control/containers/control.jsx
  5. 2
      web/client/src/utils/webapi.js

2
api/.vscode/launch.json

@ -56,7 +56,7 @@
// "--clickHouseDataAlarm default",
//
"--clickHouseAnxincloud Anxinyun20",
"--clickHouseAnxincloud Anxinyun21",
"--clickHousePepEmis pepca8",
"--clickHouseProjectManage peppm8",
"--clickHouseVcmp video_access_dev",

167
api/app/lib/controllers/control/toolLink.js

@ -114,21 +114,24 @@ 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) || []
@ -177,7 +180,7 @@ async function count (ctx) {
`).toPromise();
//今日确认数据告警
const confirmedAlarmDetailMax = confirmedAlarm.length ?
const alarmConfirme = confirmedAlarm.length ?
await clickHouse.dataAlarm.query(`
SELECT
max(Time) AS Time, AlarmId , max(Content) AS Content
@ -194,26 +197,166 @@ async function count (ctx) {
[];
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
ctx.status = 200;
ctx.body = {
dataAlarm: {
alarm: alarm[0].count || 0,
alarm: dataAlarm.filter(r => r.State < 3).length || 0,
alarmSurplus: alarmSurplus,
alarmNewAdd: alarmNewAdd[0].count || 0,
confirmedAlarmDetailMax: confirmedAlarmDetailMax.length || 0,
alarmConfirme: alarmConfirme.length || 0,
},
videoAlarm:{
videoAlarm: {
video: returnD.filter(r => !r.confirmTime).length || 0,
videoSurplus: videoSurplus,
videoNewAdd: videoNewAdd,
videoConfirme: videoConfirme,
},
appAlarm: {
app: listRes.rows.filter(r => !r.confirmTime).length || 0,
appSurplus: appSurplus,
appNewAdd: appNewAdd,
appConfirme: appConfirme,
}
}
} else {
ctx.body = {

57
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: '' }
});
}

123
web/client/src/sections/control/containers/control.jsx

@ -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,62 @@ 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({})).then(res => {
console.log(res);
if (res.success) setWorkData(res.payload.data)
})
}, [])
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))
@ -139,9 +146,9 @@ 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: 2, key: 'data', data: workData?.dataAlarm?.alarm || 0, img: 'url(/assets/images/console/lv_1.png)' },
{ name: '应用告警', sort: 2, key: 'app', data: workData?.appAlarm?.alarm || 0, img: 'url(/assets/images/console/hong_1.png)' },
{ name: '设备告警', sort: 2, key: 'device', data: workData?.dataAlarm?.alarm || 0, img: 'url(/assets/images/console/hong_1.png)' },
]
@ -152,10 +159,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 +170,7 @@ const Control = (props) => {
return (
11 ? <img src="/assets/images/install/watting.png" alt="" style={{ width: 'calc(100% + 16px)', position: "relative", top: -12, left: -8, }} /> :
// 11 ? <img src="/assets/images/install/watting.png" alt="" style={{ width: 'calc(100% + 16px)', position: "relative", top: -12, left: -8, }} /> :
<>
<div style={{ padding: '0px 40px', width: '100%' }} className='console'>
{/* 头部 */}
@ -209,7 +214,7 @@ const Control = (props) => {
剩余问题:
</div>
<div style={{ fontSize: 16, color: '#4A4A4A', width: 91 }}>
122
{(workData?.appAlarm?.appSurplus + workData?.dataAlarm?.alarmSurplus + workData?.videoAlarm?.videoSurplus) || 0}
</div>
</div>
<div style={{ display: 'flex', alignItems: 'center', marginTop: 26 }}>
@ -218,7 +223,7 @@ const Control = (props) => {
</div>
<div style={{ fontSize: 16, color: '#4A4A4A', width: 91, display: 'flex' }}>
<div>
12223
{(workData?.appAlarm?.appNewAdd + workData?.dataAlarm?.alarmNewAdd + workData?.videoAlarm?.videoNewAdd) || 0}
</div>
<div style={{ display: 'flex', alignItems: 'center', marginLeft: 4 }}>
<img title='设置' src="/assets/images/console/icon_up.png" style={{ width: 18, height: 18 }} />
@ -230,7 +235,7 @@ const Control = (props) => {
今日处理:
</div>
<div style={{ fontSize: 16, color: '#4A4A4A', width: 91 }}>
3
{(workData?.appAlarm?.appConfirme + workData?.dataAlarm?.alarmConfirme + workData?.videoAlarm?.videoConfirme) || 0}
</div>
</div>
</div>

2
web/client/src/utils/webapi.js

@ -54,7 +54,9 @@ export const ApiTable = {
//控制台
consoleToollink: 'console/toollink', //常用工具
deleteConsoleToollink: 'console/toollink/{linkId}', //删除常用工具
geteteConsoleCount: 'console/count', //工作台数量查询
};
export const RouteTable = {
apiRoot: "/api/root",

Loading…
Cancel
Save