2021-08-27 14:21:48 +05:00
|
|
|
|
import { Table, Tag, Button, Badge, Divider, Modal } from "antd";
|
2021-08-31 12:44:39 +05:00
|
|
|
|
import { useParams, Link } from "react-router-dom";
|
2021-08-27 14:21:48 +05:00
|
|
|
|
import { LineChartOutlined, ProfileOutlined } from "@ant-design/icons";
|
|
|
|
|
import { useState, useEffect } from "react";
|
|
|
|
|
import {
|
|
|
|
|
makeTextColumn,
|
2021-08-30 11:26:00 +05:00
|
|
|
|
makeNumericColumnPlanFact
|
2021-08-27 14:21:48 +05:00
|
|
|
|
} from "../../components/Table";
|
2021-08-30 12:13:30 +05:00
|
|
|
|
import { calcAndUpdateStatsBySections, makeFilterMinMaxFunction } from "./functions";
|
|
|
|
|
|
2021-08-27 14:21:48 +05:00
|
|
|
|
|
|
|
|
|
const filtersMinMax = [
|
|
|
|
|
{
|
|
|
|
|
text: "min",
|
|
|
|
|
value: "min",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
text: "max",
|
|
|
|
|
value: "max",
|
|
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
const filtersSectionsType = [];
|
|
|
|
|
|
|
|
|
|
const ModalWindowButton = ({
|
|
|
|
|
buttonIcon,
|
|
|
|
|
buttonText,
|
|
|
|
|
modalTitle,
|
|
|
|
|
modalContent,
|
|
|
|
|
}) => {
|
|
|
|
|
const [isModalVisible, setIsModalVisible] = useState(false);
|
|
|
|
|
|
|
|
|
|
let content =
|
|
|
|
|
typeof modalContent === "string" ? (
|
|
|
|
|
<img src={modalContent} alt="" style={{ width: "100%" }} />
|
|
|
|
|
) : (
|
|
|
|
|
modalContent
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<>
|
|
|
|
|
<Button
|
|
|
|
|
type="secondary"
|
|
|
|
|
onClick={() => setIsModalVisible(true)}
|
|
|
|
|
icon={buttonIcon}
|
|
|
|
|
>
|
|
|
|
|
{buttonText}
|
|
|
|
|
</Button>
|
|
|
|
|
<Modal
|
|
|
|
|
title={modalTitle}
|
|
|
|
|
centered
|
|
|
|
|
visible={isModalVisible}
|
|
|
|
|
onOk={() => setIsModalVisible(false)}
|
|
|
|
|
onCancel={() => setIsModalVisible(false)}
|
|
|
|
|
width={1400}
|
|
|
|
|
>
|
|
|
|
|
{content}
|
|
|
|
|
</Modal>
|
|
|
|
|
</>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const columns = [
|
2021-08-31 12:44:39 +05:00
|
|
|
|
makeTextColumn("скв №", "caption", null, null, (_, item) => (
|
|
|
|
|
<Link to={`/well/${item.id}`}>{item.caption}</Link>
|
|
|
|
|
)),
|
2021-08-27 14:21:48 +05:00
|
|
|
|
makeTextColumn("Секция", "sectionType", filtersSectionsType),
|
2021-08-30 12:13:30 +05:00
|
|
|
|
makeNumericColumnPlanFact("Глубина", "sectionWellDepth", filtersMinMax, makeFilterMinMaxFunction),
|
2021-08-27 14:21:48 +05:00
|
|
|
|
makeNumericColumnPlanFact(
|
|
|
|
|
"Продолжительность",
|
|
|
|
|
"sectionBuildDays",
|
2021-08-30 12:13:30 +05:00
|
|
|
|
filtersMinMax,
|
|
|
|
|
makeFilterMinMaxFunction
|
2021-08-27 14:21:48 +05:00
|
|
|
|
), //Цикл строительства
|
2021-08-30 12:13:30 +05:00
|
|
|
|
makeNumericColumnPlanFact("МСП", "sectionRateOfPenetration", filtersMinMax, makeFilterMinMaxFunction),
|
2021-08-27 14:21:48 +05:00
|
|
|
|
makeNumericColumnPlanFact(
|
|
|
|
|
"Рейсовая скорость",
|
|
|
|
|
"sectionRouteSpeed",
|
2021-08-30 12:13:30 +05:00
|
|
|
|
filtersMinMax,
|
|
|
|
|
makeFilterMinMaxFunction
|
2021-08-27 14:21:48 +05:00
|
|
|
|
),
|
2021-08-30 12:13:30 +05:00
|
|
|
|
makeNumericColumnPlanFact("Спуск КНБК", "sectionBhaDownSpeed", filtersMinMax, makeFilterMinMaxFunction), //Скорость спуска КНБК
|
|
|
|
|
makeNumericColumnPlanFact("Подъем КНБК", "sectionBhaUpSpeed", filtersMinMax, makeFilterMinMaxFunction), //Скорость подъема КНБК
|
2021-08-27 14:21:48 +05:00
|
|
|
|
makeNumericColumnPlanFact(
|
|
|
|
|
"Скорость спуска ОК",
|
|
|
|
|
"sectionCasingDownSpeed",
|
2021-08-30 12:13:30 +05:00
|
|
|
|
filtersMinMax,
|
|
|
|
|
makeFilterMinMaxFunction
|
2021-08-27 14:21:48 +05:00
|
|
|
|
),
|
|
|
|
|
makeNumericColumnPlanFact(
|
|
|
|
|
"НПВ, сут",
|
|
|
|
|
"nonProductiveTime",
|
|
|
|
|
filtersMinMax,
|
2021-08-30 12:13:30 +05:00
|
|
|
|
makeFilterMinMaxFunction,
|
2021-08-27 14:21:48 +05:00
|
|
|
|
"70px"
|
|
|
|
|
),
|
|
|
|
|
{
|
|
|
|
|
title: "TVD",
|
|
|
|
|
render: (_, record) => (
|
|
|
|
|
<ModalWindowButton
|
|
|
|
|
buttonIcon={<LineChartOutlined />}
|
|
|
|
|
modalTitle={`График по скв.:${record.caption}`}
|
|
|
|
|
/>
|
|
|
|
|
),
|
|
|
|
|
//modalContent = {resources['Chart' + record.caption]}/>,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: "Операции",
|
|
|
|
|
render: (_, record) => (
|
|
|
|
|
<ModalWindowButton
|
|
|
|
|
buttonIcon={<ProfileOutlined />}
|
|
|
|
|
modalTitle={`Операции по скв.:${record.caption}`}
|
|
|
|
|
/>
|
|
|
|
|
),
|
|
|
|
|
//modalContent = {resources['Table' + record.caption]},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: "Подрядчики",
|
|
|
|
|
dataIndex: "companies",
|
|
|
|
|
render: (item) =>
|
|
|
|
|
item?.map((company) => <Tag color="blue">{company.caption}</Tag>),
|
|
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
export default function ClusterSections({ clusterData }) {
|
|
|
|
|
let { id } = useParams();
|
|
|
|
|
const [wellsStat, setWellsStat] = useState([]);
|
|
|
|
|
const [selectedWells, setSelectedWells] = useState([]);
|
|
|
|
|
const [selectedWellsKeys, setSelectedWellsKeys] = useState([]);
|
|
|
|
|
|
|
|
|
|
calcAndUpdateStatsBySections(wellsStat ?? [], [
|
|
|
|
|
"sectionWellDepthPlan",
|
|
|
|
|
"sectionWellDepthFact",
|
|
|
|
|
"sectionBuildDaysPlan",
|
|
|
|
|
"sectionBuildDaysFact",
|
|
|
|
|
"sectionRateOfPenetrationPlan",
|
|
|
|
|
"sectionRateOfPenetrationFact",
|
|
|
|
|
"sectionRouteSpeedPlan",
|
|
|
|
|
"sectionRouteSpeedFact",
|
|
|
|
|
"sectionBhaDownSpeedPlan",
|
|
|
|
|
"sectionBhaDownSpeedFact",
|
|
|
|
|
"sectionBhaUpSpeedPlan",
|
|
|
|
|
"sectionBhaUpSpeedFact",
|
|
|
|
|
"sectionCasingDownSpeedPlan",
|
|
|
|
|
"sectionCasingDownSpeedFact",
|
|
|
|
|
"nonProductiveTimePlan",
|
|
|
|
|
"nonProductiveTimeFact",
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
let rows = [];
|
|
|
|
|
|
2021-08-30 12:13:30 +05:00
|
|
|
|
clusterData.statsWells?.forEach((well) => {
|
|
|
|
|
well.sections.forEach((section) => {
|
2021-08-27 14:21:48 +05:00
|
|
|
|
let row = {
|
2021-08-30 12:13:30 +05:00
|
|
|
|
key: well.caption + section.id,
|
2021-08-31 12:44:39 +05:00
|
|
|
|
id: well.id,
|
2021-08-30 12:13:30 +05:00
|
|
|
|
caption: well.caption,
|
2021-08-27 14:21:48 +05:00
|
|
|
|
sectionType: section.caption,
|
|
|
|
|
sectionWellDepthPlan: section.plan.wellDepthEnd,
|
|
|
|
|
sectionWellDepthFact: section.fact.wellDepthEnd,
|
|
|
|
|
sectionBuildDaysPlan: (
|
2021-08-30 12:13:30 +05:00
|
|
|
|
(new Date(section.plan.end) - new Date(section.plan.start)) /
|
|
|
|
|
(1000 * 60 * 60 * 24)
|
2021-08-27 14:21:48 +05:00
|
|
|
|
).toFixed(2),
|
|
|
|
|
sectionBuildDaysFact: (
|
2021-08-30 12:13:30 +05:00
|
|
|
|
(new Date(section.fact.end) - new Date(section.fact.start)) /
|
|
|
|
|
(1000 * 60 * 60 * 24)
|
2021-08-27 14:21:48 +05:00
|
|
|
|
).toFixed(2),
|
|
|
|
|
sectionRateOfPenetrationPlan: section.plan.rop.toFixed(2),
|
|
|
|
|
sectionRateOfPenetrationFact: section.fact.rop.toFixed(2),
|
|
|
|
|
sectionRouteSpeedPlan: section.plan.routeSpeed.toFixed(2),
|
|
|
|
|
sectionRouteSpeedFact: section.fact.routeSpeed.toFixed(2),
|
|
|
|
|
sectionBhaDownSpeedPlan: section.plan.bhaDownSpeed.toFixed(2),
|
|
|
|
|
sectionBhaDownSpeedFact: section.fact.bhaDownSpeed.toFixed(2),
|
|
|
|
|
sectionBhaUpSpeedPlan: section.plan.bhaUpSpeed.toFixed(2),
|
|
|
|
|
sectionBhaUpSpeedFact: section.fact.bhaUpSpeed.toFixed(2),
|
|
|
|
|
sectionCasingDownSpeedPlan: section.plan.casingDownSpeed.toFixed(2),
|
|
|
|
|
sectionCasingDownSpeedFact: section.fact.casingDownSpeed.toFixed(2),
|
|
|
|
|
nonProductiveTimePlan: section.plan.nonProductiveHours.toFixed(2),
|
|
|
|
|
nonProductiveTimeFact: section.fact.nonProductiveHours.toFixed(2),
|
2021-08-30 12:13:30 +05:00
|
|
|
|
companies: well.companies,
|
2021-08-27 14:21:48 +05:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
rows.push(row);
|
|
|
|
|
|
|
|
|
|
if (!filtersSectionsType.some((el) => el.text === section.caption))
|
|
|
|
|
filtersSectionsType.push({
|
|
|
|
|
text: section.caption,
|
|
|
|
|
value: section.caption,
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
setWellsStat(rows);
|
|
|
|
|
}, [id, clusterData]);
|
|
|
|
|
|
|
|
|
|
const rowSelection = {
|
|
|
|
|
selectedRowKeys: selectedWellsKeys,
|
|
|
|
|
onChange: (keys, items) => {
|
|
|
|
|
setSelectedWells(items);
|
|
|
|
|
setSelectedWellsKeys(keys);
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<>
|
|
|
|
|
<Table
|
|
|
|
|
columns={columns}
|
|
|
|
|
dataSource={wellsStat}
|
|
|
|
|
size={"small"}
|
|
|
|
|
bordered
|
|
|
|
|
scroll={{ x: true, y: 620 }}
|
|
|
|
|
rowSelection={rowSelection}
|
|
|
|
|
pagination={false}
|
|
|
|
|
/>
|
|
|
|
|
<Divider />
|
|
|
|
|
<Badge.Ribbon text="комбинированная скважина" color="gray">
|
|
|
|
|
<h3>
|
|
|
|
|
Выбранные секции<></>
|
|
|
|
|
</h3>
|
|
|
|
|
</Badge.Ribbon>
|
|
|
|
|
<Table
|
|
|
|
|
columns={columns}
|
|
|
|
|
dataSource={selectedWells}
|
|
|
|
|
rowSelection={rowSelection}
|
|
|
|
|
size={"small"}
|
|
|
|
|
bordered
|
|
|
|
|
scroll={{ x: true }}
|
|
|
|
|
pagination={false}
|
|
|
|
|
/>
|
|
|
|
|
</>
|
|
|
|
|
);
|
|
|
|
|
}
|