Добавлен макет начального экрана

This commit is contained in:
Александр Сироткин 2022-11-16 11:08:03 +05:00
parent 9c9fc63bc2
commit a491f2c191
5 changed files with 263 additions and 2 deletions

View File

@ -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 />),

View File

@ -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'} />

View 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, [])

View File

@ -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 />} />

View 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;
}
}