Browse Source

报表优化

dev
wenlele 1 year ago
parent
commit
a56b9390b5
  1. 45
      api/app/lib/controllers/service/report.js
  2. 5
      api/app/lib/routes/service/report.js
  3. 5
      api/config.js
  4. 13
      web/client/src/sections/service/actions/report.js
  5. 27
      web/client/src/sections/service/components/automatic-Modal.jsx
  6. 31
      web/client/src/sections/service/containers/automaticReport.jsx
  7. 1
      web/client/src/utils/webapi.js

45
api/app/lib/controllers/service/report.js

@ -107,12 +107,13 @@ async function getFactorList (ctx) {
const factorId = factor.map(a => a.id)
const sensor = factorId.length ? await clickHouse.anxinyun.query(`
const sensor = factorId.length && anxinStrucIds.length ? await clickHouse.anxinyun.query(`
SELECT
id,name,factor
id,name,factor,structure
FROM t_sensor
WHERE
t_sensor.factor IN (${factorId.join(',')}, -1)
AND t_sensor.structure IN (${anxinStrucIds.join(',')}, -1)
`).toPromise() : []
@ -134,7 +135,7 @@ async function getFactorList (ctx) {
anxinStruc.forEach(s => {
s.factor = factor.filter(d => {
if (d.structure == s.strucId) {
d.sensor = sensor.filter(f => f.factor == d.id)
d.sensor = sensor.filter(f => f.factor == d.id && f.structure == s.strucId)
return true
} else {
return false
@ -167,7 +168,8 @@ async function postAutomaticReport (ctx) {
await models.ReportAutomatic.update(data, {
where: {
id: data.id
}})
}
})
} else {
await models.ReportAutomatic.create(data)
}
@ -239,6 +241,38 @@ async function delAutomaticReport (ctx) {
}
async function postGenerateReport (ctx) {
try {
const { models } = ctx.fs.dc;
const data = ctx.request.body
let res = await ctx.app.fs.reportGenerate.post('gen', {
data: data
})
if (res.code == 200) {
await models.ReportFile.create({
fileName: data.reportName,
projectId: data.projectId,
url: res.outLink,
startTime: moment().format('YYYY-MM-DD HH:mm:ss'),
reportType: data.reportType
})
ctx.status = 200;
ctx.body = res.outLink
} 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 = {
@ -248,5 +282,6 @@ module.exports = {
getFactorList,
postAutomaticReport,
getAutomaticReport,
delAutomaticReport
delAutomaticReport,
postGenerateReport
};

5
api/app/lib/routes/service/report.js

@ -24,9 +24,8 @@ module.exports = function (app, router, opts) {
app.fs.api.logAttr['DEL/automatic/report/:id'] = { content: '删除报表规则', visible: true };
router.del('/automatic/report/:id', report.delAutomaticReport);
app.fs.api.logAttr['POST/generate/report'] = { content: '生成报表', visible: true };
router.post('/generate/report', report.postGenerateReport);
// app.fs.api.logAttr['GET/respond-record'] = { content: '获取响应记录数据', visible: true };
// router.get('/respond-record', record.respondRecord);
};

5
api/config.js

@ -90,6 +90,8 @@ const AP_MERGE_DEVE_ANXINPROJECT_ID = process.env.AP_MERGE_DEVE_ANXINPROJECT_ID
const API_ANXINYUN_URL = process.env.API_ANXINYUN_URL || flags.axyApiUrl;
// 企业管理 api
const API_EMIS_URL = process.env.API_EMIS_URL || flags.apiEmisUrl;
//报表生成 api
const API_REPOR_GENERATE_URL = process.env.API_REPOR_GENERATE_URL || 'http://222.186.227.196:30567';
// 视频平台 api
const API_VCMP_URL = process.env.API_VCMP_URL || flags.apiVcmpUrl;
// iot鉴权平台 api
@ -281,6 +283,9 @@ const product = {
}, {
name: 'emisRequest',
root: API_EMIS_URL
}, {
name: 'reportGenerate',
root: API_REPOR_GENERATE_URL
}, {
name: 'vcmpRequest',
root: API_VCMP_URL

13
web/client/src/sections/service/actions/report.js

@ -57,7 +57,7 @@ export function getFactorList (query = {}) { //获取报表文件
});
}
export function postAutomaticReport (data = {}) { //上传文件
export function postAutomaticReport (data = {}) {
return dispatch => basicAction({
type: 'post',
data,
@ -97,7 +97,16 @@ export function delAutomaticReport (id) {//删除报表文件
});
}
export function postGenerateReport (data = {}) { //生成报表
return dispatch => basicAction({
type: 'post',
data,
dispatch: dispatch,
actionType: 'POST_GENERATE_REPORT',
url: `${ApiTable.generateReport}`,
msg: { option: "生成报表" },
});
}

27
web/client/src/sections/service/components/automatic-Modal.jsx

@ -16,6 +16,7 @@ const AutomaticModal = ({ actions, dispatch, apiRoot, qiniuUrl, visible, eidtDat
const [factorId, setFactorId] = useState([]); //id
const [factorList, setFactorList] = useState([]); //
const [factorChech, setFactorChech] = useState([]); //
const [activeKey, setActiveKey] = useState([]); //
useEffect(async () => {
@ -28,6 +29,7 @@ const AutomaticModal = ({ actions, dispatch, apiRoot, qiniuUrl, visible, eidtDat
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)))
setActiveKey(eidtData?.factors?.map(s => s.codeName) || [])
}
}, [])
@ -50,8 +52,8 @@ const AutomaticModal = ({ actions, dispatch, apiRoot, qiniuUrl, visible, eidtDat
cancelText="取消"
visible={visible}
onOk={() => {
form.current.validate().then((v) => {
console.log(v);
let data = {
id: eidtData?.id,
reportName: v.reportName,
@ -100,8 +102,8 @@ const AutomaticModal = ({ actions, dispatch, apiRoot, qiniuUrl, visible, eidtDat
})
}
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) == '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')
@ -109,12 +111,13 @@ const AutomaticModal = ({ actions, dispatch, apiRoot, qiniuUrl, visible, eidtDat
}
}
}
factorData.glStaName = factorData?.tempName?.find(s => s.index == 1)?.name
factorData.tempStaName = factorData?.tempName?.find(s => s.index == 2)?.name || factorData?.tempName?.find(s => s.index == 1)?.name
data.factors?.push(factorData)
})
console.log(111, data);
dispatch(service.postAutomaticReport(data)).then((res) => {
console.log(res);
if (res.success) {
close()
success()
@ -215,6 +218,7 @@ const AutomaticModal = ({ actions, dispatch, apiRoot, qiniuUrl, visible, eidtDat
rules={[{ required: true, message: "请选择监测因素" }]} disabled={structId ? false : true}
onChange={v => {
setFactorChech(factorList?.filter(s => v.includes(s.proto)))
setActiveKey(v)
}} >
{factorList?.map((item) => {
return <Form.Select.Option value={item.proto} label={item.name}></Form.Select.Option>
@ -222,16 +226,23 @@ const AutomaticModal = ({ actions, dispatch, apiRoot, qiniuUrl, visible, eidtDat
</Form.Select>
{factorChech?.length > 0 ? <Collapse style={{ margin: '20px 0 20px 30px', width: '90%', background: '#b7c9e624' }}>
{factorChech?.length > 0 ? <Collapse style={{ margin: '20px 0 20px 30px', width: '90%', background: '#b7c9e624' }}
activeKey={activeKey}
onChange={v => {
// setActiveKey(v)
}}
>
{
factorChech?.map(s => {
return <Collapse.Panel header={s.name} itemKey={s.proto}>
<div style={{ background: "#FFF" }}>
<Form.TextArea field={s.proto + "pointDescrip"} label='布点描述' style={{ width: 400 }} autosize={{ minRows: 2, maxRows: 10 }} placeholder="请输入布点描述" showClear
initValue={eidtData?.factors?.find(c => c.codeName == s.proto)?.pointDescrip || ""}
rules={[{ required: true, message: "请输入布点描述" }]}
/>
<Form.Upload label="布点图片" field={s.proto + "pointPicPath"} style={{ display: 'inline-block', }}
initValue={eidtData?.factors?.find(c => 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}
rules={[{ required: true, message: "请删上传布点图片" }]}
action={`${apiRoot}/attachments/p`}
accept={'.png, .jpg, .jpeg'}
limit={1} maxSize={5120}
@ -249,6 +260,7 @@ const AutomaticModal = ({ actions, dispatch, apiRoot, qiniuUrl, visible, eidtDat
<Form.Select label="测点选择" field={s.proto + "sensorNames"} multiple={true} placeholder="请选择测点选择" style={{ width: 300 }} filter
initValue={eidtData?.factors?.find(c => c.codeName == s.proto)?.sensorNames?.map(a => a.id) || []}
rules={[{ required: true, message: "请选择测点选择" }]}
>
{s.sensor?.map((item) => {
return <Form.Select.Option value={item.id} label={item.name}></Form.Select.Option>
@ -256,6 +268,7 @@ const AutomaticModal = ({ actions, dispatch, apiRoot, qiniuUrl, visible, eidtDat
</Form.Select>
<Form.DatePicker field={s.proto + 'startEndTime'} label='开始结束时间' type='dateTimeRange' showClear style={{ width: 360 }}
initValue={eidtData?.factors?.find(c => 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}
rules={[{ required: true, message: "请选择开始结束时间" }]}
/>
{
['2001', '4004', '4007', '4008'].includes(s.proto) &&
@ -280,12 +293,12 @@ const AutomaticModal = ({ actions, dispatch, apiRoot, qiniuUrl, visible, eidtDat
})}
</Form.Select>
<Form.Input field={s.proto + "glStaName"} label='关联温度的测点名称' style={{ width: 300 }} placeholder="请输入关联温度的测点名称" showClear
{/* <Form.Input field={s.proto + "glStaName"} label='' style={{ width: 300 }} placeholder="" showClear
initValue={eidtData?.factors?.find(c => c.codeName == s.proto)?.glStaName || ""}
/>
<Form.Input field={s.proto + "tempStaName"} label='关联温度名称' style={{ width: 300 }} placeholder="请输入关联温度名称" showClear
initValue={eidtData?.factors?.find(c => c.codeName == s.proto)?.tempStaName || ""}
/>
/> */}
<Form.DatePicker field={s.proto + 'releTime'} label='关联开始结束时间' type='dateTimeRange' showClear style={{ width: 360 }}
initValue={eidtData?.factors?.find(c => 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}
/>

31
web/client/src/sections/service/containers/automaticReport.jsx

@ -104,7 +104,38 @@ const AutomaticReport = ({ dispatch, actions, user, clientHeight, loading, socke
<Button theme="borderless" type='danger'>删除</Button>
</Popconfirm>
<Button theme="borderless" onClick={() => {
// 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
let dataList = {
1002: 'WSDJC',
1001: 'FSFXJC',
4009: 'SSFJC',
2001: 'SLJC',
3001: 'YBJC',
4004: 'NDJC',
5002: 'ZDJC',
4001: 'ZZWYJC',
4002: 'QTPWJC',
4008: 'LFJC',
4007: 'QDQXJC',
1004: 'JGWDJC'
}
row?.factors?.forEach(d => {
d.codeName = dataList[d.codeName]
})
dispatch(service.postGenerateReport(row))
}}>
立即生成
</Button>

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

@ -83,6 +83,7 @@ export const ApiTable = {
factorList: "factor/list", //获取监测因素数据
automaticReport: "automatic/report", //自动化报表
delAutomaticReport: "automatic/report/{id}", //删除报表规则
generateReport: "generate/report", //报表生成
//控制台
consoleToollink: 'console/toollink', //常用工具

Loading…
Cancel
Save