forked from ddrilling/asb_cloud_front
308 lines
9.4 KiB
JavaScript
308 lines
9.4 KiB
JavaScript
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) => {
|
||
|
||
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) {
|
||
var link = document.createElement("a");
|
||
link.download = reportFileName;
|
||
link.href = e.target.result
|
||
link.click();
|
||
link.remove();
|
||
};
|
||
});
|
||
} 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>
|
||
</>
|
||
)
|
||
}
|