Показ TVD унифицирован, Сохранение режимов из окна композитной скважины теперь заменят другие существующие

This commit is contained in:
goodmice 2021-10-15 10:52:01 +05:00
parent 2f6a776eb9
commit 3a9c4331d7
4 changed files with 170 additions and 172 deletions

View File

@ -1,69 +1,56 @@
import { Link } from "react-router-dom";
import { useState, useEffect } from "react";
import { Table, Tag, Button, Modal } from "antd";
import { LineChartOutlined, ProfileOutlined } from "@ant-design/icons";
import { Link } from 'react-router-dom'
import { useState, useEffect } from 'react'
import { Table, Tag, Button, Modal } from 'antd'
import { LineChartOutlined, ProfileOutlined } from '@ant-design/icons'
import {
makeTextColumn,
makeGroupColumn,
makeColumn,
makeDateSorter,
makeNumericColumnPlanFact} from "../../components/Table";
import { calcAndUpdateStatsBySections, makeFilterMinMaxFunction, getPrecision } from "./functions";
import { invokeWebApiWrapperAsync } from '../../components/factory';
import ChartTvD from '../WellOperations/ChartTvD';
makeNumericColumnPlanFact} from '../../components/Table'
import { calcAndUpdateStatsBySections, makeFilterMinMaxFunction, getPrecision } from './functions'
import { invokeWebApiWrapperAsync } from '../../components/factory'
import { Tvd } from '../WellOperations/Tvd'
import WellOperationsTable from './WellOperationsTable'
import { getOperations } from "./functions";
import LoaderPortal from "../../components/LoaderPortal";
import { getOperations } from './functions'
import LoaderPortal from '../../components/LoaderPortal'
const filtersMinMax = [
{
text: "min",
value: "min",
},
{
text: "max",
value: "max",
},
];
{ text: 'min', value: 'min' },
{ text: 'max', value: 'max' },
]
const filtersWellsType = [];
const DAY_IN_MS = 1000 * 60 * 60 * 24;
const filtersWellsType = []
const DAY_IN_MS = 1000 * 60 * 60 * 24
export default function ClusterWells({statsWells}) {
const [selectedWellId, setSelectedWellId] = useState(0)
const [isTVDModalVisible, setIsTVDModalVisible] = useState(false)
const [isOpsModalVisible, setIsOpsModalVisible] = useState(false)
const [tvdDataPlan, setTvdDataPlan] = useState([]);
const [tvdDataFact, setTvdDataFact] = useState([]);
const [tvdDataForecast, setTvdDataForecast] = useState([]);
const [wellOperations, setWellOperations] = useState([]);
const [wellOperations, setWellOperations] = useState([])
const [tableData, setTableData] = useState([])
const [showLoader, setShowLoader] = useState(false)
useEffect(() => {
if (selectedWellId > 0) {
if (!isOpsModalVisible || selectedWellId <= 0) {
setWellOperations([])
return
}
invokeWebApiWrapperAsync(
async () => {
const operations = await getOperations(selectedWellId);
const operations = await getOperations(selectedWellId)
setWellOperations(operations.operations)
setTvdDataPlan(operations.plan)
setTvdDataFact(operations.fact)
setTvdDataForecast(operations.predict)
},
setShowLoader,
`Не удалось загрузить операции по скважине "${selectedWellId}"`,
);
} else {
setWellOperations([])
}
}, [selectedWellId]);
)
}, [selectedWellId, isOpsModalVisible])
useEffect(() => {
let data = statsWells?.map((well) => {
if (!filtersWellsType.some((el) => el.text === well.wellType))
filtersWellsType.push({ text: well.wellType, value: well.wellType,});
filtersWellsType.push({ text: well.wellType, value: well.wellType,})
return {
key: well.caption,
@ -81,20 +68,20 @@ export default function ClusterWells({statsWells}) {
notProductiveTimePlan: well.total?.plan?.nonProductiveHours,
notProductiveTimeFact: well.total?.fact?.nonProductiveHours,
companies: well.companies
};
});
}
})
calcAndUpdateStatsBySections(data ?? [], [
"factStart",
"factEnd",
"periodPlan",
"periodFact",
"rateOfPenetrationPlan",
"rateOfPenetrationFact",
"routeSpeedPlan",
"routeSpeedFact",
"notProductiveTime",
]);
'factStart',
'factEnd',
'periodPlan',
'periodFact',
'rateOfPenetrationPlan',
'rateOfPenetrationFact',
'routeSpeedPlan',
'routeSpeedFact',
'notProductiveTime',
])
setTableData(data)
}, [statsWells])
@ -102,21 +89,21 @@ export default function ClusterWells({statsWells}) {
const getDate = (str) => Number.isNaN(new Date(str).getTime()) ? '-' : new Date(str).toLocaleString()
const columns = [
makeTextColumn("скв №", "caption", null, null,
makeTextColumn('скв №', 'caption', null, null,
(_, item) => (<Link to={`/well/${item.id}`}>{item.caption ?? '-'}</Link>
)),
makeTextColumn("Тип скв.", "wellType", filtersWellsType, null, (text) => text ?? '-'),
makeGroupColumn("Фактические сроки", [
makeColumn("начало", "factStart", { sorter: makeDateSorter('factStart'), render: getDate }),
makeColumn("окончание", "factEnd", { sorter: makeDateSorter('factEnd'), render: getDate })
makeTextColumn('Тип скв.', 'wellType', filtersWellsType, null, (text) => text ?? '-'),
makeGroupColumn('Фактические сроки', [
makeColumn('начало', 'factStart', { sorter: makeDateSorter('factStart'), render: getDate }),
makeColumn('окончание', 'factEnd', { sorter: makeDateSorter('factEnd'), render: getDate })
]),
makeNumericColumnPlanFact("Продолжительность", "period", filtersMinMax, makeFilterMinMaxFunction, getPrecision),
makeNumericColumnPlanFact("МСП", "rateOfPenetration", filtersMinMax, makeFilterMinMaxFunction, getPrecision),
makeNumericColumnPlanFact("Рейсовая скорость", "routeSpeed", filtersMinMax, makeFilterMinMaxFunction, getPrecision),
makeNumericColumnPlanFact("НПВ, сут", "notProductiveTime", filtersMinMax, makeFilterMinMaxFunction, getPrecision),
makeNumericColumnPlanFact('Продолжительность', 'period', filtersMinMax, makeFilterMinMaxFunction, getPrecision),
makeNumericColumnPlanFact('МСП', 'rateOfPenetration', filtersMinMax, makeFilterMinMaxFunction, getPrecision),
makeNumericColumnPlanFact('Рейсовая скорость', 'routeSpeed', filtersMinMax, makeFilterMinMaxFunction, getPrecision),
makeNumericColumnPlanFact('НПВ, сут', 'notProductiveTime', filtersMinMax, makeFilterMinMaxFunction, getPrecision),
{
title: "TVD",
key: "tvd",
title: 'TVD',
key: 'tvd',
render: (value) => <Button onClick={()=> {
setSelectedWellId(value.id)
setIsTVDModalVisible(true)
@ -124,8 +111,8 @@ export default function ClusterWells({statsWells}) {
align: 'center'
},
{
title: "Операции",
key: "operations",
title: 'Операции',
key: 'operations',
render: (value) => <Button onClick={()=> {
setSelectedWellId(value.id)
setIsOpsModalVisible(true)
@ -133,43 +120,37 @@ export default function ClusterWells({statsWells}) {
align: 'center'
},
{
title: "Подрядчики",
key: "companies",
dataIndex: "companies",
render: (item) => item?.map((company) => <Tag key={company.caption} color="blue">{company.caption}</Tag>) ?? '-',
title: 'Подрядчики',
key: 'companies',
dataIndex: 'companies',
render: (item) => item?.map((company) => <Tag key={company.caption} color='blue'>{company.caption}</Tag>) ?? '-',
},
];
]
return (
<>
<Table
columns={columns}
dataSource={tableData}
size={"small"}
size={'small'}
bordered
pagination={false}
rowKey={(record) => record.caption}
/>
<Modal
title='TVD'
title={'TVD'}
centered
visible={isTVDModalVisible}
onCancel={() => setIsTVDModalVisible(false)}
width={1500}
footer={null}
>
<LoaderPortal show={showLoader}>
<ChartTvD
dataPlan={tvdDataPlan}
dataFact={tvdDataFact}
dataPredict={tvdDataForecast}
/>
</LoaderPortal>
<Tvd idWell={selectedWellId} />
</Modal>
<Modal
title='Операции'
title={'Операции'}
centered
visible={isOpsModalVisible}
onCancel={() => setIsOpsModalVisible(false)}
@ -181,5 +162,5 @@ export default function ClusterWells({statsWells}) {
</LoaderPortal>
</Modal>
</>
);
)
}

View File

@ -1,36 +1,43 @@
import ChartTvD from './ChartTvD';
import { useState, useEffect } from 'react';
import { invokeWebApiWrapperAsync } from '../../components/factory';
import { getOperations } from '../Cluster/functions';
import ChartTvD from './ChartTvD'
import { useState, useEffect } from 'react'
import { invokeWebApiWrapperAsync } from '../../components/factory'
import { getOperations } from '../Cluster/functions'
import LoaderPortal from '../../components/LoaderPortal'
export const Tvd = ({ idWell }) => {
const [dataPlan, setDataPlan] = useState([]);
const [dataFact, setDataFact] = useState([]);
const [dataPredict, setDataPredict] = useState([]);
export const Tvd = ({ idWell, title }) => {
const [dataPlan, setDataPlan] = useState([])
const [dataFact, setDataFact] = useState([])
const [dataPredict, setDataPredict] = useState([])
const [showLoader, setShowLoader] = useState(false)
useEffect(() => {
invokeWebApiWrapperAsync(
async () => {
const operations = await getOperations(idWell);
const operations = await getOperations(idWell)
setDataPlan(operations.plan)
setDataFact(operations.fact)
setDataPredict(operations.predict)
},
null,
setShowLoader,
`Не удалось загрузить операции по скважине "${idWell}"`,
);
}, [idWell]);
)
}, [idWell])
return (
<div className="container">
<div className='container'>
<div>
{title ? title : (
<h2 className={'mt-20px'}>График Глубина-день</h2>
)}
<LoaderPortal show={showLoader}>
<ChartTvD
dataPlan={dataPlan}
dataFact={dataFact}
dataPredict={dataPredict} />
dataPredict={dataPredict}
/>
</LoaderPortal>
</div>
</div>
);
};
)
}

View File

@ -1,5 +1,5 @@
import { LineChartOutlined, ProfileOutlined } from '@ant-design/icons'
import { Table, Tag, Button, Badge, Divider, Modal, Row, Col } from 'antd'
import { Table, Tag, Button, Badge, Divider, Modal, Row, Col, Popconfirm } from 'antd'
import { Link } from 'react-router-dom'
import { useState, useEffect } from 'react'
import {
@ -14,7 +14,7 @@ import {
makeFilterMinMaxFunction,
getOperations
} from '../../Cluster/functions'
import ChartTvD from '../ChartTvD'
import { Tvd } from '../Tvd'
import { DrillParamsService, WellCompositeService } from '../../../services/api'
import LoaderPortal from '../../../components/LoaderPortal'
import WellOperationsTable from '../../Cluster/WellOperationsTable'
@ -23,8 +23,8 @@ import { dictionarySectionType, getByKeyOrReturnKey } from '../dictionary'
const filtersMinMax = [
{ text: "min", value: "min" },
{ text: "max", value: "max" },
{ text: 'min', value: 'min' },
{ text: 'max', value: 'max' },
]
const filtersSectionsType = []
@ -33,15 +33,13 @@ const DAY_IN_MS = 1000 * 60 * 60 * 24
export const WellCompositeSections = ({idWell, statsWells, selectedSections}) => {
const [showLoader, setShowLoader] = useState(false)
const [showParamsLoader, setShowParamsLoader] = useState(false)
const [selectedWellId, setSelectedWellId] = useState(0)
const [selectedWells, setSelectedWells] = useState([])
const [selectedWellsKeys, setSelectedWellsKeys] = useState([])
const [isTVDModalVisible, setIsTVDModalVisible] = useState(false)
const [isOpsModalVisible, setIsOpsModalVisible] = useState(false)
const [isParamsModalVisible, setIsParamsModalVisible] = useState(false)
const [tvdDataPlan, setTvdDataPlan] = useState([])
const [tvdDataFact, setTvdDataFact] = useState([])
const [tvdDataForecast, setTvdDataForecast] = useState([])
const [wellOperations, setWellOperations] = useState([])
const [rows, setRows] = useState([])
const [params, setParams] = useState([])
@ -50,15 +48,12 @@ export const WellCompositeSections = ({idWell, statsWells, selectedSections}) =>
if (selectedWellId > 0) {
invokeWebApiWrapperAsync(
async () => {
const operations = await getOperations(selectedWellId);
const operations = await getOperations(selectedWellId)
setWellOperations(operations.operations)
setTvdDataPlan(operations.plan)
setTvdDataFact(operations.fact)
setTvdDataForecast(operations.predict)
},
setShowLoader,
`Не удалось загрузить операции по скважине "${selectedWellId}"`,
`Не удалось загрузить операции по скважине '${selectedWellId}'`,
)
}
}, [selectedWellId])
@ -100,22 +95,22 @@ export const WellCompositeSections = ({idWell, statsWells, selectedSections}) =>
})
calcAndUpdateStatsBySections(rows ?? [], [
"sectionWellDepthPlan",
"sectionWellDepthFact",
"sectionBuildDaysPlan",
"sectionBuildDaysFact",
"sectionRateOfPenetrationPlan",
"sectionRateOfPenetrationFact",
"sectionRouteSpeedPlan",
"sectionRouteSpeedFact",
"sectionBhaDownSpeedPlan",
"sectionBhaDownSpeedFact",
"sectionBhaUpSpeedPlan",
"sectionBhaUpSpeedFact",
"sectionCasingDownSpeedPlan",
"sectionCasingDownSpeedFact",
"nonProductiveTimePlan",
"nonProductiveTimeFact",
'sectionWellDepthPlan',
'sectionWellDepthFact',
'sectionBuildDaysPlan',
'sectionBuildDaysFact',
'sectionRateOfPenetrationPlan',
'sectionRateOfPenetrationFact',
'sectionRouteSpeedPlan',
'sectionRouteSpeedFact',
'sectionBhaDownSpeedPlan',
'sectionBhaDownSpeedFact',
'sectionBhaUpSpeedPlan',
'sectionBhaUpSpeedFact',
'sectionCasingDownSpeedPlan',
'sectionCasingDownSpeedFact',
'nonProductiveTimePlan',
'nonProductiveTimeFact',
])
setRows(rows)
@ -131,20 +126,20 @@ export const WellCompositeSections = ({idWell, statsWells, selectedSections}) =>
}, [rows, selectedSections])
const columns = [
makeTextColumn("скв №", "caption", null, null,
makeTextColumn('скв №', 'caption', null, null,
(text, item) => <Link to={`/well/${item?.id}`}>{text ?? '-'}</Link>
),
makeTextColumn("Секция", "sectionType", filtersSectionsType, null, (text) => text ?? '-'),
makeNumericColumnPlanFact("Глубина", "sectionWellDepth", filtersMinMax, makeFilterMinMaxFunction),
makeNumericColumnPlanFact("Продолжительность", "sectionBuildDays", filtersMinMax, makeFilterMinMaxFunction),
makeNumericColumnPlanFact("МСП", "sectionRateOfPenetration", filtersMinMax, makeFilterMinMaxFunction),
makeNumericColumnPlanFact("Рейсовая скорость", "sectionRouteSpeed", filtersMinMax, makeFilterMinMaxFunction),
makeNumericColumnPlanFact("Спуск КНБК", "sectionBhaDownSpeed", filtersMinMax, makeFilterMinMaxFunction),
makeNumericColumnPlanFact("Подъем КНБК", "sectionBhaUpSpeed", filtersMinMax, makeFilterMinMaxFunction),
makeNumericColumnPlanFact("Скорость спуска ОК", "sectionCasingDownSpeed", filtersMinMax, makeFilterMinMaxFunction),
makeNumericColumnPlanFact("НПВ, сут", "nonProductiveTime", filtersMinMax, makeFilterMinMaxFunction, null, "70px"),
makeTextColumn('Секция', 'sectionType', filtersSectionsType, null, (text) => text ?? '-'),
makeNumericColumnPlanFact('Глубина', 'sectionWellDepth', filtersMinMax, makeFilterMinMaxFunction),
makeNumericColumnPlanFact('Продолжительность', 'sectionBuildDays', filtersMinMax, makeFilterMinMaxFunction),
makeNumericColumnPlanFact('МСП', 'sectionRateOfPenetration', filtersMinMax, makeFilterMinMaxFunction),
makeNumericColumnPlanFact('Рейсовая скорость', 'sectionRouteSpeed', filtersMinMax, makeFilterMinMaxFunction),
makeNumericColumnPlanFact('Спуск КНБК', 'sectionBhaDownSpeed', filtersMinMax, makeFilterMinMaxFunction),
makeNumericColumnPlanFact('Подъем КНБК', 'sectionBhaUpSpeed', filtersMinMax, makeFilterMinMaxFunction),
makeNumericColumnPlanFact('Скорость спуска ОК', 'sectionCasingDownSpeed', filtersMinMax, makeFilterMinMaxFunction),
makeNumericColumnPlanFact('НПВ, сут', 'nonProductiveTime', filtersMinMax, makeFilterMinMaxFunction, null, '70px'),
{
title: "TVD",
title: 'TVD',
render: (value) => <Button onClick={()=> {
setSelectedWellId(value.id)
setIsTVDModalVisible(true)
@ -152,7 +147,7 @@ export const WellCompositeSections = ({idWell, statsWells, selectedSections}) =>
align: 'center'
},
{
title: "Операции",
title: 'Операции',
render: (value) => <Button onClick={()=> {
setSelectedWellId(value.id)
setIsOpsModalVisible(true)
@ -160,10 +155,10 @@ export const WellCompositeSections = ({idWell, statsWells, selectedSections}) =>
align: 'center'
},
{
title: "Подрядчики",
dataIndex: "companies",
title: 'Подрядчики',
dataIndex: 'companies',
render: (item) =>
item?.map((company) => <Tag key={company.caption} color="blue">{company.caption}</Tag>),
item?.map((company) => <Tag key={company.caption} color={'blue'}>{company.caption}</Tag>),
},
]
@ -192,28 +187,28 @@ export const WellCompositeSections = ({idWell, statsWells, selectedSections}) =>
setSelectedWells(items)
setSelectedWellsKeys(keys)
},
setShowLoader,
'Не удалось сохранить изменения выбранных секций для композитной скважины'
setShowParamsLoader,
`Не удалось сохранить изменения выбранных секций для композитной скважины "${idWell}"`
)
}
const onParamButtonClick = () => invokeWebApiWrapperAsync(
async () => {
setIsParamsModalVisible(true)
const params = await DrillParamsService.getCompositeAll(idWell)
setParams(params)
setIsParamsModalVisible(true)
},
setShowLoader,
`Не удалось загрузить список режимов для скважины ${idWell}`
setShowParamsLoader,
`Не удалось загрузить список режимов для скважины "${idWell}"`
)
const onParamsAddClick = () => invokeWebApiWrapperAsync(
async () => {
await DrillParamsService.insertRange(idWell, params)
await DrillParamsService.save(idWell, params)
setIsParamsModalVisible(false)
},
setShowLoader,
`Не удалось добавить режимы в список скважины ${idWell}`
`Не удалось добавить режимы в список скважины "${idWell}"`
)
return (
@ -221,21 +216,21 @@ export const WellCompositeSections = ({idWell, statsWells, selectedSections}) =>
<Table
columns={columns}
dataSource={rows}
size={"small"}
size={'small'}
bordered
scroll={{ x: true, y: 620 }}
rowSelection={rowSelection}
pagination={false}
/>
<Divider />
<Badge.Ribbon text="комбинированная скважина" color="gray">
<Badge.Ribbon text={'комбинированная скважина'} color={'gray'}>
<h3>Выбранные секции</h3>
</Badge.Ribbon>
<Table
columns={columns}
dataSource={selectedWells}
rowSelection={rowSelection}
size={"small"}
size={'small'}
bordered
scroll={{ x: true }}
pagination={false}
@ -249,23 +244,18 @@ export const WellCompositeSections = ({idWell, statsWells, selectedSections}) =>
</Col></Row>
<Modal
title='TVD'
title={'TVD'}
centered
visible={isTVDModalVisible}
onCancel={() => setIsTVDModalVisible(false)}
width={1500}
footer={null}
>
<LoaderPortal show={showLoader}>
<ChartTvD
dataPlan={tvdDataPlan}
dataFact={tvdDataFact}
dataPredict={tvdDataForecast} />
</LoaderPortal>
<Tvd idWell={selectedWellId}/>
</Modal>
<Modal
title='Операции'
title={'Операции'}
centered
visible={isOpsModalVisible}
onCancel={() => setIsOpsModalVisible(false)}
@ -284,14 +274,15 @@ export const WellCompositeSections = ({idWell, statsWells, selectedSections}) =>
onCancel={() => setIsParamsModalVisible(false)}
width={1700}
footer={
<Popconfirm title='Заменить существующие режимы выбранными?' onConfirm={onParamsAddClick}>
<Button
size={'large'}
disabled={params.length <= 0}
onClick={onParamsAddClick}
>Добавить</Button>
>Сохранить</Button>
</Popconfirm>
}
>
<LoaderPortal show={showLoader}>
<LoaderPortal show={showParamsLoader}>
<Table
size={'small'}
bordered
@ -302,5 +293,5 @@ export const WellCompositeSections = ({idWell, statsWells, selectedSections}) =>
</LoaderPortal>
</Modal>
</>
);
)
}

View File

@ -129,6 +129,25 @@ export class DrillParamsService {
return result.body;
}
/**
* Удаляет старые режимы бурения по скважине и добавляет новые
* @param idWell Id скважины для добавления
* @param requestBody Новые режимы бурения
* @returns number Success
* @throws ApiError
*/
public static async save(
idWell: number,
requestBody?: Array<DrillParamsDto>,
): Promise<number> {
const result = await __request({
method: 'POST',
path: `/api/well/${idWell}/drillParams/save`,
body: requestBody,
});
return result.body;
}
/**
* Возвращает значения для режимов бурения на композитной скважине
* @param idWell id скважины