asb_cloud_front/src/pages/Report.jsx

304 lines
9.4 KiB
React
Raw Normal View History

import { useState, useEffect } from "react";
import { useParams } from 'react-router-dom';
import {
Form,
DatePicker,
Radio,
Button,
Select,
Table,
Progress,
notification
} from 'antd';
import 'moment/locale/ru';
import locale from 'antd/lib/locale/ru_RU';
import moment from "moment";
import {Subscribe} from '../services/signalr';
import notify from '../components/notify';
import LoaderPortal from '../components/LoaderPortal';
import { ReportService } from '../services/api';
const { RangePicker } = DatePicker;
const { Option } = Select;
let reportDatesRange = {
from: moment("0001-01-01T00:00:00"),
to: moment("9999-12-31T23:59:59.9999999")
}
const timePeriodNames = [
{label: '1 секунда', value: 1},
{label: '10 секунд', value: 10},
{label: '1 минута', value: 60},
{label: '5 минут', value: 300},
{label: '30 минут', value: 1800},
{label: '1 час', value: 3600},
{label: '6 часов', value: 21600},
{label: '12 часов', value: 43200},
{label: '1 день', value: 86400},
{label: '1 неделя', value: 604800}
]
const firstStep = timePeriodNames[2]["value"]
const imgPaths = {
'.pdf': '/images/pdf.png',
'.las': '/images/las.png'
}
// Экспорт рендера
export default function Report(props) {
const [rangeDate, setRangeDate] = useState([moment().subtract(1,'days'), moment()])
const [step, setStep] = useState(firstStep)
const [format, setFormat] = useState(0)
const [approxPages, setPagesCount] = useState(0)
const [suitableReports, setSuitableReports] = useState([])
const [loader, setLoader] = useState(false)
let wellId = useParams().id;
const periods = timePeriodNames.map((line) => <Option key={line.value} value={line.value}>{line.label}</Option>)
const columns = [
{
title: '',
dataIndex: 'reportFormat',
key: 'reportFormat',
render: format => <img src={imgPaths[format]} width="50" alt={format}></img>
},
{
title: 'Параметры отчета',
dataIndex: 'reportParams',
key: 'reportParams',
},
{
title: 'Название отчета',
dataIndex: 'reportName',
key: 'reportName',
2021-07-26 10:16:20 +05:00
render: name => <button onClick={event => getReportFile(event, name)} download={name}>{name}</button>
},
];
const ReportCreationNotify = ({progressData}) => {
progressData = progressData ?? {progress: 0.0, operation: 'Создание отчета', reportName: ''}
return (
<>
<Progress percent={ progressData.progress } />
<br />
<span> { progressData.operation } </span>
<br />
2021-07-26 10:16:20 +05:00
<button onClick={event => {getReportFile(event, progressData.reportName)}}
download={progressData.reportName}>
{ progressData.reportName }
2021-07-26 10:16:20 +05:00
</button>
</>
)
}
const getReportFile = async (event, reportFileName) => {
const element = event.target
if(!element.href.length) {
try {
await fetch(`/api/report/${wellId}/${reportFileName}`, {
headers: {
Authorization: 'Bearer ' + localStorage['token']
}
})
.then(async (response) => {
const blob = await response.blob();
let reader = new FileReader();
reader.readAsDataURL(blob);
reader.onload = function (e) {
element.href = e.target.result
element.click()
};
});
} catch (error) {
notify(`Не удалось скачать отчет по скважине (${wellId}) c
${rangeDate[0].format("DD.MM.YYYY hh:mm:ss")} по
${rangeDate[1].format("DD.MM.YYYY hh:mm:ss")}`, 'error')
console.log(error)
}
}
}
const handleReportCreation = async (values) => {
let begin = rangeDate[0].toISOString()
let end = rangeDate[1].toISOString()
try {
const taskId = await ReportService.createReport(wellId, values.step, values.format, begin, end)
if(!taskId)
return
const handleReportProgress = (progressData) => {
if(progressData) {
notification.open({
key: taskId,
message: 'Создание отчета:',
description: <ReportCreationNotify progressData={progressData}></ReportCreationNotify>,
duration: 0
});
if (progressData.reportName?.length)
unSubscribeReportHub()
}
}
const unSubscribeReportHub = Subscribe('hubs/reports', 'GetReportProgress', `Report_${taskId}`, handleReportProgress)
}
catch(error) {
notify(`Не удалось создать отчет по скважине (${wellId}) c
${rangeDate[0].format("DD.MM.YYYY hh:mm:ss")} по
${rangeDate[1].format("DD.MM.YYYY hh:mm:ss")}`, 'error')
console.log(error)
}
}
function disabledDate(current) {
return reportDatesRange.From >= current || reportDatesRange.To <= current;
}
useEffect(()=>{
async function getRepostSizeAsync() {
let begin = rangeDate[0].toISOString()
let end = rangeDate[1].toISOString()
try {
let approxPagesResponse = await ReportService.getReportSize(wellId, step, format, begin, end)
setPagesCount(approxPagesResponse)
} catch(error) {
notify(`Не удалось получить предварительный размер отчета c
${rangeDate[0].format("DD.MM.YYYY hh:mm:ss")} по
${rangeDate[1].format("DD.MM.YYYY hh:mm:ss")}`, 'error')
console.log(error)
} finally {
setLoader(false)
}
}
getRepostSizeAsync()
2021-07-19 16:19:01 +05:00
},[rangeDate, step, format, wellId])
useEffect(()=>{
async function getSuitableReportsAsync() {
let begin = rangeDate[0].toISOString()
let end = rangeDate[1].toISOString()
try {
setLoader(true)
let suitableReportsResponse = await ReportService.getSuitableReportsNames(wellId, step, format, begin, end)
let suitableReports = suitableReportsResponse.map(value => {
return {
key: value.id,
reportFormat: value.format,
reportParams: `Дата создания: ${new Date(value.date).toLocaleDateString()},
Данные от ${new Date(value.begin).toLocaleString()}
до ${new Date(value.end).toLocaleString()},
Шаг: ${timePeriodNames[value.step]}`,
reportName: value.name
}
})
setSuitableReports(suitableReports)
} catch(error) {
notify(`Не удалось получить подходящие по параметрам отчеты c
${rangeDate[0].format("DD.MM.YYYY hh:mm:ss")} по
${rangeDate[1].format("DD.MM.YYYY hh:mm:ss")}`, 'error')
console.log(error)
} finally {
setLoader(false)
}
}
getSuitableReportsAsync()
2021-07-19 16:19:01 +05:00
},[rangeDate, step, format, wellId])
useEffect(()=>{
async function getDatesRange() {
let response = await ReportService.getReportsDateRange(wellId)
reportDatesRange.from = moment(response.from)
reportDatesRange.to = moment(response.to)
}
getDatesRange()
2021-07-19 16:19:01 +05:00
},[wellId])
return (<>
<div className="w-100 mt-20px">
<Form
layout="vertical"
name="reportForm"
initialValues={{ remember: true }}
onFinish={handleReportCreation}
>
<div className={'d-flex'}>
<Form.Item
label="Диапазон дат отчета"
name="period"
initialValue = { [rangeDate[0], rangeDate[1]] }
>
<RangePicker
disabledDate={disabledDate}
allowClear={false}
onCalendarChange = { (dates, dateStrings, info) => {
setRangeDate([moment(dateStrings[0]), moment(dateStrings[1])])
}
}
locale={locale}
showTime
/>
</Form.Item>
<Form.Item
label="Шаг графиков"
name="step"
initialValue={step}
className="ml-30px"
>
<Select onChange={setStep}
>
{periods}
</Select>
</Form.Item>
<Form.Item
label="Формат отчета"
name="format"
initialValue = {format}
onChange={(e) => setFormat(e.target.value)}
className="ml-30px"
>
<Radio.Group>
<Radio.Button value={0}>PDF</Radio.Button>
<Radio.Button value={1}>LAS</Radio.Button>
</Radio.Group>
</Form.Item>
<Button
type="primary"
htmlType="submit"
className="mt-30px ml-30px">
<span>Получить рапорт</span>
<span className={'ml-5px'}>
({approxPages} стр.)
</span>
<span style={{display: approxPages > 100 ? 'inline' : 'none'}} className={'ml-5px'}>
!!!
</span>
</Button>
</div>
</Form>
</div>
<br/>
<h3>
Отчеты с аналогичными параметрами, доступные для скачивания:
</h3> <br/>
<LoaderPortal show={loader}>
<Table dataSource={suitableReports} columns={columns} />
</LoaderPortal>
</>
)
}