Browse Source

项目结构物选择--{ 一图统揽}

dev
wenlele 1 year ago
parent
commit
c1988aa9be
  1. 320
      api/app/lib/controllers/analysis/network.js
  2. 0
      api/app/lib/controllers/analysis/operationData.js
  3. 0
      api/app/lib/controllers/analysis/problemData.js
  4. 2
      api/app/lib/index.js
  5. 16
      api/app/lib/routes/analysis/network.js
  6. 2
      api/app/lib/routes/analysis/operationData.js
  7. 2
      api/app/lib/routes/analysis/problemData.js
  8. 3
      web/client/src/sections/analysis/actions/index.js
  9. 50
      web/client/src/sections/analysis/actions/network.js
  10. 82
      web/client/src/sections/analysis/containers/network.jsx
  11. 3
      web/client/src/sections/firmwareUpgrade/containers/deviceManagement.jsx
  12. 31
      web/client/src/utils/webapi.js

320
api/app/lib/controllers/analysis/network.js

@ -0,0 +1,320 @@
'use strict';
const moment = require('moment')
async function getMaintenceRecordRank (ctx) {
const sequelize = ctx.fs.dc.orm
const Sequelize = ctx.fs.dc.ORM;
const { clickHouse } = ctx.app.fs
const models = ctx.fs.dc.models
const { startTime, endTime } = ctx.query
console.log(startTime, endTime, ctx.query, '1212312')
try {
const res = await sequelize.query(`
SELECT emrp.project_id,count(1)
FROM equipment_maintenance_record
RIGHT JOIN equipment_maintenance_record_project emrp
on equipment_maintenance_record.id = emrp.equipment_maintenance_record_id
where report_time BETWEEN :startTime AND :endTime
GROUP BY emrp.project_id
`
, {
replacements: {
startTime: moment(startTime).format('YYYY-MM-DD HH:mm:ss'),
endTime: moment(endTime).format('YYYY-MM-DD HH:mm:ss ')
}
//, type: sequelize.QueryTypes.SELECT
}
)
//查询equipment_maintenance_record返回的结果[{project_id: 22, count: 1}]
let projectList = []
//存project的id
let projectIdList = []
// console.log('resssss', res)
if (res.length > 0) {
res[0].forEach((item) => {
projectList.push({ project_id: item.project_id, count: Number(item.count) })
projectIdList.push(item.project_id)
})
}
const projectNameList = await models.ProjectCorrelation.findAll({
attributes:
['id', 'name'],
where: {
id: { $in: projectIdList },
name: {
[Sequelize.Op.not]: null//有name的结果
}
// del: false
}
}) || []
//在ProjectCorrelation中查不到名字,去clickHouse中去查
const projectNameList1 = await models.ProjectCorrelation.findAll({
attributes:
['id', 'name', 'pepProjectId'],
where: {
id: { $in: projectIdList },
name: {
[Sequelize.Op.eq]: null//无name的结果
}
// del: false
}
})
//存放需要去查询clickHouse的id
let idList = new Set()
if (projectNameList1.length) {
projectNameList1.forEach((item) => {
idList.add(item.pepProjectId)
})
}
//pepProject名称
const projectManageName = idList.size ? await clickHouse.projectManage.query(`
SELECT id,project_name FROM t_pim_project
WHERE id IN (${[...idList].join(',')}, -1)
`).toPromise() : []
// if (projectList.length) {
// projectList.forEach((item) => {
// projectManageName
// })
// }
//存的是{id,projectName}
let project = []
if (projectNameList1.length && projectManageName.length) {
projectManageName.forEach((item) => {
const pepObj = projectNameList1.find((item1) => { return item1.pepProjectId === item.id })
project.push({ id: pepObj.id, projectName: item.project_name })
})
}
const resAll = project.concat(projectNameList)
let mergedArray = []
if (resAll.length && projectList) {
mergedArray = projectList.map(obj1 => {
const matchingObj = resAll.find(obj2 => obj2.id === obj1.project_id);
return { id: obj1.project_id, pepProjectId: matchingObj.id, projectName: matchingObj.projectName || matchingObj.dataValues.name, count: obj1.count };
});
}
// console.log('ididididid', resAll)
// console.log('ididididid', project)
// console.log('ididididid', projectManageName)
// console.log('ididididid', projectNameList)
// console.log('ididididid', projectList)
ctx.status = 200
ctx.body = mergedArray
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: '查询维修记录排名失败'
}
}
}
async function getMaintenceTotal (ctx) {
const sequelize = ctx.fs.dc.orm
const Sequelize = ctx.fs.dc.ORM;
const { clickHouse } = ctx.app.fs
const models = ctx.fs.dc.models
const { startTime, endTime } = ctx.query
try {
//所有维修记录
const res = await sequelize.query(`
SELECT emrp.project_id,
count(case when record.status in ('维修中','待维修','维修完成') then record.id end) incomplete,
count(case when record.status in ('维修完成') then record.id end) completed
FROM equipment_maintenance_record record
RIGHT JOIN equipment_maintenance_record_project emrp
on record.id = emrp.equipment_maintenance_record_id
where report_time BETWEEN :startTime AND :endTime
GROUP BY emrp.project_id
`
, {
replacements: {
startTime: moment(startTime).format('YYYY-MM-DD HH:mm:ss '),
endTime: moment(endTime).format('YYYY-MM-DD HH:mm:ss ')
}
//, type: sequelize.QueryTypes.SELECT
}
)
//查询equipment_maintenance_record返回的结果[{project_id: 22,status:'' count: 1}]
let projectList = []
//存project的id
let projectIdList = new Set()
// console.log('resssss', res)
if (res.length > 0) {
res[0].forEach((item) => {
projectList.push({ project_id: item.project_id, 'incomplete': Number(item.incomplete), completed: Number(item.completed) })
projectIdList.add(item.project_id)
})
}
// const result = projectList.reduce((acc, curr) => {
// if (curr.status === '待维修' || curr.status === '维修中') {
// const existingItem = acc.find(item => item.project_id === curr.project_id && item.status === '异常数');
// if (existingItem) {
// existingItem.count += curr.count;
// } else {
// acc.push({ project_id: curr.project_id, status: '异常数', count: curr.count });
// }
// } else if (curr.status === '维修完成') {
// const existingItem = acc.find(item => item.project_id === curr.project_id && item.status === '维修数');
// if (existingItem) {
// existingItem.count += curr.count;
// } else {
// acc.push({ project_id: curr.project_id, status: '维修数', count: curr.count });
// }
// }
// return acc;
// }, [])
//console.log('resssssresult', result)
const projectNameList = await models.ProjectCorrelation.findAll({
attributes:
['id', 'name'],
where: {
id: { $in: [...projectIdList] },
name: {
[Sequelize.Op.not]: null//有name的结果
}
// del: false
}
}) || []
//在ProjectCorrelation中查不到名字,去clickHouse中去查
const projectNameList1 = await models.ProjectCorrelation.findAll({
attributes:
['id', 'name', 'pepProjectId'],
where: {
id: { $in: [...projectIdList] },
name: {
[Sequelize.Op.eq]: null//无name的结果
}
// del: false
}
})
//存放需要去查询clickHouse的id
let idList = new Set()
if (projectNameList1.length) {
projectNameList1.forEach((item) => {
idList.add(item.pepProjectId)
})
}
//pepProject名称
const projectManageName = idList.size ? await clickHouse.projectManage.query(`
SELECT id,project_name FROM t_pim_project
WHERE id IN (${[...idList].join(',')}, -1)
`).toPromise() : []
let project = []
if (projectNameList1.length && projectManageName.length) {
projectManageName.forEach((item) => {
const pepObj = projectNameList1.find((item1) => { return item1.pepProjectId === item.id })
project.push({ id: pepObj.id, projectName: item.project_name })
})
}
//pg的数据和clcikHouse的数据(名字)合并
const resAll = project.concat(projectNameList)
let mergedArray = []
if (resAll.length && projectList) {
mergedArray = projectList.map(obj1 => {
const matchingObj = resAll.find(obj2 => obj2.id === obj1.project_id)
return {
id: obj1.project_id, incomplete: obj1.incomplete, completed: obj1.completed, pepProjectId: matchingObj.id,
projectName: matchingObj.projectName || matchingObj.dataValues.name
}
});
}
// console.log('ididididid', resAll)
// console.log('ididididid', project)
// console.log('ididididid', projectManageName)
// console.log('ididididid', projectNameList)
// console.log('ididididid', projectList)
ctx.status = 200
ctx.body = mergedArray
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: '查询维修记录统计失败'
}
}
}
async function getEquipmentCategory (ctx) {
const { startTime, endTime } = ctx.query
const Sequelize = ctx.fs.dc.ORM
const models = ctx.fs.dc.models
try {
const res = await models.EquipmentMaintenanceRecord.findAll({
attributes: [
'equipment_category',
[Sequelize.fn('COUNT', Sequelize.col('equipment_category')), 'count']
],
where: { reportTime: { $between: [moment(startTime).format('YYYY-MM-DD HH:mm:ss '), moment(endTime).format('YYYY-MM-DD HH:mm:ss ')] } },
group: ['equipment_category']
})
ctx.status = 200
ctx.body = res
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: '查询设备类型失败'
}
}
}
async function getStatus (ctx) {
const { startTime, endTime } = ctx.query
const Sequelize = ctx.fs.dc.ORM
const models = ctx.fs.dc.models
try {
const res = await models.EquipmentMaintenanceRecord.findAll({
attributes: [
'status',
[Sequelize.fn('COUNT', Sequelize.col('status')), 'count']
],
where: { reportTime: { $between: [moment(startTime).format('YYYY-MM-DD HH:mm:ss '), moment(endTime).format('YYYY-MM-DD HH:mm:ss ')] } },
group: ['status']
})
ctx.status = 200
ctx.body = res
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: '查询设备类型失败'
}
}
}
async function getOrganizationsStruc (ctx) {
try {
const { utils: { anxinStrucIdRange } } = ctx.app.fs
const { pepProjectId } = ctx.params
if (!pepProjectId) {
throw '缺少参数 pepProjectId'
}
let anxinStruc = await anxinStrucIdRange({
ctx, pepProjectId
}) || []
ctx.status = 200
ctx.body = anxinStruc
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: '查询设备类型失败'
}
}
}
module.exports = {
getOrganizationsStruc,
}

