asb_cloud_front/src/pages/Report.jsx

308 lines
9.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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',
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 />
<button onClick={event => {getReportFile(event, progressData.reportName)}}
download={progressData.reportName}>
{ progressData.reportName }
</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 idUser = localStorage['userId'];
const taskId = await ReportService.createReport(wellId,
idUser, 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()
},[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()
},[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()
},[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>
</>
)
}