forked from ddrilling/asb_cloud_front
Compare commits
1 Commits
dev
...
feature/st
Author | SHA1 | Date | |
---|---|---|---|
a491f2c191 |
@ -6,6 +6,7 @@ import {
|
|||||||
ControlOutlined,
|
ControlOutlined,
|
||||||
DatabaseOutlined,
|
DatabaseOutlined,
|
||||||
DeploymentUnitOutlined,
|
DeploymentUnitOutlined,
|
||||||
|
DesktopOutlined,
|
||||||
ExperimentOutlined,
|
ExperimentOutlined,
|
||||||
FilePdfOutlined,
|
FilePdfOutlined,
|
||||||
FolderOutlined,
|
FolderOutlined,
|
||||||
@ -17,6 +18,7 @@ import {
|
|||||||
import { makeItem, PrivateWellMenu } from '@components/PrivateWellMenu'
|
import { makeItem, PrivateWellMenu } from '@components/PrivateWellMenu'
|
||||||
|
|
||||||
export const menuItems = [
|
export const menuItems = [
|
||||||
|
makeItem('Начальная страница', 'start_screen', [], <DesktopOutlined />),
|
||||||
makeItem('Телеметрия', 'telemetry', [], <FundViewOutlined />, [
|
makeItem('Телеметрия', 'telemetry', [], <FundViewOutlined />, [
|
||||||
makeItem('Мониторинг', 'telemetry', [], <FundViewOutlined />),
|
makeItem('Мониторинг', 'telemetry', [], <FundViewOutlined />),
|
||||||
makeItem('Сообщения', 'messages', [], <AlertOutlined />),
|
makeItem('Сообщения', 'messages', [], <AlertOutlined />),
|
||||||
|
@ -51,7 +51,7 @@ const styleBlock = {
|
|||||||
// fill: '#b3b3b3',
|
// fill: '#b3b3b3',
|
||||||
// };
|
// };
|
||||||
|
|
||||||
export const RigMnemo = memo(({ blockPosition, bitPosition, wellDepth }) => {
|
export const RigMnemo = memo(({ blockPosition, bitPosition, wellDepth, ...other }) => {
|
||||||
let blockPositionY = 0
|
let blockPositionY = 0
|
||||||
let bitPositionY = 0
|
let bitPositionY = 0
|
||||||
|
|
||||||
@ -81,7 +81,7 @@ export const RigMnemo = memo(({ blockPosition, bitPosition, wellDepth }) => {
|
|||||||
const bitTranslate = `translate(0, ${bitPositionY})`
|
const bitTranslate = `translate(0, ${bitPositionY})`
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<svg width={'170'} height={'540'} viewBox={'20 0 40 145'} version={'1.1'}>
|
<svg width={'170'} height={'540'} viewBox={'20 0 40 145'} version={'1.1'} {...other}>
|
||||||
<g id={'Casing'} style={styleCasing}>
|
<g id={'Casing'} style={styleCasing}>
|
||||||
<path d={'m 29.897917,67.46875 v -1.322917 l 4.497916,-10e-7 v -1.322916 h 3.96875 v 1.322916 l 4.497917,10e-7 v 1.322917 z'} />
|
<path d={'m 29.897917,67.46875 v -1.322917 l 4.497916,-10e-7 v -1.322916 h 3.96875 v 1.322916 l 4.497917,10e-7 v 1.322917 z'} />
|
||||||
<path d={'M 31.75,97.895832 V 67.468749 h 9.260416 v 30.427083 z'} />
|
<path d={'M 31.75,97.895832 V 67.468749 h 9.260416 v 30.427083 z'} />
|
164
src/pages/Well/StartScreen/index.jsx
Normal file
164
src/pages/Well/StartScreen/index.jsx
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
import { Descriptions, Progress } from 'antd'
|
||||||
|
import { memo, useMemo, useState } from 'react'
|
||||||
|
|
||||||
|
import { makeColumn, makeNumericColumn, makeNumericRender, Table } from '@components/Table'
|
||||||
|
import { withPermissions } from '@utils'
|
||||||
|
|
||||||
|
import RigMnemo from './RigMnemo'
|
||||||
|
|
||||||
|
import '@styles/start_screen.less'
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
makeColumn('', 'caption'),
|
||||||
|
makeNumericColumn('Ходы насоса', 'count', undefined, undefined, makeNumericRender(0)),
|
||||||
|
makeNumericColumn('Расход на входе, л/с', 'input_flow'),
|
||||||
|
makeNumericColumn('Давление на входе, атм', 'input_pressure'),
|
||||||
|
]
|
||||||
|
|
||||||
|
const data = [
|
||||||
|
{ caption: 'Насос №1', count: 55, input_flow: 16, input_pressure: 32 },
|
||||||
|
{ caption: 'Насос №2', count: 55, input_flow: 16, input_pressure: 34 },
|
||||||
|
]
|
||||||
|
|
||||||
|
const formatMSE = (percent) => (
|
||||||
|
<div style={{ display: 'flex', flexDirection: 'column' }}>
|
||||||
|
<span>MSE</span>
|
||||||
|
<span>{percent}%</span>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
|
const formatRPM = (percent) => (
|
||||||
|
<div style={{ display: 'flex', flexDirection: 'column' }}>
|
||||||
|
<span>{percent}</span>
|
||||||
|
<span>об/мин</span>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
|
const StatusDashboardItem = memo(({ status, title }) => {
|
||||||
|
const color = useMemo(() => {
|
||||||
|
switch (status) {
|
||||||
|
case 'off':
|
||||||
|
case 'error':
|
||||||
|
return '#ff4d4f'
|
||||||
|
case 'warn':
|
||||||
|
case 'warning':
|
||||||
|
return '#faad14'
|
||||||
|
case 'ok':
|
||||||
|
case 'success':
|
||||||
|
return '#52c41a'
|
||||||
|
default: return '#1890ff'
|
||||||
|
}
|
||||||
|
}, [status])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Progress
|
||||||
|
type={'dashboard'}
|
||||||
|
format={() => title}
|
||||||
|
trailColor={color}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
const StartScreen = memo(() => {
|
||||||
|
const [dataSaub, setDataSaub] = useState([])
|
||||||
|
|
||||||
|
const dataLast = useMemo(() => dataSaub.at(-1), [dataSaub])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={'start-screen'}>
|
||||||
|
<div className={'left-panel'}>
|
||||||
|
<div className={'card customer'}>
|
||||||
|
<div className={'header'}>Заказчик</div>
|
||||||
|
<div className={'content'}>ООО "Газпромнефть-Хантос"</div>
|
||||||
|
</div>
|
||||||
|
<div className={'card current-process'}>
|
||||||
|
<div className={'header'}>Текущий процесс</div>
|
||||||
|
<div className={'content'}>Бурение в слайде с АПД</div>
|
||||||
|
</div>
|
||||||
|
<div className={'card mnemo'}>
|
||||||
|
<div className={'header'}>Конструкция скважины</div>
|
||||||
|
<div style={{ overflow: 'hidden', flex: '1 0 fit-content' }}>
|
||||||
|
<RigMnemo
|
||||||
|
width={'auto'}
|
||||||
|
height={'100%'}
|
||||||
|
wellDepth={dataLast?.wellDepth ?? Number.NaN}
|
||||||
|
bitPosition={dataLast?.bitDepth ?? Number.NaN}
|
||||||
|
blockPosition={dataLast?.blockPosition ?? Number.NaN}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className={'right-panel'}>
|
||||||
|
<div className={'top-panel'}>
|
||||||
|
<div className={'main-panel'}>
|
||||||
|
<div className={'card drilling-modes'}>
|
||||||
|
<div className={'header'}>Режимы бурения</div>
|
||||||
|
<div className={'content'}>
|
||||||
|
<Descriptions bordered size={'small'} column={2} style={{ flexGrow: 1 }}>
|
||||||
|
<Descriptions.Item label={'Wд, т'}>12.5</Descriptions.Item>
|
||||||
|
<Descriptions.Item label={'dP, атм'}>32</Descriptions.Item>
|
||||||
|
<Descriptions.Item label={'Nрот, об/мин'}>40</Descriptions.Item>
|
||||||
|
<Descriptions.Item label={'Вес на крюке, т'}>68</Descriptions.Item>
|
||||||
|
<Descriptions.Item label={'Таль. блок, м'}>13.4</Descriptions.Item>
|
||||||
|
<Descriptions.Item label={'Mрот, кН/м'}>40</Descriptions.Item>
|
||||||
|
</Descriptions>
|
||||||
|
<Progress type={'dashboard'} format={formatMSE} percent={53} status={'normal'} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className={'card pumping-equipment'}>
|
||||||
|
<div className={'header'}>Работа насосного оборудования</div>
|
||||||
|
<div className={'content'}>
|
||||||
|
<Table
|
||||||
|
bordered
|
||||||
|
size={'small'}
|
||||||
|
className={'content'}
|
||||||
|
columns={columns}
|
||||||
|
dataSource={data}
|
||||||
|
pagination={false}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className={'card saub-modules-work'}>
|
||||||
|
<div className={'header'}>Работа модулей САУБ</div>
|
||||||
|
<div className={'content'}>
|
||||||
|
<span>Spin Master:</span>
|
||||||
|
<span>кол-во обр. - 4.5обр; V 25 обр/мин</span>
|
||||||
|
<div style={{ display: 'flex', gap: '10px' }}>
|
||||||
|
<Progress type={'dashboard'} format={formatRPM} percent={25} />
|
||||||
|
<StatusDashboardItem title={'АПД'} status={'error'} />
|
||||||
|
<StatusDashboardItem title={'MCE'} status={'warning'} />
|
||||||
|
<StatusDashboardItem title={'Торк'} status={'success'} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className={'card drilling-fluid'}>
|
||||||
|
<div className={'header'}>Буровой раствор</div>
|
||||||
|
<div className={'content'}>
|
||||||
|
<Descriptions className={'content'} bordered size={'small'} column={1}>
|
||||||
|
<Descriptions.Item label={'Vсумм, м3'}>68</Descriptions.Item>
|
||||||
|
<Descriptions.Item label={'V 1 емк, м3'}>68</Descriptions.Item>
|
||||||
|
<Descriptions.Item label={'V 2 емк, м3'}>68</Descriptions.Item>
|
||||||
|
<Descriptions.Item label={'V 3 емк, м3'}>68</Descriptions.Item>
|
||||||
|
<Descriptions.Item label={'V 4 емк, м3'}>68</Descriptions.Item>
|
||||||
|
<Descriptions.Item label={'V 5 емк, м3'}>68</Descriptions.Item>
|
||||||
|
<Descriptions.Item label={'V 6 емк, м3'}>68</Descriptions.Item>
|
||||||
|
<Descriptions.Item label={'Vцсго, м3'}>12</Descriptions.Item>
|
||||||
|
<Descriptions.Item label={'Темп вх'}>31</Descriptions.Item>
|
||||||
|
<Descriptions.Item label={'Темп вых'}>31</Descriptions.Item>
|
||||||
|
<Descriptions.Item label={'Плот вх'}>1.23</Descriptions.Item>
|
||||||
|
<Descriptions.Item label={'Темп вых'}>1.25</Descriptions.Item>
|
||||||
|
</Descriptions>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className={'card operation-journal'}>
|
||||||
|
<div className={'header'}>Журнал операций</div>
|
||||||
|
<div className={'content'}></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
export default withPermissions(StartScreen, [])
|
@ -18,6 +18,7 @@ const WellCase = lazy(() => import('./WellCase'))
|
|||||||
const Analytics = lazy(() => import('./Analytics'))
|
const Analytics = lazy(() => import('./Analytics'))
|
||||||
const Documents = lazy(() => import('./Documents'))
|
const Documents = lazy(() => import('./Documents'))
|
||||||
const Telemetry = lazy(() => import('./Telemetry'))
|
const Telemetry = lazy(() => import('./Telemetry'))
|
||||||
|
const StartScreen = lazy(() => import('./StartScreen'))
|
||||||
const WellOperations = lazy(() => import('./WellOperations'))
|
const WellOperations = lazy(() => import('./WellOperations'))
|
||||||
const DrillingProgram = lazy(() => import('./DrillingProgram'))
|
const DrillingProgram = lazy(() => import('./DrillingProgram'))
|
||||||
|
|
||||||
@ -93,6 +94,8 @@ const Well = memo(() => {
|
|||||||
<Route index element={<Navigate to={'telemetry'} replace />} />
|
<Route index element={<Navigate to={'telemetry'} replace />} />
|
||||||
<Route path={'*'} element={<NoAccessComponent />} />
|
<Route path={'*'} element={<NoAccessComponent />} />
|
||||||
|
|
||||||
|
<Route path={'start_screen/*'} element={<StartScreen />} />
|
||||||
|
|
||||||
<Route path={'telemetry/*'} element={<Telemetry />}>
|
<Route path={'telemetry/*'} element={<Telemetry />}>
|
||||||
<Route index element={<Navigate to={'telemetry'} replace />} />
|
<Route index element={<Navigate to={'telemetry'} replace />} />
|
||||||
<Route path={'*'} element={<NoAccessComponent />} />
|
<Route path={'*'} element={<NoAccessComponent />} />
|
||||||
|
92
src/styles/start_screen.less
Normal file
92
src/styles/start_screen.less
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
.start-screen {
|
||||||
|
--screen-gap: 10px;
|
||||||
|
--screen-padding: 10px;
|
||||||
|
|
||||||
|
@screen-gap: var(--screen-gap);
|
||||||
|
@screen-padding: var(--screen-padding);
|
||||||
|
|
||||||
|
.flex-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: stretch;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: @screen-gap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-container;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
& .card {
|
||||||
|
.flex-container;
|
||||||
|
flex-direction: column;
|
||||||
|
border: 1px solid #f0f0f0;
|
||||||
|
padding: @screen-padding;
|
||||||
|
|
||||||
|
& > .header {
|
||||||
|
align-self: center;
|
||||||
|
text-align: center;
|
||||||
|
width: 80%;
|
||||||
|
border-bottom: 1px solid #f0f0f0;
|
||||||
|
padding-bottom: 5px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > .content { flex-grow: 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
& .left-panel, & .right-panel {
|
||||||
|
flex-direction: column;
|
||||||
|
.flex-container;
|
||||||
|
}
|
||||||
|
|
||||||
|
& .right-panel, & .left-panel .mnemo { flex-grow: 1; }
|
||||||
|
|
||||||
|
& .left-panel {
|
||||||
|
& .customer .content, & .current-process .content {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& .right-panel {
|
||||||
|
& .top-panel {
|
||||||
|
.flex-container;
|
||||||
|
|
||||||
|
& .main-panel {
|
||||||
|
.flex-container;
|
||||||
|
flex-direction: column;
|
||||||
|
flex-grow: 1;
|
||||||
|
|
||||||
|
& > * { flex-grow: 1; }
|
||||||
|
|
||||||
|
& .drilling-modes .content {
|
||||||
|
display: flex;
|
||||||
|
gap: @screen-gap;
|
||||||
|
}
|
||||||
|
|
||||||
|
& .saub-modules-work .content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: @screen-gap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& .operation-journal { flex-grow: 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
& .top-panel { .flex-container; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 1280px) {
|
||||||
|
.start-screen {
|
||||||
|
--screen-gap: 7.5px;
|
||||||
|
--screen-padding: 7.5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 1024px) {
|
||||||
|
.start-screen {
|
||||||
|
--screen-gap: 5px;
|
||||||
|
--screen-padding: 5px;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user