diff --git a/api/app/lib/controllers/calculability/index.js b/api/app/lib/controllers/calculability/index.js new file mode 100644 index 0000000..1ea5a64 --- /dev/null +++ b/api/app/lib/controllers/calculability/index.js @@ -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 +} \ No newline at end of file diff --git a/api/app/lib/controllers/maintenancePlan/index.js b/api/app/lib/controllers/maintenancePlan/index.js new file mode 100644 index 0000000..e08a9ce --- /dev/null +++ b/api/app/lib/controllers/maintenancePlan/index.js @@ -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 +} \ No newline at end of file diff --git a/api/app/lib/controllers/record/index.js b/api/app/lib/controllers/record/index.js new file mode 100644 index 0000000..23f0f92 --- /dev/null +++ b/api/app/lib/controllers/record/index.js @@ -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 +}; \ No newline at end of file diff --git a/api/app/lib/index.js b/api/app/lib/index.js index fb167d3..12b6f78 100644 --- a/api/app/lib/index.js +++ b/api/app/lib/index.js @@ -59,8 +59,7 @@ module.exports.models = function (dc) { // dc = { orm: Sequelize对象, ORM: Seq const { AppInspection, ProjectApp, ProjectCorrelation, AppAlarm, App, AlarmAppearRecord, AlarmConfirmLog, EmailSendLog, LatestDynamicList, AlarmPushConfig, - AlarmDataContinuityType, AlarmDataContinuity - } = dc.models; + MaintenanceRecord, MaintenanceRecordExecuteUser, MaintenancePlanExecuteUser, MaintenancePlan } = dc.models; AppInspection.belongsTo(App, { foreignKey: 'projectAppId', targetKey: 'id' }); App.hasMany(AppInspection, { foreignKey: 'projectAppId', sourceKey: 'id' }); @@ -105,6 +104,9 @@ module.exports.models = function (dc) { // dc = { orm: Sequelize对象, ORM: Seq LatestDynamicList.belongsTo(ProjectCorrelation, { foreignKey: 'projectCorrelationId', targetKey: 'id' }); ProjectCorrelation.hasMany(LatestDynamicList, { foreignKey: 'projectCorrelationId', sourceKey: 'id' }); - AlarmDataContinuityType.belongsTo(AlarmDataContinuity, { foreignKey: 'typeNumber', targetKey: 'type' }); - AlarmDataContinuity.hasOne(AlarmDataContinuityType, { foreignKey: 'typeNumber', sourceKey: 'type' }); + MaintenanceRecordExecuteUser.belongsTo(MaintenanceRecord, { foreignKey: 'maintenanceRecordId', targetKey: 'id' }) + MaintenanceRecord.hasMany(MaintenanceRecordExecuteUser, { foreignKey: 'maintenanceRecordId', targetKey: 'id' }) + + MaintenancePlanExecuteUser.belongsTo(MaintenancePlan, { foreignKey: 'maintenancePlanId', targetKey: 'id' }) + MaintenancePlan.hasMany(MaintenancePlanExecuteUser, { foreignKey: 'maintenancePlanId', targetKey: 'id' }) }; diff --git a/api/app/lib/models/maintenance_plan.js b/api/app/lib/models/maintenance_plan.js new file mode 100644 index 0000000..d31d614 --- /dev/null +++ b/api/app/lib/models/maintenance_plan.js @@ -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; +}; \ No newline at end of file diff --git a/api/app/lib/models/maintenance_plan_execute_user.js b/api/app/lib/models/maintenance_plan_execute_user.js new file mode 100644 index 0000000..fd570f7 --- /dev/null +++ b/api/app/lib/models/maintenance_plan_execute_user.js @@ -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; +}; \ No newline at end of file diff --git a/api/app/lib/models/maintenance_record.js b/api/app/lib/models/maintenance_record.js new file mode 100644 index 0000000..c286827 --- /dev/null +++ b/api/app/lib/models/maintenance_record.js @@ -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; +}; \ No newline at end of file diff --git a/api/app/lib/models/maintenance_record_execute_user.js b/api/app/lib/models/maintenance_record_execute_user.js new file mode 100644 index 0000000..89e848b --- /dev/null +++ b/api/app/lib/models/maintenance_record_execute_user.js @@ -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; +}; \ No newline at end of file diff --git a/api/app/lib/routes/calculability/index.js b/api/app/lib/routes/calculability/index.js new file mode 100644 index 0000000..e6339a4 --- /dev/null +++ b/api/app/lib/routes/calculability/index.js @@ -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); + +} \ No newline at end of file diff --git a/api/app/lib/routes/maintenancePlan/index.js b/api/app/lib/routes/maintenancePlan/index.js new file mode 100644 index 0000000..7fad591 --- /dev/null +++ b/api/app/lib/routes/maintenancePlan/index.js @@ -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); + +}; \ No newline at end of file diff --git a/api/app/lib/routes/record/index.js b/api/app/lib/routes/record/index.js new file mode 100644 index 0000000..284c66f --- /dev/null +++ b/api/app/lib/routes/record/index.js @@ -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); + + +}; \ No newline at end of file diff --git a/web/client/src/sections/service/actions/index.js b/web/client/src/sections/service/actions/index.js index 1014015..aa55316 100644 --- a/web/client/src/sections/service/actions/index.js +++ b/web/client/src/sections/service/actions/index.js @@ -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 } \ No newline at end of file diff --git a/web/client/src/sections/service/actions/maintenancePlan.js b/web/client/src/sections/service/actions/maintenancePlan.js new file mode 100644 index 0000000..f6fca8c --- /dev/null +++ b/web/client/src/sections/service/actions/maintenancePlan.js @@ -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 }, + }) +} \ No newline at end of file diff --git a/web/client/src/sections/service/actions/record.js b/web/client/src/sections/service/actions/record.js new file mode 100644 index 0000000..55897b4 --- /dev/null +++ b/web/client/src/sections/service/actions/record.js @@ -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 } + } + + }); +} \ No newline at end of file diff --git a/web/client/src/sections/service/components/cycAddmodal.jsx b/web/client/src/sections/service/components/cycAddmodal.jsx new file mode 100644 index 0000000..cd6c178 --- /dev/null +++ b/web/client/src/sections/service/components/cycAddmodal.jsx @@ -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 (
+ {onClose()}} title={recordRow?'周期性计划编辑':'周期性计划添加'} + onOk={okHandler} + + > +
{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' + > + + + {pepList?.map((item)=>{return ( + {item.users.map((item1)=>{ + return + })} + )})} + + + 未完成 + 进行中 + 已完成 + 挂起 + + + + + +
+
+ +
) +} + + +function mapStateToProps (state) { + const { global } = state; + return { + actions: global.actions, + }; + } +export default connect(mapStateToProps)(AddModal) \ No newline at end of file diff --git a/web/client/src/sections/service/components/recordModal.jsx b/web/client/src/sections/service/components/recordModal.jsx new file mode 100644 index 0000000..6ebeabb --- /dev/null +++ b/web/client/src/sections/service/components/recordModal.jsx @@ -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 取消:
+ + +
} + onCancel={cancelHandler} + onOk={okHandler} + > +
{return item.account}),'type':recordRow?.type,'record':recordRow?.record}} + getFormApi={formApi => FormApi.current = formApi} + labelPosition='left' + labelAlign='right'> + + { + setStartTime(e) + ///console.log('e1',e) + }} + /> + {setEndTime(e);//console.log('sss',moment(endTime-startTime).format('DD天hh时mm分')) + }} /> + 中断时间:{endTime&&startTime? {`${tdd}天${tdh}时${tds}分`}:''} + + {pepList?.map((item)=>{return ( + {item.users.map((item1)=>{ + return + + })} + )})} + + + es异常 + 数据库异常 + 应用异常 + kafka异常 + 服务器异常 + 其他 + + + + + + + + +
+} +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); diff --git a/web/client/src/sections/service/components/temporyModal.jsx b/web/client/src/sections/service/components/temporyModal.jsx new file mode 100644 index 0000000..f65bd4d --- /dev/null +++ b/web/client/src/sections/service/components/temporyModal.jsx @@ -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 (
+ {onClose()}} title={recordRow?'临时响应编辑':'临时响应添加'} + onOk={okHandler} + > +
{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' + > + + + {pepList?.map((item)=>{return ( + {item.users.map((item1)=>{ + return + })} + )})} + + + + + 未完成 + 进行中 + 已完成 + 挂起 + + + + +
+
+ +
) +} +function mapStateToProps (state) { + const { global} = state; + return { + + actions: global.actions, + + }; + } + +export default connect(mapStateToProps)(TemporyModal) \ No newline at end of file diff --git a/web/client/src/sections/service/containers/cyclePlan.jsx b/web/client/src/sections/service/containers/cyclePlan.jsx index 8abf95c..7659fd2 100644 --- a/web/client/src/sections/service/containers/cyclePlan.jsx +++ b/web/client/src/sections/service/containers/cyclePlan.jsx @@ -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 + {record?.maintenancePlanExecuteUsers.map((item)=>{ + return item.name + }).toString() + } + + } + }, + { + title: '完成情况', + dataIndex: 'state', + }, + { + title: '备注', + dataIndex: 'remark', + }, + { + title: '计划完成时间', + render:(record)=>{ + return {moment(record.planFinishTime).format('YYYY-MM-DD HH:mm:ss')} + }, + }, + { + title: '实际完成时间', + render:(record)=>{ + return {moment(record.actualFinishTime).format('YYYY-MM-DD HH:mm:ss')} + }, + }, + { + title: '操作', + render:(record)=>{ + return (
+ + {delHandler(record)}}> +
) + } + }, + ]; return ( - <> -
- -
- +
+
+ + +
+
+
+
+ {setAddVis(false);setRecordRow(null);getCycPlan()}} recordRow={recordRow} pepList={pepList}> +
+ ) } -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); diff --git a/web/client/src/sections/service/containers/serviceRecord.jsx b/web/client/src/sections/service/containers/serviceRecord.jsx index 8abf95c..254170e 100644 --- a/web/client/src/sections/service/containers/serviceRecord.jsx +++ b/web/client/src/sections/service/containers/serviceRecord.jsx @@ -1,22 +1,219 @@ -import React, { useEffect } from 'react'; -import { connect } from 'react-redux'; - +'use strict'; +import React, { useEffect,useState,useMemo } from 'react'; +import { Calendar,DatePicker,RadioGroup, Radio,Button,Table,Modal,Tooltip } from '@douyinfe/semi-ui'; +import moment from 'moment' +import { connect } from 'react-redux'; +import RecordModal from '../components/recordModal' const Server = (props) => { const { dispatch, actions, user, loading, socket } = props + //console.log('actions',actions) + const {install,service}=actions + const [dateValue,setDateValue]=useState([]) + const [mode,setMode]=useState('') + const [modalVis,setModalVis]=useState(false) + const [recordRow,setRecordRow]=useState(null) + const [recordList,setRecordList]=useState([]) + const [pepList, setPepList] = useState([])//角色分配 + const [startTime,setStartTime]=useState('1970-1-1') + const [endTime,setEndTime]=useState('2099-1-1') + const [sTime,setStime]=useState('1970-1-1') + const [eTime,setEtime]=useState('2099-1-1') + const [calculability,setCalculability]=useState('') + const [pageSize,setPageSize]=useState(10) + const [pageIndex,setPageIndex]=useState(1) + const [total,setTotal]=useState() + const getRecordList=(query={ + startTime,endTime,pageIndex,pageSize + })=>{ + dispatch(service.getRecord(query)).then((res)=>{ + console.log('res1',res) + setRecordList(res?.payload.data.res) + setTotal(res?.payload.data.count) + }) + } + //('endTime',endTime) + useEffect(() => { + getRecordList() + dispatch(install.getOrganizationDeps()).then((res) => {//获取项企(PEP)全部部门及其下用户 + setPepList(res.payload.data) + }) + }, []) useEffect(() => { + const query={ + sTime, eTime + } + console.log('sTime',sTime,eTime) + dispatch(service.calculability(query)).then((res)=>{ + if(res.success) setCalculability((Math.round(res.payload.data * 10000)) / 100 + '%'); // console.log(res.payload.data,'dateee') + }) + }, [sTime,eTime]) - }, []) + 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)=>{ + setPageIndex(pageIndex) + setPageSize(pageSize) + const query={ + startTime,endTime,pageIndex,pageSize + } + getRecordList(query) + } + } + //console.log(recordList,'11111111') + + const columns = [ + { + title: '序号', + render:(t, r, i) => { + return i + 1 + } + }, + { + title: '故障描述', + dataIndex: 'sketch', + }, + { + title: '发生时间', + render:(record)=>{ + return {moment(record.occurrenceTime).format('YYYY-MM-DD HH:mm:ss')} + }, + }, + { + title: '解决时间', + render:(record)=>{ + return {moment(record.solvingTime).format('YYYY-MM-DD HH:mm:ss')} + }, + }, + { + title: '恢复时间', + render:(record)=>{ + const tdd=parseInt((moment(record.solvingTime).format('x')-moment(record.occurrenceTime).format('x'))/1000/60/60/24)//取整天 + const tdh=parseInt((moment(record.solvingTime).format('x')-moment(record.occurrenceTime).format('x'))/1000/60/60%24)//取整时 + const tds=parseInt((moment(record.solvingTime).format('x')-moment(record.occurrenceTime).format('x'))/1000/60%60)//取整分 + return {`${tdd}天${tdh}时${tds}分`} + } + }, + { + title: '故障类型', + dataIndex: 'type', + }, + { + title: '解决者', + //width:20, + render:(record)=>{ + return + {record?.maintenanceRecordExecuteUsers.map((item)=>{ + return item.name + }).toString() + } + + + } + }, + { + title: '当前状态', + render:(record)=>{ + return () + }, +}, + ]; +const onChangeDate=(e)=> { + setMode('') + setDateValue(e) + setStime(moment(dateValue[0]).format('YYYY-MM-DD HH:mm:ss')) + setEtime(moment(dateValue[1]).format('YYYY-MM-DD HH:mm:ss')) + const query={ + sTime, eTime + } + //console.log('sTime',sTime,eTime) + dispatch(service.calculability(query)).then((res)=>{ + if(res.success) setCalculability((Math.round(res.payload.data * 10000)) / 100 + '%'); // console.log(res.payload.data,'dateee') + }) + + } +const clearHandler=()=>{ +} +const addHandler=()=>{ + setModalVis(true) +} + + const onSelect=(e)=> { + if(e.target.value==='month'){ + setStime(moment().startOf('month').format('YYYY-MM-DD HH:mm:ss')); + setEtime(moment().endOf('month').format('YYYY-MM-DD HH:mm:ss')) + + }else{ + setStime(moment().startOf('year').format("YYYY-MM-DD HH:mm:ss")) + setEtime(moment().endOf('year').format('YYYY-MM-DD HH:mm:ss')) + + } + console.log('11111',moment().startOf('year').format('YYYY-MM-DD HH:mm:ss')) + setMode(e.target.value) + setDateValue([]) + +} return ( - <> -
- +
+
+
+
系统可用性
+
+ onSelect(e)} value={mode} type="button"> + 本月 + 全年 + + onChangeDate(e)} + density="compact" + style={{ width: 260 }} + value={dateValue} + onClear={()=>{clearHandler()}} + + /> +
+
+
+ {`系统可用性=(平均故障间隔MTBF)/(平均故障间隔MTBF+故障恢复时间MTTR)*100%`} + {calculability} +
+
+ +
+ 产生时间 + {//console.log('1',e[0],e[1]) + setStartTime((e[0])+'');setEndTime(e[1]+'') }} + onClear={()=>{setStartTime(null);setEndTime(null);setCalculability('')}} /> + +
+
+
+ { + return { + background:'#000000', + } + }}/> + + { setModalVis(false);getRecordList();setRecordRow(null)}} recordRow={recordRow} pepList={pepList}> - + ) } @@ -25,7 +222,7 @@ function mapStateToProps (state) { return { // loading: members.isRequesting, // user: auth.user, - // actions: global.actions, + actions: global.actions, // members: members.data, // socket: webSocket.socket }; diff --git a/web/client/src/sections/service/containers/temporaryResponse.jsx b/web/client/src/sections/service/containers/temporaryResponse.jsx index c116207..4128345 100644 --- a/web/client/src/sections/service/containers/temporaryResponse.jsx +++ b/web/client/src/sections/service/containers/temporaryResponse.jsx @@ -1,23 +1,139 @@ -import React, { useEffect } from 'react'; -import { connect } from 'react-redux'; +import React, { useEffect,useState } from 'react' +import { connect } from 'react-redux' +import { Button,Table,Popconfirm } from '@douyinfe/semi-ui' +import moment from 'moment' +import TemporyModal from '../components/temporyModal' + const SetControl = (props) => { const { dispatch, actions, user, loading, socket } = props - + const [addVis,setAddVis]=useState(false) + const [recordRow,setRecordRow]=useState(null) + const [response,setResponse]=useState([]) + const [pepList, setPepList] = useState([])//角色分配 + const [pageSize,setPageSize]=useState(10) + const [pageIndex,setPageIndex]=useState(1) + const [total,setTotal]=useState() + const {service,install}=actions + const getResponse=(query={type:'temp',msg:'获取临时响应',pageIndex,pageSize})=>{ + dispatch(service.getMaintenancePlan(query)).then((res)=>{ + console.log('res111',res) + setResponse(res?.payload.data.responseRes) + setTotal(res?.payload.data.count) + }) + } + //配置分页 + 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:'获取临时响应' + } + getResponse(query) + } + } useEffect(() => { - + getResponse() + dispatch(install.getOrganizationDeps()).then((res) => {//获取项企(PEP)全部部门及其下用户 + setPepList(res.payload.data) + }) }, []) + + const delHandler=(record)=>{ + // console.log('record.id',record.id,'maintenancePlanExecuteUsersId',record.maintenancePlanExecuteUsers.map((item)=>{return item.pepUserId})) + const query={ + responseId:record.id, + msg:'删除周期性计划' + } + //console.log('service',response) + dispatch(service.delMaintenancePlan(query)).then((res)=>{ + if(res.success) getResponse() + }) + } + const columns = [ + { + title: '序号', + render:(t, r, i) => { + return i + 1 + } + }, + { + title: '任务名称', + dataIndex: 'missionName', + }, + { + title: '执行人', + render:(record)=>{ + return + {record?.maintenancePlanExecuteUsers.map((item)=>{ + return item.name + }).toString() + } + + } + }, + { + title: '操作原因', + dataIndex: 'reason', + }, + { + title: '备注', + dataIndex: 'remark', + }, + { + title: '计划完成时间', + render:(record)=>{ + return {moment(record.planFinishTime).format('YYYY-MM-DD HH:mm:ss')} + }, + }, + { + title: '实际完成时间', + render:(record)=>{ + return {moment(record.actualFinishTime).format('YYYY-MM-DD HH:mm:ss')} + }, + + }, + { + title: '状态', + dataIndex: 'state' + }, + { + title: '操作', + render:(record)=>{ + return (
+ + {delHandler(record)}}> +
) + } + }, + ]; + return ( +
+
+ +
+
+
+
+ {setAddVis(false);getResponse();setRecordRow(null)}} recordRow={recordRow} pepList={pepList}> +
- return ( - <> -
- -
- - ) + ) } function mapStateToProps (state) { @@ -25,7 +141,7 @@ function mapStateToProps (state) { return { // loading: members.isRequesting, // user: auth.user, - // actions: global.actions, + actions: global.actions, // members: members.data, // socket: webSocket.socket }; diff --git a/web/client/src/sections/service/style.less b/web/client/src/sections/service/style.less index d26536b..0eaa50f 100644 --- a/web/client/src/sections/service/style.less +++ b/web/client/src/sections/service/style.less @@ -1,5 +1,5 @@ -.myempush{ - .semi-input-wrapper{ +.myempush { + .semi-input-wrapper { margin-bottom: 0px !important; } -} \ No newline at end of file +} diff --git a/web/client/src/utils/webapi.js b/web/client/src/utils/webapi.js index bb6fda1..ca2b3b3 100644 --- a/web/client/src/utils/webapi.js +++ b/web/client/src/utils/webapi.js @@ -86,6 +86,18 @@ export const ApiTable = { //工单 getEnabledWorkflowProcess: 'workflow/process/enabled',//获取工作流可用表单 getPomsProjectBasicAll: 'basic-data/workflow/single/allProject', + + //服务记录 + getRecord: 'record', + addRecord: 'record', + //获取维护计划 + getMaintenancePlan: 'maintenancePlan', + //删除维护计划 + delMaintenancePlan: 'maintenancePlan', + //编辑维护计划 + editMaintenancePlan: 'maintenancePlan', + //计算系统可用性 + calculability: 'calculability' }; // 项企的接口 @@ -104,6 +116,8 @@ export const EmisApiTable = { getApprovalActionUrl: 'process-instance/audit/{type}', // 审批、撤销操作 //删除草稿 delDraftUrl: 'process/drafts/{draftId}', + + } export const RouteTable = { diff --git a/web/package.json b/web/package.json index 4e07fdb..13f960a 100644 --- a/web/package.json +++ b/web/package.json @@ -47,7 +47,7 @@ "vite": "^2.9.5" }, "dependencies": { - "@douyinfe/semi-ui": "2.8.0", + "@douyinfe/semi-ui": "2.32.0", "@douyinfe/semi-webpack-plugin": "^2.13.0", "@micro-zoe/micro-app": "^1.0.0-alpha.1", "@peace/utils": "^0.0.64",