diff --git a/src/pages/Reports/DailyReport/ReportEditor.jsx b/src/pages/Reports/DailyReport/ReportEditor.jsx index 383df80..89c6abd 100644 --- a/src/pages/Reports/DailyReport/ReportEditor.jsx +++ b/src/pages/Reports/DailyReport/ReportEditor.jsx @@ -1,58 +1,119 @@ -import { useForm } from 'antd/lib/form/Form' -import { ConfigProvider, Descriptions, Divider, Form, Input, InputNumber, Modal, Select, Space, Table, Tag } from 'antd' -import { memo, useCallback, useEffect, useMemo, useState } from 'react' +import moment from 'moment' +import { DatePicker, Descriptions, Divider, Form, Input, InputNumber, Modal, Select, Space, Table } from 'antd' +import { memo, useCallback, useContext, useEffect, useState } from 'react' import LoaderPortal from '@components/LoaderPortal' import { invokeWebApiWrapperAsync } from '@components/factory' -import { DatePickerWrapper, makeColumn, makeGroupColumn } from '@components/Table' -import { formatDate } from '@utils' +import { makeColumn, makeGroupColumn } from '@components/Table' +import { DailyReportService } from '@api' -const { Item } = Form +import { IdWellContext } from '@pages/Well' + +const { Item: RawItem } = Form const { Summary } = Table +const Item = memo(({ style, ...other }) => ) + const table1Columns = [ makeGroupColumn('Отчётный период', [ - makeColumn('От (дата, время)', 'dateStart', { width: 200, render: (date) => formatDate(date) ?? '---' }), + makeColumn('От (дата, время)', 'dateStart', { width: 200, render: (disabled) => ( + + + + )}), ]), makeGroupColumn('Забой за отчётный период, м', [ makeColumn('От', 'depthStart', { width: 200, render: () => ( - + )}), makeColumn('До', 'depthEnd', { width: 200, render: () => ( - + )}), ]) ] +const cellData = { + width: 200, + render: (name) => ( + + + + ) +} + const table2Columns = [ - makeColumn('Работа модулей САУБ', 'label', { width: 500 }), - makeColumn('Часов:', 'hours', { width: 200, render: (data) => ( - - - - )}), - makeColumn('Метров:', 'meters', { width: 200, render: (data) => ( - - - - )}), + makeColumn('Работа модулей САУБ', 'label', { width: 400 }), + makeColumn('Часов:', 'hours', cellData), + makeColumn('Метров:', 'meters', cellData), ] const table2Data = [ - { label: 'АПД (автоматическая подача долота), ч/м:', hours: 'workTimeSaub', meters: 'drilledMetersSaub' }, - { label: 'Спин Мастер (осцилляция), ч/м:', hours: 'workTimeSpinMaster', meters: 'drilledMetersSpinMaster' }, - { label: 'Торк Мастер (демпфирование), ч/м:', hours: 'workTimeTorkMaster', meters: 'drilledMetersTorkMaster' }, + { label: 'АПД (автоматическая подача долота), ч/м:', hours: 'workTimeSAUB', meters: 'penetrationSAUB' }, + { label: 'Спин Мастер (осцилляция), ч/м:', hours: 'workTimeSpinMaster', meters: 'penetrationSpinMaster' }, + { label: 'Торк Мастер (демпфирование), ч/м:', hours: 'workTimeTorkMaster', meters: 'penetrationTorkMaster' }, ] +const table3Columns = [ + makeGroupColumn('Бурение в роторе (за отчётный период) с использованием САУБ-1', [ + makeColumn('Проходка', 'sinking', cellData), + makeColumn('Часы бурения', 'hours', cellData), + makeColumn('Среднее диф. Давление', 'pressure', cellData), + ]), +] + +const table3Data = [{ sinking: 'penetrationInRotor', hours: 'numberDrillingHours', pressure: 'avgDiffDropRotor' }] + +const table4Columns = [ + makeGroupColumn('Бурение в слайде (за отчётный период) с использованием САУБ-1', [ + makeColumn('Проходка', 'sinking', cellData), + makeColumn('Часы бурения', 'hours', cellData), + makeColumn('Среднее диф. Давление', 'pressure', cellData), + ]), +] + +const table4Data = [{ sinking: 'penetrationInSlide', hours: 'drillingTimeInRotor', pressure: 'avgDiffPressureSlide' }] + +const table6Columns = [ + makeGroupColumn('БЕЗМЕТРАЖНЫЕ РАБОТЫ', [ + makeColumn('Подготовка ствола скважины к наращиванию', 'l_label', { colSpan: 2, width: 200 }), + makeColumn('', 'l_value', { colSpan: 0, ...cellData }), + makeColumn('Наращивание', 'r_label', { colSpan: 2, width: 200 }), + makeColumn('', 'r_value', { colSpan: 0, ...cellData }), + ]), +] + +const table6Data = [{ + l_label: 'Норматив на одну операцию, (мин):', + r_label: 'Норматив на одну операцию, (мин):', + l_value: 'standardTimeBarrelPreparation', + r_value: 'standardTimeExtension' +}, { + l_label: 'Проработка при бур, факт (ч):', + r_label: 'Наращивание, факт (ч):', + l_value: 'actualTimeBarrelPreparation', + r_value: 'actualTimeExtension' +}] + +const table6Summary = () => ( + + + Краткие причины: доп проработки при переходе из слайда в ротор, в середине свечи. + + + Краткие причины: нехватка пальцев на обоих руках у первого помощника бурильщика. + + +) + const table2Summary = () => ( МСЕ, колличество запусков, раз: - + @@ -60,27 +121,36 @@ const table2Summary = () => ( ) export const ReportEditor = memo(({ visible, data, onDone, onCancel }) => { - const [form] = useForm() + const [form] = Form.useForm() const [isInvalid, setIsInvalid] = useState(false) const [isLoading, setIsLoading] = useState(false) - useEffect(() => form.setFieldsValue(data), [data]) + const idWell = useContext(IdWellContext) + + useEffect(() => form.setFieldsValue(data ? { + ...data, + rotorDrillingModes: Array.isArray(data.rotorDrillingModes) ? data.rotorDrillingModes ?? [] : [], + slideDrillingModes: Array.isArray(data.slideDrillingModes) ? data.slideDrillingModes ?? [] : [], + reportDate: moment.utc(data.reportDate).local(), + } : {}), [data, form]) const onFormChange = useCallback(async () => await form.validateFields() .then(() => setIsInvalid(false)) .catch(() => setIsInvalid(true)) , [form]) - const onFormFinish = useCallback((data) => invokeWebApiWrapperAsync( + const onFormFinish = useCallback((formData) => invokeWebApiWrapperAsync( async () => { - onDone?.(data) + if (data) + await DailyReportService.update(idWell, data.reportDate, formData) + else + await DailyReportService.add(idWell, formData) + onDone?.(formData) }, setIsLoading, 'Не удалось сохранить суточный рапорт', 'Сохранение суточного рапорта', - ), [onDone]) - - const table1Data = useMemo(() => [{ dateStart: form.getFieldValue('reportDate') }], [form]) + ), [data, onDone, idWell]) return ( { visible={visible} onCancel={onCancel} okText={'Сохранить'} - title={data ? `Суточная сводка бурения скважины № ${data.wellName} куст № ${data.clusterName}`: 'Новая суточная сводка бурения'} + title={data ? + <>Суточная сводка бурения скважины № {data?.wellName} куст № {data?.clusterName} : + <>Новая cуточная сводка бурения скважины + } onOk={form.submit} okButtonProps={{ disabled: isInvalid, @@ -103,49 +176,87 @@ export const ReportEditor = memo(({ visible, data, onDone, onCancel }) => { onChange={onFormChange} > - + -

Суточная сводка бурения скважины № {data?.wellName} куст № {data?.clusterName}

- - - - - + + + +
+ + -
+
- - - + + + - - - - - - - +
+ + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/pages/Reports/DailyReport/index.jsx b/src/pages/Reports/DailyReport/index.jsx index c67a3be..64241af 100644 --- a/src/pages/Reports/DailyReport/index.jsx +++ b/src/pages/Reports/DailyReport/index.jsx @@ -1,26 +1,30 @@ import moment from 'moment' import { Button } from 'antd' -import { memo, useCallback, useEffect, useMemo, useState } from 'react' +import { memo, useCallback, useContext, useEffect, useMemo, useState } from 'react' import { FileExcelOutlined, EditOutlined, PlusOutlined } from '@ant-design/icons' import LoaderPortal from '@components/LoaderPortal' import DateRangeWrapper from '@components/Table/DateRangeWrapper' import { Table, makeDateColumn, makeColumn } from '@components/Table' import { download, invokeWebApiWrapperAsync } from '@components/factory' +import { DailyReportService } from '@api' import { arrayOrDefault } from '@utils' import ReportEditor from './ReportEditor' +import { IdWellContext } from '@pages/Well' -export const DailyReport = memo(({ idWell }) => { +export const DailyReport = memo(() => { const [data, setData] = useState([]) const [isLoading, setIsLoading] = useState(false) const [searchDate, setSearchDate] = useState(null) const [selectedReport, setSelectedReport] = useState(null) - const [isEditorVisible, setIsEditorVisible] = useState(true) + const [isEditorVisible, setIsEditorVisible] = useState(false) - useEffect(() => invokeWebApiWrapperAsync( + const idWell = useContext(IdWellContext) + + const updateTable = useCallback(() => invokeWebApiWrapperAsync( async () => { - const data = [{ date: '2022-10-01' }] // arrayOrDefault(await DailyreportService.getData(idWell)) + const data = arrayOrDefault(await DailyReportService.getList(idWell)) setData(data) }, setIsLoading, @@ -28,14 +32,16 @@ export const DailyReport = memo(({ idWell }) => { 'Получение списка суточных рапортов', ), [idWell]) + useEffect(updateTable, [updateTable]) + const columns = useMemo(() => [ - makeDateColumn('Дата', 'date', undefined, undefined, { width: 300 }), - makeColumn('', '', { width: 200, render: (_, report, idx) => ( + makeDateColumn('Дата', 'reportDate', undefined, undefined, { width: 300 }), + makeColumn('', '', { width: 200, render: (_, report) => ( <> @@ -51,7 +57,7 @@ export const DailyReport = memo(({ idWell }) => { )}), - ], []) + ], [idWell]) const filteredData = useMemo(() => { if (!searchDate) return data @@ -89,6 +95,10 @@ export const DailyReport = memo(({ idWell }) => { data={selectedReport} visible={isEditorVisible} onCancel={() => setIsEditorVisible(false)} + onDone={() => { + setIsEditorVisible(false) + updateTable() + }} /> ) diff --git a/src/pages/Reports/index.jsx b/src/pages/Reports/index.jsx index 056eb9b..7d889a5 100644 --- a/src/pages/Reports/index.jsx +++ b/src/pages/Reports/index.jsx @@ -1,43 +1,40 @@ -import { Switch, useParams } from 'react-router-dom' -import { memo, useMemo } from 'react' -import { Layout, Menu } from 'antd' +import { useParams } from 'react-router-dom' +import { memo, useContext, useMemo } from 'react' import { FilePdfOutlined } from '@ant-design/icons' +import { Layout } from 'antd' -import { PrivateMenuItemLink, PrivateRoute, PrivateDefaultRoute } from '@components/Private' +import { PrivateMenu, PrivateSwitch } from '@components/Private' import DailyReport from './DailyReport' import DiagramReport from './DiagramReport' +import { RootPathContext } from '@pages/Main' const { Content } = Layout -export const Reports = memo(({ idWell }) => { +export const Reports = memo(() => { const { tab } = useParams() - const rootPath = useMemo(() => `/well/${idWell}/reports`, [idWell]) + + const root = useContext(RootPathContext) + const rootPath = useMemo(() => `${root}/reports`, [root]) return ( - - - } title={'Диаграмма'}/> - - - + - - - - - - - - - - - + + } title={'Диаграмма'}/> + + + + + + + + + + + - + ) })