added formula

pull/39/head
DmitriyA 2025-10-21 09:14:58 -04:00
parent aaa2482f04
commit 6a47ef4601
6 changed files with 152 additions and 6 deletions

3
.env
View File

@ -28,6 +28,9 @@ COOKIE_SAME_SITE=lax
RANGES_API_URL=http://192.168.2.39:9999
RANGES_API_ENDPOINT=/api/ranges/9999
FORMULA_API_URL=http://192.168.2.39:9999
FORMULA_API_ENDPOINT=/api/integration/7777
# ClickHouse
CLICKHOUSE_HOST=http://192.168.2.37:8123
CLICKHOUSE_USER=vlad

View File

@ -42,7 +42,7 @@ async function bootstrap() {
});
// Настройка CORS
app.enableCors({//ПОСТАВИТЬ ПРОКСИ, ЧТОБЫ КОРС НЕ РУГАЛСЯ, ИЗМЕНЕНИЕ ПОЛИТИКИ СЕТЕВЫХ ПАКЕТОВ. ПИШУ IP СВОЙ, А ПОРТ ПРОКСИ. REVERSE PROXY.
app.enableCors({
origin: [process.env.FRONTEND_URL, "http://dev.msf.enode"],
credentials: true,
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS',

View File

@ -0,0 +1,48 @@
import { Controller, Get, Post, Body, HttpException, HttpStatus, Param } from '@nestjs/common';
import { FormulaService } from './formula.service';
import { MenuService } from './menu.service';
@Controller('formula')
export class FormulaController {
constructor(
private readonly FormulaService: FormulaService,
private readonly menuService: MenuService
) { }
@Get(':id')
async getFormulaData(@Param('id') id: string) {
try {
return await this.FormulaService.getFormulaData(id);
} catch (error) {
throw new HttpException('Failed to fetch Formula data', HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@Post(':id/update')
async updateFormulaData(
@Param('id') id: string,
@Body() data: any
) {
if (!data) {
throw new HttpException('Invalid data format', HttpStatus.BAD_REQUEST);
}
try {
const result = await this.FormulaService.updateFormulaData(id, data);
this.menuService.invalidateCache();
return result;
} catch (error) {
throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
// OPTIONS метод для получения данных (как в вашем примере curl)
@Get(':id/options')
async getFormulaOptions(@Param('id') id: string) {
try {
return await this.FormulaService.getFormulaOptions(id);
} catch (error) {
throw new HttpException('Failed to fetch Formula options', HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}

View File

@ -0,0 +1,92 @@
import { Injectable } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { firstValueFrom } from 'rxjs';
import { ConfigService } from '@nestjs/config';
@Injectable()
export class FormulaService {
private readonly FormulaApiUrl: string;
private readonly FormulaApiEndpoint: string;
constructor(
private readonly httpService: HttpService,
private readonly configService: ConfigService
) {
this.FormulaApiUrl = this.configService.get<string>('FORMULA_API_URL', 'http://192.168.2.39:9999');
this.FormulaApiEndpoint = this.configService.get<string>('FORMULA_API_ENDPOINT', '/api/integration/7777');
}
async getFormulaData(id: string): Promise<any> {
try {
const response = await firstValueFrom(
this.httpService.get(`${this.FormulaApiUrl}${this.FormulaApiEndpoint}/${id}`, {
headers: {
'Accept': 'application/json'
}
})
);
return response.data;
} catch (error) {
console.error('Failed to fetch Formula data:', error);
this.handleError(error);
return {};
}
}
async getFormulaOptions(id: string): Promise<any> {
try {
const url = `${this.FormulaApiUrl}${this.FormulaApiEndpoint}`;
console.log('Fetching Formula options via OPTIONS:', url);
const response = await firstValueFrom(
this.httpService.request({
method: 'OPTIONS',
url,
headers: { 'Accept': 'application/json' }
})
);
console.log('Response from Formula API:', response.data);
return response.data;
} catch (error) {
console.error('Failed to fetch Formula options:', error);
this.handleError(error);
return [];
}
}
async updateFormulaData(id: string, data: any) {
try {
const response = await firstValueFrom(
this.httpService.post(
`${this.FormulaApiUrl}${this.FormulaApiEndpoint}/${id}`,
data,
{
headers: {
'Content-Type': 'application/json'
},
}
)
);
return response.data;
} catch (error) {
console.error('Failed to update Formula data:', error);
this.handleError(error);
throw new Error('Failed to update Formula data');
}
}
private handleError(error: any): void {
if (error.response) {
console.error('Server responded with:', {
status: error.response.status,
data: error.response.data
});
} else if (error.request) {
console.error('No response received:', error.request);
} else {
console.error('Request setup error:', error.message);
}
}
}

View File

@ -5,10 +5,12 @@ import { MenuService } from './menu.service';
import { PrometheusModule } from '../prometheus/prometheus.module';
import { RangeService } from './range.service';
import { RangeController } from './range.controller';
import { FormulaController } from './formula.controller';
import { FormulaService } from './formula.service';
@Module({
imports: [PrometheusModule, HttpModule],
controllers: [MenuController, RangeController],
providers: [MenuService, RangeService]
controllers: [MenuController, RangeController, FormulaController],
providers: [MenuService, RangeService, FormulaService]
})
export class MenuModule { }

View File

@ -56,13 +56,14 @@ export class MetricsGateway implements OnModuleInit, OnModuleDestroy {
);
const wsPort = Number(this.configService.get('WS_PORT') || 3001);
this.httpServer.listen(wsPort, () => {
const wsHost = this.configService.get('WS_HOST') || '0.0.0.0';
this.httpServer.listen(wsPort, wsHost, () => {
this.logger.log(
`WebSocket server running at ws://localhost:${wsPort}/metrics-ws`
`WebSocket server running at ws://${wsHost}:${wsPort}/metrics-ws`
);
});
}
onModuleDestroy() {
// Очистка всех ресурсов
this.clearAllSubscriptions();