diff --git a/api/app/lib/controllers/patrolManage/patrolReport.js b/api/app/lib/controllers/patrolManage/patrolReport.js
index acf6bb0..be46f6b 100644
--- a/api/app/lib/controllers/patrolManage/patrolReport.js
+++ b/api/app/lib/controllers/patrolManage/patrolReport.js
@@ -20,7 +20,7 @@ async function getPatrolReport(ctx, next) {
options.where.projectId = projectId;
}
if (startTime && endTime) {
- options.where.inspectTm = { $between: [startTime, endTime] };
+ options.where.inspectTm = { $between: [startTime, endTime] }
}
const res = await models.ReportInfo.findAndCountAll(options);
ctx.status = 200;
diff --git a/api/app/lib/controllers/reportConfiguration/index.js b/api/app/lib/controllers/reportConfiguration/index.js
new file mode 100644
index 0000000..efbfb58
--- /dev/null
+++ b/api/app/lib/controllers/reportConfiguration/index.js
@@ -0,0 +1,119 @@
+'use strict';
+const request = require('superagent');
+const fs = require('fs');
+const path = require('path')
+const moment = require('moment');
+
+async function reportList(ctx, next) {
+ try {
+ const models = ctx.fs.dc.models
+ const { limit, page, name } = ctx.query
+ let options = {
+ where: {
+
+ },
+ }
+ if (limit) {
+ options.limit = Number(limit)
+ }
+ if (page && limit) {
+ options.offset = Number(page) * Number(limit)
+ }
+ if (name) {
+ options.where.name = { $like: `%${name}%` }
+ }
+ const res = await models.ReportConfiguration.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": "获取报表列表失败"
+ }
+ }
+}
+
+async function postReport (ctx) {
+ try {
+ const { models } = ctx.fs.dc;
+ const data = ctx.request.body
+
+ if (data.id) {
+ await models.ReportConfiguration.update(data, {
+ where: {
+ id: data.id
+ }
+ })
+ } else {
+ await models.ReportConfiguration.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 delReport (ctx) {
+ try {
+ const { models } = ctx.fs.dc;
+ const { id } = ctx.params
+ await models.ReportConfiguration.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 postGenerateReport (ctx) {
+ try {
+ const { models } = ctx.fs.dc;
+ const data = ctx.request.body
+
+ let res = await ctx.app.fs.reportGenerate.post('creatReport', {
+ data: data
+ })
+ if (res.includes('xjGLReport')) {
+ await models.ReportInfo.create({
+ excelPath: res,
+ reportTm: moment().format('YYYY-MM-DD HH:mm:ss'),
+ structure:data.structIds,
+ inspectTm:moment().format('YYYY-MM-DD HH:mm:ss')
+ })
+ ctx.status = 200;
+ ctx.body = res
+ } else {
+ throw '生成报表失败'
+ }
+
+ } catch (error) {
+ ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
+ ctx.status = 400;
+ ctx.body = {
+ message: typeof error == 'string' ? error : undefined
+ }
+ }
+}
+
+
+
+ module.exports = {
+ reportList,
+ postReport,
+ delReport,
+ postGenerateReport
+ }
diff --git a/api/app/lib/index.js b/api/app/lib/index.js
index 7d02a88..3f1d05c 100644
--- a/api/app/lib/index.js
+++ b/api/app/lib/index.js
@@ -6,7 +6,7 @@ const utils = require('./utils')
const routes = require('./routes');
//const redisConnect = require('./service/redis')
const socketConect = require('./service/socket')
-//const paasRequest = require('./service/paasRequest');
+const paasRequest = require('./service/paasRequest');
const authenticator = require('./middlewares/authenticator');
//const clickHouseClient = require('./service/clickHouseClient')
const schedule = require('./schedule')
@@ -26,7 +26,7 @@ module.exports.entry = function (app, router, opts) {
socketConect(app, opts)
// 实例其他平台请求方法
- //paasRequest(app, opts)
+ paasRequest(app, opts)
// clickHouse 数据库 client
//clickHouseClient(app, opts)
diff --git a/api/app/lib/models/report_configuration.js b/api/app/lib/models/report_configuration.js
new file mode 100644
index 0000000..fb91f3d
--- /dev/null
+++ b/api/app/lib/models/report_configuration.js
@@ -0,0 +1,89 @@
+/* eslint-disable*/
+'use strict';
+
+module.exports = dc => {
+ const DataTypes = dc.ORM;
+ const sequelize = dc.orm;
+ const ReportConfiguration = sequelize.define("report_configuration", {
+ id: {
+ type: DataTypes.INTEGER,
+ allowNull: false,
+ defaultValue: null,
+ comment: null,
+ primaryKey: true,
+ field: "id",
+ autoIncrement: true,
+ unique: "report_configuration_pk"
+ },
+ name: {
+ type: DataTypes.STRING,
+ allowNull: false,
+ defaultValue: null,
+ comment: null,
+ primaryKey: false,
+ field: "name",
+ autoIncrement: false
+ },
+ type: {
+ type: DataTypes.INTEGER,
+ allowNull: false,
+ defaultValue: null,
+ comment: null,
+ primaryKey: false,
+ field: "type",
+ autoIncrement: false
+ },
+ structure: {
+ type: DataTypes.ARRAY(DataTypes.INTEGER),
+ allowNull: false,
+ defaultValue: null,
+ comment: null,
+ primaryKey: false,
+ field: "structure",
+ autoIncrement: false
+ },
+ startTime: {
+ type: DataTypes.STRING,
+ allowNull: false,
+ defaultValue: null,
+ comment: null,
+ primaryKey: false,
+ field: "start_time",
+ autoIncrement: false
+ },
+ endTime: {
+ type: DataTypes.STRING,
+ allowNull: false,
+ defaultValue: null,
+ comment: null,
+ primaryKey: false,
+ field: "end_time",
+ autoIncrement: false
+ },
+ reportpic: {
+ type: DataTypes.ARRAY(DataTypes.STRING),
+ allowNull: false,
+ defaultValue: null,
+ comment: null,
+ primaryKey: false,
+ field: "reportpic",
+ autoIncrement: false
+ },
+ system: {
+ type: DataTypes.INTEGER,
+ allowNull: true,
+ defaultValue: null,
+ comment: '1.动力系统,2.网络系统',
+ primaryKey: false,
+ field: "system",
+ autoIncrement: false
+ },
+
+ }, {
+ tableName: "report_configuration",
+ comment: "",
+ indexes: []
+ });
+ dc.models.ReportConfiguration = ReportConfiguration;
+ return ReportConfiguration;
+};
\ No newline at end of file
diff --git a/api/app/lib/models/report_info.js b/api/app/lib/models/report_info.js
index d4ffbe8..130afe9 100644
--- a/api/app/lib/models/report_info.js
+++ b/api/app/lib/models/report_info.js
@@ -16,7 +16,7 @@ module.exports = dc => {
},
projectId: {
type: DataTypes.INTEGER,
- allowNull: false,
+ allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
@@ -34,7 +34,7 @@ module.exports = dc => {
},
inspectTm: {
type: DataTypes.DATE,
- allowNull: false,
+ allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
@@ -49,7 +49,16 @@ module.exports = dc => {
primaryKey: false,
field: "report_tm",
autoIncrement: false
- }
+ },
+ structure: {
+ type: DataTypes.ARRAY(DataTypes.INTEGER),
+ allowNull: true,
+ defaultValue: null,
+ comment: null,
+ primaryKey: false,
+ field: "structureIds",
+ autoIncrement: false
+ },
}, {
tableName: "report_info",
comment: "",
diff --git a/api/app/lib/routes/reportConfiguration/index.js b/api/app/lib/routes/reportConfiguration/index.js
new file mode 100644
index 0000000..079267d
--- /dev/null
+++ b/api/app/lib/routes/reportConfiguration/index.js
@@ -0,0 +1,19 @@
+'use strict';
+
+const reportConfiguration = require('../../controllers/reportConfiguration');
+
+module.exports = function (app, router, opts) {
+
+ app.fs.api.logAttr['GET/reportList'] = { content: '获取报表配置列表', visible: false };
+ router.get('/reportList', reportConfiguration.reportList);
+
+ app.fs.api.logAttr['POST/postReport'] = { content: '编辑或者新增报表配置', visible: false };
+ router.post('/postReport', reportConfiguration.postReport);
+
+ app.fs.api.logAttr['DELETE/reportList/:id'] = { content: '删除报表配置', visible: false };
+ router.delete('/reportList/:id', reportConfiguration.delReport);
+
+ app.fs.api.logAttr['POST/generate/report'] = { content: '生成报表', visible: true };
+ router.post('/generate/report', reportConfiguration.postGenerateReport)
+
+}
\ No newline at end of file
diff --git a/api/config.js b/api/config.js
index 3aa9876..2f0c38f 100644
--- a/api/config.js
+++ b/api/config.js
@@ -36,7 +36,8 @@ const QINIU_SK = process.env.ANXINCLOUD_QINIU_SECRETKEY || flags.qnsk;
const WX_DOMAIN = process.env.WX_DOMAIN || flags.wxDomain;
const WX_APP_ID = process.env.WX_APP_ID || flags.wxAppId;
const WX_APP_SECRET = process.env.WX_APP_SECRET || flags.wxAppSecret;
-
+//报表
+const API_REPOR_GENERATE_URL = process.env.API_REPOR_GENERATE_URL || 'http://10.8.30.95:31825'
if (!XUNJIAN_DB || !QINIU_DOMAIN_QNDMN_RESOURCE || !QINIU_BUCKET_RESOURCE || !QINIU_AK || !QINIU_SK || !WX_DOMAIN || !WX_APP_ID || !WX_APP_SECRET) {
console.log('缺少启动参数,异常退出');
@@ -89,6 +90,13 @@ const product = {
accessKey: 'LTAI5tAFdjz7j38aNF2C9Qe8',
accessSecret: '1trYkmiqfBtvZL6BxkNH2uQcQQPs0S'
},
+ pssaRequest:[ { name: 'reportGenerate',
+ root: API_REPOR_GENERATE_URL,
+ dataWord: 'text'
+
+ }
+ ],
+
email: {
enabled: true,
host: 'smtp.exmail.qq.com',
diff --git a/script/1.4/schema/1.create_report_configuration.sql b/script/1.4/schema/1.create_report_configuration.sql
new file mode 100644
index 0000000..5822303
--- /dev/null
+++ b/script/1.4/schema/1.create_report_configuration.sql
@@ -0,0 +1,51 @@
+CREATE TABLE IF NOT EXISTS report_configuration
+(
+ id serial
+ constraint "report_configuration_pk"
+ primary key,
+ name varchar(300),
+ type integer,
+ structure integer[],
+ start_time timestamp with time zone,
+ end_time timestamp with time zone,
+ reportPic text[]
+);
+
+
+comment on column report_configuration.name is '报表名字';
+
+comment on column report_configuration.type is '1 周报,2月报';
+
+comment on column report_configuration.structure is '结构物id';
+
+comment on column report_configuration.start_time is '生成时间起';
+
+comment on column report_configuration.end_time is '生成时间止';
+
+comment on column report_configuration.reportpic is '上传的图片地址';
+
+
+
+alter table report_configuration
+ alter column name set not null;
+
+alter table report_configuration
+ alter column type set not null;
+
+alter table report_configuration
+ alter column structure set not null;
+
+alter table report_configuration
+ alter column start_time set not null;
+
+alter table report_configuration
+ alter column end_time set not null;
+
+alter table report_configuration
+ alter column reportpic set not null;
+
+alter table report_configuration
+ add system integer;
+comment on column public.report_configuration.system is '系统,/1.动力系统,2.网络系统/';
+
+
diff --git a/script/1.4/schema/2.update_report_info.sql b/script/1.4/schema/2.update_report_info.sql
new file mode 100644
index 0000000..4d95b69
--- /dev/null
+++ b/script/1.4/schema/2.update_report_info.sql
@@ -0,0 +1,10 @@
+alter table report_info
+ add "structureIds" integer[];
+
+comment on column report_info."structureIds" is '报表配置新增的结构物,为了存放多结构物';
+
+
+
+alter table report_info
+ alter column project_id drop not null;
+
diff --git a/web/client/src/components/Uploads/index.js b/web/client/src/components/Uploads/index.js
index 8725880..349e221 100644
--- a/web/client/src/components/Uploads/index.js
+++ b/web/client/src/components/Uploads/index.js
@@ -23,7 +23,7 @@ class Uploads extends Component {
}
dealName = (uploaded) => {
- let realName = uploaded.split('/')[2]
+ let realName = uploaded?.split('/')[2]
// let x1 = realName.split('.')
// let postfix = x1.pop()
// let allName = x1.join('.')
@@ -51,6 +51,7 @@ class Uploads extends Component {
// };
setFileList = (nextEditData, isQiniu, isAli) => {
+ console.log('nextEditData',nextEditData)
let defaultFileList = [];
defaultFileList = nextEditData.map((u, index) => {
let fileUrl =
diff --git a/web/client/src/sections/patrolManage/actions/index.js b/web/client/src/sections/patrolManage/actions/index.js
index 690f08c..ad8a1be 100644
--- a/web/client/src/sections/patrolManage/actions/index.js
+++ b/web/client/src/sections/patrolManage/actions/index.js
@@ -6,12 +6,13 @@ import * as report from './report'
import * as template from './template'
import * as checkItems from './checkItems'
import * as yujingguanli from './yujingguanli'
-
+import * as reportConf from './reportConf'
export default {
...plan,
...record,
...report,
...template,
...checkItems,
- ...yujingguanli
+ ...yujingguanli,
+ ...reportConf
}
\ No newline at end of file
diff --git a/web/client/src/sections/patrolManage/actions/reportConf.js b/web/client/src/sections/patrolManage/actions/reportConf.js
new file mode 100644
index 0000000..aed5f25
--- /dev/null
+++ b/web/client/src/sections/patrolManage/actions/reportConf.js
@@ -0,0 +1,55 @@
+'use strict';
+
+import { basicAction } from '@peace/utils'
+import { ApiTable } from '$utils'
+
+export function getReportList (query) {
+ return dispatch => basicAction({
+ type: 'get',
+ query,
+ dispatch: dispatch,
+ actionType: 'GET_REPORT_LIST',
+ url: ApiTable.getReportList,
+ msg: { error: '获取报表配置列表失败' },
+ });
+}
+
+
+export function postReport (data = {}) {
+ return dispatch => basicAction({
+ type: 'post',
+ data,
+ dispatch: dispatch,
+ actionType: 'POST_REPORT',
+ url: `${ApiTable.postReport}`,
+ msg: { option: data?.id ? '编辑报表生成规则' : "新增报表生成规则" },
+ });
+ }
+
+
+ export function delReport (id) {//删除报表文件
+ return dispatch => basicAction({
+ type: 'del',
+ dispatch: dispatch,
+ actionType: 'DEL_REPORT',
+ url: `${ApiTable.delReport.replace('{id}', id)}`,
+ msg: { option: '删除报表规则' },
+
+
+ });
+ }
+
+ export function postGenerateReport (data = {}) { //生成报表
+ return dispatch => basicAction({
+ type: 'post',
+ data,
+ dispatch: dispatch,
+ actionType: 'POST_GENERATE_REPORT',
+ url: `${ApiTable.generateReport}`,
+ msg: { option: "生成报表" },
+ reducer: {
+ name: "generateReport",
+ params: { noClear: true }
+ }
+ });
+}
\ No newline at end of file
diff --git a/web/client/src/sections/patrolManage/components/addReportRulesModal.js b/web/client/src/sections/patrolManage/components/addReportRulesModal.js
new file mode 100644
index 0000000..b86833a
--- /dev/null
+++ b/web/client/src/sections/patrolManage/components/addReportRulesModal.js
@@ -0,0 +1,276 @@
+import { Button, Form, Input, Modal, Select, DatePicker } from 'antd'
+import React, { useState, useEffect } from 'react'
+import { connect } from 'react-redux'
+import Uploads from '$components/Uploads'
+const { RangePicker } = DatePicker
+import moment from 'moment'
+
+const AddReportRulesModal = props => {
+ const [form] = Form.useForm()
+ const { user, visible, cancelHandle, actions, dispatch, onOk, modalData,typeList,structAll} = props
+ const [systemList, setSystemList] = useState([{ value: 1, label: '动力系统' },{ value: 2, label: '网络系统' }])
+ const { patrolManage } = actions
+ const [type, setType] = useState(0)
+ const [system,setSystem]=useState(0)//system
+ const [isShow, setIsShow] = useState(false)
+ const [structlist, setStructlist] = useState([])//结构物列表(只包括id和name)
+ // const [startTime,setStartTime]=useState('')
+ // const [endTime,setEndTime]=useState('')
+ useEffect(()=>{
+ if(modalData){
+ setType(modalData.type)
+ }
+ },[modalData])
+ const typeChange = e => {
+ setType(e)
+ form.setFieldValue('system', '')
+ form.setFieldValue('structure', undefined)
+ }
+ useEffect(()=>{
+ if(type){
+ if(type==1){
+ const list = structAll.filter(v => v.type === '管廊')?.map(k => {
+ return {
+ value: k.id,
+ label: k.name
+ }
+ })
+ setStructlist(list)
+ }
+ }
+ },[type])
+ useEffect(()=>{
+ //过滤管廊类型的数据
+ const list = structAll.filter(v => v.type === '管廊')?.map(k => {
+ return {
+ value: k.id,
+ label: k.name
+ }
+ })
+ setStructlist(list)
+ },[])
+ useEffect(() => {
+ // setPic(modalData?.reportpic)
+ form.setFieldsValue({
+ structure: null,
+ pic: null,
+ name: null,
+ type: null,
+ timeRange: null,
+ })
+ form.setFieldsValue({
+ structure: modalData?.structure,
+ pic: modalData?.reportpic,
+ name: modalData?.name,
+ type: modalData?.type,
+ system:modalData?.system,
+ timeRange: modalData?.startTime ? [moment(modalData?.startTime), moment(modalData?.endTime)] : [],
+ })
+ }, [visible])
+ const timeChane = e => {}
+ const okHandler = () => {
+ form
+ .validateFields()
+ .then(values => {
+ const params = {
+ id: modalData?.id,
+ name: values.name,
+ type: values.type,
+ system:values.system,
+ structure: Array.isArray(values.structure) ? [...values.structure] : [values.structure],
+ endTime: moment(values.timeRange[1]).format('YYYY-MM-DD HH:mm:ss'),
+ startTime: moment(values.timeRange[0]).format('YYYY-MM-DD HH:mm:ss'),
+ reportpic: values?.pic[0]?.name ? values?.pic.map(u => u.storageUrl) : modalData?.reportpic,
+ }
+ dispatch(patrolManage.postReport(params)).then(res => {
+ if (res.success) {
+ // form.resetFields()
+ cancelHandle()
+ onOk()
+ setType(null)
+ }
+ })
+ })
+ .catch(info => {
+ console.log('Validate Failed:', info)
+ })
+ }
+ //use
+ // const structChange=(e)=>{
+ // setStructObj(structAll.find(item=>item.id==e))
+ // }
+ // useEffect(()=>{
+ // if(strcutObj){
+ // if(strcutObj.subType.includes('供配电系统')||strcutObj.subType.includes('防雷')){
+ // setSystemList([{ value: 1, label: '动力系统' }])
+ // setIsShow(true)
+ // }else if(strcutObj.subType.includes('指挥中心')||strcutObj.subType.includes('安防'))
+ // setSystemList([{ value: 2, label: '网络系统' }])
+ // setIsShow(true)
+ // }
+
+ // },[strcutObj])
+
+ const systemChange=(e)=>{
+ setSystem(e)
+ // setType(null)
+ form.setFieldValue('structure', undefined)
+ if(e==1){
+ const list=structAll.filter(v => v.type === '管廊')?.filter(item=>item.subType.includes('供配电系统')||item.subType.includes('防雷'))
+ if(list&&list.length){
+ setStructlist( list?.map(item=>{
+ return {value: item.id,
+ label: item.name}
+ }))
+
+ }else{
+ setStructlist([])
+ }
+ }else if(e==2){
+ const list=structAll.filter(v => v.type === '管廊')?.filter(item=>item.subType.includes('指挥中心')||item.subType.includes('安防'))
+ if(list&&list.length){
+ setStructlist( list?.map(item=>{
+ return {value: item.id,
+ label: item.name}
+ }))
+
+ }else{
+ setStructlist([])
+ }
+ }
+
+
+
+ }
+
+
+ return (
+ <>
+