From 30e2b43cd09d86d08f1f39d45b9e4ca9df6aa227 Mon Sep 17 00:00:00 2001 From: wenlele Date: Fri, 27 Oct 2023 12:54:45 +0800 Subject: [PATCH] =?UTF-8?q?=E8=87=AA=E5=8A=A8=E5=8C=96=E6=8A=A5=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/app/lib/controllers/service/report.js | 252 +++++ api/app/lib/models/reportFile.js | 70 ++ api/app/lib/models/report_automatic.js | 151 +++ api/app/lib/routes/service/report.js | 32 + .../3.6/schema/1.create_report_file copy.sql | 30 + .../3.6/schema/2.create_report_automatic.sql | 26 + .../src/layout/components/header/index.jsx | 2 +- .../src/sections/service/actions/index.js | 3 +- .../src/sections/service/actions/report.js | 105 +++ .../service/components/automatic-Modal.jsx | 318 +++++++ .../sections/service/components/fileModal.jsx | 140 +++ .../service/containers/automaticReport.jsx | 892 ++++-------------- .../service/containers/reportFile.jsx | 173 ++-- web/client/src/sections/service/nav-item.jsx | 10 +- web/client/src/utils/webapi.js | 9 +- 15 files changed, 1386 insertions(+), 827 deletions(-) create mode 100644 api/app/lib/controllers/service/report.js create mode 100644 api/app/lib/models/reportFile.js create mode 100644 api/app/lib/models/report_automatic.js create mode 100644 api/app/lib/routes/service/report.js create mode 100644 script/3.6/schema/1.create_report_file copy.sql create mode 100644 script/3.6/schema/2.create_report_automatic.sql create mode 100644 web/client/src/sections/service/actions/report.js create mode 100644 web/client/src/sections/service/components/automatic-Modal.jsx create mode 100644 web/client/src/sections/service/components/fileModal.jsx diff --git a/api/app/lib/controllers/service/report.js b/api/app/lib/controllers/service/report.js new file mode 100644 index 0000000..8ce6c5e --- /dev/null +++ b/api/app/lib/controllers/service/report.js @@ -0,0 +1,252 @@ +'use strict'; +const moment = require('moment'); + +async function postReportFile (ctx) { + try { + const { models } = ctx.fs.dc; + const data = ctx.request.body + + await models.ReportFile.create(data) + + ctx.status = 204; + } catch (error) { + + ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); + ctx.status = 400; + ctx.body = { + message: typeof error == 'string' ? error : undefined + } + } +} + + +async function getReportFile (ctx) { + try { + const { models } = ctx.fs.dc; + const { limit, page, projectId } = ctx.query; + const { userInfo } = ctx.fs.api; + + let options = { + where: {}, + order: [['startTime', 'desc']] + } + if (limit || page) { + options.limit = Number(limit) + options.page = Number(page) * Number(limit) + } + if (projectId) { + options.where.projectId = projectId + } + + let res = await models.ReportFile.findAndCountAll(options); + + + + ctx.status = 200; + ctx.body = res + } catch (error) { + + ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); + ctx.status = 400; + ctx.body = { + message: typeof error == 'string' ? error : undefined + } + } +} + +async function delReportFile (ctx) { + try { + const { models } = ctx.fs.dc; + const { id } = ctx.params + + await models.ReportFile.destroy({ + where: { + id: id + } + }) + + ctx.status = 204; + } catch (error) { + ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); + ctx.status = 400; + ctx.body = { + message: typeof error == 'string' ? error : undefined + } + } +} + + +async function getFactorList (ctx) { + try { + const { models } = ctx.fs.dc; + const { clickHouse, utils: { anxinStrucIdRange } } = ctx.app.fs + const { userInfo } = ctx.fs.api; + const { pepProjectId } = ctx.query + + + let anxinStruc = await anxinStrucIdRange({ + ctx, pepProjectId + }) + + if (anxinStruc.length) { + const anxinStrucIds = anxinStruc.map(a => a.strucId) + let factorProto = [1002, 1001, 4009, 2001, 3001, 4004, 5002, 4001, 4002, 4008, 4007, 1004] + + + const factor = anxinStrucIds.length ? await clickHouse.anxinyun.query(` + SELECT + id,name,proto, + t_structure_factor.structure AS structure + FROM t_factor + INNER JOIN t_structure_factor + ON t_structure_factor.factor = t_factor.id + AND t_structure_factor.structure IN (${anxinStrucIds.join(',')}, -1) + WHERE + t_factor.proto IN (${factorProto.join(',')}, -1) + `).toPromise() : [] + + const factorId = factor.map(a => a.id) + + const sensor = factorId.length ? await clickHouse.anxinyun.query(` + SELECT + id,name,factor + FROM t_sensor + WHERE + t_sensor.factor IN (${factorId.join(',')}, -1) + `).toPromise() : [] + + + + // WSDJC(温湿度监测) 1002 + // FSFXJC(风速风向监测) 1001 + // SSFJC(伸缩缝监测) 4009 + // SLJC(索力监测) 2001 + // YBJC(应力应变监测) 3001 + // NDJC(挠度监测) 4004 + // ZDJC(振动监测) 5002 + // CLZHJC(车辆载荷监测) + // ZZWYJC(支座位移监测) 4001 + // QTPWJC(桥塔偏位监测) 4002 + // LFJC(裂缝监测) 4008 + // QDQXJC(桥墩倾斜监测) 4007 + // JGWDJC(结构温度监测) 1004 + + anxinStruc.forEach(s => { + s.factor = factor.filter(d => { + if (d.structure == s.strucId) { + d.sensor = sensor.filter(f => f.factor == d.id) + return true + } else { + return false + } + + }) + }) + + ctx.status = 200; + ctx.body = anxinStruc + } else { + ctx.status = 200; + ctx.body = [] + } + } catch (error) { + ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); + ctx.status = 400; + ctx.body = { + message: typeof error == 'string' ? error : undefined + } + } +} + +async function postAutomaticReport (ctx) { + try { + const { models } = ctx.fs.dc; + const data = ctx.request.body + + if (data.id) { + await models.ReportAutomatic.update(data, { + where: { + id: data.id + }}) + } else { + await models.ReportAutomatic.create(data) + } + ctx.status = 204; + } catch (error) { + ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); + ctx.status = 400; + ctx.body = { + message: typeof error == 'string' ? error : undefined + } + } +} + + +async function getAutomaticReport (ctx) { + try { + const { models } = ctx.fs.dc; + const { limit, page, projectId, keyword } = ctx.query; + const { userInfo } = ctx.fs.api; + + let options = { + where: {}, + order: [['time', 'desc']] + } + if (limit || page) { + options.limit = Number(limit) + options.page = Number(page) * Number(limit) + } + if (projectId) { + options.where.projectId = { $in: String(projectId).split(',') } + } + + if (keyword) { + options.where.reportName = { $iLike: `%${keyword}%` } + } + + let res = await models.ReportAutomatic.findAndCountAll(options); + + ctx.status = 200; + ctx.body = res + } catch (error) { + ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); + ctx.status = 400; + ctx.body = { + message: typeof error == 'string' ? error : undefined + } + } +} + +async function delAutomaticReport (ctx) { + try { + const { models } = ctx.fs.dc; + const { id } = ctx.params + + await models.ReportAutomatic.destroy({ + where: { + id: id + } + }) + + ctx.status = 204; + } catch (error) { + ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); + ctx.status = 400; + ctx.body = { + message: typeof error == 'string' ? error : undefined + } + } +} + + + +module.exports = { + + getReportFile, + postReportFile, + delReportFile, + getFactorList, + postAutomaticReport, + getAutomaticReport, + delAutomaticReport +}; \ No newline at end of file diff --git a/api/app/lib/models/reportFile.js b/api/app/lib/models/reportFile.js new file mode 100644 index 0000000..9f81b81 --- /dev/null +++ b/api/app/lib/models/reportFile.js @@ -0,0 +1,70 @@ +/* eslint-disable*/ + +'use strict'; + +module.exports = dc => { + const DataTypes = dc.ORM; + const sequelize = dc.orm; + const ReportFile = sequelize.define("reportFile", { + id: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: null, + comment: "id", + primaryKey: true, + field: "id", + autoIncrement: true + }, + projectId: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: null, + comment: "项目id", + primaryKey: false, + field: "project_id", + autoIncrement: false + }, + fileName: { + type: DataTypes.STRING, + allowNull: false, + defaultValue: null, + comment: "文件名称", + primaryKey: false, + field: "file_name", + autoIncrement: false + }, + url: { + type: DataTypes.STRING, + allowNull: false, + defaultValue: null, + comment: "文件路径", + primaryKey: false, + field: "url", + autoIncrement: false + }, + reportType: { + type: DataTypes.STRING, + allowNull: false, + defaultValue: null, + comment: "报表类型", + primaryKey: false, + field: "report_type", + autoIncrement: false + }, + startTime: { + type: DataTypes.DATE, + allowNull: false, + defaultValue: null, + comment: "开始时间", + primaryKey: false, + field: "start_time", + autoIncrement: false + }, + }, { + tableName: "report_file", + comment: "", + indexes: [] + }); + dc.models.ReportFile = ReportFile; + return ReportFile; +}; \ No newline at end of file diff --git a/api/app/lib/models/report_automatic.js b/api/app/lib/models/report_automatic.js new file mode 100644 index 0000000..116f63e --- /dev/null +++ b/api/app/lib/models/report_automatic.js @@ -0,0 +1,151 @@ +/* eslint-disable*/ + +'use strict'; + +module.exports = dc => { + const DataTypes = dc.ORM; + const sequelize = dc.orm; + const ReportAutomatic = sequelize.define("reportAutomatic", { + id: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: null, + comment: "id", + primaryKey: true, + field: "id", + autoIncrement: true + }, + reportName: { + type: DataTypes.STRING, + allowNull: false, + defaultValue: null, + comment: "", + primaryKey: false, + field: "report_name", + autoIncrement: false + }, + projectId: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: null, + comment: "项目id", + primaryKey: false, + field: "project_id", + autoIncrement: false + }, + projectName: { + type: DataTypes.STRING, + allowNull: false, + defaultValue: null, + comment: "", + primaryKey: false, + field: "project_name", + autoIncrement: false + }, + reportType: { + type: DataTypes.STRING, + allowNull: false, + defaultValue: null, + comment: "报表类型", + primaryKey: false, + field: "report_type", + autoIncrement: false + }, + reportPicPath: { + type: DataTypes.STRING, + allowNull: false, + defaultValue: null, + comment: "", + primaryKey: false, + field: "reportpic_path", + autoIncrement: false + }, + framer: { + type: DataTypes.STRING, + allowNull: false, + defaultValue: null, + comment: "", + primaryKey: false, + field: "framer", + autoIncrement: false + }, + auditor: { + type: DataTypes.STRING, + allowNull: false, + defaultValue: null, + comment: "", + primaryKey: false, + field: "auditor", + autoIncrement: false + }, + ratifier: { + type: DataTypes.STRING, + allowNull: false, + defaultValue: null, + comment: "", + primaryKey: false, + field: "ratifier", + autoIncrement: false + }, + structId: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: null, + comment: "", + primaryKey: false, + field: "struct_id", + autoIncrement: false + }, + projectOverview: { + type: DataTypes.STRING, + allowNull: false, + defaultValue: null, + comment: "", + primaryKey: false, + field: "project_overview", + autoIncrement: false + }, + reportStartTime: { + type: DataTypes.DATE, + allowNull: false, + defaultValue: null, + comment: "开始时间", + primaryKey: false, + field: "report_start_time", + autoIncrement: false + }, + reportEndTime: { + type: DataTypes.DATE, + allowNull: false, + defaultValue: null, + comment: "开始时间", + primaryKey: false, + field: "report_end_time", + autoIncrement: false + }, + time: { + type: DataTypes.DATE, + allowNull: false, + defaultValue: null, + comment: "", + primaryKey: false, + field: "time", + autoIncrement: false + }, + factors: { + type: DataTypes.JSON, + allowNull: false, + defaultValue: null, + comment: "", + primaryKey: false, + field: "factors", + autoIncrement: false + }, + }, { + tableName: "report_automatic", + comment: "", + indexes: [] + }); + dc.models.ReportAutomatic = ReportAutomatic; + return ReportAutomatic; +}; \ No newline at end of file diff --git a/api/app/lib/routes/service/report.js b/api/app/lib/routes/service/report.js new file mode 100644 index 0000000..d8474a3 --- /dev/null +++ b/api/app/lib/routes/service/report.js @@ -0,0 +1,32 @@ +'use strict'; + +const report = require('../../controllers/service/report'); + +module.exports = function (app, router, opts) { + app.fs.api.logAttr['GET/report/file'] = { content: '获取服务记录列表', visible: true }; + router.get('/report/file', report.getReportFile); + + app.fs.api.logAttr['POST/report/file'] = { content: '上传文件', visible: true }; + router.post('/report/file', report.postReportFile); + + app.fs.api.logAttr['DEL/report/file/:id'] = { content: '删除报表文件', visible: true }; + router.del('/report/file/:id', report.delReportFile); + + app.fs.api.logAttr['GET/factor/list'] = { content: '获取监测因素信息', visible: true }; + router.get('/factor/list', report.getFactorList); + + app.fs.api.logAttr['POST/automatic/report'] = { content: '新增/编辑报表生成规则', visible: true }; + router.post('/automatic/report', report.postAutomaticReport); + + app.fs.api.logAttr['GET/automatic/report'] = { content: '获取报表生成规则', visible: true }; + router.get('/automatic/report', report.getAutomaticReport); + + app.fs.api.logAttr['DEL/automatic/report/:id'] = { content: '删除报表规则', visible: true }; + router.del('/automatic/report/:id', report.delAutomaticReport); + + + + // app.fs.api.logAttr['GET/respond-record'] = { content: '获取响应记录数据', visible: true }; + // router.get('/respond-record', record.respondRecord); + +}; \ No newline at end of file diff --git a/script/3.6/schema/1.create_report_file copy.sql b/script/3.6/schema/1.create_report_file copy.sql new file mode 100644 index 0000000..fd80a2e --- /dev/null +++ b/script/3.6/schema/1.create_report_file copy.sql @@ -0,0 +1,30 @@ +create table report_file +( + -- Only integer types can be auto increment + id serial not null, + file_name varchar(255) not null, + project_id int not null, + url varchar(1024) not null, + start_time timestamp not null, + report_type varchar(255) not null +); + +comment on table report_file is '报表文件'; + +comment on column report_file.file_name is '报表文件名'; + +comment on column report_file.project_id is '运维项目id'; + +comment on column report_file.url is '文件路径'; + +comment on column report_file.start_time is '产生时间'; + +comment on column report_file.report_type is '报表类型'; + +create unique index report_file_id_uindex + on report_file (id); + +alter table report_file + add constraint report_file_pk + primary key (id); + diff --git a/script/3.6/schema/2.create_report_automatic.sql b/script/3.6/schema/2.create_report_automatic.sql new file mode 100644 index 0000000..77d4016 --- /dev/null +++ b/script/3.6/schema/2.create_report_automatic.sql @@ -0,0 +1,26 @@ +create table report_automatic +( + id serial not null, + report_name varchar(255) not null, + project_id int not null, + project_Name varchar(255) not null, + report_type varchar(255) not null, + reportpic_path varchar(255) not null, + framer varchar(255) not null, + auditor varchar(255) not null, + ratifier varchar(255) not null, + struct_id int not null, + report_start_time timestamp not null, + report_end_time timestamp not null, + factors json not null, + time timestamp not null, + project_overview varchar not null +); + +create unique index report_automatic_id_uindex + on report_automatic (id); + +alter table report_automatic + add constraint report_automatic_pk + primary key (id); + diff --git a/web/client/src/layout/components/header/index.jsx b/web/client/src/layout/components/header/index.jsx index effa4b9..11a5cac 100644 --- a/web/client/src/layout/components/header/index.jsx +++ b/web/client/src/layout/components/header/index.jsx @@ -197,7 +197,7 @@ const Header = (props) => { }}>全局} itemKey="全局"> { - setPepProjectId('') + // setPepProjectId('') }}>自定义分组} itemKey="自定义分组">
diff --git a/web/client/src/sections/service/actions/index.js b/web/client/src/sections/service/actions/index.js index aa913ce..3c85b7f 100644 --- a/web/client/src/sections/service/actions/index.js +++ b/web/client/src/sections/service/actions/index.js @@ -5,6 +5,7 @@ import * as redcord from './record' import * as maintenancePlan from './maintenancePlan' import * as equipment from './equipment' import * as firmwareUpgrade from './firmwareUpgrade' +import * as report from './report' export default { - ...emPush, ...redcord, ...maintenancePlan, ...equipment,...firmwareUpgrade + ...emPush, ...redcord, ...maintenancePlan, ...equipment, ...firmwareUpgrade, ...report } \ No newline at end of file diff --git a/web/client/src/sections/service/actions/report.js b/web/client/src/sections/service/actions/report.js new file mode 100644 index 0000000..ae48f5f --- /dev/null +++ b/web/client/src/sections/service/actions/report.js @@ -0,0 +1,105 @@ +'use strict'; + +import { ApiTable, basicAction } from '$utils' + +export function getReportFile (query = {}) { //获取报表文件 + return dispatch => basicAction({ + type: 'get', + dispatch: dispatch, + query: query, + actionType: 'GET_REPORT_FILE', + url: `${ApiTable.reportFile}`, + msg: { option: '获取报表文件信息' }, + reducer: { + name: "reportFile", + params: { noClear: true } + } + }); +} + +export function postReportFile (data = {}) { //上传文件 + return dispatch => basicAction({ + type: 'post', + data, + dispatch: dispatch, + actionType: 'POST_REPORT_FILE', + url: `${ApiTable.reportFile}`, + msg: { option: '上传文件' }, + }); +} + + +export function delReportFile (id) {//删除报表文件 + return dispatch => basicAction({ + type: 'del', + dispatch: dispatch, + actionType: 'DEL_REPORT_FILE', + url: `${ApiTable.delReportFile.replace('{id}', id)}`, + msg: { option: '删除报表文件' }, + + + }); +} + + +export function getFactorList (query = {}) { //获取报表文件 + return dispatch => basicAction({ + type: 'get', + dispatch: dispatch, + query: query, + actionType: 'GET_FACTOR_LIST', + url: `${ApiTable.factorList}`, + msg: { error: '获取监测因素信息失败' }, + reducer: { + name: "", + params: { noClear: true } + } + }); +} + +export function postAutomaticReport (data = {}) { //上传文件 + return dispatch => basicAction({ + type: 'post', + data, + dispatch: dispatch, + actionType: 'POST_AUTOMATIC_REPORT', + url: `${ApiTable.automaticReport}`, + msg: { option: data?.id ? '编辑报表生成规则' : "新增报表生成规则" }, + }); +} + + +export function getAutomaticReport (query = {}) { //获取报表文件 + return dispatch => basicAction({ + type: 'get', + dispatch: dispatch, + query: query, + actionType: 'GET_AUTOMATIC_REPORT', + url: `${ApiTable.automaticReport}`, + msg: { error: '获取报表生成规则' }, + reducer: { + name: "automaticReport", + params: { noClear: true } + } + }); +} + + +export function delAutomaticReport (id) {//删除报表文件 + return dispatch => basicAction({ + type: 'del', + dispatch: dispatch, + actionType: 'DEL_AUTOMATIC_REPORT', + url: `${ApiTable.delAutomaticReport.replace('{id}', id)}`, + msg: { option: '删除报表规则' }, + + + }); +} + + + + + + + diff --git a/web/client/src/sections/service/components/automatic-Modal.jsx b/web/client/src/sections/service/components/automatic-Modal.jsx new file mode 100644 index 0000000..d6897fa --- /dev/null +++ b/web/client/src/sections/service/components/automatic-Modal.jsx @@ -0,0 +1,318 @@ +import React, { useState, useRef, useEffect } from "react"; +import { connect } from "react-redux"; +import { Modal, Form, Notification, Tooltip, Upload, Button, Checkbox, CheckboxGroup, Collapse } from "@douyinfe/semi-ui"; +import { IconUpload } from '@douyinfe/semi-icons'; +import moment from "moment"; + + +const AutomaticModal = ({ actions, dispatch, apiRoot, qiniuUrl, visible, eidtData, close, success, projectList }) => { + + const { service, problem } = actions; + const form = useRef();//表单 + const [strucData, setStrucData] = useState([]) //结构物数据 + + const [projectId, setProjectId] = useState(); //项目id + const [structId, setStructId] = useState(); //结构物id + const [factorId, setFactorId] = useState([]); //监测因素id + const [factorList, setFactorList] = useState([]); //监测因素 + const [factorChech, setFactorChech] = useState([]); //选中的监测因素 + + + useEffect(async () => { + if (eidtData?.id) { + setProjectId(eidtData?.projectId) + setStructId(eidtData?.structId) + setFactorId(eidtData?.factors?.map(s => s.codeName) || []) + + let data = await getData(eidtData?.projectId) + let Factor = data?.find(s => s.strucId == eidtData?.structId)?.factor || [] + setFactorList(Factor) + setFactorChech(Factor?.filter(s => eidtData?.factors?.map(s => s.codeName)?.includes(s.proto))) + } + }, []) + + const getData = async (projectId) => { + let data = [] + await dispatch(service.getFactorList({ pepProjectId: projectId })).then((res) => { + if (res.success) { + setStrucData(res.payload.data) + data = res.payload.data + } + }) + return data + } + + return ( + <> + { + form.current.validate().then((v) => { + console.log(v); + let data = { + id: eidtData?.id, + reportName: v.reportName, + projectId: v.projectId, + projectName: v.projectName, + reportType: v.reportType, + reportPicPath: v.reportPicPath[0]?.response?.url, + framer: v.framer, + auditor: v.auditor, + ratifier: v.ratifier, + structId: v.structId, + projectOverview: v.projectOverview, + reportStartTime: moment(v.reportTime[0]).format('YYYY-MM-DD HH:mm:ss'), + reportEndTime: moment(v.reportTime[1]).format('YYYY-MM-DD HH:mm:ss'), + time: moment().format('YYYY-MM-DD HH:mm:ss'), + factors: [] + } + + v.factorId?.forEach(d => { + let index = d.length + let factorData = {} + for (let key in v) { + factorData.codeName = d + factorData.tempName = factorData.tempName || [] + if (key?.indexOf(d) != -1) { + if (key?.slice(index) == 'pointDescrip') factorData.pointDescrip = v[key] + if (key?.slice(index) == 'pointPicPath') factorData.pointPicPath = v[key] && v[key][0]?.response?.url + if (key?.slice(index) == 'factorDescrip') factorData.factorDescrip = v[key] + if (key?.slice(index) == 'sensorNames') factorData.sensorNames = factorChech?.find(p => p.proto == d)?.sensor?.filter(f => v[key]?.includes(f.id))?.map(c => ({ id: c.id, name: c.name })) || [] + if (key?.slice(index) == 'startEndTime') { + factorData.startTime = v[key] && moment(v[key][0]).format('YYYY-MM-DD HH:mm:ss') + factorData.endTime = v[key] && moment(v[key][1]).format('YYYY-MM-DD HH:mm:ss') + } + if (key?.slice(index) == 'tempName1') { + factorData.tempName?.push({ + index: 1, + id: v[key], + name: factorChech?.find(p => p.proto == d)?.sensor?.find(f => v[key] == f.id)?.name + }) + } + if (key?.slice(index) == 'tempName2') { + factorData.tempName?.push({ + index: 2, + id: v[key], + name: factorChech?.find(p => p.proto == 1004)?.sensor?.find(f => v[key] == f.id)?.name + }) + } + if (key?.slice(index) == 'factorDescrip') factorData.factorDescrip = v[key] + if (key?.slice(index) == 'glStaName') factorData.glStaName = v[key] + if (key?.slice(index) == 'tempStaName') factorData.tempStaName = v[key] + if (key?.slice(index) == 'initialTime') factorData.initialTime = v[key] && moment(v[key]).format('YYYY-MM-DD HH:mm:ss') + if (key?.slice(index) == 'releTime') { + factorData.releStartTime = v[key] && moment(v[key][0]).format('YYYY-MM-DD HH:mm:ss') + factorData.releEndTime = v[key] && moment(v[key][1]).format('YYYY-MM-DD HH:mm:ss') + } + } + } + data.factors?.push(factorData) + }) + console.log(111, data); + + dispatch(service.postAutomaticReport(data)).then((res) => { + console.log(res); + if (res.success) { + close() + success() + } + }) + + }) + }} + width={700} + onCancel={() => close()} + > +
{ }} + getFormApi={(formApi) => (form.current = formApi)} + > + + { + setProjectId(v) + getData(v) + form.current.setValue('structId', null) + setStructId("") + setFactorList([]) + form.current.setValue('factorId', []) + setFactorChech([]) + }} > + {projectList?.map((item) => { + return + + })} + + + + + + + + + + + { + setFactorList(strucData?.find(s => s.strucId == v)?.factor || []) + setStructId(v) + form.current.setValue('factorId', []) + setFactorChech([]) + }} > + {strucData?.map((item) => { + return + + })} + + + + + s.codeName) || []} + rules={[{ required: true, message: "请选择监测因素" }]} disabled={structId ? false : true} + onChange={v => { + setFactorChech(factorList?.filter(s => v.includes(s.proto))) + }} > + {factorList?.map((item) => { + return + })} + + + + {factorChech?.length > 0 ? + { + factorChech?.map(s => { + return +
+ c.codeName == s.proto)?.pointDescrip || ""} + /> + c.codeName == s.proto)?.pointPicPath && [{ url: `/_file-server/${eidtData?.factors?.find(c => c.codeName == s.proto)?.pointPicPath?.slice(qiniuUrl.length + 1)}`, name: eidtData?.factors?.find(c => c.codeName == s.proto)?.pointPicPath?.split('/')?.pop(), status: 'success', preview: ['png', 'jpg', 'jpeg'].includes(eidtData?.factors?.find(c => c.codeName == s.proto)?.pointPicPath?.split('.')?.pop()?.replace('.', '')) }] || null} + action={`${apiRoot}/attachments/p`} + accept={'.png, .jpg, .jpeg'} + limit={1} maxSize={5120} + > + + + + {s.proto == 2001 && + c.codeName == s.proto)?.factorDescrip || ""} + /> + } + + c.codeName == s.proto)?.sensorNames?.map(a => a.id) || []} + > + {s.sensor?.map((item) => { + return + })} + + c.codeName == s.proto)?.startTime && [moment(eidtData?.factors?.find(c => c.codeName == s.proto)?.startTime).format('YYYY-MM-DD HH:mm:ss'), moment(eidtData?.factors?.find(c => c.codeName == s.proto)?.endTime).format('YYYY-MM-DD HH:mm:ss')] || null} + /> + { + ['2001', '4004', '4007', '4008'].includes(s.proto) && + c.codeName == s.proto)?.initialTime && moment(eidtData?.factors?.find(c => c.codeName == s.proto)?.initialTime).format('YYYY-MM-DD HH:mm:ss')} + /> + } + + c.codeName == s.proto)?.tempName?.find(c => c.index == 1)?.id || ""} + > + {s.sensor?.map((item) => { + return + + })} + + c.codeName == s.proto)?.tempName?.find(c => c.index == 2)?.id || ""} + > + {factorList?.find(d => s.proto == 1004)?.sensor?.map((item) => { + return + + })} + + c.codeName == s.proto)?.glStaName || ""} + /> + c.codeName == s.proto)?.tempStaName || ""} + /> + c.codeName == s.proto)?.releStartTime && [moment(eidtData?.factors?.find(c => c.codeName == s.proto)?.releStartTime).format('YYYY-MM-DD HH:mm:ss'), moment(eidtData?.factors?.find(c => c.codeName == s.proto)?.releEndTime).format('YYYY-MM-DD HH:mm:ss')] || null} + /> + +
+
+ }) + } + + +
: ""} + + +
+ + ); +} +function mapStateToProps (state) { + const { auth, global, members } = state; + + return { + // loading: members.isRequesting, + user: auth.user, + actions: global.actions, + apiRoot: global.apiRoot, + qiniuUrl: global.qiniu?.domain + }; +} + +export default connect(mapStateToProps)(AutomaticModal); diff --git a/web/client/src/sections/service/components/fileModal.jsx b/web/client/src/sections/service/components/fileModal.jsx new file mode 100644 index 0000000..226622e --- /dev/null +++ b/web/client/src/sections/service/components/fileModal.jsx @@ -0,0 +1,140 @@ +import React, { useState, useRef, useEffect } from "react"; +import { connect } from "react-redux"; +import { Modal, Form, Notification, Tooltip, Upload, Button } from "@douyinfe/semi-ui"; +import { IconUpload } from '@douyinfe/semi-icons'; +import moment from "moment"; + + +const FileModal = ({ actions, dispatch, apiRoot, qiniuUrl, visible, close,success, projectList }) => { + + const { service, problem } = actions; + const form = useRef();//表单 + const [abnormal, setAbnormal] = useState(false); //异常率推送机制disable + const [usersList, setUsersList] = useState([]); //获取全部未删除用户 + const [structure, setStructure] = useState(true); //结构物disable + const [projectPoms, setProjectPoms] = useState([]); //获取已绑定项目 + const [projectStructure, setProjectStructure] = useState([]); //获取绑定项目下结构物 + const [timeTypeDis, setTimeTypeDis] = useState(true); //通知时效disable + const [projectStatus, setProjectStatus] = useState([]); //获取项目状态列表 + const timeTypePOMS = useRef([]);//表单 + + const [interval1, setInterval1] = useState(undefined); // + const [interval2, setInterval2] = useState(undefined); // + const [interval3, setInterval3] = useState(undefined); // + const [deviceProportion, setDeviceProportion] = useState(undefined); // + const [subType, setSubType] = useState([]); //监听模块中的子类 + const [factorShow, setFactorShow] = useState([]); //结构物对应监测项 + const [firstPass, setFirstPass] = useState(true) + const [uploadData, setUploadData] = useState({}) + + return ( + <> + { + form.current.validate().then((v) => { + if (uploadData?.url) { + dispatch(service.postReportFile({ + projectId: v.projectId, + fileName: v.fileName, + reportType: v.reportType, + startTime: moment().format('YYYY-MM-DD HH:mm:ss'), + url: qiniuUrl + '/' + uploadData?.url + })).then((res) => { + if (res.success) { + close() + success() + } + }) + } else { + Notification.error({ + content: '请上传文件', + duration: 2, + }) + } + }) + }} + width={500} + onCancel={() => close()} + > +
{ + + }} + getFormApi={(formApi) => (form.current = formApi)} + > + ({ value: v.id, label: v.name || v.pepProjectName }))} + /> + + +
+
文件:*
+ { + setUploadData({}) + }} + onSuccess={(responseBody, file) => { + setUploadData({ + name: file.name, + size: file.size, + url: responseBody?.uploaded, + uploadTime: moment().format("YYYY-MM-DD HH:mm:ss") + }) + }} + > + + +
+ +
+ + ); +} +function mapStateToProps (state) { + const { auth, global, members } = state; + + return { + // loading: members.isRequesting, + user: auth.user, + actions: global.actions, + apiRoot: global.apiRoot, + qiniuUrl: global.qiniu?.domain + }; +} + +export default connect(mapStateToProps)(FileModal); diff --git a/web/client/src/sections/service/containers/automaticReport.jsx b/web/client/src/sections/service/containers/automaticReport.jsx index 22952a6..e058001 100644 --- a/web/client/src/sections/service/containers/automaticReport.jsx +++ b/web/client/src/sections/service/containers/automaticReport.jsx @@ -1,69 +1,118 @@ import React, { useEffect, useRef, useState } from 'react'; import { connect } from 'react-redux'; -import { Skeleton, Button, Pagination, Form, Popconfirm, Table, Tooltip } from '@douyinfe/semi-ui'; +import { Skeleton, Button, Pagination, Form, Popconfirm, Table, Tooltip, Input } from '@douyinfe/semi-ui'; import { IconSearch } from '@douyinfe/semi-icons'; import { SkeletonScreen, } from "$components"; import moment from "moment"; -import PushModal from '../components/pushModal' -import '../style.less' -import { Setup } from "$components"; +import AutomaticModal from '../components/automatic-Modal' +import SimpleBar from 'simplebar-react'; + + +const AutomaticReport = ({ dispatch, actions, user, clientHeight, loading, socket, projectPoms, pepProjectId }) => { + + const { service, } = actions; -const AutomaticReport = (props) => { - const form = useRef();//表单 - const { dispatch, actions, user, loading, socket } = props - const { service, problem } = actions; - const [setup, setSetup] = useState(false); //表格设置是否显现 - const [setupp, setSetupp] = useState([]);//实际显示的表格列表 const [query, setQuery] = useState({ limit: 10, page: 0 }); //页码信息 - const [limits, setLimits] = useState()//每页实际条数 + const [limits, setLimits] = useState()//总数 const mylimits = useRef(); //每页实际条数 - const [pushModal, setPushModal] = useState(false) //信鸽弹框 - const [pushEdit, setPushEdit] = useState(false) //是否是修改 - const [change, setChange] = useState(false) //是否改变 - const [allTableData, setAllTableData] = useState([]) //获取到的所有表格信息 - const [editObj, setEditObj] = useState({});//管理员弹框修改内容 - const [projectStatus, setProjectStatus] = useState([]); //获取项目状态列表 - const [subTypeData, setSubTypedata] = useState({ - data_outages: [], - data_exception: [], - strategy_hit: [], - video_exception: [], - app_exception: [], - device_exception: [], - }); //数据类监听模块中的子类 + const [automaticModal, setAutomaticModall] = useState(false) //弹框 + const [eidtData, setEidtData] = useState({}) //是否改变 + + const [tableData, setTableData] = useState([]) //表格数据 + const [projectList, setProjectList] = useState([]) //项目数据 + const [projectId, setProjectId] = useState() //项目id + const [projectSearch, setProjectSearch] = useState() //项目搜索 + const [keyword, setKeyword] = useState() //报表关键字 + const page = useRef(query.page);//哪一页 - const EMPUSH = "empush"; - const tableList = [//表格属性 - { - title: '推送信息', - list: [ - { name: "关联项目", value: "projectName" }, - { name: "策略名称", value: "name" }, - { name: "创建时间", value: "createTime" }, - { name: "接收人", value: "receiverPepUser" }, - { name: "推送方式", value: "pushType" }, - { name: "监听问题模块", value: "alarmType" }, - { name: "生效项目节点", value: "timeType" }, - { name: "推送机制", value: "tactics" }, - { name: "启用状态", value: "disable" }, - { name: "推送次数", value: "pushCount" }, - ] - }, - ]; - const alarmTypeObj = { - data_outages: '数据中断', - data_exception: '数据异常', - strategy_hit: '策略命中', - video_exception: '视频异常', - app_exception: '应用异常', - device_exception: '设备异常', - } - const tacticsObj = { - immediately: '即时推送机制', - continue: '持续时长推送机制', - abnormal_rate: '异常率推送机制', + + + + useEffect(() => { + if (projectPoms?.length) { + let dataList = projectPoms?.filter(v => v.pepProjectIsDelete != 1 && (!pepProjectId || (pepProjectId?.length > 0 ? pepProjectId?.split(',')?.map(s => Number(s.id))?.includes(v.id) : pepProjectId))) + setProjectList(dataList) + getData({ limit: 10, page: 0 }) + setQuery({ limit: 10, page: 0 }) + } + }, [projectPoms, pepProjectId, projectSearch]) + + + + const getData = (data = {}) => { + dispatch(service.getAutomaticReport({ projectId: pepProjectId, ...query, keyword, ...data })).then((res) => { + if (res.success) { + setTableData(res.payload.data?.rows) + setLimits(res.payload.data?.count) + } + }) } + const columns = [{ + title: "序号", + dataIndex: "index", + key: 'index', + render: (txet, row, index) => index + 1 + }, { + title: "报表名称", + dataIndex: "reportName", + key: 'reportName', + }, { + title: "所属项目", + dataIndex: "projectId", + key: 'projectId', + render: (_, row) => { + let project = projectPoms?.find(s => s.id == row?.projectId) + return project?.name || project?.pepProjectName || '--' + } + }, { + title: "报表类型", + dataIndex: "reportType", + key: 'reportType', + }, { + title: "最近生产时间", + dataIndex: "time", + key: 'time', + render: (txet, row) => txet && moment(txet).format('YYYY-MM-DD HH:mm:ss') || '--' + }, { + title: "操作", + dataIndex: "text", + key: 'text', + render: (_, row) => { + return ( +
+ + { + dispatch(service.delAutomaticReport(row.id)).then((res) => { + if (res.success) { + setQuery({ limit: 10, page: 0 }) + getData({ limit: 10, page: 0, keyword: keyword }) + } + }) + }} + > + + + +
+ ); + }, + }, + ] function handleRow (record, index) {//斑马条纹 // 给偶数行设置斑马纹 @@ -77,684 +126,105 @@ const AutomaticReport = (props) => { return {}; } } - const [tableData, setTableData] = useState([]) //表格数据 - - useEffect(() => { - localStorage.getItem(EMPUSH) == null - ? localStorage.setItem( - EMPUSH, - JSON.stringify(['projectName', 'name', 'createTime', 'receiverPepUser', 'alarmType', 'timeType', 'tactics', 'disable']) - ) - : ""; - getProjectStatusList() - getPushList(query); - //数据异常异常类型子类 - dispatch(problem.getAlarmDataGroup({ showAll: 'true' })).then((res) => { - if (res.success) { - let data = { ...subTypeData } - res.payload.data?.map(v => { - if (v.id === 1) { - data['data_outages'].push(v.unit) - } else if (v.id === 2) { - data['data_exception'].push(v.unit) - } else if (v.id == 3) { - data['strategy_hit'].push(v.unit) - } else { - data['device_exception'].push(v.unit) - } - }) - //视频异常异常类型子类 - dispatch(problem.getAlarmVideoDeviceKind({ showAll: true })).then((res) => { - if (res.success) { - data['video_exception'].push(res.payload.data) - } - }) - data['app_exception'].push([{ id: 'apiError', name: "接口报错", }, { id: 'element', name: "元素异常", }, { id: 'timeout', name: "加载超时", },]) - setSubTypedata(data) - } - }) - }, []) - - useEffect(() => { - let showTableData = JSON.parse(JSON.stringify(allTableData)).slice(query.page * query.limit, (query.page + 1) * query.limit) - setTableData(showTableData) - mylimits.current = showTableData.length - }, [change]); - function getPushList (query) { - let val = form.current.getValues() - dispatch(service.getPush({ ...val })).then((res) => {//获取已绑定项目 - if (res.success) { - let mytableData = JSON.parse(JSON.stringify(res.payload.data)); - for (let index = 0; index < mytableData.length; index++) { - mytableData[index].key = String(mytableData[index].id) - } - setAllTableData(mytableData) - let showTableData = mytableData.slice(query.page * query.limit, (query.page + 1) * query.limit) - setTableData(showTableData) - setQuery(query) - setLimits(res.payload.data.length) - mylimits.current = showTableData.length - } - }) - } - function getProjectStatusList () {//获取项目状态列表 - dispatch(service.getProjectStatus()).then((res) => { - if (res.success) { - setProjectStatus(res.payload?.data) - attribute(res.payload?.data); - } - }) - } - const columns = [//表格属性 - { - title: "操作", - width: "12%", - dataIndex: "text", - key: 'text', - render: (_, row) => { - return ( -
- - {row?.disable ? ( - - ) : ( - { - dispatch(service.putPushPushId({ pushId: row?.id, del: false, disable: true, msg: '更改推送配置状态' })).then(() => { - getPushList({ limit: query.limit, page: page.current }); - }) - }} - > - - - )} - { - dispatch(service.putPushPushId({ pushId: row?.id, del: true, disable: false, msg: '删除推送配置' })).then(() => { - if (page.current > 0 && mylimits.current < 2) { - getPushList({ limit: query.limit, page: page.current - 1 }); - } else { - getPushList({ limit: query.limit, page: page.current }); - } - }) - }} - > - - + return ( + <> +
+
+
+
自动化报表
+
AUTOMATIC REPORT
+
+
+ +
+ { + setKeyword(e) + }} /> +
- ); - }, - }, - ] - function expandRowRender (record, index) { - return ( -
- 结构物: - { - record.structure?.map((item, index) => { - return ( - - {item.name} - - ) - }) - } -
- ) - } - //获取表格属性设置 - function attribute (val) { - const arr = localStorage.getItem(EMPUSH) - ? JSON.parse(localStorage.getItem(EMPUSH)) - : []; - const column = [ - { - title: '关联项目', - dataIndex: "projectName", - key: "projectName", - render: (_, row) => { - let projectData = [] - row.pomsProject?.map(v => { - projectData.push({ - projectName: v.pepProject?.projectName, - name: v.name, - anxinerror: v.del, - constructionStatus: v.pepProject?.constructionStatus, - }) - }) - let anxinerror = false - let anxinerrorArr = '' - if (row.pomsProject.del == true) { - anxinerror = true - anxinerrorArr = row.pomsProject.pepProject?.projectName || row.pomsProject.name - } - return ( - projectData.map((u, index) =>
- { - u.anxinerror ? ( - -
- -
-
) : ('') - } - { -
- -
7 || u.name?.length > 7 ? '112px' : '', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', color: row.pomsProject.del ? '#F93920' : '' }}> - {u.projectName || u.name} -
-
-
- } - { - u.projectName ? ( -
-
- -
-
- {u.constructionStatus} -
-
- ) : ( -
-
- -
-
- POMS -
-
- ) - } -
) - ) - } - }, - { - title: '策略名称', - dataIndex: "name", - key: 'name', - render: (_, row) => { - return row.name - } - }, - { - title: "创建时间", - dataIndex: "createTime", - key: "createTime", - render: (_, r, index) => { - return moment(r.createTime).format('YYYY-MM-DD HH:mm:ss'); - }, - }, - { - title: '接收人', - dataIndex: "receiverPepUser", - key: 'receiverPepUser', - render: (_, row) => { - return ( -
- { - row.receiverPepUser.map((item, index) => { - return ( -
-
1 ? 'none' : '', color: '#005ABD' }}> - {item.name} -
-
0 ? 'none' : '' }}>
-
- ) - }) - } - { - row.receiverPepUser.length > 2 ? ( - - { - row.receiverPepUser.map((item, index) => { - return ( -
- {item.name}, -
- ) - }) - } -
- } trigger="click" style={{ lineHeight: 2 }}> -
- +{row.receiverPepUser.length - 2} -
- - ) : ('') - } -
- ) - } - }, - { - title: "推送方式", - dataIndex: "pushType", - key: "pushType", - render: (_, r, index) => { - return '邮件通知'; - }, - }, - { - title: "监听问题模块", - dataIndex: "alarmType", - key: "alarmType", - render: (_, row) => { - return ( -
- { - row.alarmType.map((item, index) => { - return ( -
-
1 ? 'none' : '' }}> - {alarmTypeObj[item]} -
-
0 ? 'none' : '' }}>
-
- ) - }) - } - { - row.alarmType.length > 2 ? ( - - { - row.alarmType.map((item, index) => { - return ( -
- {alarmTypeObj[item]}, -
- ) - }) - } -
- } trigger="click" style={{ lineHeight: 2 }}> -
- +{row.alarmType.length - 2} -
- - ) : ('') - } -
- ) - } - }, - { - title: "生效项目节点", - dataIndex: "timeType", - key: "timeType", - render: (_, row, index) => { - return ( -
- { - row.timeType.length > 0 ? ( - row.timeType.map((item, index) => { - return ( -
1 ? 'none' : 'flex', alignItems: 'center' - }}> -
- -
-
- { - val.map((ite, idx) => { - return ( -
- {ite.id == item ? ite.construction_status : ''} -
- ) - }) - } -
-
- ) - }) - ) : ( -
-
- -
-
- POMS -
-
- ) - } - { - row.timeType.length > 2 ? ( - - { - row.timeType.map((item, index) => { - return ( -
- { - val.map((ite, idx) => { - return ( - - {ite.id == item ? ite.construction_status : ''} - - ) - }) - }, -
- ) - }) - } -
- } trigger="click" style={{ lineHeight: 2 }}> -
- +{row.timeType.length - 2} -
- - ) : ('') - } -
- ) - }, - }, - { - title: "推送机制", - dataIndex: "tactics", - key: "tactics", - render: (_, r, index) => { - return tacticsObj[r.tactics] - }, - }, - { - title: "启用状态", - dataIndex: "disable", - key: "disable", - render: (_, row, index) => { - let enableType = '' - if (row.disable) { - enableType = '禁用' - } else { - let construcId = row.pomsProject?.map(v => (v.pepProject?.constructionStatusId || 'POMS')) || [] - if (construcId?.includes('POMS')) { - enableType = '已生效' - } else { - let timeType = row.timeType?.map(Number) || [] - for (let i = 0; i < timeType.length; i++) { - if (construcId?.includes(timeType[i])) { - enableType = '已生效' - break - } else { - enableType = '未生效' - } - } - } +
- } - return ( -
- {enableType} -
- ) - }, - }, - { - title: "推送次数", - dataIndex: "pushCount", - key: "pushCount", - render: (_, r, index) => { - return (r.pushCount || 0) + '次' - }, - }, - ]; - for (let i = 0; i < arr.length; i++) { - let colum = column.filter((item) => { - return item.key === arr[i]; - }); - columns.splice(columns.length - 1, 0, colum[0]); - } - setSetupp(columns); - } - return ( - <> -
-
-
-
-
EM推送
-
Em push
+ + + + {limits > 0 &&
+
-
-
console.log(values)} - getFormApi={(formApi) => (form.current = formApi)} - layout="horizontal" - style={{ position: "relative", width: "100%", flex: 1 }} - > - - 项目 - 结构物 - 策略名 - - } - field="keyword" - pure - showClear - style={{ width: 260, marginLeft: 12, marginRight: 12 }} - placeholder="请输入或选择关键词" - /> - - 即时推送机制 - 持续时长推送机制 - 异常率推送机制 - - - 已生效 - 未生效 - 禁用 - - - -
- setSetup(true)} /> -
- -
-
-
-
EM推送提供对映射关系组的项目、结构物问题的监听和通知服务,支持对设备异常率、问题持续时间、即时响应等策略定义的动态推送。
-
-
- -
s)} - dataSource={tableData} - bordered={false} - hideExpandedColumn={false} - empty="暂无数据" - expandedRowRender={expandRowRender} - pagination={false} - onRow={handleRow} /> - -
-
-
-
- - 共{limits}条信息 - - { - setQuery({ limit: pageSize, page: currentPage - 1 }); - page.current = currentPage - 1 - setChange(!change) - }} - /> -
- + } {//推送配置弹框 - pushModal ? - { - setPushModal(false); - }} + projectList={projectList} + eidtData={eidtData} close={() => { - setPushModal(false); - getPushList(query) - }} > - : '' + setAutomaticModall(false); + setEidtData({}) + }} + success={() => { + setQuery({ limit: 10, page: 0 }) + getData({ limit: 10, page: 0, keyword: keyword }) + }} + /> : '' } - {setup ? ( - { - setSetup(false); - attribute(projectStatus); - }} - /> - ) : ( - "" - )} ) } function mapStateToProps (state) { - const { auth, global, getPush } = state; + const { auth, global, automaticReport, ProjectPoms } = state; return { - loading: getPush.isRequesting, + loading: automaticReport.isRequesting, user: auth.user, actions: global.actions, - // members: members.data, + pepProjectId: global.pepProjectId, + clientHeight: global?.clientHeight, + projectPoms: ProjectPoms?.data?.rows }; } diff --git a/web/client/src/sections/service/containers/reportFile.jsx b/web/client/src/sections/service/containers/reportFile.jsx index 50c4e18..0bb8594 100644 --- a/web/client/src/sections/service/containers/reportFile.jsx +++ b/web/client/src/sections/service/containers/reportFile.jsx @@ -1,86 +1,66 @@ import React, { useEffect, useRef, useState } from 'react'; import { connect } from 'react-redux'; -import { Skeleton, Button, Pagination, Form, Popconfirm, Table, Tooltip } from '@douyinfe/semi-ui'; +import { Skeleton, Button, Pagination, Form, Popconfirm, Table, Tooltip, Input } from '@douyinfe/semi-ui'; import { IconSearch } from '@douyinfe/semi-icons'; import { SkeletonScreen, } from "$components"; import moment from "moment"; -import PushModal from '../components/pushModal' +import FileModal from '../components/fileModal' import SimpleBar from 'simplebar-react'; -import '../style.less' -import { Setup } from "$components"; -const AutomaticReport = ({ dispatch, actions, user, clientHeight, loading, socket, projectPoms }) => { - const form = useRef();//表单 - const { service, problem } = actions; - const [setup, setSetup] = useState(false); //表格设置是否显现 + +const ReportFile = ({ dispatch, actions, user, clientHeight, loading, socket, qiniuUrl, projectPoms, pepProjectId }) => { + + const { service, } = actions; const [query, setQuery] = useState({ limit: 10, page: 0 }); //页码信息 - const [limits, setLimits] = useState()//每页实际条数 + const [limits, setLimits] = useState()//总数 const mylimits = useRef(); //每页实际条数 - const [pushModal, setPushModal] = useState(false) //信鸽弹框 - const [pushEdit, setPushEdit] = useState(false) //是否是修改 + const [fileModal, setFileModal] = useState(false) //信鸽弹框 const [change, setChange] = useState(false) //是否改变 - const [editObj, setEditObj] = useState({});//管理员弹框修改内容 - const [projectStatus, setProjectStatus] = useState([]); //获取项目状态列表 const [tableData, setTableData] = useState([]) //表格数据 const [projectList, setProjectList] = useState([]) //项目数据 const [projectId, setProjectId] = useState() //项目id const [projectSearch, setProjectSearch] = useState() //项目搜索 - - const [subTypeData, setSubTypedata] = useState({ - data_outages: [], - data_exception: [], - strategy_hit: [], - video_exception: [], - app_exception: [], - device_exception: [], - }); //数据类监听模块中的子类 const page = useRef(query.page);//哪一页 - const EMPUSH = "empush"; - const tableList = [//表格属性 - { - title: '推送信息', - list: [ - { name: "关联项目", value: "projectName" }, - { name: "策略名称", value: "name" }, - { name: "创建时间", value: "createTime" }, - { name: "接收人", value: "receiverPepUser" }, - { name: "推送方式", value: "pushType" }, - { name: "监听问题模块", value: "alarmType" }, - { name: "生效项目节点", value: "timeType" }, - { name: "推送机制", value: "tactics" }, - { name: "启用状态", value: "disable" }, - { name: "推送次数", value: "pushCount" }, - ] - }, - ]; + useEffect(() => { if (projectPoms?.length) { - let dataList = projectPoms?.filter(v => v.pepProjectIsDelete != 1) + let dataList = projectPoms?.filter(v => (!projectSearch || (v.name || v.pepProjectName).indexOf(projectSearch) != -1) && v.pepProjectIsDelete != 1 && (!pepProjectId || (pepProjectId?.length > 0 ? pepProjectId?.split(',')?.map(s => Number(s.id))?.includes(v.id) : pepProjectId))) setProjectId(dataList[0]?.id) setProjectList(dataList) - } - }, [projectPoms]) + getData({ projectId: dataList[0]?.id, limit: 10, page: 0 }) + setQuery({ limit: 10, page: 0 }) + } + }, [projectPoms, pepProjectId, projectSearch]) + const getData = (data = {}) => { + dispatch(service.getReportFile({ projectId: projectId, ...query, ...data })).then((res) => { + if (res.success) { + setTableData(res.payload.data?.rows) + setLimits(res.payload.data?.count) + } + }) + } const columns = [{ title: "文件名称", - dataIndex: "name", - key: 'name', + dataIndex: "fileName", + key: 'fileName', }, { title: "报表类型", - dataIndex: "type", - key: 'type', + dataIndex: "reportType", + key: 'reportType', }, { title: "最近生产时间", - dataIndex: "time", - key: 'time', + dataIndex: "startTime", + key: 'tistartTimeme', + render: (txet, row) => txet && moment(txet).format('YYYY-MM-DD HH:mm:ss') || '--' }, { title: "操作", dataIndex: "text", @@ -88,27 +68,23 @@ const AutomaticReport = ({ dispatch, actions, user, clientHeight, loading, socke render: (_, row) => { return ( - +
-
+
setProjectSearch(v)} /> - {/* */} - + {projectList?.map(v => { - return
{ - setPepProjectId(v.pepProjectId) - fileList(v.pepProjectId) - setDataSource([]) - setFileId('') + setProjectId(v.id) + setQuery({ limit: 10, page: 0 }) + getData({ projectId: v.id, limit: 10, page: 0 }) }}> -
{v.pepProjectName}
+
{v.name || v.pepProjectName}
})} - {/*
*/}
@@ -213,8 +184,7 @@ const AutomaticReport = ({ dispatch, actions, user, clientHeight, loading, socke pageSizeOpts={[10, 20, 30, 40]} onChange={(currentPage, pageSize) => { setQuery({ limit: pageSize, page: currentPage - 1 }); - page.current = currentPage - 1 - setChange(!change) + getData({ limit: pageSize, page: currentPage - 1 }) }} />
@@ -225,47 +195,34 @@ const AutomaticReport = ({ dispatch, actions, user, clientHeight, loading, socke
{//推送配置弹框 - pushModal ? - { - setPushModal(false); - }} + projectList={projectList} close={() => { - setPushModal(false); - getPushList(query) - }} > - : '' + setFileModal(false); + }} + success={() => { + setQuery({ limit: 10, page: 0 }) + getData({ limit: 10, page: 0 }) + }} + /> : '' } - {setup ? ( - { - setSetup(false); - attribute(projectStatus); - }} - /> - ) : ( - "" - )} ) } function mapStateToProps (state) { - const { auth, global, getPush, ProjectPoms } = state; - console.log(global); + const { auth, global, reportFile, ProjectPoms } = state; return { - loading: getPush.isRequesting, + loading: reportFile.isRequesting, user: auth.user, actions: global.actions, + qiniuUrl: global.qiniu?.domain, + pepProjectId: global.pepProjectId, clientHeight: global?.clientHeight, projectPoms: ProjectPoms?.data?.rows }; } -export default connect(mapStateToProps)(AutomaticReport); +export default connect(mapStateToProps)(ReportFile); diff --git a/web/client/src/sections/service/nav-item.jsx b/web/client/src/sections/service/nav-item.jsx index 9811751..e722b51 100644 --- a/web/client/src/sections/service/nav-item.jsx +++ b/web/client/src/sections/service/nav-item.jsx @@ -17,11 +17,11 @@ export function getNavItem (user, dispatch) { items: [{ itemKey: 'reportManagement', to: '/service/reportingServices/reportManagement', text: '报表管理' } - // , { - // itemKey: 'automaticReport', to: '/service/reportingServices/automaticReport', text: '自动化报表' - // }, { - // itemKey: 'reportFile', to: '/service/reportingServices/reportFile', text: '报表文件' - // } + , { + itemKey: 'automaticReport', to: '/service/reportingServices/automaticReport', text: '自动化报表' + }, { + itemKey: 'reportFile', to: '/service/reportingServices/reportFile', text: '报表文件' + } ] }, { itemKey: 'maintenancePlan', diff --git a/web/client/src/utils/webapi.js b/web/client/src/utils/webapi.js index 8ba6bef..10f7534 100644 --- a/web/client/src/utils/webapi.js +++ b/web/client/src/utils/webapi.js @@ -77,6 +77,13 @@ export const ApiTable = { getProjectStatus: "project/status", //获取项目状态列表 putPushPushId: "push/{pushId}", //更改推送配置状态(禁用或删除) + // 报表服务 + reportFile: "report/file", //报表上传 + delReportFile: "report/file/{id}",//报表删除 + factorList: "factor/list", //获取监测因素数据 + automaticReport: "automatic/report", //自动化报表 + delAutomaticReport: "automatic/report/{id}", //删除报表规则 + //控制台 consoleToollink: 'console/toollink', //常用工具 deleteConsoleToollink: 'console/toollink/{linkId}', //删除常用工具 @@ -93,7 +100,7 @@ export const ApiTable = { getStatisticOnline: 'statisticOnline', //查询在线率 getStrucSeries: 'strucSeries', //查询连续率 - + //资料库 addEditFile: 'file/addEdit', //添加、编辑文件夹 fileList: 'file/list', //获取问文件夹列表