add translation for tags
This commit is contained in:
145
migrations/003_tag_translations.sql
Normal file
145
migrations/003_tag_translations.sql
Normal file
@@ -0,0 +1,145 @@
|
||||
CREATE TABLE IF NOT EXISTS tag_translation (
|
||||
edge_id text NOT NULL,
|
||||
tag_id text NOT NULL,
|
||||
locale text NOT NULL DEFAULT 'ru',
|
||||
display_name text NOT NULL,
|
||||
source text,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
PRIMARY KEY (edge_id, tag_id, locale)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS tag_translation_edge_locale_idx
|
||||
ON tag_translation (edge_id, locale, tag_id);
|
||||
|
||||
INSERT INTO tag_translation (edge_id, tag_id, locale, display_name, source)
|
||||
VALUES
|
||||
('edge5', 'hook_weight_1', 'ru', 'Вес на крюке 1', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'hookblock_position', 'ru', 'Положение крюкоблока', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'manifold_pressure_1', 'ru', 'Давление в манифольде 1', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'hydraulic_tong_torque', 'ru', 'Момент на гидроключе', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'hook_weight_2', 'ru', 'Вес на крюке 2', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'outlet_flow', 'ru', 'Расход на выходе', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'gas_1_lfl', 'ru', 'Загазованность 1 (НКПР)', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'gas_1_h2s', 'ru', 'Загазованность 1 (H2S)', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'gas_2_h2s', 'ru', 'Загазованность 2 (H2S)', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'gas_3_h2s', 'ru', 'Загазованность 3 (H2S)', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'outlet_temperature', 'ru', 'Температура на выходе', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'inlet_flow_1', 'ru', 'Расход на входе 1', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'akb_tong_torque', 'ru', 'Момент на ключе АКБ', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'rotary_torque', 'ru', 'Момент на роторе', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'rotary_rpm', 'ru', 'Обороты ротора', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'manifold_pressure_2', 'ru', 'Давление в манифольде 2', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'machine_tong_torque', 'ru', 'Момент на машинном ключе', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'inlet_temperature', 'ru', 'Температура на входе', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'gas_4_h2s', 'ru', 'Загазованность 4 (H2S)', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'density_1', 'ru', 'Плотность 1', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'density_2', 'ru', 'Плотность 2', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'density_3', 'ru', 'Плотность 3', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'density_4', 'ru', 'Плотность 4', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'density_5', 'ru', 'Плотность 5', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'density_6', 'ru', 'Плотность 6', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'level_1', 'ru', 'Уровень 1', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'level_2', 'ru', 'Уровень 2', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'level_3', 'ru', 'Уровень 3', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'level_4', 'ru', 'Уровень 4', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'level_5', 'ru', 'Уровень 5', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'level_6', 'ru', 'Уровень 6', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'volume_1', 'ru', 'Объем 1', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'volume_2', 'ru', 'Объем 2', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'volume_3', 'ru', 'Объем 3', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'volume_4', 'ru', 'Объем 4', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'volume_5', 'ru', 'Объем 5', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'volume_6', 'ru', 'Объем 6', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'total_volume', 'ru', 'Объем суммарный', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'weight_on_bit', 'ru', 'Нагрузка на долото', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'penetration_rate', 'ru', 'Скорость проходки', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'tripping_speed', 'ru', 'Скорость СПО', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'tool_depth', 'ru', 'Глубина инструмента', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'bottom_depth', 'ru', 'Глубина забоя', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'outlet_flow_change', 'ru', 'Изм. расхода на выходе', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'stand_feed', 'ru', 'Подача свечи', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'lowered_stands_count', 'ru', 'Количество опущенных свеч', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'inlet_flow_2', 'ru', 'Расход на входе 2', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'slips_position', 'ru', 'Положение клиньев', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'gas_2_lfl', 'ru', 'Загазованность 2 (НКПР)', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'level_7', 'ru', 'Уровень 7', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'volume_7', 'ru', 'Объем 7', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'top_drive_rpm', 'ru', 'Обороты СВП', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'top_drive_torque', 'ru', 'Крутящий момент СВП', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'level_8', 'ru', 'Уровень 8', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'volume_8', 'ru', 'Объем 8', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'pump_1_strokes', 'ru', 'Ходы насоса 1', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'pump_2_strokes', 'ru', 'Ходы насоса 2', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'pump_strokes_total', 'ru', 'Сумма ходов насосов', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'gas_3_lfl', 'ru', 'Загазованность 3 (НКПР)', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'pump_3_strokes', 'ru', 'Ходы насоса 3', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'level_9', 'ru', 'Уровень 9', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'volume_9', 'ru', 'Объем 9', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'level_10', 'ru', 'Уровень 10', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'volume_10', 'ru', 'Объем 10', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'level_11', 'ru', 'Уровень 11', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'volume_11', 'ru', 'Объем 11', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'level_12', 'ru', 'Уровень 12', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'volume_12', 'ru', 'Объем 12', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'level_13', 'ru', 'Уровень 13', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'volume_13', 'ru', 'Объем 13', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'level_14', 'ru', 'Уровень 14', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'volume_14', 'ru', 'Объем 14', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'total_volume_change', 'ru', 'Изменение суммарного объема (±)', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'casing_tong_1_torque', 'ru', 'Момент на ключе 1 обсадных труб', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'casing_tong_2_torque', 'ru', 'Момент на ключе 2 обсадных труб', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'drill_pipe_tong_hydraulic_pressure', 'ru', 'Давление в гидросистеме ключа для бурильных труб', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'drill_pipe_tong_high_low_speed', 'ru', 'Высокая/низкая скорость ключа бурильных труб', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'hydraulic_distributor_section_1', 'ru', 'Секция 1 гидрораспределителя', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'hydraulic_distributor_section_2', 'ru', 'Секция 2 гидрораспределителя', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'tong_type', 'ru', 'Тип ключа', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'gas_4_lfl', 'ru', 'Загазованность 4 (НКПР)', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'gas_5_lfl', 'ru', 'Загазованность 5 (НКПР)', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'gas_6_lfl', 'ru', 'Загазованность 6 (НКПР)', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'gas_7_lfl', 'ru', 'Загазованность 7 (НКПР)', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'gas_8_lfl', 'ru', 'Загазованность 8 (НКПР)', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'guyline_tension_1', 'ru', 'Усилие в растяжке 1', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'guyline_tension_2', 'ru', 'Усилие в растяжке 2', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'guyline_tension_3', 'ru', 'Усилие в растяжке 3', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'guyline_tension_4', 'ru', 'Усилие в растяжке 4', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'gas_9_lfl_ch4', 'ru', 'Загазованность 9 (НКПР) CH4', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'gas_10_lfl_ch4', 'ru', 'Загазованность 10 (НКПР) CH4', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'gas_1_lfl_c3h8', 'ru', 'Загазованность 1 (НКПР) C3H8', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'gas_2_lfl_c3h8', 'ru', 'Загазованность 2 (НКПР) C3H8', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'gas_3_lfl_c3h8', 'ru', 'Загазованность 3 (НКПР) C3H8', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'gas_4_lfl_c3h8', 'ru', 'Загазованность 4 (НКПР) C3H8', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'gas_5_lfl_c3h8', 'ru', 'Загазованность 5 (НКПР) C3H8', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'gas_6_lfl_c3h8', 'ru', 'Загазованность 6 (НКПР) C3H8', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'gas_7_lfl_c3h8', 'ru', 'Загазованность 7 (НКПР) C3H8', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'gas_8_lfl_c3h8', 'ru', 'Загазованность 8 (НКПР) C3H8', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'gas_9_lfl_c3h8', 'ru', 'Загазованность 9 (НКПР) C3H8', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'gas_10_lfl_c3h8', 'ru', 'Загазованность 10 (НКПР) C3H8', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'rotary_torque_2', 'ru', 'Момент на роторе 2', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'density_7', 'ru', 'Плотность 7', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'density_8', 'ru', 'Плотность 8', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'density_9', 'ru', 'Плотность 9', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'density_10', 'ru', 'Плотность 10', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'bit_position_above_bottom', 'ru', 'Положение долота над забоем', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'disperser_pump_pressure', 'ru', 'Давление насоса диспергации', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'disperser_pump_strokes', 'ru', 'Число ходов насоса диспергации', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'disperser_pump_outlet_flow', 'ru', 'Расход на выходе насоса диспергации', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'pump_1_outlet_flow', 'ru', 'Расход на выходе насоса 1', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'pump_2_outlet_flow', 'ru', 'Расход на выходе насоса 2', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'drilling_line_runtime', 'ru', 'Наработка талевого каната (в реальном времени)', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'tripping_fill_volume_total', 'ru', 'Суммарный объем долива скважины при СПО', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'pump_1_outlet_pressure', 'ru', 'Давление на выходе насоса 1', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'pump_2_outlet_pressure', 'ru', 'Давление на выходе насоса 2', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'drilling_time_per_meter', 'ru', 'Время бурения 1м проходки', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'gas_11_lfl_ch4', 'ru', 'Загазованность 11 (НКПР) CH4', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'gas_12_lfl_ch4', 'ru', 'Загазованность 12 (НКПР) CH4', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'gas_13_lfl_ch4', 'ru', 'Загазованность 13 (НКПР) CH4', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'pump_3_outlet_flow', 'ru', 'Расход на выходе насоса 3', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'pump_3_outlet_pressure', 'ru', 'Давление на выходе насоса 3', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'gas_5_h2s', 'ru', 'Загазованность 5 (H2S)', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'gas_6_h2s', 'ru', 'Загазованность 6 (H2S)', 'edge5-modbus_rus.json'),
|
||||
('edge5', 'gas_7_h2s', 'ru', 'Загазованность 7 (H2S)', 'edge5-modbus_rus.json')
|
||||
ON CONFLICT (edge_id, tag_id, locale) DO UPDATE SET
|
||||
display_name = EXCLUDED.display_name,
|
||||
source = EXCLUDED.source,
|
||||
updated_at = now();
|
||||
@@ -6,6 +6,7 @@ import { EdgeModule } from './edge/edge.module';
|
||||
import { HealthController } from './health.controller';
|
||||
import { HistoryModule } from './history/history.module';
|
||||
import { IngestModule } from './ingest/ingest.module';
|
||||
import { TagTranslationModule } from './tag-translation/tag-translation.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@@ -15,6 +16,7 @@ import { IngestModule } from './ingest/ingest.module';
|
||||
EdgeModule,
|
||||
CurrentModule,
|
||||
HistoryModule,
|
||||
TagTranslationModule,
|
||||
],
|
||||
controllers: [HealthController],
|
||||
})
|
||||
|
||||
19
src/tag-translation/dto/get-tag-translations.dto.ts
Normal file
19
src/tag-translation/dto/get-tag-translations.dto.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { Transform } from 'class-transformer';
|
||||
import { IsArray, IsNotEmpty, IsOptional, IsString } from 'class-validator';
|
||||
import { parseCommaSeparatedList } from '../../common/query-list';
|
||||
|
||||
export class GetTagTranslationsDto {
|
||||
@IsNotEmpty()
|
||||
@IsString()
|
||||
edge!: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
locale?: string;
|
||||
|
||||
@IsOptional()
|
||||
@Transform(({ value }) => parseCommaSeparatedList(value))
|
||||
@IsArray()
|
||||
@IsString({ each: true })
|
||||
tags?: string[];
|
||||
}
|
||||
15
src/tag-translation/tag-translation.controller.ts
Normal file
15
src/tag-translation/tag-translation.controller.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { Controller, Get, Header, Query } from '@nestjs/common';
|
||||
import { GetTagTranslationsDto } from './dto/get-tag-translations.dto';
|
||||
import { TagTranslationService } from './tag-translation.service';
|
||||
|
||||
@Controller('tag-translations')
|
||||
export class TagTranslationController {
|
||||
constructor(private readonly translations: TagTranslationService) {}
|
||||
|
||||
@Get()
|
||||
@Header('Cache-Control', 'no-store')
|
||||
findByEdge(@Query() query: GetTagTranslationsDto) {
|
||||
return this.translations.findByEdge(query);
|
||||
}
|
||||
}
|
||||
|
||||
10
src/tag-translation/tag-translation.module.ts
Normal file
10
src/tag-translation/tag-translation.module.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TagTranslationController } from './tag-translation.controller';
|
||||
import { TagTranslationService } from './tag-translation.service';
|
||||
|
||||
@Module({
|
||||
controllers: [TagTranslationController],
|
||||
providers: [TagTranslationService],
|
||||
})
|
||||
export class TagTranslationModule {}
|
||||
|
||||
67
src/tag-translation/tag-translation.service.ts
Normal file
67
src/tag-translation/tag-translation.service.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { parseCommaSeparatedList } from '../common/query-list';
|
||||
import { normalizeRequiredText } from '../common/normalize-text';
|
||||
import { DbService } from '../db/db.service';
|
||||
import { GetTagTranslationsDto } from './dto/get-tag-translations.dto';
|
||||
|
||||
type TagTranslationRow = {
|
||||
edge_id: string;
|
||||
tag_id: string;
|
||||
locale: string;
|
||||
display_name: string;
|
||||
source: string | null;
|
||||
updated_at: Date;
|
||||
};
|
||||
|
||||
type TagTranslationItem = {
|
||||
edge: string;
|
||||
tag: string;
|
||||
locale: string;
|
||||
displayName: string;
|
||||
source: string | null;
|
||||
updatedAt: Date;
|
||||
};
|
||||
|
||||
type TagTranslationResponse = {
|
||||
edge: string;
|
||||
locale: string;
|
||||
items: TagTranslationItem[];
|
||||
};
|
||||
|
||||
@Injectable()
|
||||
export class TagTranslationService {
|
||||
constructor(private readonly db: DbService) {}
|
||||
|
||||
// Возвращает человекочитаемые названия тегов для выбранного edge и языка.
|
||||
async findByEdge(query: GetTagTranslationsDto): Promise<TagTranslationResponse> {
|
||||
const edge = normalizeRequiredText(query.edge, 'edge');
|
||||
const locale = (query.locale?.trim() || 'ru').toLowerCase();
|
||||
const tags = parseCommaSeparatedList(query.tags) ?? null;
|
||||
|
||||
const result = await this.db.query<TagTranslationRow>(
|
||||
`
|
||||
SELECT edge_id, tag_id, locale, display_name, source, updated_at
|
||||
FROM tag_translation
|
||||
WHERE edge_id = $1
|
||||
AND locale = $2
|
||||
AND ($3::text[] IS NULL OR tag_id = ANY($3::text[]))
|
||||
ORDER BY tag_id ASC
|
||||
`,
|
||||
[edge, locale, tags],
|
||||
);
|
||||
|
||||
return {
|
||||
edge,
|
||||
locale,
|
||||
items: result.rows.map((row) => ({
|
||||
edge: row.edge_id,
|
||||
tag: row.tag_id,
|
||||
locale: row.locale,
|
||||
displayName: row.display_name,
|
||||
source: row.source,
|
||||
updatedAt: row.updated_at,
|
||||
})),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user