巴林闲侠
2 years ago
14 changed files with 1277 additions and 54 deletions
@ -0,0 +1,154 @@ |
|||
'use strict'; |
|||
|
|||
const moment = require('moment') |
|||
//const db = require('../')
|
|||
async function getFailureTime(ctx) { |
|||
const sequelize = ctx.fs.dc.orm |
|||
try { |
|||
const res = await sequelize.query( |
|||
`SELECT substring(to_char(w.wmonth,'yyyy-mm'),1,7) wmonth,COALESCE(e.counts,0) count
|
|||
from ( SELECT COUNT(1) counts,to_char(maintenance_record.occurrence_time, 'yyyy-mm') months |
|||
FROM maintenance_record |
|||
GROUP BY months |
|||
) e |
|||
RIGHT JOIN |
|||
( |
|||
SELECT to_date(EXTRACT(YEAR FROM (current_date - INTERVAL '1 month' * (t - 1))) ||'-' |
|||
|| EXTRACT(MONTH FROM (current_date - INTERVAL '1 month' * (t - 1))),'yyyy-mm')as wmonth |
|||
from generate_series(1, 12) as t |
|||
) w on e.months = substring(to_char(w.wmonth,'yyyy-mm'),1,7) |
|||
GROUP BY w.wmonth,e.counts |
|||
ORDER BY w.wmonth desc` |
|||
) |
|||
console.log('111112232', res) |
|||
let resList = [] |
|||
if (res.length > 0) { |
|||
res[0].forEach((item) => { |
|||
resList.push(item) |
|||
}) |
|||
|
|||
} |
|||
ctx.status = 200 |
|||
ctx.body = resList |
|||
} catch (error) { |
|||
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
|||
ctx.status = 400; |
|||
ctx.body = { |
|||
message: '查询故障发生时间失败' |
|||
} |
|||
} |
|||
|
|||
} |
|||
async function getSystemAvailability(ctx) { |
|||
const sequelize = ctx.fs.dc.orm |
|||
try { |
|||
const res = await sequelize.query( |
|||
`SELECT substring(to_char(w.wmonth,'yyyy-mm'),1,7) wmonth,
|
|||
COALESCE((w.seconds-e.counts)/w.seconds,0) ability |
|||
from ( |
|||
SELECT to_char(maintenance_record.occurrence_time, 'yyyy-MM') months, |
|||
SUM(maintenance_record.interrupt_duration) counts |
|||
FROM maintenance_record |
|||
where maintenance_record.occurrence_time is not null |
|||
GROUP BY months |
|||
) e |
|||
RIGHT JOIN |
|||
( |
|||
SELECT to_date(EXTRACT(YEAR FROM (current_date - INTERVAL '1 month' * (n - 1))) ||'-'|| EXTRACT(MONTH FROM (current_date - INTERVAL '1 month' * (n - 1))),'yyyy-mm') as wmonth, |
|||
(EXTRACT(DAY FROM (DATE_TRUNC('MONTH', current_date - INTERVAL '1 month' * (n - 1) + INTERVAL '1 MONTH') - DATE_TRUNC('MONTH', current_date - INTERVAL '1 month' * (n - 1)) - INTERVAL '1 DAY'))+1)* 24 * 60 * 60 AS seconds |
|||
from generate_series(1, 12) AS n |
|||
) w |
|||
on e.months = substring(to_char(w.wmonth,'yyyy-mm'),1,7) |
|||
GROUP BY w.wmonth,w.seconds,e.counts |
|||
ORDER BY w.wmonth DESC;` |
|||
) |
|||
let resList = [] |
|||
if (res.length > 0) { |
|||
res[0].forEach((item) => { |
|||
resList.push(item) |
|||
}) |
|||
} |
|||
ctx.status = 200 |
|||
ctx.body = resList |
|||
|
|||
} catch (error) { |
|||
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
|||
ctx.status = 400; |
|||
ctx.body = { |
|||
message: '查询系统可用性失败' |
|||
} |
|||
} |
|||
} |
|||
|
|||
async function getProblemType(ctx) { |
|||
const sequelize = ctx.fs.dc.orm |
|||
try { |
|||
const res = await sequelize.query(` |
|||
SELECT n.type,COALESCE(m.count,0) count FROM (SELECT t.type,count(1) FROM maintenance_record t GROUP BY t.type) m |
|||
RIGHT JOIN (SELECT p.type FROM system_problem p) n |
|||
ON m.type=n.type |
|||
GROUP BY n.type,m.count |
|||
`)
|
|||
let resList = [] |
|||
if (res.length > 0) { |
|||
res[0].forEach((item) => { |
|||
resList.push(item) |
|||
}) |
|||
|
|||
} |
|||
ctx.status = 200 |
|||
ctx.body = resList |
|||
} catch (error) { |
|||
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
|||
ctx.status = 400; |
|||
ctx.body = { |
|||
message: '查询故障类型失败' |
|||
} |
|||
} |
|||
} |
|||
async function getOperationsPersonnel(ctx) { |
|||
const sequelize = ctx.fs.dc.orm |
|||
const { clickHouse } = ctx.app.fs |
|||
try { |
|||
//查询用户id
|
|||
const res = await sequelize.query(`SELECT t.pep_user_id userId,count(1) FROM maintenance_plan_execute_user t GROUP BY pep_user_id`) |
|||
let useList = new Set() |
|||
console.log('rss', res) |
|||
if (res.length > 0) { |
|||
res[0].forEach((item) => { |
|||
useList.add(item.userid) |
|||
}) |
|||
} |
|||
let users = useList ? await clickHouse.pepEmis.query(`SELECT DISTINCT user.id AS id, "user"."name" AS name FROM user WHERE user.id IN
|
|||
(${[...useList].join(',')}, -1)`).toPromise() : []
|
|||
let resRecord = [] |
|||
if (res.length > 0) { |
|||
res[0].forEach((item) => { |
|||
resRecord.push(item) |
|||
}) |
|||
} |
|||
let mergedArray = [] |
|||
if (users.length > 0 && resRecord.length > 0) { |
|||
mergedArray = users.map(item1 => { |
|||
const item2 = resRecord.find(item2 => item2.userid === item1.id); |
|||
return { |
|||
userid: item1.id, |
|||
name: item1.name, |
|||
count: parseInt(item2.count) |
|||
} |
|||
}) |
|||
} |
|||
ctx.status = 200 |
|||
ctx.body = mergedArray |
|||
} catch (error) { |
|||
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
|||
ctx.status = 400; |
|||
ctx.body = { |
|||
message: '查询运维人员失败' |
|||
} |
|||
} |
|||
} |
|||
|
|||
module.exports = { |
|||
getFailureTime, getSystemAvailability, getProblemType, getOperationsPersonnel |
|||
} |
@ -0,0 +1,297 @@ |
|||
'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: '查询设备类型失败' |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
module.exports = { |
|||
getMaintenceRecordRank, getMaintenceTotal, getEquipmentCategory, getStatus |
|||
} |
@ -0,0 +1,34 @@ |
|||
/* eslint-disable*/ |
|||
|
|||
'use strict'; |
|||
|
|||
module.exports = dc => { |
|||
const DataTypes = dc.ORM; |
|||
const sequelize = dc.orm; |
|||
const SystemProblem = sequelize.define("systemProblem", { |
|||
id: { |
|||
type: DataTypes.INTEGER, |
|||
allowNull: false, |
|||
defaultValue: null, |
|||
comment: null, |
|||
primaryKey: true, |
|||
field: "id", |
|||
autoIncrement: true |
|||
}, |
|||
type: { |
|||
type: DataTypes.STRING, |
|||
allowNull: true, |
|||
defaultValue: null, |
|||
comment: "问题类型:数据库异常、es异常、kafka异常、服务器异常、应用异常、其他", |
|||
primaryKey: false, |
|||
field: "type", |
|||
autoIncrement: false |
|||
} |
|||
}, { |
|||
tableName: "system_problem", |
|||
comment: "", |
|||
indexes: [] |
|||
}); |
|||
dc.models.SystemProblem = SystemProblem; |
|||
return SystemProblem; |
|||
}; |
@ -0,0 +1,16 @@ |
|||
'use strict'; |
|||
const operationData = require('../../controllers/operationData'); |
|||
|
|||
module.exports = function (app, router, opts) { |
|||
app.fs.api.logAttr['GET/failureTime'] = { content: '获取故障发生时间', visible: true }; |
|||
router.get('/failureTime', operationData.getFailureTime) |
|||
|
|||
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) |
|||
} |
@ -0,0 +1,16 @@ |
|||
'use strict'; |
|||
const problemData = require('../../controllers/problemData'); |
|||
|
|||
module.exports = function (app, router, opts) { |
|||
app.fs.api.logAttr['GET/maintenceRecordRank'] = { content: '获取维修记录排名', visible: true }; |
|||
router.get('/maintenceRecordRank', problemData.getMaintenceRecordRank) |
|||
|
|||
app.fs.api.logAttr['GET/maintenceTotal'] = { content: '获取维修次数统计', visible: true }; |
|||
router.get('/maintenceTotal', problemData.getMaintenceTotal) |
|||
|
|||
app.fs.api.logAttr['GET/equipmentCategory'] = { content: '获取设备类型', visible: true }; |
|||
router.get('/equipmentCategory', problemData.getEquipmentCategory) |
|||
|
|||
app.fs.api.logAttr['GET/maintenanceStatus'] = { content: '获取状态', visible: true }; |
|||
router.get('/maintenanceStatus', problemData.getStatus) |
|||
} |
@ -0,0 +1,15 @@ |
|||
create table public.system_problem( |
|||
id serial primary key, |
|||
type varchar(20) |
|||
); |
|||
comment on column public.system_problem.type is '问题类型:数据库异常、es异常、kafka异常、服务器异常、应用异常、其他'; |
|||
|
|||
insert into system_problem (id, type)values ('es异常'); |
|||
insert into system_problem (id, type)values ('数据库异常'); |
|||
insert into system_problem (id, type)values ('应用异常'); |
|||
insert into system_problem (id, type)values ('kafka异常'); |
|||
insert into system_problem (id, type)values ('服务器异常'); |
|||
insert into system_problem (id, type)values ('DAC进程异常'); |
|||
insert into system_problem (id, type)values ('K8S集群异常'); |
|||
insert into system_problem (id, type)values ('redis服务异常'); |
|||
insert into system_problem (id, type)values ('其他'); |
@ -1,7 +1,8 @@ |
|||
'use strict'; |
|||
|
|||
import * as console from './console' |
|||
|
|||
import * as operation from './operationData' |
|||
import * as maintenceRecord from './maintenceRecordTotal' |
|||
export default { |
|||
...console |
|||
...console, ...operation, ...maintenceRecord |
|||
} |
@ -0,0 +1,53 @@ |
|||
'use strict'; |
|||
|
|||
import { ApiTable, basicAction } from '$utils' |
|||
|
|||
|
|||
export function getMaintenceRecordRank(query) { |
|||
return dispatch => basicAction({ |
|||
type: 'get', |
|||
dispatch: dispatch, |
|||
query: query, |
|||
actionType: 'GET_MAINTENCE_RECORD_RANK', |
|||
url: ApiTable.getMaintenceRecordRank, |
|||
msg: { option: '获取维修记录排名' }, |
|||
reducer: { name: 'maintenceRecordRank' } |
|||
}) |
|||
} |
|||
|
|||
|
|||
export function getMaintenceTotal(query) { |
|||
return dispatch => basicAction({ |
|||
type: 'get', |
|||
dispatch: dispatch, |
|||
query: query, |
|||
actionType: 'GET_MAINTENCE_TOTAL', |
|||
url: ApiTable.getMaintenceTotal, |
|||
msg: { option: '获取维修次数统计' }, |
|||
reducer: { name: 'maintenceTotal' } |
|||
}) |
|||
} |
|||
|
|||
export function getEquipmentCategory(query) { |
|||
return dispatch => basicAction({ |
|||
type: 'get', |
|||
dispatch: dispatch, |
|||
query: query, |
|||
actionType: 'GET_EQUIPMENT_CATEGORY', |
|||
url: ApiTable.getEquipmentCategory, |
|||
msg: { option: '获取设备类型' }, |
|||
reducer: { name: 'equipmentCategory' } |
|||
}) |
|||
} |
|||
|
|||
export function getStatus(query) { |
|||
return dispatch => basicAction({ |
|||
type: 'get', |
|||
dispatch: dispatch, |
|||
query: query, |
|||
actionType: 'GET_STATUS', |
|||
url: ApiTable.getMaintenanceStatus, |
|||
msg: { option: '获取维修状态数据' }, |
|||
reducer: { name: 'maintenanceStatus' } |
|||
}) |
|||
} |
@ -0,0 +1,50 @@ |
|||
'use strict'; |
|||
|
|||
import { ApiTable, basicAction } from '$utils' |
|||
|
|||
|
|||
export function getFailureTime() { |
|||
return dispatch => basicAction({ |
|||
type: 'get', |
|||
dispatch: dispatch, |
|||
actionType: 'GET_FAILURE_TIME', |
|||
url: ApiTable.getFailureTime, |
|||
msg: { error: '获取故障发生时间分析' }, |
|||
reducer: { name: 'failureTime' } |
|||
}) |
|||
} |
|||
|
|||
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' } |
|||
}) |
|||
} |
@ -1,48 +1,267 @@ |
|||
import React, { useEffect } from 'react'; |
|||
import React, { useEffect, useState } from 'react'; |
|||
import { connect } from 'react-redux'; |
|||
import { Spin, Card } from '@douyinfe/semi-ui'; |
|||
import { Spin, Card, Divider, CardGroup } from '@douyinfe/semi-ui'; |
|||
import '../style.less' |
|||
import ReactECharts from 'echarts-for-react'; |
|||
const { Meta } = Card; |
|||
|
|||
const Console = (props) => { |
|||
const { dispatch, actions, user, loading, socket } = props |
|||
|
|||
useEffect(() => { |
|||
// ACTION 示例 |
|||
// dispatch(actions.example.getMembers(user.orgId)) |
|||
}, []) |
|||
|
|||
// websocket 使用测试 |
|||
// useEffect(() => { |
|||
// if (socket) { |
|||
// socket.on('TEST', function (msg) { |
|||
// console.info(msg); |
|||
// }); |
|||
// return () => { |
|||
// socket.off("TEST"); |
|||
// } |
|||
// } |
|||
|
|||
// }, [socket]) |
|||
|
|||
return ( |
|||
<> |
|||
<div> |
|||
<img src="/assets/images/install/watting.png" alt="" style={{ width: 'calc(100% + 16px)', position: "relative",top: -12, left: -8, }} /> |
|||
const { dispatch, actions, user, loading, socket, clientHeight } = props |
|||
const [left1List, setLeft1List] = useState([])//故障发生时间分析的数据 |
|||
const [right1List, setRight1List] = useState([])//系统可用性分析的数据 |
|||
const [left2List, setLeft2List] = useState([])//故障类型分析的数据 |
|||
const [right2List, setRight2List] = useState([])//运维人员分析的数据 |
|||
const { analysis } = actions |
|||
console.log('actions', actions) |
|||
useEffect(() => { |
|||
// ACTION 示例 |
|||
// dispatch(actions.example.getMembers(user.orgId)) |
|||
}, []) |
|||
useEffect(() => { |
|||
//故障发生时间分析接口 |
|||
dispatch(analysis.getFailureTime()).then((res) => { |
|||
if (res.success) setLeft1List(res.payload.data) |
|||
}) |
|||
//系统可用性分析接口 |
|||
dispatch(analysis.getSystemAvailability()).then((res) => { |
|||
if (res.success) setRight1List(res.payload.data) |
|||
}) |
|||
//故障类型接口 |
|||
dispatch(analysis.getProblemType()).then((res) => { |
|||
if (res.success) setLeft2List(res.payload.data) |
|||
}) |
|||
//运维人员 |
|||
dispatch(analysis.getOperationsPersonnel()).then((res) => { |
|||
if (res.success) setRight2List(res.payload.data) |
|||
}) |
|||
|
|||
}, []) |
|||
|
|||
|
|||
// websocket 使用测试 |
|||
// useEffect(() => { |
|||
// if (socket) { |
|||
// socket.on('TEST', function (msg) { |
|||
// console.info(msg); |
|||
// }); |
|||
// return () => { |
|||
// socket.off("TEST"); |
|||
// } |
|||
// } |
|||
|
|||
// }, [socket]) |
|||
|
|||
return ( |
|||
<> |
|||
{/* <img src="/assets/images/install/watting.png" alt="" style={{ width: 'calc(100% + 16px)', position: "relative",top: -12, left: -8, }} /> */} |
|||
<div style={{ background: '#FFFFFF', margin: '8px 12px', padding: '20px 20px 0px 20px', minHeight: clientHeight - 32, display: 'flex', flexDirection: 'column' }}> |
|||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}> |
|||
<div style={{ display: 'flex', alignItems: 'center' }}> |
|||
<div style={{ width: 0, height: 20, borderLeft: '3px solid #005ABD', borderTop: '3px solid transparent', borderBottom: '3px solid transparent' }}></div> |
|||
<div style={{ fontFamily: "YouSheBiaoTiHei", fontSize: 24, color: '#101531', marginLeft: 8 }}>维修记录统计</div> |
|||
<div style={{ marginLeft: 6, fontSize: 12, color: '#969799', fontFamily: "DINExp", }}>MAINTAIN RECORDS STATISTICAL</div> |
|||
</div> |
|||
</div> |
|||
</> |
|||
) |
|||
<div style={{ margin: '20px 0', flex: 1, display: 'flex', }}> |
|||
<CardGroup type='grid' style={{ width: '100%' }}> |
|||
{ |
|||
[{ |
|||
t: '故障发生时间分析', |
|||
echartOption: { |
|||
xAxis: { |
|||
type: 'category', |
|||
data: left1List.map((item) => { |
|||
return item.wmonth |
|||
}), |
|||
axisLabel: { |
|||
interval: 0,//x轴强制显示每个 |
|||
rotate: 40 |
|||
}, |
|||
}, |
|||
yAxis: { |
|||
type: 'value', |
|||
name: "单位:次数", |
|||
// nameLocation: "end", |
|||
// nameGap: 20 |
|||
}, |
|||
legend: { |
|||
orient: 'vertical', |
|||
right: '5%', |
|||
top: '0%', |
|||
data: ['异常数'] |
|||
}, |
|||
tooltip: {}, |
|||
grid: { |
|||
top: '10%', |
|||
right: '5%', |
|||
left: '5%', |
|||
bottom: '10%', |
|||
containLabel: true |
|||
}, |
|||
|
|||
series: [ |
|||
{ |
|||
data: left1List.map((item) => { |
|||
return Number(item.count) |
|||
}), |
|||
type: 'bar', |
|||
name: '异常数', |
|||
} |
|||
] |
|||
}, |
|||
}, { |
|||
t: '系统可用性分析', |
|||
echartOption: { |
|||
xAxis: { |
|||
type: 'category', |
|||
data: right1List.map((item) => { |
|||
return item.wmonth |
|||
}), |
|||
axisLabel: { |
|||
interval: 0,//x轴强制显示每个 |
|||
rotate: 40 |
|||
}, |
|||
}, |
|||
yAxis: { |
|||
type: 'value', |
|||
name: "单位:%", |
|||
// nameLocation: "end", |
|||
// nameGap: 20 |
|||
}, |
|||
legend: {}, |
|||
tooltip: {}, |
|||
grid: { |
|||
//left: '3%', |
|||
//right: '3%', |
|||
bottom: '1%', |
|||
// top: '24%', |
|||
containLabel: true |
|||
}, |
|||
|
|||
series: [ |
|||
{ |
|||
data: right1List.map((item) => { |
|||
return Math.round(item.ability * 10000) / 100 |
|||
|
|||
}), |
|||
type: 'line', |
|||
} |
|||
] |
|||
}, |
|||
}, { |
|||
t: '故障类型分析', |
|||
echartOption: { |
|||
xAxis: { |
|||
type: 'category', |
|||
data: left2List.map((item) => { |
|||
return item.type |
|||
}), |
|||
axisLabel: { |
|||
interval: 0,//x轴强制显示每个 |
|||
rotate: 40 |
|||
}, |
|||
}, |
|||
yAxis: { |
|||
type: 'value', |
|||
name: "单位:个", |
|||
nameLocation: "end", |
|||
nameGap: 20 |
|||
}, |
|||
legend: {}, |
|||
tooltip: {}, |
|||
grid: { |
|||
left: '3%', |
|||
right: '4%', |
|||
bottom: '1%', |
|||
// top: '24%', |
|||
containLabel: true |
|||
}, |
|||
series: [ |
|||
{ |
|||
data: left2List.map((item) => { |
|||
return Number(item.count) |
|||
}), |
|||
type: 'bar', |
|||
//name: '发起数' |
|||
} |
|||
|
|||
] |
|||
}, |
|||
}, { |
|||
t: '运维人员分析', |
|||
echartOption: { |
|||
tooltip: {}, |
|||
series: [ |
|||
{ |
|||
// name: right2List?.map((item)=>{ |
|||
// return item.name |
|||
// }), |
|||
type: 'pie', |
|||
radius: '80%',//饼图大小 |
|||
data: right2List?.map((item) => { |
|||
return { value: item.count, name: item.name } |
|||
}), |
|||
label: { |
|||
|
|||
} |
|||
} |
|||
], |
|||
media: [ |
|||
{ |
|||
query: { minAspectRatio: 1 }, |
|||
option: { |
|||
series: [ |
|||
{ center: ['50%', '50%'] }, |
|||
{ center: ['50%', '50%'] } |
|||
] |
|||
} |
|||
}, |
|||
] |
|||
}, |
|||
},].map((c, idx) => ( |
|||
<Card |
|||
key={idx} |
|||
shadows='hover' |
|||
title={c.t} |
|||
bordered={false} |
|||
headerLine={false} |
|||
headerStyle={{ |
|||
padding: '12px', |
|||
}} |
|||
bodyStyle={{ |
|||
padding: '12px', |
|||
}} |
|||
style={{ width: '50%', height: '50%' }} |
|||
> |
|||
|
|||
<ReactECharts |
|||
notMerge={true} |
|||
lazyUpdate={true} |
|||
option={c.echartOption} |
|||
/> |
|||
</Card> |
|||
)) |
|||
} |
|||
</CardGroup> |
|||
</div> |
|||
</div> |
|||
|
|||
|
|||
</> |
|||
) |
|||
} |
|||
|
|||
function mapStateToProps (state) { |
|||
const { auth, global, members, webSocket } = state; |
|||
return { |
|||
// loading: members.isRequesting, |
|||
// user: auth.user, |
|||
// actions: global.actions, |
|||
// members: members.data, |
|||
// socket: webSocket.socket |
|||
}; |
|||
function mapStateToProps(state) { |
|||
const { auth, global, members, webSocket } = state; |
|||
return { |
|||
// loading: members.isRequesting, |
|||
// user: auth.user, |
|||
actions: global.actions, |
|||
// members: members.data, |
|||
// socket: webSocket.socket |
|||
clientHeight: global.clientHeight |
|||
|
|||
}; |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(Console); |
|||
|
Loading…
Reference in new issue