0
api/app/lib/controllers/operationData/index.js → api/app/lib/controllers/analysis/operationData.js

0
api/app/lib/controllers/problemData/index.js → api/app/lib/controllers/analysis/problemData.js

2
api/app/lib/index.js

@ -35,7 +35,7 @@ module.exports.entry = function (app, router, opts) {
es(app, opts)
kafka(app, opts)
// kafka(app, opts)
// clickHouse 数据库 client
clickHouseClient(app, opts)

16
api/app/lib/routes/analysis/network.js

@ -0,0 +1,16 @@
'use strict';
const network = require('../../controllers/analysis/network');
module.exports = function (app, router, opts) {
app.fs.api.logAttr['GET/organizations/:pepProjectId/struc'] = { content: '获取项目下的结构物信息', visible: true };
router.get('/organizations/:pepProjectId/struc', network.getOrganizationsStruc)
// app.fs.api.logAttr['GET/systemAvailability'] = { content: '获取系统可用性', visible: true };
// router.get('/systemAvailability', operationData.getSystemAvailability)
// app.fs.api.logAttr['GET/problemType'] = { content: '获取故障类型', visible: true };
// router.get('/problemType', operationData.getProblemType)
// app.fs.api.logAttr['GET/operationsPersonnel'] = { content: '获取运维人员', visible: true };
// router.get('/operationsPersonnel', operationData.getOperationsPersonnel)
}

2
api/app/lib/routes/operationData/index.js → api/app/lib/routes/analysis/operationData.js

@ -1,5 +1,5 @@
'use strict';
const operationData = require('../../controllers/operationData');
const operationData = require('../../controllers/analysis/operationData');
module.exports = function (app, router, opts) {
app.fs.api.logAttr['GET/failureTime'] = { content: '获取故障发生时间', visible: true };

2
api/app/lib/routes/problemData/index.js → api/app/lib/routes/analysis/problemData.js

@ -1,5 +1,5 @@
'use strict';
const problemData = require('../../controllers/problemData');
const problemData = require('../../controllers/analysis/problemData');
module.exports = function (app, router, opts) {
app.fs.api.logAttr['GET/maintenceRecordRank'] = { content: '获取维修记录排名', visible: true };

3
web/client/src/sections/analysis/actions/index.js

@ -3,6 +3,7 @@
import * as console from './console'
import * as operation from './operationData'
import * as maintenceRecord from './maintenceRecordTotal'
import * as network from './network'
export default {
...console, ...operation, ...maintenceRecord
...console, ...operation, ...maintenceRecord, ...network
}

50
web/client/src/sections/analysis/actions/network.js

@ -0,0 +1,50 @@
'use strict';
import { ApiTable, basicAction } from '$utils'
export function getOrganizationsStruc (id) {
return dispatch => basicAction({
type: 'get',
dispatch: dispatch,
actionType: 'GET_ORGANIZATIONS_STRUC',
url: `${ApiTable.organizationsStruc.replace('{pepProjectId}', id)}`,
msg: { error: '获取项目下的结构物信息失败' },
reducer: { name: 'organizationsStruc' }
})
}
// export function getSystemAvailability() {
// return dispatch => basicAction({
// type: 'get',
// dispatch: dispatch,
// actionType: 'GET_SYSTEM_AVAILABILITY',
// url: ApiTable.getSystemAvailability,
// msg: { error: '获取可用性分析' },
// reducer: { name: 'systemAvailability' }
// })
// }
// export function getProblemType() {
// return dispatch => basicAction({
// type: 'get',
// dispatch: dispatch,
// actionType: 'GET_PROBLEM_TYPE',
// url: ApiTable.getProblemType,
// msg: { error: '获取故障类型' },
// reducer: { name: 'probleType' }
// })
// }
// export function getOperationsPersonnel() {
// return dispatch => basicAction({
// type: 'get',
// dispatch: dispatch,
// actionType: 'GET_OPERATIONS_PERSONNEL',
// url: ApiTable.getOperationsPersonnel,
// msg: { error: '获取故障类型' },
// reducer: { name: 'operationsPersonnel' }
// })
// }

82
web/client/src/sections/analysis/containers/network.jsx

@ -8,18 +8,57 @@ import TreeShow from './treeShow';
const Network = (props) => {
const { dispatch, actions, user, clientHeight } = props
const Network = ({
dispatch, actions, user, clientHeight,
projectPoms, pepProjectId, organizationsStruc
}) => {
const { analysis } = actions
const [show, setShow] = useState('tree')
const [projectList, setProjectList] = useState([]) //
const [projectValue, setProjectValue] = useState() //
const [thingId, setThingId] = useState() //thingId
const form = useRef();//
useEffect(() => {
let projectData = []
let project = projectPoms.filter(v => v.pepProjectIsDelete != 1)
if (projectPoms?.length) {
if (pepProjectId) {
if (pepProjectId?.length) {
let projectId = pepProjectId + ',-1'
projectData = project?.filter(d => projectId?.includes(d.id?.toString()))
} else {
projectData = project?.filter(d => d.id == pepProjectId)
}
} else {
projectData = [...project]
}
}
setProjectList(projectData?.map(d => ({ value: d.id, label: d.name || d.pepProjectName })))
setProjectValue(projectData[0]?.id)
form.current.setValue('projectId', projectData[0]?.id)
}, [projectPoms, pepProjectId])
}, [])
useEffect(() => {
//
if (projectValue) dispatch(analysis.getOrganizationsStruc(projectValue))
}, [projectValue])
useEffect(() => {
//
if (organizationsStruc?.length) {
setThingId(organizationsStruc[0]?.thingId)
form.current.setValue('thingId', organizationsStruc[0]?.thingId)
} else {
setThingId("")
form.current.setValue('thingId', "")
}
}, [organizationsStruc])
console.log(thingId);
return (
<>
@ -41,29 +80,32 @@ const Network = (props) => {
filter
showClear
label='项目选择'
field="keywordTarget"
field="projectId"
labelPosition="left"
placeholder="请选择项目选择"
style={{ width: 200, marginRight: 10, }}
// initValue={""}
>
<Form.Select.Option value='pepProject'>项目</Form.Select.Option>
<Form.Select.Option value='struc'>结构物</Form.Select.Option>
<Form.Select.Option value='tactics'>策略名</Form.Select.Option>
</Form.Select>
// value={projectValue}
optionList={projectList || []}
onSelect={v => {
console.log(v);
setProjectValue(v)
form.current.setValue('projectId', v)
}}
/>
<Form.Select
label='结构物选择:'
labelPosition="left"
field='tactics'
field='thingId'
style={{ width: 200, }}
placeholder="请选择结构物选择"
filter
showClear
>
<Form.Select.Option value="immediately">即时推送机制</Form.Select.Option>
<Form.Select.Option value="continue">持续时长推送机制</Form.Select.Option>
<Form.Select.Option value="abnormal_rate">异常率推送机制</Form.Select.Option>
</Form.Select>
optionList={organizationsStruc?.map(d => ({ value: d.thingId, label: d.strucName })) || []}
onSelect={v => {
setThingId(v)
form.current.setValue('thingId', v)
}}
/>
</Form>
</div>
@ -125,11 +167,15 @@ const Network = (props) => {
}
function mapStateToProps (state) {
const { auth, global, members, webSocket } = state;
const { auth, global, ProjectPoms, organizationsStruc } = state;
return {
user: auth.user,
actions: global.actions,
clientHeight: global.clientHeight
clientHeight: global.clientHeight,
projectPoms: ProjectPoms?.data?.rows || [],
pepProjectId: global.pepProjectId,
organizationsStruc: organizationsStruc?.data || [], //
};
}

3
web/client/src/sections/firmwareUpgrade/containers/deviceManagement.jsx

@ -48,7 +48,7 @@ const DeviceManagement = (props) => {
dispatch(firmwareUpgrade.getFirmware()).then(res => {
if (res.success) setVData(res.payload.data)
})
},[])
}, [pepProjectId])
useEffect(() => {
if (thingIds && thingIds.length) {
const data = { thingIds: thingIds.split(',')[0] || '000' }//
@ -242,6 +242,7 @@ return <><div style={{ background: '#FFFFFF', margin: '8px 12px', padding: '20
function mapStateToProps (state) {
const { auth, global, getPush } = state;
console.log(222, global);
return {
loading: getPush.isRequesting,
user: auth.user,

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

@ -139,23 +139,20 @@ export const ApiTable = {
editServerInfoMaintenanceRecord: 'serverInfoMaintenanceRecord',
//删除服务器信息维护记录
delServerInfoMaintenanceRecord: 'serverInfoMaintenanceRecord/{id}',
//运维分析-运维数据
//故障发生时间分析
getFailureTime: 'failureTime',
//系统可用性分析
getSystemAvailability: 'systemAvailability',
//故障类型
getProblemType: 'problemType',
//y运维人员
getOperationsPersonnel: 'operationsPersonnel',
//维修记录排名
getMaintenceRecordRank: 'maintenceRecordRank',
//维修数统计
getMaintenceTotal: 'maintenceTotal',
//获取设备类型
getEquipmentCategory: 'equipmentCategory',
//获取状态数据
getMaintenanceStatus: 'maintenanceStatus',
//分析
getFailureTime: 'failureTime', //故障发生时间分析
getSystemAvailability: 'systemAvailability',//系统可用性分析
getProblemType: 'problemType', //故障类型
getOperationsPersonnel: 'operationsPersonnel',//y运维人员
getMaintenceRecordRank: 'maintenceRecordRank', //维修记录排名
getMaintenceTotal: 'maintenceTotal',//维修数统计
getEquipmentCategory: 'equipmentCategory',//维修数统计
getMaintenanceStatus: 'maintenanceStatus',//获取状态数据
//分析-一图统揽
organizationsStruc: 'organizations/{pepProjectId}/struc', //获取项目下的结构物信息
respondRecord: 'respond-record',

Loading…
Cancel
Save