forked from ddrilling/asb_cloud_front
fix reports
This commit is contained in:
parent
f46d94f547
commit
bb73a17a77
@ -97,3 +97,20 @@ export const formatBytes = (bytes:number) => {
|
|||||||
else
|
else
|
||||||
return `${(bytes/1024/1024).toFixed(2)}Mb`
|
return `${(bytes/1024/1024).toFixed(2)}Mb`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const formatTimespan = (seconds:number) => {
|
||||||
|
const days = Math.floor(seconds / 86400)
|
||||||
|
seconds = seconds % 86400
|
||||||
|
const hours = Math.floor(seconds / 3600)
|
||||||
|
seconds = seconds % 3600
|
||||||
|
const minutes = Math.floor(seconds / 60)
|
||||||
|
seconds = seconds % 60
|
||||||
|
let formatedTimespan = ''
|
||||||
|
if(days > 0)
|
||||||
|
formatedTimespan += days + ' '
|
||||||
|
|
||||||
|
formatedTimespan += hours.toString().padStart(2,'0') + ':' +
|
||||||
|
minutes.toString().padStart(2,'0') + ':' +
|
||||||
|
seconds.toString().padStart(2,'0')
|
||||||
|
return formatedTimespan
|
||||||
|
}
|
@ -1,28 +1,34 @@
|
|||||||
import { Progress } from "antd"
|
import { Progress, Button } from "antd"
|
||||||
import { download, notify } from "../../components/factory"
|
import { download, notify } from "../../components/factory"
|
||||||
|
|
||||||
export const getReportFile = async (idWell, reportName) => {
|
export const getReportFile = async (fileInfo) => {
|
||||||
try {
|
try {
|
||||||
await download(`/api/well/${idWell}/report/${reportName}`, reportName)
|
await download(`/api/well/${fileInfo.idWell}/files/${fileInfo.id}`)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
notify(`Не удалось скачать отчет ${reportName} по скважине (${idWell})`, 'error')
|
notify(`Не удалось скачать отчет ${fileInfo.name} по скважине (${fileInfo.idWell})`, 'error')
|
||||||
console.log(error)
|
console.log(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ReportCreationNotify = ({idWell, progressData}) => {
|
export const ReportCreationNotify = ({progressData}) => {
|
||||||
progressData = progressData ?? {progress: 0.0, operation: 'Создание отчета', reportName: ''}
|
progressData = progressData ?? {progress: 0.0, operation: 'Создание отчета'}
|
||||||
|
|
||||||
|
let downloadButton = null
|
||||||
|
if (progressData.file)
|
||||||
|
downloadButton = <Button
|
||||||
|
type="link"
|
||||||
|
onClick={_ => {getReportFile(progressData.file)}}
|
||||||
|
download={progressData.file.name}>
|
||||||
|
{progressData.file.name}
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
const progressText = `${progressData.operation} стр ${progressData.currentPage} из ${progressData.totalPages}`
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Progress percent={ progressData.progress } />
|
<Progress percent={ progressData.progress } />
|
||||||
<br />
|
<br/>
|
||||||
<span> { progressData.operation } </span>
|
<span>{progressText}</span>
|
||||||
<br />
|
{downloadButton}
|
||||||
<button onClick={event => {getReportFile(idWell, progressData.reportName)}}
|
|
||||||
download={progressData.reportName}>
|
|
||||||
{ progressData.reportName }
|
|
||||||
</button>
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
91
src/pages/Report/Reports.jsx
Normal file
91
src/pages/Report/Reports.jsx
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
import { useState, useEffect } from "react"
|
||||||
|
import { Table, makeDateSorter, makeNumericSorter, formatDate} from "../../components/Table"
|
||||||
|
import { Button, Tooltip } from "antd"
|
||||||
|
import { FilePdfOutlined, FileTextOutlined} from '@ant-design/icons'
|
||||||
|
import { ReportService } from "../../services/api"
|
||||||
|
import { invokeWebApiWrapperAsync, download, formatTimespan} from "../../components/factory"
|
||||||
|
import LoaderPortal from "../../components/LoaderPortal"
|
||||||
|
import moment from "moment"
|
||||||
|
|
||||||
|
const imgPaths = {
|
||||||
|
".pdf": <FilePdfOutlined/>,
|
||||||
|
".las": <FileTextOutlined />,
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleFileDownload = async (idWell, idFile) => {
|
||||||
|
invokeWebApiWrapperAsync(
|
||||||
|
async () => {
|
||||||
|
await download(`/api/well/${idWell}/files/${idFile}`)
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
`Не удалось скачать файл ${idFile}`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
title: "Название",
|
||||||
|
dataIndex: "name",
|
||||||
|
key: "name",
|
||||||
|
render: (name, report) => (
|
||||||
|
<Button
|
||||||
|
type="link"
|
||||||
|
icon={imgPaths[report.format]}
|
||||||
|
onClick={(_) => handleFileDownload(report.idWell, report.id)}
|
||||||
|
download={name}
|
||||||
|
>
|
||||||
|
{name}
|
||||||
|
</Button>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: <Tooltip title="Дата формирования">Сформирован</Tooltip>,
|
||||||
|
dataIndex: "date",
|
||||||
|
key: "date",
|
||||||
|
sorter: makeDateSorter('date'),
|
||||||
|
render: date=>moment(date).format(formatDate),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: <Tooltip title="Дата начала периода рапорта">С</Tooltip>,
|
||||||
|
dataIndex: "begin",
|
||||||
|
key: "begin",
|
||||||
|
sorter: makeDateSorter('begin'),
|
||||||
|
render: date=>moment(date).format(formatDate),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: <Tooltip title="Дата окончания периода рапорта">По</Tooltip>,
|
||||||
|
dataIndex: "end",
|
||||||
|
key: "end",
|
||||||
|
sorter: makeDateSorter('end'),
|
||||||
|
render: date=>moment(date).format(formatDate),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: <Tooltip title="шаг сетки графиков">шаг, сек</Tooltip>,
|
||||||
|
dataIndex: "step",
|
||||||
|
key: "step",
|
||||||
|
|
||||||
|
sorter: makeNumericSorter('step'),
|
||||||
|
|
||||||
|
render: step => formatTimespan(step)
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
export const Reports = ({idWell}) => {
|
||||||
|
const [reports, setReports] = useState([])
|
||||||
|
const [showLoader, setShowLoader] = useState(false)
|
||||||
|
|
||||||
|
useEffect(()=>invokeWebApiWrapperAsync(async()=>{
|
||||||
|
const reportsResponse = await ReportService.getAllReportsNamesByWell(idWell)
|
||||||
|
const reports = reportsResponse.map(r => ({...r, key: r.id?? r.name?? r.date}))
|
||||||
|
setReports(reports)
|
||||||
|
},setShowLoader), [idWell])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<LoaderPortal show={showLoader}>
|
||||||
|
<Table
|
||||||
|
size='small' bordered
|
||||||
|
columns={columns}
|
||||||
|
dataSource={reports}
|
||||||
|
pagination={{pageSize:13}}/>
|
||||||
|
</LoaderPortal>)
|
||||||
|
}
|
@ -1,20 +1,13 @@
|
|||||||
import { useState, useEffect } from "react"
|
import { useState, useEffect } from "react"
|
||||||
import {
|
import { DatePicker, Radio, Button, Select, notification } from "antd"
|
||||||
Form,
|
|
||||||
DatePicker,
|
|
||||||
Radio,
|
|
||||||
Button,
|
|
||||||
Select,
|
|
||||||
Table,
|
|
||||||
notification,
|
|
||||||
} from "antd"
|
|
||||||
import "moment/locale/ru"
|
import "moment/locale/ru"
|
||||||
import moment from "moment"
|
import moment from "moment"
|
||||||
import { Subscribe } from "../../services/signalr"
|
import { Subscribe } from "../../services/signalr"
|
||||||
import LoaderPortal from "../../components/LoaderPortal"
|
import LoaderPortal from "../../components/LoaderPortal"
|
||||||
import { ReportService } from "../../services/api"
|
import { ReportService } from "../../services/api"
|
||||||
import { ReportCreationNotify, getReportFile } from "./ReportCreationNotify"
|
import { ReportCreationNotify } from "./ReportCreationNotify"
|
||||||
import { invokeWebApiWrapperAsync, notify} from "../../components/factory"
|
import { invokeWebApiWrapperAsync, notify } from "../../components/factory"
|
||||||
|
import { Reports } from "./Reports"
|
||||||
|
|
||||||
const { RangePicker } = DatePicker
|
const { RangePicker } = DatePicker
|
||||||
const { Option } = Select
|
const { Option } = Select
|
||||||
@ -32,20 +25,20 @@ const timePeriodNames = [
|
|||||||
{ label: "1 неделя", value: 604800 },
|
{ label: "1 неделя", value: 604800 },
|
||||||
]
|
]
|
||||||
|
|
||||||
const imgPaths = {
|
|
||||||
".pdf": "/images/pdf.png",
|
|
||||||
".las": "/images/las.png",
|
|
||||||
}
|
|
||||||
|
|
||||||
const dateTimeFormat = "DD.MM.YYYY hh:mm:ss"
|
const dateTimeFormat = "DD.MM.YYYY hh:mm:ss"
|
||||||
|
|
||||||
export default function Report({ idWell }) {
|
export default function Report({ idWell }) {
|
||||||
const [aviableDateRange, setAviableDateRange] = useState([moment(),moment()])
|
const [aviableDateRange, setAviableDateRange] = useState([
|
||||||
const [filterDateRange, setFilterDateRange] = useState([moment().subtract(1, "days"),moment(),])
|
moment(),
|
||||||
|
moment(),
|
||||||
|
])
|
||||||
|
const [filterDateRange, setFilterDateRange] = useState([
|
||||||
|
moment().subtract(1, "days").startOf("day"),
|
||||||
|
moment().startOf("day"),
|
||||||
|
])
|
||||||
const [step, setStep] = useState(timePeriodNames[2].value)
|
const [step, setStep] = useState(timePeriodNames[2].value)
|
||||||
const [format, setFormat] = useState(0)
|
const [format, setFormat] = useState(0)
|
||||||
const [pagesCount, setPagesCount] = useState(0)
|
const [pagesCount, setPagesCount] = useState(0)
|
||||||
const [suitableReports, setSuitableReports] = useState([])
|
|
||||||
const [showLoader, setShowLoader] = useState(false)
|
const [showLoader, setShowLoader] = useState(false)
|
||||||
|
|
||||||
const periodOptions = timePeriodNames.map((item) => (
|
const periodOptions = timePeriodNames.map((item) => (
|
||||||
@ -54,47 +47,15 @@ export default function Report({ idWell }) {
|
|||||||
</Option>
|
</Option>
|
||||||
))
|
))
|
||||||
|
|
||||||
const columns = [
|
const handleReportCreation = async () => {
|
||||||
{
|
|
||||||
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: (reportName) => (
|
|
||||||
<Button
|
|
||||||
onClick={(_) => getReportFile(idWell, reportName)}
|
|
||||||
download={reportName}
|
|
||||||
>
|
|
||||||
{reportName}
|
|
||||||
</Button>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
const handleReportCreation = async (values) => {
|
|
||||||
let begin = filterDateRange[0].toISOString()
|
let begin = filterDateRange[0].toISOString()
|
||||||
let end = filterDateRange[1].toISOString()
|
let end = filterDateRange[1].toISOString()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const idUser = localStorage["userId"]
|
|
||||||
|
|
||||||
const taskId = await ReportService.createReport(
|
const taskId = await ReportService.createReport(
|
||||||
idWell,
|
idWell,
|
||||||
idUser,
|
step,
|
||||||
values.step,
|
format,
|
||||||
values.format,
|
|
||||||
begin,
|
begin,
|
||||||
end
|
end
|
||||||
)
|
)
|
||||||
@ -111,9 +72,11 @@ export default function Report({ idWell }) {
|
|||||||
></ReportCreationNotify>
|
></ReportCreationNotify>
|
||||||
),
|
),
|
||||||
duration: 0,
|
duration: 0,
|
||||||
|
onClose: unSubscribeReportHub,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (progressData.reportName?.length) unSubscribeReportHub()
|
if (progressData.file)
|
||||||
|
unSubscribeReportHub()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,109 +101,93 @@ export default function Report({ idWell }) {
|
|||||||
return current < aviableDateRange[0] || current > aviableDateRange[1]
|
return current < aviableDateRange[0] || current > aviableDateRange[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateSuitableReports = (suitableReports) => {
|
useEffect(
|
||||||
const reports = suitableReports?.map(report => {
|
() =>
|
||||||
const creationDate = new Date(report.begin).toLocaleString()
|
invokeWebApiWrapperAsync(async () => {
|
||||||
const begin = new Date(report.begin).toLocaleString()
|
const datesRangeResponse = await ReportService.getReportsDateRange(
|
||||||
const end = new Date(report.end).toLocaleString()
|
idWell
|
||||||
const step = timePeriodNames[report.step]
|
)
|
||||||
const reportParams = `Дата создания: ${creationDate}, Данные от ${begin} до ${end}, Шаг: ${step}`
|
const datesRange = [
|
||||||
return {
|
moment(datesRangeResponse.from),
|
||||||
key: report.id,
|
moment(datesRangeResponse.to),
|
||||||
reportFormat: report.format,
|
]
|
||||||
reportParams: reportParams,
|
setAviableDateRange(datesRange)
|
||||||
reportName: report.name,
|
|
||||||
}})
|
|
||||||
setSuitableReports(reports??[])
|
|
||||||
}
|
|
||||||
|
|
||||||
const updateAviableDatesRange = (aviableDatesRange) =>{
|
let from = moment(datesRangeResponse.to)
|
||||||
const datesRange = [
|
from = from.subtract(1, "days")
|
||||||
moment(aviableDatesRange.from),
|
if (from < datesRange[0]) from = datesRange[0]
|
||||||
moment(aviableDatesRange.to)
|
|
||||||
]
|
|
||||||
|
|
||||||
let from = moment(aviableDatesRange.to)
|
const filterDateDefaults = [
|
||||||
from = from.subtract(1, "days")
|
from.startOf("day"),
|
||||||
if (from < datesRange[0])
|
moment(datesRangeResponse.to).startOf("day"),
|
||||||
from = datesRange[0]
|
]
|
||||||
|
setFilterDateRange(filterDateDefaults)
|
||||||
|
}, setShowLoader),
|
||||||
|
[idWell]
|
||||||
|
)
|
||||||
|
|
||||||
const filterDateDefaults = [from, moment(aviableDatesRange.to)]
|
useEffect(
|
||||||
setFilterDateRange(filterDateDefaults)
|
() =>
|
||||||
setAviableDateRange(datesRange)
|
invokeWebApiWrapperAsync(
|
||||||
}
|
async () => {
|
||||||
|
if (!filterDateRange || filterDateRange.length < 2) return
|
||||||
useEffect(() => invokeWebApiWrapperAsync(async() => {
|
const begin = filterDateRange[0].toISOString()
|
||||||
const aviableDatesRange = await ReportService.getReportsDateRange(idWell)
|
const end = filterDateRange[1].toISOString()
|
||||||
updateAviableDatesRange(aviableDatesRange)
|
const pagesCount = await ReportService.getReportSize(
|
||||||
const suitableReports = await ReportService.getSuitableReportsNames(idWell, 4294967295, 3, '0001-01-01T00:00:00.000Z', '9999-01-01T00:00:00.000Z')
|
idWell,
|
||||||
updateSuitableReports(suitableReports)
|
step,
|
||||||
}), [idWell])
|
format,
|
||||||
|
begin,
|
||||||
useEffect(() => invokeWebApiWrapperAsync(async() => {
|
end
|
||||||
if(!filterDateRange || filterDateRange.length < 2)
|
)
|
||||||
return
|
setPagesCount(pagesCount)
|
||||||
const begin = filterDateRange[0].toISOString()
|
},
|
||||||
const end = filterDateRange[1].toISOString()
|
setShowLoader,
|
||||||
const pagesCount = await ReportService.getReportSize(idWell, step, format, begin, end)
|
`Не удалось получить предварительные параметры отчета c
|
||||||
setPagesCount(pagesCount)
|
|
||||||
},
|
|
||||||
setShowLoader,
|
|
||||||
`Не удалось получить предварительные параметры отчета c
|
|
||||||
${filterDateRange[0].format(dateTimeFormat)} по
|
${filterDateRange[0].format(dateTimeFormat)} по
|
||||||
${filterDateRange[1].format(dateTimeFormat)}`
|
${filterDateRange[1].format(dateTimeFormat)}`
|
||||||
), [filterDateRange, step, format, idWell])
|
),
|
||||||
|
[filterDateRange, step, format, idWell]
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LoaderPortal show={showLoader}>
|
<div>
|
||||||
<div className="w-100 mt-20px">
|
<LoaderPortal show={showLoader}>
|
||||||
<Form
|
<div className="w-100 mt-20px mb-20px d-flex">
|
||||||
layout="vertical"
|
<div>
|
||||||
name="reportForm"
|
<div>Диапазон дат отчета</div>
|
||||||
initialValues={{ remember: true }}
|
<RangePicker
|
||||||
onFinish={handleReportCreation}
|
disabledDate={disabledDate}
|
||||||
>
|
allowClear={false}
|
||||||
<div className={"d-flex"}>
|
onCalendarChange={setFilterDateRange}
|
||||||
<Form.Item
|
showTime
|
||||||
label="Диапазон дат отчета"
|
value={filterDateRange}
|
||||||
name="period"
|
/>
|
||||||
initialValue={filterDateRange}
|
</div>
|
||||||
>
|
<div className="ml-30px">
|
||||||
<RangePicker
|
<div>Шаг графиков</div>
|
||||||
disabledDate={disabledDate}
|
<Select style={{ width: "8rem" }}
|
||||||
allowClear={false}
|
onChange={e=>{
|
||||||
onCalendarChange={(dates) => {
|
setStep(e)
|
||||||
setFilterDateRange(dates)
|
}}
|
||||||
}}
|
value={step}>
|
||||||
value = {filterDateRange}
|
{periodOptions}
|
||||||
showTime
|
</Select>
|
||||||
/>
|
</div>
|
||||||
</Form.Item>
|
|
||||||
<Form.Item
|
<div className="ml-30px">
|
||||||
label="Шаг графиков"
|
<div>Формат отчета</div>
|
||||||
name="step"
|
<Radio.Group
|
||||||
initialValue={step}
|
|
||||||
className="ml-30px"
|
|
||||||
>
|
|
||||||
<Select onChange={setStep}>{periodOptions}</Select>
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item
|
|
||||||
label="Формат отчета"
|
|
||||||
name="format"
|
|
||||||
initialValue={format}
|
|
||||||
onChange={(e) => setFormat(e.target.value)}
|
onChange={(e) => setFormat(e.target.value)}
|
||||||
className="ml-30px"
|
value={format}
|
||||||
>
|
|
||||||
<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"
|
|
||||||
>
|
>
|
||||||
|
<Radio.Button value={0}>PDF</Radio.Button>
|
||||||
|
<Radio.Button value={1}>LAS</Radio.Button>
|
||||||
|
</Radio.Group>
|
||||||
|
</div>
|
||||||
|
<div className="ml-30px">
|
||||||
|
<div> </div>
|
||||||
|
<Button type="primary" onClick={handleReportCreation}>
|
||||||
<span>Получить рапорт</span>
|
<span>Получить рапорт</span>
|
||||||
<span className={"ml-5px"}>({pagesCount} стр.)</span>
|
<span className={"ml-5px"}>({pagesCount} стр.)</span>
|
||||||
<span
|
<span
|
||||||
@ -251,13 +198,9 @@ export default function Report({ idWell }) {
|
|||||||
</span>
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</Form>
|
</div>
|
||||||
</div>
|
</LoaderPortal>
|
||||||
<br />
|
<Reports idWell={idWell} />
|
||||||
<h3>Отчеты с аналогичными параметрами, доступные для скачивания:</h3>{" "}
|
</div>
|
||||||
<br />
|
|
||||||
|
|
||||||
<Table dataSource={suitableReports} columns={columns} />
|
|
||||||
</LoaderPortal>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user