zhaobing’
1 year ago
15 changed files with 916 additions and 47 deletions
@ -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 |
||||
|
} |
@ -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; |
||||
|
}; |
@ -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) |
||||
|
|
||||
|
} |
@ -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.网络系统/'; |
||||
|
|
||||
|
|
@ -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; |
||||
|
|
@ -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 } |
||||
|
} |
||||
|
}); |
||||
|
} |
@ -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) |
Loading…
Reference in new issue