zhaobing
2 years ago
23 changed files with 1526 additions and 53 deletions
@ -0,0 +1,48 @@ |
|||
'use strict'; |
|||
const moment = require('moment'); |
|||
|
|||
|
|||
//系统可用性
|
|||
async function getCalculability(ctx) { |
|||
try { |
|||
const { models } = ctx.fs.dc |
|||
const query = ctx.query |
|||
const sequelize = ctx.fs.dc.ORM; |
|||
//console.log('query2', query)
|
|||
const { eTime, sTime } = query |
|||
const timer = (new Date(eTime) - new Date(sTime)) / 1000 //时间之间的秒数
|
|||
//console.log('timer', timer)
|
|||
let recordRes = await models.MaintenanceRecord.findAndCount({ |
|||
attributes: ['occurrenceTime', 'solvingTime'], |
|||
where: { |
|||
$and: [ |
|||
sequelize.where(sequelize.fn('date', sequelize.col('occurrence_time')), '>=', moment(sTime).format('YYYY-MM-DD HH:mm:ss')), |
|||
sequelize.where(sequelize.fn('date', sequelize.col('occurrence_time')), '<=', moment(eTime).format('YYYY-MM-DD HH:mm:ss')), |
|||
] |
|||
} |
|||
|
|||
}) |
|||
let problemtime = 0 |
|||
recordRes.rows.forEach((item) => { |
|||
problemtime += item.solvingTime - item.occurrenceTime |
|||
}) |
|||
//console.log('problemtime', problemtime)
|
|||
//console.log('recordRes', recordRes)
|
|||
//console.log(time, 'time1')
|
|||
const abilty = timer / (timer + problemtime) |
|||
//console.log('abc', abilty)
|
|||
ctx.status = 200 |
|||
|
|||
ctx.body = abilty |
|||
} catch (error) { |
|||
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`) |
|||
ctx.status = 400 |
|||
ctx.body = { |
|||
message: `查询系统可用性失败` |
|||
} |
|||
} |
|||
} |
|||
|
|||
module.exports = { |
|||
getCalculability |
|||
} |
@ -0,0 +1,183 @@ |
|||
'use strict'; |
|||
|
|||
|
|||
//维护计划
|
|||
async function getMaintenancePlan(ctx) { |
|||
try { |
|||
const { models } = ctx.fs.dc |
|||
const { clickHouse } = ctx.app.fs |
|||
const query = ctx.query |
|||
//console.log('11121', query)
|
|||
let resCount = await models.MaintenancePlan.count({ |
|||
where: { type: query.type } |
|||
}) |
|||
const res = await models.MaintenancePlan.findAndCount({ |
|||
order: [['id', 'DESC']], |
|||
offset: (query.pageIndex - 1) * query.pageSize, |
|||
|
|||
limit: query.pageSize, |
|||
attributes: ['id', 'missionName', 'remark', 'reason', 'planFinishTime', 'actualFinishTime', 'type', 'state'], |
|||
where: { type: query.type }, |
|||
include: [{ |
|||
attributes: ['id', 'maintenancePlanId', 'pepUserId'], |
|||
model: models.MaintenancePlanExecuteUser |
|||
}] |
|||
}) |
|||
//console.log('res1', res)
|
|||
const arrayUserId = [] |
|||
res.rows.forEach((item) => { item.maintenancePlanExecuteUsers.forEach((item1) => { arrayUserId.push(item1.pepUserId) }) }) |
|||
const arrayUserIdCopy = [...new Set(arrayUserId)] |
|||
const whereOption = '(' + arrayUserIdCopy.toString() + ')' |
|||
const userRes = await clickHouse.pepEmis.query(` |
|||
SELECT * FROM user |
|||
WHERE id in ${whereOption} |
|||
`).toPromise()
|
|||
//console.log('userRes', userRes)
|
|||
//console.log('res.rows', res.rows)
|
|||
const responseRes = res.rows.map((item) => { |
|||
return { |
|||
id: item.id, |
|||
missionName: item.missionName, |
|||
remark: item.remark, |
|||
reason: item.reason, |
|||
planFinishTime: item.planFinishTime, |
|||
actualFinishTime: item.actualFinishTime, |
|||
type: item.type, |
|||
state: item.state, |
|||
maintenancePlanExecuteUsers: |
|||
item.maintenancePlanExecuteUsers.map((item1) => { |
|||
return { |
|||
id: item1.id, |
|||
maintenancePlanId: item1.maintenancePlanId, |
|||
pepUserId: item1.pepUserId, |
|||
name: userRes.filter((ac) => { return ac.id == item1.pepUserId })[0].name |
|||
} |
|||
}) |
|||
} |
|||
}) |
|||
ctx.body = { count: resCount, responseRes } |
|||
//console.log('responseRes', responseRes)
|
|||
ctx.status = 200 |
|||
|
|||
} catch (error) { |
|||
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`) |
|||
ctx.status = 400 |
|||
ctx.body = { |
|||
message: `${query.msg}失败` |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
async function delMaintenancePlan(ctx) { |
|||
const transaction = await ctx.fs.dc.orm.transaction(); |
|||
try { |
|||
const { models } = ctx.fs.dc |
|||
const query = ctx.query |
|||
const { responseId } = query |
|||
//console.log('queryzz', [...responseId])
|
|||
await models.MaintenancePlanExecuteUser.destroy({ where: { maintenancePlanId: responseId } }) |
|||
await models.MaintenancePlan.destroy({ where: { id: responseId } }) |
|||
ctx.status = 204 |
|||
await transaction.commit(); |
|||
|
|||
} catch (error) { |
|||
await transaction.rollback(); |
|||
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`) |
|||
ctx.status = 400 |
|||
ctx.body = { |
|||
message: '删除临时响应失败' |
|||
} |
|||
} |
|||
} |
|||
|
|||
async function editMaintenancePlan(ctx) { |
|||
const transaction = await ctx.fs.dc.orm.transaction(); |
|||
try { |
|||
const { models } = ctx.fs.dc |
|||
const data = ctx.request.body |
|||
//console.log('data1', data)
|
|||
//存在id为编辑,否则是添加
|
|||
if (data.id) { |
|||
if (data.type == 'temp') { |
|||
await models.MaintenancePlan.update({ |
|||
actualFinishTime: data.actualFinishTime, |
|||
missionName: data.missionName, |
|||
remark: data.remark, |
|||
reason: data.reason, |
|||
planFinishTime: data.planFinishTime, |
|||
state: data.state |
|||
}, { where: { id: data.id } }) |
|||
} else { |
|||
await models.MaintenancePlan.update({ |
|||
actualFinishTime: data.actualFinishTime, |
|||
missionName: data.missionName, |
|||
remark: data.remark, |
|||
planFinishTime: data.planFinishTime, |
|||
state: data.state |
|||
}, { where: { id: data.id } }) |
|||
} |
|||
//删除相关联的所有执行者
|
|||
await models.MaintenancePlanExecuteUser.destroy({ where: { maintenancePlanId: data.id } }) |
|||
//重新创建相关的执行者
|
|||
const insertVal = data.manger.map((item) => { |
|||
return { |
|||
maintenancePlanId: data.id, pepUserId: item |
|||
} |
|||
}) |
|||
await models.MaintenancePlanExecuteUser.bulkCreate(insertVal) |
|||
|
|||
} else { |
|||
if (data.type == 'temp') { |
|||
const plan = await models.MaintenancePlan.create({ |
|||
actualFinishTime: data.actualFinishTime, |
|||
missionName: data.missionName, |
|||
remark: data.remark, |
|||
reason: data.reason, |
|||
planFinishTime: data.planFinishTime, |
|||
type: data.type, |
|||
state: data.state |
|||
}) |
|||
//console.log('data.manger',data.manger)
|
|||
const insertVal = data.manger.map((item) => { |
|||
return { |
|||
maintenancePlanId: plan.id, pepUserId: item |
|||
} |
|||
}) |
|||
await models.MaintenancePlanExecuteUser.bulkCreate(insertVal) |
|||
} else { |
|||
//console.log('data.manger', data.manger)
|
|||
const plan = await models.MaintenancePlan.create({ |
|||
actualFinishTime: data.actualFinishTime, |
|||
missionName: data.missionName, |
|||
remark: data.remark, |
|||
planFinishTime: data.planFinishTime, |
|||
type: data.type, |
|||
state: data.state |
|||
}) |
|||
//console.log('planId1', plan.id)
|
|||
const insertVal = data.manger.map((item) => { |
|||
return { |
|||
maintenancePlanId: plan.id, pepUserId: item |
|||
} |
|||
}) |
|||
await models.MaintenancePlanExecuteUser.bulkCreate(insertVal) |
|||
} |
|||
} |
|||
ctx.status = 204 |
|||
await transaction.commit(); |
|||
} |
|||
|
|||
catch (error) { |
|||
await transaction.rollback(); |
|||
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`) |
|||
ctx.status = 400 |
|||
ctx.body = { |
|||
message: `${data.msg}失败` |
|||
} |
|||
} |
|||
} |
|||
|
|||
module.exports = { |
|||
getMaintenancePlan, delMaintenancePlan, editMaintenancePlan |
|||
} |
@ -0,0 +1,112 @@ |
|||
'use strict'; |
|||
const moment = require('moment'); |
|||
|
|||
async function getRecord(ctx) { |
|||
try { |
|||
const { redis } = ctx.app |
|||
const { models } = ctx.fs.dc; |
|||
const sequelize = ctx.fs.dc.ORM; |
|||
const { startTime, endTime, pageSize, pageIndex } = ctx.query |
|||
//console.log('queryz', ctx.query)
|
|||
let resCount = await models.MaintenanceRecord.count({ |
|||
where: { |
|||
$and: [ |
|||
sequelize.where(sequelize.fn('date', sequelize.col('occurrence_time')), '>=', moment(startTime).format('YYYY-MM-DD')), |
|||
sequelize.where(sequelize.fn('date', sequelize.col('occurrence_time')), '<=', moment(endTime).format('YYYY-MM-DD')), |
|||
] |
|||
} |
|||
}) |
|||
let recordRes = await models.MaintenanceRecord.findAndCountAll({ |
|||
order: [['id', 'DESC']], |
|||
attributes: ['id', 'sketch', 'occurrenceTime', 'solvingTime', 'interruptDuration', 'type', 'record'], |
|||
offset: (pageIndex - 1) * pageSize, |
|||
limit: pageSize, |
|||
where: { |
|||
$and: [ |
|||
sequelize.where(sequelize.fn('date', sequelize.col('occurrence_time')), '>=', moment(startTime).format('YYYY-MM-DD')), |
|||
sequelize.where(sequelize.fn('date', sequelize.col('occurrence_time')), '<=', moment(endTime).format('YYYY-MM-DD')), |
|||
] |
|||
}, |
|||
include: [{ |
|||
attributes: ['id', 'maintenanceRecordId', 'pepUserId'], |
|||
model: models.MaintenanceRecordExecuteUser |
|||
}] |
|||
}) |
|||
//console.log('recordRes', recordRes)
|
|||
const arrayUserId = [] |
|||
recordRes.rows.forEach((item) => { item.maintenanceRecordExecuteUsers.forEach((item1) => { arrayUserId.push(item1.pepUserId) }) }) |
|||
const arrayUserIdCopy = [...new Set(arrayUserId)] |
|||
// console.log('(' + arrayUserIdCopy.toString() + ')', '22222')
|
|||
let userRes = await redis.get('allUser') |
|||
userRes = JSON.parse(userRes) |
|||
userRes = userRes.filter((item) => { |
|||
return arrayUserIdCopy.some((children) => { return children == item.id }) |
|||
}) |
|||
//console.log('userRes', userRes)
|
|||
const res = recordRes.rows.map((item) => { |
|||
return { |
|||
id: item.id, |
|||
interruptDuration: item.interruptDuration, |
|||
occurrenceTime: item.occurrenceTime, |
|||
record: item.record, |
|||
sketch: item.sketch, |
|||
solvingTime: item.solvingTime, |
|||
type: item.type, |
|||
maintenanceRecordExecuteUsers: |
|||
item.maintenanceRecordExecuteUsers.map((item1) => { |
|||
return { |
|||
id: item1.id, |
|||
maintenanceRecordId: item1.maintenanceRecordId, |
|||
pepUserId: item1.pepUserId, |
|||
name: userRes.filter((ac) => { return ac.id == item1.pepUserId })[0].name |
|||
} |
|||
}) |
|||
} |
|||
} |
|||
) |
|||
//console.log('res1', res)
|
|||
ctx.body = { count: resCount, res } |
|||
ctx.status = 200 |
|||
} catch (error) { |
|||
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
|||
ctx.status = 400; |
|||
ctx.body = { |
|||
message: '获取服务记录失败' |
|||
} |
|||
} |
|||
} |
|||
//新增服务记录
|
|||
async function addRecord(ctx) { |
|||
const transaction = await ctx.fs.dc.orm.transaction(); |
|||
const { models } = ctx.fs.dc |
|||
const params = ctx.request.body |
|||
const { solvingTime, occurrencTime, sketch, record, settler, type } = params |
|||
try { |
|||
//console.log('params1', params)
|
|||
const aa = await models.MaintenanceRecord.create({ solvingTime, occurrenceTime: occurrencTime, sketch, record, settler, type }) |
|||
const recordId = aa.id |
|||
const resArry = settler.map((item) => { |
|||
return { |
|||
maintenanceRecordId: recordId, pepUserId: item |
|||
} |
|||
}) |
|||
await models.MaintenanceRecordExecuteUser.bulkCreate(resArry) |
|||
await transaction.commit(); |
|||
ctx.status = 200 |
|||
} catch (error) { |
|||
await transaction.rollback(); |
|||
|
|||
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
|||
ctx.status = 400; |
|||
ctx.body = { |
|||
message: '新增服务记录失败' |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
module.exports = { |
|||
getRecord, addRecord |
|||
}; |
@ -0,0 +1,89 @@ |
|||
/* eslint-disable*/ |
|||
|
|||
'use strict'; |
|||
|
|||
module.exports = dc => { |
|||
const DataTypes = dc.ORM; |
|||
const sequelize = dc.orm; |
|||
const MaintenancePlan = sequelize.define("maintenancePlan", { |
|||
id: { |
|||
type: DataTypes.INTEGER, |
|||
allowNull: false, |
|||
defaultValue: null, |
|||
comment: null, |
|||
primaryKey: true, |
|||
field: "id", |
|||
autoIncrement: true, |
|||
unique: "maintenance_plan_id_uindex" |
|||
}, |
|||
missionName: { |
|||
type: DataTypes.STRING, |
|||
allowNull: false, |
|||
defaultValue: null, |
|||
comment: "任务名称", |
|||
primaryKey: false, |
|||
field: "mission_name", |
|||
autoIncrement: false |
|||
}, |
|||
remark: { |
|||
type: DataTypes.STRING, |
|||
allowNull: true, |
|||
defaultValue: null, |
|||
comment: "备注", |
|||
primaryKey: false, |
|||
field: "remark", |
|||
autoIncrement: false |
|||
}, |
|||
reason: { |
|||
type: DataTypes.STRING, |
|||
allowNull: true, |
|||
defaultValue: null, |
|||
comment: "操作/故障原因", |
|||
primaryKey: false, |
|||
field: "reason", |
|||
autoIncrement: false |
|||
}, |
|||
planFinishTime: { |
|||
type: DataTypes.DATE, |
|||
allowNull: true, |
|||
defaultValue: null, |
|||
comment: "计划完成时间", |
|||
primaryKey: false, |
|||
field: "plan_finish_time", |
|||
autoIncrement: false |
|||
}, |
|||
actualFinishTime: { |
|||
type: DataTypes.DATE, |
|||
allowNull: true, |
|||
defaultValue: null, |
|||
comment: "实际完成时间\n", |
|||
primaryKey: false, |
|||
field: "actual_finish_time", |
|||
autoIncrement: false |
|||
}, |
|||
type: { |
|||
type: DataTypes.STRING, |
|||
allowNull: false, |
|||
defaultValue: null, |
|||
comment: "分类 period 周期 / temp 临时", |
|||
primaryKey: false, |
|||
field: "type", |
|||
autoIncrement: false |
|||
}, |
|||
state: { |
|||
type: DataTypes.STRING, |
|||
allowNull: false, |
|||
defaultValue: null, |
|||
comment: "完成状态 unfinished 未完成 / underway 进行中 / completed 已完成 / suspend 挂起暂停 / inspected 已检查", |
|||
primaryKey: false, |
|||
field: "state", |
|||
autoIncrement: false |
|||
} |
|||
}, { |
|||
tableName: "maintenance_plan", |
|||
comment: "", |
|||
indexes: [] |
|||
}); |
|||
dc.models.MaintenancePlan = MaintenancePlan; |
|||
return MaintenancePlan; |
|||
}; |
@ -0,0 +1,48 @@ |
|||
/* eslint-disable*/ |
|||
|
|||
'use strict'; |
|||
|
|||
module.exports = dc => { |
|||
const DataTypes = dc.ORM; |
|||
const sequelize = dc.orm; |
|||
const MaintenancePlanExecuteUser = sequelize.define("maintenancePlanExecuteUser", { |
|||
id: { |
|||
type: DataTypes.INTEGER, |
|||
allowNull: false, |
|||
defaultValue: null, |
|||
comment: null, |
|||
primaryKey: true, |
|||
field: "id", |
|||
autoIncrement: true, |
|||
unique: "maintenance_plan_execute_user_id_uindex" |
|||
}, |
|||
maintenancePlanId: { |
|||
type: DataTypes.INTEGER, |
|||
allowNull: false, |
|||
defaultValue: null, |
|||
comment: null, |
|||
primaryKey: false, |
|||
field: "maintenance_plan_id", |
|||
autoIncrement: false, |
|||
references: { |
|||
key: "id", |
|||
model: "maintenancePlan" |
|||
} |
|||
}, |
|||
pepUserId: { |
|||
type: DataTypes.INTEGER, |
|||
allowNull: false, |
|||
defaultValue: null, |
|||
comment: "项企用户id", |
|||
primaryKey: false, |
|||
field: "pep_user_id", |
|||
autoIncrement: false |
|||
} |
|||
}, { |
|||
tableName: "maintenance_plan_execute_user", |
|||
comment: "", |
|||
indexes: [] |
|||
}); |
|||
dc.models.MaintenancePlanExecuteUser = MaintenancePlanExecuteUser; |
|||
return MaintenancePlanExecuteUser; |
|||
}; |
@ -0,0 +1,80 @@ |
|||
/* eslint-disable*/ |
|||
|
|||
'use strict'; |
|||
|
|||
module.exports = dc => { |
|||
const DataTypes = dc.ORM; |
|||
const sequelize = dc.orm; |
|||
const MaintenanceRecord = sequelize.define("maintenanceRecord", { |
|||
id: { |
|||
type: DataTypes.INTEGER, |
|||
allowNull: false, |
|||
defaultValue: null, |
|||
comment: null, |
|||
primaryKey: true, |
|||
field: "id", |
|||
autoIncrement: true, |
|||
unique: "maintenance_record_id_uindex" |
|||
}, |
|||
sketch: { |
|||
type: DataTypes.STRING, |
|||
allowNull: false, |
|||
defaultValue: null, |
|||
comment: "简述", |
|||
primaryKey: false, |
|||
field: "sketch", |
|||
autoIncrement: false |
|||
}, |
|||
occurrenceTime: { |
|||
type: DataTypes.DATE, |
|||
allowNull: true, |
|||
defaultValue: null, |
|||
comment: "发生时间", |
|||
primaryKey: false, |
|||
field: "occurrence_time", |
|||
autoIncrement: false |
|||
}, |
|||
solvingTime: { |
|||
type: DataTypes.DATE, |
|||
allowNull: true, |
|||
defaultValue: null, |
|||
comment: "解决时间", |
|||
primaryKey: false, |
|||
field: "solving_time", |
|||
autoIncrement: false |
|||
}, |
|||
interruptDuration: { |
|||
type: DataTypes.INTEGER, |
|||
allowNull: true, |
|||
defaultValue: null, |
|||
comment: "中断时长 / 秒", |
|||
primaryKey: false, |
|||
field: "interrupt_duration", |
|||
autoIncrement: false |
|||
}, |
|||
type: { |
|||
type: DataTypes.STRING, |
|||
allowNull: true, |
|||
defaultValue: null, |
|||
comment: "故障类型", |
|||
primaryKey: false, |
|||
field: "type", |
|||
autoIncrement: false |
|||
}, |
|||
record: { |
|||
type: DataTypes.STRING, |
|||
allowNull: true, |
|||
defaultValue: null, |
|||
comment: "故障记录", |
|||
primaryKey: false, |
|||
field: "record", |
|||
autoIncrement: false |
|||
} |
|||
}, { |
|||
tableName: "maintenance_record", |
|||
comment: "", |
|||
indexes: [] |
|||
}); |
|||
dc.models.MaintenanceRecord = MaintenanceRecord; |
|||
return MaintenanceRecord; |
|||
}; |
@ -0,0 +1,48 @@ |
|||
/* eslint-disable*/ |
|||
|
|||
'use strict'; |
|||
|
|||
module.exports = dc => { |
|||
const DataTypes = dc.ORM; |
|||
const sequelize = dc.orm; |
|||
const MaintenanceRecordExecuteUser = sequelize.define("maintenanceRecordExecuteUser", { |
|||
id: { |
|||
type: DataTypes.INTEGER, |
|||
allowNull: false, |
|||
defaultValue: null, |
|||
comment: null, |
|||
primaryKey: true, |
|||
field: "id", |
|||
autoIncrement: true, |
|||
unique: "maintenance_record_execute_user_id_uindex" |
|||
}, |
|||
maintenanceRecordId: { |
|||
type: DataTypes.INTEGER, |
|||
allowNull: false, |
|||
defaultValue: null, |
|||
comment: null, |
|||
primaryKey: false, |
|||
field: "maintenance_record_id", |
|||
autoIncrement: false, |
|||
references: { |
|||
key: "id", |
|||
model: "maintenanceRecord" |
|||
} |
|||
}, |
|||
pepUserId: { |
|||
type: DataTypes.INTEGER, |
|||
allowNull: false, |
|||
defaultValue: null, |
|||
comment: null, |
|||
primaryKey: false, |
|||
field: "pep_user_id", |
|||
autoIncrement: false |
|||
} |
|||
}, { |
|||
tableName: "maintenance_record_execute_user", |
|||
comment: "", |
|||
indexes: [] |
|||
}); |
|||
dc.models.MaintenanceRecordExecuteUser = MaintenanceRecordExecuteUser; |
|||
return MaintenanceRecordExecuteUser; |
|||
}; |
@ -0,0 +1,9 @@ |
|||
'use strict'; |
|||
|
|||
const calculability = require('../../controllers/calculability'); |
|||
|
|||
module.exports = function (app, router, opts) { |
|||
app.fs.api.logAttr['GET/calculability'] = { content: '获取系统可用性', visible: true }; |
|||
router.get('/calculability', calculability.getCalculability); |
|||
|
|||
} |
@ -0,0 +1,15 @@ |
|||
'use strict'; |
|||
|
|||
const maintenancePlan = require('../../controllers/maintenancePlan'); |
|||
|
|||
module.exports = function (app, router, opts) { |
|||
app.fs.api.logAttr['GET/maintenancePlan'] = { content: '获取维护计划列表', visible: true }; |
|||
router.get('/maintenancePlan', maintenancePlan.getMaintenancePlan); |
|||
|
|||
app.fs.api.logAttr['DEL/maintenancePlan'] = { content: '删除维护计划列表', visible: true }; |
|||
router.del('/maintenancePlan', maintenancePlan.delMaintenancePlan); |
|||
|
|||
app.fs.api.logAttr['POST/maintenancePlan'] = { content: '编辑或者添加维护计划列表', visible: true }; |
|||
router.post('/maintenancePlan', maintenancePlan.editMaintenancePlan); |
|||
|
|||
}; |
@ -0,0 +1,13 @@ |
|||
'use strict'; |
|||
|
|||
const record = require('../../controllers/record'); |
|||
|
|||
module.exports = function (app, router, opts) { |
|||
app.fs.api.logAttr['GET/record'] = { content: '获取服务记录列表', visible: true }; |
|||
router.get('/record', record.getRecord); |
|||
|
|||
app.fs.api.logAttr['PUT/record'] = { content: '新增/服务记录', visible: true }; |
|||
router.put('/record', record.addRecord); |
|||
|
|||
|
|||
}; |
@ -1,7 +1,8 @@ |
|||
'use strict'; |
|||
|
|||
import * as emPush from './emPush' |
|||
|
|||
import * as redcord from './record' |
|||
import * as maintenancePlan from './maintenancePlan' |
|||
export default { |
|||
...emPush |
|||
...emPush, ...redcord, ...maintenancePlan |
|||
} |
@ -0,0 +1,55 @@ |
|||
'use strict'; |
|||
|
|||
import { ApiTable, basicAction } from '$utils' |
|||
|
|||
export function getMaintenancePlan(query) { //获取周期性计划
|
|||
let msg = '' |
|||
if (query) { |
|||
msg = query.msg |
|||
} |
|||
return dispatch => basicAction({ |
|||
type: 'get', |
|||
dispatch: dispatch, |
|||
query, |
|||
actionType: 'GET_MAINTENANCEPLAN', |
|||
url: `${ApiTable.getMaintenancePlan}`, |
|||
msg: { option: msg }, |
|||
reducer: { |
|||
name: "getMaintenancePlan", |
|||
params: { noClear: true } |
|||
} |
|||
}); |
|||
} |
|||
|
|||
export function delMaintenancePlan(query) {//删除周期性计划
|
|||
let msg = '' |
|||
if (query) { |
|||
msg = query.msg |
|||
} |
|||
return dispatch => basicAction({ |
|||
type: 'del', |
|||
dispatch: dispatch, |
|||
query: query, |
|||
actionType: 'DEL_MAINTENANCEPLAN', |
|||
url: `${ApiTable.delMaintenancePlan}`, |
|||
msg: { option: msg }, |
|||
}); |
|||
|
|||
|
|||
} |
|||
|
|||
|
|||
export function editMaintenancePlan(query) {//编辑或者添加临时周期周期性计划
|
|||
let msg = '' |
|||
if (query) { |
|||
msg = query.msg |
|||
} |
|||
return dispatch => basicAction({ |
|||
type: 'post', |
|||
data: query, |
|||
dispatch: dispatch, |
|||
actionType: 'EDIT_MAINTENANCEPLAN', |
|||
url: `${ApiTable.editMaintenancePlan}`, |
|||
msg: { option: msg }, |
|||
}) |
|||
} |
@ -0,0 +1,46 @@ |
|||
'use strict'; |
|||
|
|||
import { ApiTable, basicAction } from '$utils' |
|||
|
|||
export function getRecord(query) { //获取服务记录
|
|||
return dispatch => basicAction({ |
|||
type: 'get', |
|||
dispatch: dispatch, |
|||
query: query, |
|||
actionType: 'GET_RECORD', |
|||
url: `${ApiTable.getRecord}`, |
|||
msg: { option: '获取服务记录' }, |
|||
reducer: { |
|||
name: "getRecord", |
|||
params: { noClear: true } |
|||
} |
|||
}); |
|||
} |
|||
|
|||
|
|||
export function addRecord(query) { //新增服务记录
|
|||
return dispatch => basicAction({ |
|||
type: 'put', |
|||
dispatch: dispatch, |
|||
data: query, |
|||
actionType: 'ADD_RECORD', |
|||
url: `${ApiTable.addRecord}`, |
|||
msg: { option: '新增服务记录' } |
|||
|
|||
}); |
|||
} |
|||
export function calculability(query) {//计算系统可用性
|
|||
return dispatch => basicAction({ |
|||
type: 'get', |
|||
dispatch: dispatch, |
|||
query: query, |
|||
actionType: 'CACLUABILITY', |
|||
url: `${ApiTable.calculability}`, |
|||
msg: { option: '获取系统可用性' }, |
|||
reducer: { |
|||
name: "calculability", |
|||
params: { noClear: true } |
|||
} |
|||
|
|||
}); |
|||
} |
@ -0,0 +1,88 @@ |
|||
import React,{useState,useEffect,useRef} from 'react' |
|||
import { connect } from 'react-redux'; |
|||
import { Button,Table,Modal,Form } from '@douyinfe/semi-ui'; |
|||
|
|||
|
|||
const AddModal=(props)=>{ |
|||
const {visible,onClose,recordRow,pepList,actions,dispatch}=props |
|||
const{service}=actions |
|||
const api = useRef(); |
|||
useEffect(()=>{ |
|||
},[]) |
|||
//编辑和新增的逻辑 |
|||
const okHandler=()=>{ |
|||
//api.current.setValues({'manger':recordRow?.maintenancePlanExecuteUsers.map((item)=>{return item.id})},) |
|||
api.current.validate().then((res)=>{ |
|||
res.manger |
|||
recordRow?.maintenancePlanExecuteUsers |
|||
const query={ |
|||
id:recordRow?.id, |
|||
actualFinishTime:res.realityTime, |
|||
planFinishTime:res.planTime, |
|||
remark:res.notes, |
|||
state:res.status, |
|||
type:'period', |
|||
missionName:res.taskName, |
|||
manger:res.manger, |
|||
msg:recordRow?'编辑周期性计划':'添加周期性计划' |
|||
} |
|||
dispatch(service.editMaintenancePlan(query)).then((res)=>{ |
|||
if(res.success) onClose() |
|||
|
|||
}) |
|||
|
|||
}) |
|||
} |
|||
return (<div> |
|||
<Modal visible={visible} onCancel={()=>{onClose()}} title={recordRow?'周期性计划编辑':'周期性计划添加'} |
|||
onOk={okHandler} |
|||
|
|||
> |
|||
<Form |
|||
initValues={{'taskName':recordRow?.missionName, |
|||
'manger':recordRow?.maintenancePlanExecuteUsers.map((item)=>{return item.pepUserId}), |
|||
'reason':recordRow?.reason, |
|||
'status':recordRow?.state, |
|||
'notes':recordRow?.remark, |
|||
'planTime':recordRow?.planFinishTime, |
|||
'realityTime':recordRow?.actualFinishTime}} |
|||
|
|||
getFormApi={formApi => api.current = formApi} |
|||
labelCol={{ span: 6 }} |
|||
labelPosition='left' |
|||
> |
|||
<Form.Input field='taskName' label='任务名称:' maxLength={30} rules={[ |
|||
{ required: true, message: '请输入任务名称' }, |
|||
]} ></Form.Input> |
|||
<Form.Select field='manger' label='责任人' rules={[{ required: true, message: '请输入责任人' }]} trigger='blur' style={{ width:'100%' }} |
|||
multiple filter> |
|||
{pepList?.map((item)=>{return ( <Form.Select.OptGroup label={item.name}> |
|||
{item.users.map((item1)=>{ |
|||
return <Form.Select.Option value={item1.id} label={item1.name}></Form.Select.Option> |
|||
})} |
|||
</Form.Select.OptGroup> )})} |
|||
</Form.Select> |
|||
<Form.Select label='完成情况'style={{ width: 200 }} field='status'> |
|||
<Form.Select.Option value='未完成'>未完成</Form.Select.Option> |
|||
<Form.Select.Option value='进行中'>进行中</Form.Select.Option> |
|||
<Form.Select.Option value='已完成'>已完成</Form.Select.Option> |
|||
<Form.Select.Option value='挂起'>挂起</Form.Select.Option> |
|||
</Form.Select> |
|||
<Form.TextArea label='备注' field='notes' placeholder='故障发生原因及解决方案'></Form.TextArea> |
|||
<Form.DatePicker label='计划完成时间:' field='planTime' rules={[{ required: true, message: '请选择计划完成时间' },]}></Form.DatePicker> |
|||
<Form.DatePicker label='实际完成时间:' field='realityTime' rules={[{ required: true, message: '请选择实际完成时间' },]}></Form.DatePicker> |
|||
|
|||
</Form> |
|||
</Modal> |
|||
|
|||
</div>) |
|||
} |
|||
|
|||
|
|||
function mapStateToProps (state) { |
|||
const { global } = state; |
|||
return { |
|||
actions: global.actions, |
|||
}; |
|||
} |
|||
export default connect(mapStateToProps)(AddModal) |
@ -0,0 +1,114 @@ |
|||
'use strict'; |
|||
|
|||
import React, { useEffect,useState,useRef } from 'react'; |
|||
import { Modal,Form,DatePicker,useFormApi,actions,Button } from '@douyinfe/semi-ui'; |
|||
import { connect } from 'react-redux'; |
|||
import moment from 'moment' |
|||
|
|||
const RecordModal =(props)=>{ |
|||
const{visible,onClose,dispatch,recordRow,pepList,actions}=props |
|||
const [startTime,setStartTime]=useState('') |
|||
const [endTime,setEndTime]=useState('') |
|||
const FormApi = useRef(); |
|||
const{service} =actions |
|||
const tdd=parseInt((endTime-startTime)/1000/60/60/24)//取整天 |
|||
const tdh=parseInt((endTime-startTime)/1000/60/60%24)//取整时 |
|||
const tds=parseInt((endTime-startTime)/1000/60%60)//取整分 |
|||
// console.log('endTimex',endTime) |
|||
useEffect(()=>{ |
|||
setEndTime(recordRow?.solvingTime) |
|||
},[recordRow]) |
|||
const cancelHandler=()=>{ |
|||
onClose() |
|||
setStartTime('') |
|||
setEndTime('') |
|||
|
|||
} |
|||
const okHandler=()=>{ |
|||
FormApi.current.validate().then((res)=>{ |
|||
// console.log('res',res) |
|||
const editVal={ |
|||
solvingTime:res.endTime, |
|||
occurrencTime:res.startTime, |
|||
sketch:res.name, |
|||
record:res.record, |
|||
settler:res.settler, |
|||
type:res.type |
|||
} |
|||
dispatch(service.addRecord(editVal)).then(res => { |
|||
if (res.success) { |
|||
onClose() |
|||
FormApi.current.reset() |
|||
setStartTime('');setEndTime('') |
|||
} |
|||
}) |
|||
}) |
|||
} |
|||
return <Modal |
|||
title={recordRow?'查看':'服务记录添加'} |
|||
visible={visible} |
|||
footer={recordRow?<Button onClick={cancelHandler}>取消</Button>:<div> |
|||
<Button onClick={cancelHandler}>取消</Button> |
|||
<Button theme='solid' type='primary' onClick={okHandler}>确定</Button> |
|||
</div>} |
|||
onCancel={cancelHandler} |
|||
onOk={okHandler} |
|||
> |
|||
<Form wrapperCol={{ span: 20 }} |
|||
initValues={{'name':recordRow?.sketch,'startTime':recordRow?.occurrenceTime, |
|||
'endTime':recordRow?.solvingTime,'settler':recordRow?.maintenanceRecordExecuteUsers.map((item)=>{return item.account}),'type':recordRow?.type,'record':recordRow?.record}} |
|||
getFormApi={formApi => FormApi.current = formApi} |
|||
labelPosition='left' |
|||
labelAlign='right'> |
|||
<Form.Input field='name' label='故障简述:' trigger='blur' |
|||
disabled={recordRow?true:false} |
|||
placeholder='选择或搜索项目' rules={[{ required: true, message:'请输入故障简述' }]} maxLength={30}/> |
|||
<Form.DatePicker disabled={recordRow?true:false} field='startTime' label='发生时间:' rules={[{ required: true, message:'请输入发生时间' }]} |
|||
type="dateTime" onChange={(e)=>{ |
|||
setStartTime(e) |
|||
///console.log('e1',e) |
|||
}} |
|||
/> |
|||
<Form.DatePicker disabled={recordRow?true:false} field='endTime' label='解决时间:' initValue={endTime} rules={[{ required: true, message:'请输入解决时间' }]} |
|||
type="dateTime" onChange={(e)=>{setEndTime(e);//console.log('sss',moment(endTime-startTime).format('DD天hh时mm分')) |
|||
}} /> |
|||
中断时间:{endTime&&startTime? <span style={{marginLeft:30}}>{`${tdd}天${tdh}时${tds}分`}</span>:''} |
|||
<Form.Select disabled={recordRow?true:false} field='settler' label='解决者:' trigger='blur' style={{ width:'100%' }} |
|||
filter |
|||
rules={[{ required: true, message:'请输入解决者' }]} multiple> |
|||
{pepList?.map((item)=>{return ( <Form.Select.OptGroup label={item.name}> |
|||
{item.users.map((item1)=>{ |
|||
return <Form.Select.Option value={item1.id} label={item1.name}></Form.Select.Option> |
|||
|
|||
})} |
|||
</Form.Select.OptGroup> )})} |
|||
</Form.Select> |
|||
<Form.Select disabled={recordRow?true:false} field="type" label={{ text: '故障类型'}} style={{ width: 200 }}> |
|||
<Form.Select.Option value="es异常">es异常</Form.Select.Option> |
|||
<Form.Select.Option value="数据库异常">数据库异常</Form.Select.Option> |
|||
<Form.Select.Option value="应用异常">应用异常</Form.Select.Option> |
|||
<Form.Select.Option value="kafka异常">kafka异常</Form.Select.Option> |
|||
<Form.Select.Option value="服务器异常">服务器异常</Form.Select.Option> |
|||
<Form.Select.Option value="其他">其他</Form.Select.Option> |
|||
</Form.Select> |
|||
<Form.TextArea disabled={recordRow?true:false} field="record" label={{text:'故障记录'}} rules={[{ required: true, message:'请输入故障记录' }]}> |
|||
</Form.TextArea> |
|||
|
|||
</Form> |
|||
|
|||
|
|||
|
|||
</Modal> |
|||
} |
|||
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 |
|||
}; |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(RecordModal); |
@ -0,0 +1,92 @@ |
|||
import React,{useState,useEffect,useRef} from 'react' |
|||
import { connect } from 'react-redux'; |
|||
import { Button,Table,Modal,Form } from '@douyinfe/semi-ui'; |
|||
|
|||
|
|||
const TemporyModal=(props)=>{ |
|||
const {visible,onClose,recordRow,pepList,actions,dispatch}=props |
|||
const api = useRef(); |
|||
const {service}=actions |
|||
useEffect(()=>{ |
|||
|
|||
},[]) |
|||
|
|||
const okHandler=()=>{ |
|||
//api.current.setValues({'manger':recordRow?.maintenancePlanExecuteUsers.map((item)=>{return item.id})},) |
|||
api.current.validate().then((res)=>{ |
|||
res.manger |
|||
recordRow?.maintenancePlanExecuteUsers |
|||
const query={ |
|||
id:recordRow?.id, |
|||
actualFinishTime:res.realityTime, |
|||
planFinishTime:res.planTime, |
|||
reason:res.reason, |
|||
remark:res.notes, |
|||
state:res.status, |
|||
type:'temp', |
|||
missionName:res.taskName, |
|||
manger:res.manger, |
|||
msg:recordRow?'编辑临时响应':'添加临时响应' |
|||
} |
|||
dispatch(service.editMaintenancePlan(query)).then((res)=>{ |
|||
if(res.success) onClose() |
|||
|
|||
}) |
|||
|
|||
}) |
|||
} |
|||
return (<div> |
|||
<Modal visible={visible} |
|||
onCancel={()=>{onClose()}} title={recordRow?'临时响应编辑':'临时响应添加'} |
|||
onOk={okHandler} |
|||
> |
|||
<Form |
|||
initValues={{'taskName':recordRow?.missionName, |
|||
'manger':recordRow?.maintenancePlanExecuteUsers.map((item)=>{return item.pepUserId}), |
|||
'reason':recordRow?.reason, |
|||
'status':recordRow?.state, |
|||
'notes':recordRow?.remark, |
|||
'planTime':recordRow?.planFinishTime, |
|||
'realityTime':recordRow?.actualFinishTime |
|||
}} |
|||
getFormApi={formApi => api.current = formApi} |
|||
labelCol={{ span: 6 }} |
|||
labelPosition='left' |
|||
> |
|||
<Form.Input field='taskName' label='任务名称:' maxLength={30} rules={[ |
|||
{ required: true, message: '请输入任务名称' }, |
|||
]} ></Form.Input> |
|||
<Form.Select field='manger' label='执行人' rules={[{ required: true, message: '请输入执行人' }]} trigger='blur' style={{ width:'100%' }} |
|||
multiple filter> |
|||
{pepList?.map((item)=>{return ( <Form.Select.OptGroup label={item.name}> |
|||
{item.users.map((item1)=>{ |
|||
return <Form.Select.Option value={item1.id} label={item1.name}></Form.Select.Option> |
|||
})} |
|||
</Form.Select.OptGroup> )})} |
|||
</Form.Select> |
|||
<Form.Input field='reason' label='操作原因' maxLength={30} rules={[{ required: true, message: '请输入操作原因' }]}></Form.Input> |
|||
|
|||
<Form.Select label='状态'style={{ width: 200 }} field='status'> |
|||
<Form.Select.Option value='未完成'>未完成</Form.Select.Option> |
|||
<Form.Select.Option value='进行中'>进行中</Form.Select.Option> |
|||
<Form.Select.Option value='已完成'>已完成</Form.Select.Option> |
|||
<Form.Select.Option value='挂起'>挂起</Form.Select.Option> |
|||
</Form.Select> |
|||
<Form.TextArea label='备注' field='notes' placeholder='故障发生原因及解决方案'></Form.TextArea> |
|||
<Form.DatePicker label='计划完成时间:' field='planTime' rules={[{ required: true, message: '请选择计划完成时间' }]}></Form.DatePicker> |
|||
<Form.DatePicker label='实际完成时间:' field='realityTime' rules={[{ required: true, message: '请选择实际完成时间' }]}></Form.DatePicker> |
|||
</Form> |
|||
</Modal> |
|||
|
|||
</div>) |
|||
} |
|||
function mapStateToProps (state) { |
|||
const { global} = state; |
|||
return { |
|||
|
|||
actions: global.actions, |
|||
|
|||
}; |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(TemporyModal) |
@ -1,34 +1,137 @@ |
|||
import React, { useEffect } from 'react'; |
|||
import React, { useEffect,useState} from 'react'; |
|||
import { connect } from 'react-redux'; |
|||
|
|||
import { Button,Table,Popconfirm } from '@douyinfe/semi-ui'; |
|||
import Addmodal from '../components/cycAddmodal' |
|||
import moment from 'moment' |
|||
|
|||
|
|||
const Server = (props) => { |
|||
const { dispatch, actions, user, loading, socket } = props |
|||
const{service,install}=actions |
|||
const [addVis,setAddVis]=useState(false) |
|||
const [cycPlan,setCysPlan]=useState([]) |
|||
const [recordRow,setRecordRow]=useState(null) |
|||
const [pepList, setPepList] = useState([])//角色分配 |
|||
const [pageSize,setPageSize]=useState(10) |
|||
const [pageIndex,setPageIndex]=useState(1) |
|||
const [total,setTotal]=useState() |
|||
|
|||
useEffect(() => { |
|||
|
|||
}, []) |
|||
|
|||
|
|||
const getCycPlan=(query={type:'period',msg:'获取周期性计划',pageIndex,pageSize})=>{ |
|||
dispatch(service.getMaintenancePlan(query)).then((res)=>{ |
|||
setCysPlan(res?.payload.data.responseRes) |
|||
setTotal(res?.payload.data.count) |
|||
}) |
|||
} |
|||
useEffect(()=>{ |
|||
getCycPlan() |
|||
dispatch(install.getOrganizationDeps()).then((res) => {//获取项企(PEP)全部部门及其下用户 |
|||
setPepList(res.payload.data) |
|||
}) |
|||
},[]) |
|||
const delHandler=(record)=>{ |
|||
const query={ |
|||
responseId:record.id, |
|||
msg:'删除周期性计划' |
|||
} |
|||
dispatch(service.delMaintenancePlan(query)).then((res)=>{ |
|||
if(res.success) getCycPlan() |
|||
}) |
|||
} |
|||
//配置分页 |
|||
const pagination={ |
|||
total:total, |
|||
defaultCurrent: 1, |
|||
pageSize:pageSize, |
|||
showSizeChanger: true, |
|||
currentPage:pageIndex, |
|||
showQuickJumper: true, |
|||
pageSizeOpts: ["5", "10", "15"], |
|||
showTotal: function () { |
|||
return `共有${total}条` |
|||
}, |
|||
onChange:(pageIndex,pageSize)=>{ |
|||
console.log('pageIndex1',pageIndex,pageSize) |
|||
setPageIndex(pageIndex) |
|||
setPageSize(pageSize) |
|||
const query={ |
|||
pageIndex,pageSize,type:'temp',msg:'获取周期性计划' |
|||
} |
|||
getCycPlan(query) |
|||
} |
|||
} |
|||
//console.log('cycPlan',cycPlan) |
|||
const columns = [ |
|||
{ |
|||
title: '序号', |
|||
render:(t, r, i) => { |
|||
return i + 1 |
|||
} |
|||
}, |
|||
{ |
|||
title: '任务名称', |
|||
dataIndex: 'missionName', |
|||
}, |
|||
{ |
|||
title: '责任人', |
|||
render:(record)=>{ |
|||
return <span> |
|||
{record?.maintenancePlanExecuteUsers.map((item)=>{ |
|||
return item.name |
|||
}).toString() |
|||
} |
|||
</span> |
|||
} |
|||
}, |
|||
{ |
|||
title: '完成情况', |
|||
dataIndex: 'state', |
|||
}, |
|||
{ |
|||
title: '备注', |
|||
dataIndex: 'remark', |
|||
}, |
|||
{ |
|||
title: '计划完成时间', |
|||
render:(record)=>{ |
|||
return <span>{moment(record.planFinishTime).format('YYYY-MM-DD HH:mm:ss')}</span> |
|||
}, |
|||
}, |
|||
{ |
|||
title: '实际完成时间', |
|||
render:(record)=>{ |
|||
return <span>{moment(record.actualFinishTime).format('YYYY-MM-DD HH:mm:ss')}</span> |
|||
}, |
|||
}, |
|||
{ |
|||
title: '操作', |
|||
render:(record)=>{ |
|||
return (<div> |
|||
<Button onClick={()=>{setAddVis(true);setRecordRow(record)}}>编辑</Button> |
|||
<Popconfirm title="确定是否删除?" onConfirm={()=>{delHandler(record)}}><Button type='danger'> 删除</Button></Popconfirm> |
|||
</div>) |
|||
} |
|||
}, |
|||
]; |
|||
return ( |
|||
<> |
|||
<div> |
|||
<img src="/assets/images/install/watting.png" alt="" style={{ width: 'calc(100% + 16px)', position: "relative", top: -12, left: -8, }} /> |
|||
</div> |
|||
</> |
|||
<div style={{background: '#FFFFFF', margin: '8px 12px', padding: '20px 20px 0px 20px'}}> |
|||
<div style={{marginBottom:20}}> |
|||
<Button theme='solid' type='secondary' onClick={()=>{setAddVis(true)}}>新增</Button> |
|||
<Button theme='solid' type='secondary' style={{marginLeft:50}}>导入</Button> |
|||
</div> |
|||
<div> |
|||
<Table columns={columns} dataSource={cycPlan} pagination={pagination}></Table> |
|||
</div> |
|||
<Addmodal visible={addVis} onClose={()=>{setAddVis(false);setRecordRow(null);getCycPlan()}} recordRow={recordRow} pepList={pepList}></Addmodal> |
|||
</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 { global } = state; |
|||
return { |
|||
actions: global.actions, |
|||
}; |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(Server); |
|||
|
@ -1,5 +1,5 @@ |
|||
.myempush{ |
|||
.semi-input-wrapper{ |
|||
.myempush { |
|||
.semi-input-wrapper { |
|||
margin-bottom: 0px !important; |
|||
} |
|||
} |
|||
} |
|||
|
Loading…
Reference in new issue