cf2-2 выбор скважин перенесён в заголовок

This commit is contained in:
Alexey 2021-05-12 17:53:35 +05:00
parent 218d4b97fd
commit 86974e201b
20 changed files with 21642 additions and 80 deletions

21408
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,7 @@
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"dependencies": { "dependencies": {
"@craco/craco": "^6.1.1", "@craco/craco": "^6.1.2",
"@microsoft/signalr": "^5.0.5", "@microsoft/signalr": "^5.0.5",
"@testing-library/jest-dom": "^5.11.10", "@testing-library/jest-dom": "^5.11.10",
"@testing-library/react": "^11.2.6", "@testing-library/react": "^11.2.6",
@ -11,9 +11,11 @@
"antd": "^4.15.0", "antd": "^4.15.0",
"chart.js": "^3.0.2", "chart.js": "^3.0.2",
"chartjs-adapter-date-fns": "^1.1.0-beta.1", "chartjs-adapter-date-fns": "^1.1.0-beta.1",
"chartjs-plugin-datalabels": "^2.0.0-beta.1",
"craco-less": "^1.17.1", "craco-less": "^1.17.1",
"date-fns": "^2.20.0", "date-fns": "^2.20.0",
"react": "^17.0.2", "react": "^17.0.2",
"react-datepicker": "^3.8.0",
"react-dom": "^17.0.2", "react-dom": "^17.0.2",
"react-router-dom": "^5.2.0", "react-router-dom": "^5.2.0",
"react-scripts": "4.0.3", "react-scripts": "4.0.3",
@ -29,7 +31,7 @@
"react_test": "react-scripts test", "react_test": "react-scripts test",
"eject": "react-scripts eject" "eject": "react-scripts eject"
}, },
"proxy": "http://localhost:5000", "proxy": "http://192.168.1.70:5000",
"eslintConfig": { "eslintConfig": {
"extends": [ "extends": [
"react-app", "react-app",

View File

@ -0,0 +1,76 @@
import { useState, useEffect } from 'react'
import { WellService } from '../services/api'
import Loader from '../components/Loader'
import { TreeSelect } from 'antd' // TreeSelect
import { useHistory } from 'react-router-dom'
const groupBy = (table, ...keys) => {
let key = keys[0]
let groups = table.reduce((rv, item) => {
let keyValue = item[key]
let group = rv.find(o=>o.title === keyValue)
if(!group)
{
group = {
title: keyValue,
value: keys.length === 1 ? item : `${key} ${keyValue} ${item['id']}`,
selectable: keys.length === 1,
children:[]}
rv.push(group)
}
if(keys.length > 1)
group.children.push(item);
return rv;
}, []);
if(keys.length > 1){
for(let group of groups){
group.children = groupBy(group.children, ...keys.slice(1))
}
}
return groups
};
export default function WellTreeSelector(props){
const [wells, setWells] = useState([])
const [wellsTree, setWellsTree] = useState([]) // wellsTree,
const [loader, setLoader] = useState(false)
const history = useHistory()
let updateWellsList = async () => {
setLoader(true)
try{
let newWells = (await WellService.getWells()).map(w =>{return {key:w.id, ...w}})
let wellsTree = groupBy(newWells, 'deposit', 'cluster', 'caption')
console.log(wellsTree)
setWells( newWells )
setWellsTree(wellsTree)
}
catch(e){
console.error(`${e.message}`);
}
setLoader(false)
}
useEffect(()=>{updateWellsList()}, [])
const onChange = (value) =>{
;
}
return(
<>
<TreeSelect /* не работает пока */
style={{ width: '25%',
alignItems: 'center' }}
placeholder="Выберите месторождение"
treeData={wellsTree}
treeDefaultExpandAll
onChange={onChange}
/>
{loader&&<Loader/>}
</>
)
}

View File

@ -0,0 +1,16 @@
import ChartDataLabels from 'chartjs-plugin-datalabels'
const defaoultOptionsDeepLabels = {
borderWidth: 1,
borderColor: black,
borderRadius: 4,
clamp: true,
display: true,
data: {
datasets: [{
datalabels: {
color: '#0f4000'
}
}]
}
}

3
src/pages/Analise.jsx Normal file
View File

@ -0,0 +1,3 @@
export default function Analise(props){
return(<h2>Анализ</h2>)
}

5
src/pages/Archive.jsx Normal file
View File

@ -0,0 +1,5 @@
export default function Archive(props){
return(<h2>Архив</h2>)
}

View File

@ -1,3 +1,3 @@
export default function Files(props){ export default function Files(props){
return(<h2>Files</h2>) return(<h2>Файлы</h2>)
} }

64
src/pages/Header.jsx Normal file
View File

@ -0,0 +1,64 @@
import { useState } from 'react';
import { Layout, Button } from 'antd'
import { UserOutlined, MenuOutlined } from '@ant-design/icons'
import logo from '../images/logo_32.png'
import { Link } from "react-router-dom"
import WellTreeSelector from '../components/WellTreeSelector'
const { Header } = Layout
const groupBy = (table, ...keys) => {
let key = keys[0]
let groups = table.reduce((rv, item) => {
let keyValue = item[key]
let group = rv.find(o=>o.title === keyValue)
if(!group)
{
group = {
title: keyValue,
value: keys.length === 1 ? item : `${key} ${keyValue} ${item['id']}`,
selectable: keys.length === 1,
children:[]}
rv.push(group)
}
if(keys.length > 1)
group.children.push(item);
return rv;
}, []);
if(keys.length > 1){
for(let group of groups){
group.children = groupBy(group.children, ...keys.slice(1))
}
}
return groups
};
export default function PageHeader(props){
const [sidebarVisible, setSidebarVisible] = useState(true)
const login = localStorage['login']
let handleLogout = () => {
localStorage.removeItem('login')
localStorage.removeItem('token')
}
return(
<Layout>
<Header className="header">
<Button icon={<MenuOutlined />} onClick={()=>setSidebarVisible(!sidebarVisible)}/>
<img src={logo} alt="АСБ" className="logo"/>
<WellTreeSelector />
<h1 className="title">Мониторинг</h1>
<Link to="/login" onClick={handleLogout}>
<Button icon={<UserOutlined/>}>
({login}) Выход
</Button>
</Link>
</Header>
</Layout>
)
};

View File

@ -1,35 +1,30 @@
import { Layout, Menu, Button, } from 'antd' import { Layout, Menu, } from 'antd' // Button,
import { UserOutlined, MenuOutlined, FundViewOutlined, FolderOutlined } from '@ant-design/icons' import { FundViewOutlined, FolderOutlined } from '@ant-design/icons' // UserOutlined, MenuOutlined,
import logo from '../images/logo_32.png'
import { useState } from 'react' import { useState } from 'react'
import { Switch, Route, Redirect, Link} from "react-router-dom" import { Switch, Route, Redirect, Link} from "react-router-dom"
import Wells from './Wells' import Wells from './Wells'
import TelemetryView from './TelemetryView' import TelemetryView from './TelemetryView'
import Files from './Files' import Files from './Files'
import Archive from './Archive'
import Messages from './Messages'
import Report from './Report'
import Analise from './Analise'
import PageHeader from './Header'
const { Header, Content, Sider } = Layout const { Content, Sider } = Layout // Header
export default function Main(){ export default function Main(){
const [sidebarVisible, setSidebarVisible] = useState(true) const [sidebarVisible] = useState(true) // setSidebarVisible
const login = localStorage['login'] // const login = localStorage['login']
let handleLogout = () => { // let handleLogout = () => {
localStorage.removeItem('login') // localStorage.removeItem('login')
localStorage.removeItem('token') // localStorage.removeItem('token')
} // }
return( return(
<Layout> <Layout>
<Header className="header"> <PageHeader />
<Button icon={<MenuOutlined />} onClick={()=>setSidebarVisible(!sidebarVisible)}/>
<img src={logo} alt="АСБ" className="logo"/>
<h1 className="title">Мониторинг</h1>
<Link to="/login" onClick={handleLogout}>
<Button icon={<UserOutlined/>}>
({login}) Выход
</Button>
</Link>
</Header>
<Layout> <Layout>
{sidebarVisible && {sidebarVisible &&
<Sider width={200} className="site-layout-background"> <Sider width={200} className="site-layout-background">
@ -43,16 +38,16 @@ export default function Main(){
<Link to="/well">Мониторинг</Link> <Link to="/well">Мониторинг</Link>
</Menu.Item> </Menu.Item>
<Menu.Item key="2" icon= {<FolderOutlined />}> <Menu.Item key="2" icon= {<FolderOutlined />}>
<Link to="/file">Архив</Link> <Link to="/archive">Архив</Link>
</Menu.Item> </Menu.Item>
<Menu.Item key="3" icon= {<FolderOutlined />}> <Menu.Item key="3" icon= {<FolderOutlined />}>
<Link to="/file">Сообщения</Link> <Link to="/messages">Сообщения</Link>
</Menu.Item> </Menu.Item>
<Menu.Item key="4" icon= {<FolderOutlined />}> <Menu.Item key="4" icon= {<FolderOutlined />}>
<Link to="/file">Рапорт</Link> <Link to="/report">Рапорт</Link>
</Menu.Item> </Menu.Item>
<Menu.Item key="5" icon= {<FolderOutlined />}> <Menu.Item key="5" icon= {<FolderOutlined />}>
<Link to="/file">Анализ</Link> <Link to="/analise">Анализ</Link>
</Menu.Item> </Menu.Item>
<Menu.Item key="6" icon= {<FolderOutlined />}> <Menu.Item key="6" icon= {<FolderOutlined />}>
<Link to="/file">Файлы</Link> <Link to="/file">Файлы</Link>
@ -67,6 +62,18 @@ export default function Main(){
<Route path="/file"> <Route path="/file">
<Files /> <Files />
</Route> </Route>
<Route path="/archive">
<Archive />
</Route>
<Route path="/messages">
<Messages />
</Route>
<Route path="/report">
<Report />
</Route>
<Route path="/analise">
<Analise />
</Route>
<Route path="/well/:id"> <Route path="/well/:id">
<TelemetryView/> <TelemetryView/>
</Route> </Route>

3
src/pages/Messages.jsx Normal file
View File

@ -0,0 +1,3 @@
export default function Messages(props){
return(<h2>Сообщения</h2>)
}

32
src/pages/Report.jsx Normal file
View File

@ -0,0 +1,32 @@
import React, { useState } from "react";
import DatePicker, { registerLocale, setDefaultLocale } from "react-datepicker";
import ru from 'date-fns/locale/ru';
import "react-datepicker/dist/react-datepicker.css";
registerLocale('ru', ru)
export default function Report(props){
const PeriodOfTime = () => {
const [startDate, setStartDate] = useState(new Date());
return (
<DatePicker
selected={startDate}
onChange={date => setStartDate(date)}
locale='ru'
/>
);
};
return(<>
<h2>Рапорт</h2>
<h3>Выбор за период времени и расширение файла</h3>
<select>
<option>las</option>
<option>pdf</option>
</select>
<PeriodOfTime />
</>
)
}

View File

@ -115,7 +115,7 @@ export default function TelemetryView(props){
} }
useEffect( ()=> { useEffect( ()=> {
DataService.get(id) DataService.getData(id)
.then(handleReceiveDataSaub) .then(handleReceiveDataSaub)
.catch(error=>console.error(error)) .catch(error=>console.error(error))

View File

@ -1,7 +1,7 @@
import { useState, useEffect } from 'react'; import { useState, useEffect } from 'react'
import { WellService } from '../services/api' import { WellService } from '../services/api'
import Loader from '../components/Loader' import Loader from '../components/Loader'
import { Table, TreeSelect } from 'antd'; import { Table } from 'antd' // TreeSelect
import { useHistory } from 'react-router-dom' import { useHistory } from 'react-router-dom'
const columns = [ const columns = [
@ -59,14 +59,14 @@ const groupBy = (table, ...keys) => {
export default function Wells(props){ export default function Wells(props){
const [wells, setWells] = useState([]) const [wells, setWells] = useState([])
const [wellsTree, setWellsTree] = useState([]) const [wellsTree, setWellsTree] = useState([]) // wellsTree,
const [loader, setLoader] = useState(false) const [loader, setLoader] = useState(false)
const history = useHistory() const history = useHistory()
let updateWellsList = async () => { let updateWellsList = async () => {
setLoader(true) setLoader(true)
try{ try{
let newWells = (await WellService.get()).map(w =>{return {key:w.id, ...w}}) let newWells = (await WellService.getWells()).map(w =>{return {key:w.id, ...w}})
let wellsTree = groupBy(newWells, 'deposit', 'cluster', 'caption') let wellsTree = groupBy(newWells, 'deposit', 'cluster', 'caption')
console.log(wellsTree) console.log(wellsTree)
setWells( newWells ) setWells( newWells )
@ -85,7 +85,7 @@ export default function Wells(props){
} }
return(<> return(<>
<h2>Wells</h2> <h2>Скважины</h2>
<Table <Table
dataSource={wells} dataSource={wells}
columns={columns} columns={columns}
@ -94,13 +94,13 @@ export default function Wells(props){
onClick: event => {history.push(`well/${record.id}`)}, onClick: event => {history.push(`well/${record.id}`)},
}; };
}}/> }}/>
<TreeSelect {/* <TreeSelect
style={{ width: '100%' }} style={{ width: '100%' }}
placeholder="Please select" placeholder="Please select"
treeData={wellsTree} treeData={wellsTree}
treeDefaultExpandAll treeDefaultExpandAll
onChange={onChange} onChange={onChange}
/> /> */}
{loader&&<Loader/>} {loader&&<Loader/>}
</>) </>)
} }

View File

@ -3,11 +3,12 @@
/* eslint-disable */ /* eslint-disable */
export type TelemetryInfoDto = { export type TelemetryInfoDto = {
date?: string; drillingStartDate?: string;
timeZoneId?: string | null; timeZoneId?: string | null;
timeZoneOffsetTotalHours?: number; timeZoneOffsetTotalHours?: number;
caption?: string | null; well?: string | null;
cluster?: string | null; cluster?: string | null;
customer?: string | null;
deposit?: string | null; deposit?: string | null;
hmiVersion?: string | null; hmiVersion?: string | null;
plcVersion?: string | null; plcVersion?: string | null;

View File

@ -6,7 +6,6 @@ export type TelemetryMessageDto = {
id?: number; id?: number;
date?: string; date?: string;
idEvent?: number; idEvent?: number;
state?: number | null;
idTelemetryUser?: number | null; idTelemetryUser?: number | null;
arg0?: string | null; arg0?: string | null;
arg1?: string | null; arg1?: string | null;

View File

@ -16,7 +16,7 @@ export class DataService {
* @returns DataSaubBaseDto Success * @returns DataSaubBaseDto Success
* @throws ApiError * @throws ApiError
*/ */
public static async get( public static async getData(
wellId: number, wellId: number,
begin?: string, begin?: string,
intervalSec: number = 600, intervalSec: number = 600,

View File

@ -9,31 +9,31 @@ export class MessageService {
/** /**
* Выдает список сообщений по скважине * Выдает список сообщений по скважине
* @param wellId id скважины * @param wellId id скважины
* @param skip для пагинации кол-во записей пропустить
* @param take для пагинации кол-во записей
* @param categoryids список категорий * @param categoryids список категорий
* @param begin дата начала * @param begin дата начала
* @param end окончание * @param end окончание
* @param skip для пагинации кол-во записей пропустить
* @param take для пагинации кол-во записей
* @returns MessageDtoPaginationContainer Success * @returns MessageDtoPaginationContainer Success
* @throws ApiError * @throws ApiError
*/ */
public static async get( public static async getMessage(
wellId: number, wellId: number,
skip: number,
take: number = 32,
categoryids?: Array<number>, categoryids?: Array<number>,
begin?: string, begin?: string,
end?: string, end?: string,
skip: number,
take: number = 32,
): Promise<MessageDtoPaginationContainer> { ): Promise<MessageDtoPaginationContainer> {
const result = await __request({ const result = await __request({
method: 'GET', method: 'GET',
path: `/api/well/${wellId}/message`, path: `/api/well/${wellId}/message`,
query: { query: {
'skip': skip,
'take': take,
'categoryids': categoryids, 'categoryids': categoryids,
'begin': begin, 'begin': begin,
'end': end, 'end': end,
'skip': skip,
'take': take,
}, },
}); });
return result.body; return result.body;

View File

@ -17,7 +17,7 @@ export class TelemetryService {
* @returns any Success * @returns any Success
* @throws ApiError * @throws ApiError
*/ */
public static async info( public static async postInfo(
uid: string, uid: string,
requestBody?: TelemetryInfoDto, requestBody?: TelemetryInfoDto,
): Promise<any> { ): Promise<any> {
@ -36,7 +36,7 @@ requestBody?: TelemetryInfoDto,
* @returns any Success * @returns any Success
* @throws ApiError * @throws ApiError
*/ */
public static async data( public static async postData(
uid: string, uid: string,
requestBody?: Array<DataSaubBaseDto>, requestBody?: Array<DataSaubBaseDto>,
): Promise<any> { ): Promise<any> {
@ -55,7 +55,7 @@ requestBody?: Array<DataSaubBaseDto>,
* @returns any Success * @returns any Success
* @throws ApiError * @throws ApiError
*/ */
public static async message( public static async postMessages(
uid: string, uid: string,
requestBody?: Array<TelemetryMessageDto>, requestBody?: Array<TelemetryMessageDto>,
): Promise<any> { ): Promise<any> {
@ -74,7 +74,7 @@ requestBody?: Array<TelemetryMessageDto>,
* @returns any Success * @returns any Success
* @throws ApiError * @throws ApiError
*/ */
public static async events( public static async postEvents(
uid: string, uid: string,
requestBody?: Array<EventDto>, requestBody?: Array<EventDto>,
): Promise<any> { ): Promise<any> {
@ -93,7 +93,7 @@ requestBody?: Array<EventDto>,
* @returns any Success * @returns any Success
* @throws ApiError * @throws ApiError
*/ */
public static async users( public static async postUsers(
uid: string, uid: string,
requestBody?: Array<TelemetryUserDto>, requestBody?: Array<TelemetryUserDto>,
): Promise<any> { ): Promise<any> {

View File

@ -10,7 +10,7 @@ export class WellService {
* @returns WellDto Success * @returns WellDto Success
* @throws ApiError * @throws ApiError
*/ */
public static async get(): Promise<Array<WellDto>> { public static async getWells(): Promise<Array<WellDto>> {
const result = await __request({ const result = await __request({
method: 'GET', method: 'GET',
path: `/api/well`, path: `/api/well`,