Browse Source

feat:巡检1.4版本代码

master
zhaobing’ 1 year ago
parent
commit
ca1fe2c099
  1. 2
      api/app/lib/controllers/patrolManage/patrolReport.js
  2. 119
      api/app/lib/controllers/reportConfiguration/index.js
  3. 4
      api/app/lib/index.js
  4. 89
      api/app/lib/models/report_configuration.js
  5. 15
      api/app/lib/models/report_info.js
  6. 19
      api/app/lib/routes/reportConfiguration/index.js
  7. 10
      api/config.js
  8. 51
      script/1.4/schema/1.create_report_configuration.sql
  9. 10
      script/1.4/schema/2.update_report_info.sql
  10. 3
      web/client/src/components/Uploads/index.js
  11. 5
      web/client/src/sections/patrolManage/actions/index.js
  12. 55
      web/client/src/sections/patrolManage/actions/reportConf.js
  13. 276
      web/client/src/sections/patrolManage/components/addReportRulesModal.js
  14. 298
      web/client/src/sections/patrolManage/containers/patrolReport.js
  15. 7
      web/client/src/utils/webapi.js

2
api/app/lib/controllers/patrolManage/patrolReport.js

@ -20,7 +20,7 @@ async function getPatrolReport(ctx, next) {
options.where.projectId = projectId; options.where.projectId = projectId;
} }
if (startTime && endTime) { if (startTime && endTime) {
options.where.inspectTm = { $between: [startTime, endTime] }; options.where.inspectTm = { $between: [startTime, endTime] }
} }
const res = await models.ReportInfo.findAndCountAll(options); const res = await models.ReportInfo.findAndCountAll(options);
ctx.status = 200; ctx.status = 200;

119
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
}

4
api/app/lib/index.js

@ -6,7 +6,7 @@ const utils = require('./utils')
const routes = require('./routes'); const routes = require('./routes');
//const redisConnect = require('./service/redis') //const redisConnect = require('./service/redis')
const socketConect = require('./service/socket') const socketConect = require('./service/socket')
//const paasRequest = require('./service/paasRequest'); const paasRequest = require('./service/paasRequest');
const authenticator = require('./middlewares/authenticator'); const authenticator = require('./middlewares/authenticator');
//const clickHouseClient = require('./service/clickHouseClient') //const clickHouseClient = require('./service/clickHouseClient')
const schedule = require('./schedule') const schedule = require('./schedule')
@ -26,7 +26,7 @@ module.exports.entry = function (app, router, opts) {
socketConect(app, opts) socketConect(app, opts)
// 实例其他平台请求方法 // 实例其他平台请求方法
//paasRequest(app, opts) paasRequest(app, opts)
// clickHouse 数据库 client // clickHouse 数据库 client
//clickHouseClient(app, opts) //clickHouseClient(app, opts)

89
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;
};

15
api/app/lib/models/report_info.js

@ -16,7 +16,7 @@ module.exports = dc => {
}, },
projectId: { projectId: {
type: DataTypes.INTEGER, type: DataTypes.INTEGER,
allowNull: false, allowNull: true,
defaultValue: null, defaultValue: null,
comment: null, comment: null,
primaryKey: false, primaryKey: false,
@ -34,7 +34,7 @@ module.exports = dc => {
}, },
inspectTm: { inspectTm: {
type: DataTypes.DATE, type: DataTypes.DATE,
allowNull: false, allowNull: true,
defaultValue: null, defaultValue: null,
comment: null, comment: null,
primaryKey: false, primaryKey: false,
@ -49,7 +49,16 @@ module.exports = dc => {
primaryKey: false, primaryKey: false,
field: "report_tm", field: "report_tm",
autoIncrement: false autoIncrement: false
} },
structure: {
type: DataTypes.ARRAY(DataTypes.INTEGER),
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "structureIds",
autoIncrement: false
},
}, { }, {
tableName: "report_info", tableName: "report_info",
comment: "", comment: "",

19
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)
}

