72 lines
1.8 KiB
TypeScript
72 lines
1.8 KiB
TypeScript
import { Injectable } from '@nestjs/common';
|
||
import { DbService } from '../db/db.service';
|
||
|
||
type EdgeRow = {
|
||
id: string;
|
||
name: string;
|
||
tag_count: number;
|
||
current_tag_count: number;
|
||
live_tag_count: number;
|
||
last_data_at: Date | null;
|
||
created_at: Date;
|
||
updated_at: Date;
|
||
};
|
||
|
||
type EdgeItem = {
|
||
id: string;
|
||
name: string;
|
||
tagCount: number;
|
||
currentTagCount: number;
|
||
liveTagCount: number;
|
||
lastDataAt: Date | null;
|
||
createdAt: Date;
|
||
updatedAt: Date;
|
||
};
|
||
|
||
type EdgeResponse = {
|
||
items: EdgeItem[];
|
||
};
|
||
|
||
@Injectable()
|
||
export class EdgeService {
|
||
constructor(private readonly db: DbService) {}
|
||
|
||
// Возвращает каталог буровых с легкой сводкой по свежести данных для dashboard UI.
|
||
async findAll(): Promise<EdgeResponse> {
|
||
const result = await this.db.query<EdgeRow>(`
|
||
SELECT
|
||
e.id,
|
||
e.name,
|
||
count(DISTINCT et.tag_id)::integer AS tag_count,
|
||
count(DISTINCT cv.tag_id)::integer AS current_tag_count,
|
||
count(DISTINCT cv.tag_id) FILTER (
|
||
WHERE cv.time >= now() - INTERVAL '30 seconds'
|
||
)::integer AS live_tag_count,
|
||
max(cv.time) AS last_data_at,
|
||
e.created_at,
|
||
e.updated_at
|
||
FROM edge AS e
|
||
LEFT JOIN edge_tag AS et
|
||
ON et.edge_id = e.id
|
||
LEFT JOIN current_values AS cv
|
||
ON cv.edge_id = e.id
|
||
AND cv.tag_id = et.tag_id
|
||
GROUP BY e.id, e.name, e.created_at, e.updated_at
|
||
ORDER BY e.name ASC, e.id ASC
|
||
`);
|
||
|
||
return {
|
||
items: result.rows.map((row) => ({
|
||
id: row.id,
|
||
name: row.name,
|
||
tagCount: row.tag_count,
|
||
currentTagCount: row.current_tag_count,
|
||
liveTagCount: row.live_tag_count,
|
||
lastDataAt: row.last_data_at,
|
||
createdAt: row.created_at,
|
||
updatedAt: row.updated_at,
|
||
})),
|
||
};
|
||
}
|
||
}
|