forked from ddrilling/asb_cloud_front
* Добавлено базовое описание README.md
* TODO.md удалён за ненадобностью * В index.html добавлено более подробное описание цветовых тем * Части методов utils добавлена документация, явно указаны типа данных
This commit is contained in:
parent
5f03b751ee
commit
3af90800ff
62
README.md
62
README.md
@ -1 +1,61 @@
|
|||||||
Проект веб части ASB cloud
|
![ASB Logo](concept/ImagesSrc/logo_Asb.svg)
|
||||||
|
# Проект веб части ASB cloud
|
||||||
|
|
||||||
|
# Порядок запуска
|
||||||
|
## 1. Установка пакетов
|
||||||
|
Для запуска установки необходимо иметь уже установленый [NPM](https://www.npmjs.com).
|
||||||
|
|
||||||
|
Установка выполняется одной командой:
|
||||||
|
```bash
|
||||||
|
npm i
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2. Автогенерация сервисов
|
||||||
|
Для корректной работы веб-приложения необходимо наличие сервисов работы с RestAPI.
|
||||||
|
|
||||||
|
Для их автогенерации требуется уже запущенная серверная часть.
|
||||||
|
|
||||||
|
Автогенерацию можно запустить с помощью уже прописанных в [package.json](package.json) скриптов, либо вручную.
|
||||||
|
|
||||||
|
Если сервер запущен на текущей машине достаточно написать:
|
||||||
|
```bash
|
||||||
|
npm run update_openapi
|
||||||
|
```
|
||||||
|
|
||||||
|
Для получения сервисов с основного сервера:
|
||||||
|
```bash
|
||||||
|
npm run update_openapi_server
|
||||||
|
```
|
||||||
|
|
||||||
|
или же ручной вариант:
|
||||||
|
```bash
|
||||||
|
npx openapi -i http://{IP_ADDRESS}:{PORT}/swagger/v1/swagger.json -o src/services/api
|
||||||
|
```
|
||||||
|
|
||||||
|
где ***IP_ADDRESS*** и ***PORT*** это соответственно IP-адрес и порт сервера.
|
||||||
|
|
||||||
|
На данный момент имеются следующие IP-адреса:
|
||||||
|
| IP-адрес | Описание |
|
||||||
|
|:-|:-|
|
||||||
|
| 127.0.0.1:5000 | Локальный адрес вашей машины (привязан к `update_openapi`) |
|
||||||
|
| 192.168.1.70:5000 | Локальный адрес development-сервера (привязан к `update_openapi_server`) |
|
||||||
|
| 46.146.209.148:89 | Внешний адрес development-сервера |
|
||||||
|
| 46.146.209.148 | Внешний адрес production-сервера |
|
||||||
|
|
||||||
|
## 3. Компиляция production-версии приложения
|
||||||
|
После выполнения вышеописанных пунктов приложение готово к компиляции.
|
||||||
|
|
||||||
|
Для компиляции досточно выполнить команду:
|
||||||
|
```bash
|
||||||
|
npm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
После завершения этой команды скомпилированное приложение будет находиться в появившейся директории [build/](build/).
|
||||||
|
|
||||||
|
## 4. Запуск development-версии приложения
|
||||||
|
В [package.json](package.json) необходимо проверить и при необходимости изменить значение в поле ***proxy*** (пара адрес-порт сервера с RestAPI) на актуальное.
|
||||||
|
|
||||||
|
После чего выполнить запуск командой:
|
||||||
|
```bash
|
||||||
|
npm start
|
||||||
|
```
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="ru">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<meta name="theme-color" content="#000000" />
|
<meta name="theme-color" content="white" />
|
||||||
|
<meta name="theme-color" media="(prefers-color-scheme: light)" content="white" />
|
||||||
|
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="black" />
|
||||||
<meta
|
<meta
|
||||||
name="description"
|
name="description"
|
||||||
content="онлайн мониторинг процесса бурения в реальном времени в офисе заказчика"
|
content="Онлайн мониторинг процесса бурения в реальном времени в офисе заказчика"
|
||||||
/>
|
/>
|
||||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||||
<title>АСБ Vision</title>
|
<title>АСБ Vision</title>
|
||||||
|
@ -19,7 +19,7 @@ export function isRawDate(value: unknown): value is RawDate {
|
|||||||
return !isNaN(Date.parse(String(value)))
|
return !isNaN(Date.parse(String(value)))
|
||||||
}
|
}
|
||||||
|
|
||||||
export const formatDate = (date: unknown, utc = false, format = defaultFormat) => {
|
export const formatDate = (date: unknown, utc: boolean = false, format: string = defaultFormat) => {
|
||||||
if (!isRawDate(date)) return null
|
if (!isRawDate(date)) return null
|
||||||
const out = utc ? moment.utc(date).local() : moment(date)
|
const out = utc ? moment.utc(date).local() : moment(date)
|
||||||
return out.format(format)
|
return out.format(format)
|
||||||
@ -40,8 +40,8 @@ export const periodToString = (time?: number) => {
|
|||||||
return `${days > 0 ? days : ''} ${toFixed(hours)}:${toFixed(minutes)}:${toFixed(seconds)}`
|
return `${days > 0 ? days : ''} ${toFixed(hours)}:${toFixed(minutes)}:${toFixed(seconds)}`
|
||||||
}
|
}
|
||||||
|
|
||||||
export const calcDuration = (start: unknown, end: unknown) => {
|
export const calcDuration = (start: unknown, end: unknown): number | undefined => {
|
||||||
if (!isRawDate(start) || !isRawDate(end)) return
|
if (!isRawDate(start) || !isRawDate(end)) return undefined
|
||||||
return (+new Date(end) - +new Date(start)) * timeInS.millisecond / timeInS.day
|
return (+new Date(end) - +new Date(start)) * timeInS.millisecond / timeInS.day
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,20 +1,25 @@
|
|||||||
import { OperationStatService, WellOperationDto, WellOperationDtoPlanFactPredictBase } from '@api'
|
import { OperationStatService, WellOperationDto, WellOperationDtoPlanFactPredictBase } from '@api'
|
||||||
|
|
||||||
const maxPrefix = 'isMax'
|
const maxPrefix: string = 'isMax'
|
||||||
const minPrefix = 'isMin'
|
const minPrefix: string = 'isMin'
|
||||||
|
|
||||||
export const getPrecision = (number: number) => Number.isFinite(number) ? number.toFixed(2) : '-'
|
export const getPrecision = (number: number): string => Number.isFinite(number) ? number.toFixed(2) : '-'
|
||||||
|
|
||||||
export type KeyType = number | string
|
export type KeyType = number | string
|
||||||
|
|
||||||
export const nwtIdCategory = 1043
|
export const nwtIdCategory: number = 1043
|
||||||
|
|
||||||
export type SaubData = WellOperationDto & {
|
export type SaubData = WellOperationDto & {
|
||||||
isNPT?: boolean // Относится ли операция к НПВ
|
/** Относится ли операция к НПВ */
|
||||||
key?: number // ID операции
|
isNPT?: boolean
|
||||||
depth?: number // Глубина
|
/** ID операции */
|
||||||
date?: string // Дата
|
key?: number
|
||||||
nptHours?: number // Колличество часов НПВ с начала бурения до текущего момента
|
/** Глубина */
|
||||||
|
depth?: number
|
||||||
|
/** Дата */
|
||||||
|
date?: string
|
||||||
|
/** Колличество часов НПВ с начала бурения до текущего момента */
|
||||||
|
nptHours?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getOperations = async (idWell: number): Promise<{
|
export const getOperations = async (idWell: number): Promise<{
|
||||||
@ -25,11 +30,13 @@ export const getOperations = async (idWell: number): Promise<{
|
|||||||
}> => {
|
}> => {
|
||||||
const ops = await OperationStatService.getTvd(idWell)
|
const ops = await OperationStatService.getTvd(idWell)
|
||||||
|
|
||||||
if (!ops) return {
|
if (!ops) {
|
||||||
operations: [],
|
return {
|
||||||
plan: [],
|
operations: [],
|
||||||
fact: [],
|
plan: [],
|
||||||
predict: [],
|
fact: [],
|
||||||
|
predict: [],
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const convert = (operation?: WellOperationDto): SaubData => ({
|
const convert = (operation?: WellOperationDto): SaubData => ({
|
||||||
|
@ -1,25 +1,62 @@
|
|||||||
export type { RawDate, timeInS } from './datetime'
|
|
||||||
export { isRawDate, formatDate, defaultFormat, periodToString } from './datetime'
|
export { isRawDate, formatDate, defaultFormat, periodToString } from './datetime'
|
||||||
|
export type { RawDate, timeInS } from './datetime'
|
||||||
|
|
||||||
export const headerHeight = 64
|
export const headerHeight: number = 64
|
||||||
|
|
||||||
export const mainFrameSize = () => ({
|
export const mainFrameSize = () => ({
|
||||||
width: window.innerWidth,
|
width: window.innerWidth,
|
||||||
height: window.innerHeight - headerHeight
|
height: window.innerHeight - headerHeight
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Возвращает
|
||||||
|
*
|
||||||
|
* @param arr Входящие данные
|
||||||
|
* @param def Значение по-умолчанию
|
||||||
|
*
|
||||||
|
* @returns Если `arr` - массив будет возвращено оно, иначе `def`
|
||||||
|
*/
|
||||||
export const arrayOrDefault = <T extends unknown>(arr?: unknown, def: T[] = []): T[] => Array.isArray(arr) ? arr : def
|
export const arrayOrDefault = <T extends unknown>(arr?: unknown, def: T[] = []): T[] => Array.isArray(arr) ? arr : def
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Копирует данные в глубину.
|
||||||
|
*
|
||||||
|
* @remarks
|
||||||
|
* При копированиий объектов, содержащих функций может возникнуть исключение.
|
||||||
|
* Не предназначено для копирования функций.
|
||||||
|
*
|
||||||
|
* @param data Копируемые данные
|
||||||
|
* @returns Полная копия `data`
|
||||||
|
*/
|
||||||
export const deepCopy = <T extends any>(data: T): T => JSON.parse(JSON.stringify(data ?? null))
|
export const deepCopy = <T extends any>(data: T): T => JSON.parse(JSON.stringify(data ?? null))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Маппинг полей объекта
|
||||||
|
*
|
||||||
|
* @param data Входящие данные
|
||||||
|
* @param handler Обработчик
|
||||||
|
*
|
||||||
|
* @returns Объект с обработанными полями
|
||||||
|
*/
|
||||||
export const wrapValues = <T, R>(data: Record<string, T>, handler: (data: T, key: string, object: Record<string, T>) => R): Record<string, R> =>
|
export const wrapValues = <T, R>(data: Record<string, T>, handler: (data: T, key: string, object: Record<string, T>) => R): Record<string, R> =>
|
||||||
Object.fromEntries(Object.entries(data).map(([key, value]) => [key, handler(value, key, data)]))
|
Object.fromEntries(Object.entries(data).map(([key, value]) => [key, handler(value, key, data)]))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Генерирует массив чисел в заданном диапазоне
|
||||||
|
*
|
||||||
|
* @param end Конечное значение
|
||||||
|
* @param start Начальное значение
|
||||||
|
*
|
||||||
|
* @returns Массив чисел в диапазоне от `start` до `end`
|
||||||
|
*/
|
||||||
export const range = (end: number, start: number = 0) => Array.from({ length: end - start }, (_, i) => start + i)
|
export const range = (end: number, start: number = 0) => Array.from({ length: end - start }, (_, i) => start + i)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Объединить типы, исключив совпадающие поля справа
|
* Объединить типы, исключив совпадающие поля справа.
|
||||||
* @param T Тип, передаваемый полностью
|
*
|
||||||
* @param R Аддитивный тип
|
* @typeParam T - Тип, передаваемый полностью
|
||||||
|
* @typeParam R - Аддитивный тип
|
||||||
|
*
|
||||||
|
* @returns Общий тип с полным `T` и несовпадающими полями из `R`
|
||||||
*/
|
*/
|
||||||
export type OmitExtends<T, R> = T & Omit<R, keyof T>
|
export type OmitExtends<T, R> = T & Omit<R, keyof T>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
export const makeStringCutter = (maxLength = 100, separator = ' ', suffix = '...') => (comment?: string) => {
|
export const makeStringCutter = (maxLength: number = 100, separator: string = ' ', suffix: string = '...') => (comment?: string) => {
|
||||||
if (!comment || comment.length < maxLength)
|
if (!comment || comment.length < maxLength)
|
||||||
return comment
|
return comment
|
||||||
let lastSep = comment.lastIndexOf(separator, maxLength)
|
const lastSep = comment.lastIndexOf(separator, maxLength)
|
||||||
if (lastSep < 0)
|
if (lastSep < 0)
|
||||||
return comment.substring(0, maxLength - suffix.length) + suffix
|
return comment.substring(0, maxLength - suffix.length) + suffix
|
||||||
return comment.substring(0, lastSep)
|
return comment.substring(0, lastSep)
|
||||||
|
Loading…
Reference in New Issue
Block a user