10
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_DOMAIN = process.env.WX_DOMAIN || flags.wxDomain;
const WX_APP_ID = process.env.WX_APP_ID || flags.wxAppId; const WX_APP_ID = process.env.WX_APP_ID || flags.wxAppId;
const WX_APP_SECRET = process.env.WX_APP_SECRET || flags.wxAppSecret; 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) { if (!XUNJIAN_DB || !QINIU_DOMAIN_QNDMN_RESOURCE || !QINIU_BUCKET_RESOURCE || !QINIU_AK || !QINIU_SK || !WX_DOMAIN || !WX_APP_ID || !WX_APP_SECRET) {
console.log('缺少启动参数,异常退出'); console.log('缺少启动参数,异常退出');
@ -89,6 +90,13 @@ const product = {
accessKey: 'LTAI5tAFdjz7j38aNF2C9Qe8', accessKey: 'LTAI5tAFdjz7j38aNF2C9Qe8',
accessSecret: '1trYkmiqfBtvZL6BxkNH2uQcQQPs0S' accessSecret: '1trYkmiqfBtvZL6BxkNH2uQcQQPs0S'
}, },
pssaRequest:[ { name: 'reportGenerate',
root: API_REPOR_GENERATE_URL,
dataWord: 'text'
}
],
email: { email: {
enabled: true, enabled: true,
host: 'smtp.exmail.qq.com', host: 'smtp.exmail.qq.com',

51
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.网络系统/';

10
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;

3
web/client/src/components/Uploads/index.js

@ -23,7 +23,7 @@ class Uploads extends Component {
} }
dealName = (uploaded) => { dealName = (uploaded) => {
let realName = uploaded.split('/')[2] let realName = uploaded?.split('/')[2]
// let x1 = realName.split('.') // let x1 = realName.split('.')
// let postfix = x1.pop() // let postfix = x1.pop()
// let allName = x1.join('.') // let allName = x1.join('.')
@ -51,6 +51,7 @@ class Uploads extends Component {
// }; // };
setFileList = (nextEditData, isQiniu, isAli) => { setFileList = (nextEditData, isQiniu, isAli) => {
console.log('nextEditData',nextEditData)
let defaultFileList = []; let defaultFileList = [];
defaultFileList = nextEditData.map((u, index) => { defaultFileList = nextEditData.map((u, index) => {
let fileUrl = let fileUrl =

5
web/client/src/sections/patrolManage/actions/index.js

@ -6,12 +6,13 @@ import * as report from './report'
import * as template from './template' import * as template from './template'
import * as checkItems from './checkItems' import * as checkItems from './checkItems'
import * as yujingguanli from './yujingguanli' import * as yujingguanli from './yujingguanli'
import * as reportConf from './reportConf'
export default { export default {
...plan, ...plan,
...record, ...record,
...report, ...report,
...template, ...template,
...checkItems, ...checkItems,
...yujingguanli ...yujingguanli,
...reportConf
} }

55
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 }
}
});
}

276
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 (
<>
<Modal
destroyOnClose
title={modalData ? '编辑报表规则' : '新建报表规则'}
visible={visible}
onCancel={() => {
cancelHandle()
setIsShow(false)
setType(0)
form.setFieldsValue({
structure: null,
pic: null,
name: null,
type: null,
timeRange: null,
})
// form.resetFields()
}}
onOk={okHandler}>
<Form
form={form}
labelCol={{
span: 5,
}}
initialValues={
{
// structure:modalData?.structure,
// pic:modalData?.reportpic,
// name:modalData?.name,
// type:modalData?.type,
// timeRange:[moment(modalData?.startTime),moment(modalData?.endTime)]
}
}>
<Form.Item label='报表名称' name='name' rules={[{ required: true, message: '请输入报表名称' }]}>
<Input />
</Form.Item>
<Form.Item label='报表类型' name='type' rules={[{ required: true, message: '请选择报表类型' }]}>
<Select onChange={typeChange}>
{typeList?.map(g => {
return (
<Option key={g.value} value={g.value} label={g.label}>
<div
style={{
display: 'flex',
justifyContent: 'space-between',
}}>
{g.label}
</div>
</Option>
)
})}
</Select>
</Form.Item>
{type===2?
<Form.Item label='系统' name='system' rules={[{ required: true, message: '请选择系统' }]}>
<Select onChange={systemChange} >
{systemList?.map(g => {
return (
<Option key={g.value} value={g.value} label={g.label}>
<div
style={{
display: 'flex',
justifyContent: 'space-between',
}}>
{g.label}
</div>
</Option>
)
})}
</Select>
</Form.Item>:''}
<Form.Item label='关联结构物' name='structure' rules={[{ required: true, message: '请选择结构物' }]}>
<Select mode={type === 2 ? 'multiple' : undefined}>
{structlist?.map(g => {
return (
<Option key={g.value} value={g.value} label={g.label}>
<div
style={{
display: 'flex',
justifyContent: 'space-between',
}}>
{g.label}
</div>
</Option>
)
})}
</Select>
</Form.Item>
<Form.Item label='生成时间' name='timeRange' rules={[{ required: true, message: '请选择时间' }]}>
<RangePicker onChange={timeChane} />
</Form.Item>
<Form.Item label='发现问题上传:' name='pic' rules={[{ required: true, message: '请选择图片' }]}>
<Uploads
listType='picture-card'
uploadType='project'
maxFilesNum={4}
maxFileSize={10}
isQiniu={true}
// disabled={true}
fileTypes={['png', 'jpg']}
// fileList={pic}
defaultValue={(() => {
let nextV = []
for (let s of modalData?.reportpic || []) {
if (s) {
nextV.push({
storageUrl: s,
})
}
}
return nextV
})()}
/>
</Form.Item>
</Form>
</Modal>
</>
)
}
function mapStateToProps(state) {
const { auth, global } = state
return {
user: auth.user,
actions: global.actions,
}
}
export default connect(mapStateToProps)(AddReportRulesModal)

298
web/client/src/sections/patrolManage/containers/patrolReport.js

@ -1,31 +1,90 @@
import React, { useState, useRef, useEffect } from 'react'; import React, { useState, useRef, useEffect } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { Button } from 'antd'; import { Button, Tabs, Popconfirm, Tooltip } from 'antd';
import ProTable from '@ant-design/pro-table'; import ProTable from '@ant-design/pro-table';
import { getPatrolReport } from '../actions/report'; import { getPatrolReport } from '../actions/report';
import { getProjectList } from '../actions/plan'; import { getProjectList } from '../actions/plan';
import moment from 'moment'; import moment from 'moment';
import AddReportRulesModal from '../components/addReportRulesModal';
function patrolReport(props) { function patrolReport(props) {
const { dispatch } = props; const { dispatch, actions } = props;
const { projectRegime, patrolManage } = actions
const tableRef = useRef(); const tableRef = useRef();
const tableRef2 = useRef();
const [selectOpts, setSelectOpts] = useState([]); const [selectOpts, setSelectOpts] = useState([]);
const [date, setDate] = useState([moment().subtract(1, 'days'), moment()]); const [date, setDate] = useState([moment().subtract(1, 'days'), moment()]);
const [dataSource, setDataSource] = useState([]); const [dataSource, setDataSource] = useState([]);
const [modalVis, setModalVis] = useState(false)
const [structAll,setStructAll]=useState([])//完整的结构物列表(包括subType)
const [reportList, setReportList] = useState([])//报表
const qnDomain = localStorage.getItem('qnDomain'); const qnDomain = localStorage.getItem('qnDomain');
const [query, setQuery] = useState({ limit: 10, page: 0 })
useEffect(() => { const [typeList, setTypeList] = useState([{ value: 1, label: '周报表' }, { value: 2, label: '月报表' }])
dispatch(getProjectList()).then(res => { const [modalData, setModalData] = useState(null)
//报表配置
// const getReportConfig = (query) => {
// const { limit, page, name } = query
// dispatch(patrolManage.getReportList({ limit, page, name })).then(res => {
// if (res.success) {
// //过滤管廊类型的数据
// const list = res.payload.data?.rows
// setReportList(list)
// }
// })
// }
//结构物
const projectList = () => {
dispatch(projectRegime.getProjectList()).then(res => {
if (res.success) { if (res.success) {
const nextSelectOpts = res.payload?.data?.rows.map(d => { const nextSelectOpts = res.payload?.data?.rows.map(d => {
return { label: d.name, value: d.id } return { label: d.name, value: d.id }
}) })
setStructAll(res.payload?.data?.rows)
setSelectOpts(nextSelectOpts) setSelectOpts(nextSelectOpts)
// setStructlist(list)
} }
}); })
}
useEffect(() => {
// dispatch(getProjectList()).then(res => {
// if (res.success) {
// }
// });
projectList()
// getReportConfig(query)
}, []) }, [])
const edithandler = (e) => {
setModalData(e)
setModalVis(true)
}
const onOk = () => {
tableRef2.current.reload();
}
const confirmHandler = (id) => {
dispatch(patrolManage.delReport(id)).then(res => {
if (res.success) {
// getReportConfig(query)
tableRef2.current.reload();
}
})
}
const generateReport=(record)=>{
let data={
reportName:record?.name,
startTime:moment(record?.startTime).format('YYYY-MM-DD HH:mm:ss'),
endTime:moment(record?.endTime).format('YYYY-MM-DD HH:mm:ss'),
structIds:record?.structure,
structNames:structAll?.filter(item=>record?.structure.some(q=>q==item.id))?.map(o=>o.name)||[],
reportType:record?.type,
system:record?.system,
images:record?.reportpic.map(item=>qnDomain+'/'+item)||[]
}
dispatch(patrolManage.postGenerateReport(data)).then(res => {
})
}
const columns = [{ const columns = [{
title: '结构物名称', title: '结构物名称',
dataIndex: 'projectName', dataIndex: 'projectName',
@ -38,7 +97,19 @@ function patrolReport(props) {
}, },
ellipsis: true, ellipsis: true,
width: 150, width: 150,
render: (_, record) => <div>{record?.project?.name || '--'}</div> render: (_, record) =>
{
const rslt=structAll?.filter(p => record.structure?.some(q => q == p.id))
return <>
<div>{record?.project?.name || record.structure.length > 1 ? <Tooltip title={rslt?.map(item => item.name)?.join(',')}>
<span>{rslt&&rslt.length?rslt[0].name+'...':''}</span>
</Tooltip> : rslt?.map(item => item.name)?.join(',')
}</div>
</>
}
}, { }, {
title: '巡检报告名称', title: '巡检报告名称',
dataIndex: 'groupName', dataIndex: 'groupName',
@ -79,47 +150,200 @@ function patrolReport(props) {
</> </>
}, },
}]; }];
const column2 = [
{
title: '报表名称',
dataIndex: 'name',
key: 'name',
ellipsis: true,
width: 250,
fieldProps: {
showSearch: true,
defaultValue: '',
},
},
{
title: '报表类型',
dataIndex: 'type',
key: 'type',
ellipsis: true,
search: false,
width: 250,
render: (_, record) => {
return <>
{typeList.find(item => record.type == item.value)?.label}
</>
}
},
{
title: '关联结构物',
dataIndex: 'structure',
key: 'structure',
ellipsis: true,
search: false,
width: 250,
render: (_, record) => {
const rslt=structAll?.filter(p => record.structure?.some(q => q == p.id))
return <>
{record.structure.length > 1 ? <Tooltip title={rslt?.map(item => item.name)?.join(',')}>
<span>{rslt&&rslt.length?rslt[0].name+'...':''}</span>
</Tooltip> : rslt?.map(item => item.name)?.join(',')}
</>
}
},
{
title: '生成时间范围',
key: 'timeRange',
// ellipsis: true,
search: false,
width: 250,
render: (_, record) => {
return <>
{moment(record.startTime).format('YYYY-MM-DD')} ~ {moment(record.endTime).format('YYYY-MM-DD')}
</>
}
},
{
title: '系统',
key: 'system',
// ellipsis: true,
search: false,
width: 250,
render: (_, record) => {
return <>
{record.system?record.system===1?'动力系统':record.system===2?'网络系统':'--':'--'}
</>
}
},
{
title: '操作',
key: 'option',
// ellipsis: true,
search: false,
width: 250,
render: (_, record) => {
return <>
<Button type="primary" style={{ marginRight: 10 }} onClick={() => { edithandler(record) }}>编辑</Button>
<Popconfirm title="确定删除报表吗"
description="确定删除报表吗?"
onConfirm={() => { confirmHandler(record?.id) }}
><Button type="primary" style={{ marginRight: 10 }} danger>删除</Button></Popconfirm>
<Button type="primary" onClick={()=>{generateReport(record)}}>立即生成</Button>
</>
}
}
]
const onChange = (key) => {
};
const cancelHandle = () => {
setModalVis(false)
setModalData(null)
}
return ( return (
<> <>
<ProTable <Tabs
columns={columns} defaultActiveKey="1"
actionRef={tableRef} onChange={onChange}
options={false} items={[
dataSource={dataSource || []} {
rowKey='id' label: `报表列表`,
pagination={{ pageSize: 10, size: 'default', className: 'global-pagination' }} key: '1',
request={async (params = {}) => { children: <ProTable
const res = await dispatch(getPatrolReport({ columns={columns}
limit: params?.pageSize, actionRef={tableRef}
page: params?.current - 1, options={false}
projectId: params?.projectName, dataSource={dataSource || []}
startTime: date ? date[0].format('YYYY-MM-DD') + ' 00:00:00' : '', rowKey='id'
endTime: date ? date[1].format('YYYY-MM-DD') + ' 23:59:59' : '', pagination={{ pageSize: 10, size: 'default', className: 'global-pagination' }}
})); request={async (params = {}) => {
setDataSource(res?.payload.data?.rows); const res = await dispatch(getPatrolReport({
return { limit: params?.pageSize,
...res, page: params?.current - 1,
total: res.payload.data.count ? res.payload.data.count : 0, projectId: params?.projectName,
}; startTime: date ? date[0].format('YYYY-MM-DD') + ' 00:00:00' : '',
}} endTime: date ? date[1].format('YYYY-MM-DD') + ' 23:59:59' : '',
onReset={() => { setDate([moment().subtract(1, 'days'), moment()]) }} }));
rowClassName={(record, index) => { setDataSource(res?.payload.data?.rows);
let className = 'global-light-row'; return {
if (index % 2 === 1) className = 'global-dark-row'; ...res,
return className; total: res.payload.data.count ? res.payload.data.count : 0,
}} };
}}
onReset={() => { setDate([moment().subtract(1, 'days'), moment()]) }}
rowClassName={(record, index) => {
let className = 'global-light-row';
if (index % 2 === 1) className = 'global-dark-row';
return className;
}}
/>,
},
{
label: `报表配置`,
key: '2',
children: <>
<ProTable
actionRef={tableRef2}
options={false}
columns={column2}
dataSource={reportList || []}
pagination={{ pageSize: 10, size: 'default', className: 'global-pagination' }}
request={async (query) => {
const { limit, page, name } = query
const res = await dispatch(patrolManage.getReportList({ limit, page, name }))
const list = res?.payload?.data?.rows
setReportList(list)
return {
...res,
total: res.payload.data.count ? res.payload.data.count : 0,
};
}}
// cardProps={{ title: '新建报表规则', bordered: true }}
headerTitle={
<Button
key="primary"
type="primary"
onClick={() => {
setModalVis(true)
}}
>
新建报表规则
</Button>
}
rowKey="key"
search={true}
/>
<AddReportRulesModal structAll={structAll} typeList={typeList} modalData={modalData} onOk={onOk} visible={modalVis} cancelHandle={cancelHandle}>
</AddReportRulesModal>
</>
,
},
]}
/> />
</> </>
) )
} }
function mapStateToProps(state) { function mapStateToProps(state) {
const { auth, structureList } = state const { auth, structureList, global } = state
return { return {
user: auth.user, user: auth.user,
struList: structureList.data || [], struList: structureList.data || [],
struLoading: structureList.isRequesting, struLoading: structureList.isRequesting,
actions: global.actions,
} }
} }
export default connect(mapStateToProps)(patrolReport); export default connect(mapStateToProps)(patrolReport);

7
web/client/src/utils/webapi.js

@ -144,6 +144,13 @@ export const ApiTable = {
getDeviceList: 'device', getDeviceList: 'device',
addDevice: 'device', addDevice: 'device',
modifyDevice: 'device/{id}', modifyDevice: 'device/{id}',
//报表配置相关
getReportList:'reportList',
postReport:'postReport',
delReport: "reportList/{id}", //删除报表规则
generateReport: "generate/report",//报表生成
}; };
export const RouteTable = { export const RouteTable = {

Loading…
Cancel
Save