This commit is contained in:
Mephimeow
2026-04-29 12:28:30 +00:00
parent 0f8a80b6e1
commit 6c170fe1a2
13 changed files with 2450 additions and 7 deletions
+160
View File
@@ -6,10 +6,36 @@ import (
"github.com/jackc/pgx/v5/pgxpool"
)
type RepositoryInterface interface {
GetBales(ctx context.Context) ([]Bale, error)
GetBaleByID(ctx context.Context, id string) (*Bale, error)
CreateBale(ctx context.Context, input Bale) (*Bale, error)
UpdateBale(ctx context.Context, id string, input Bale) (*Bale, error)
DeleteBale(ctx context.Context, id string) error
GetBaleTypeByType(ctx context.Context, typeName string) (*BaleType, error)
GetBaleTypes(ctx context.Context) ([]BaleType, error)
GetBaleTypeByID(ctx context.Context, id int) (*BaleType, error)
CreateBaleType(ctx context.Context, input BaleType) (*BaleType, error)
UpdateBaleType(ctx context.Context, id int, input BaleType) (*BaleType, error)
DeleteBaleType(ctx context.Context, id int) error
GetLineStages(ctx context.Context) ([]LineStage, error)
GetLineStageByID(ctx context.Context, id int) (*LineStage, error)
CreateLineStage(ctx context.Context, input LineStage) (*LineStage, error)
UpdateLineStage(ctx context.Context, id int, input LineStage) (*LineStage, error)
DeleteLineStage(ctx context.Context, id int) error
CreateSensorReading(ctx context.Context, input SensorReading) (*SensorReading, error)
GetSensorReadingsByStage(ctx context.Context, stageID int) ([]SensorReading, error)
CreateProductionEvent(ctx context.Context, input ProductionEvent) (*ProductionEvent, error)
GetProductionEventsByStage(ctx context.Context, stageID int) ([]ProductionEvent, error)
GetLineStats(ctx context.Context) (*LineStats, error)
}
type Repository struct {
pool *pgxpool.Pool
}
var _ RepositoryInterface = (*Repository)(nil)
func NewRepository(pool *pgxpool.Pool) *Repository {
return &Repository{
pool: pool,
@@ -151,3 +177,137 @@ func (r *Repository) DeleteBaleType(ctx context.Context, id int) error {
_, err := r.pool.Exec(ctx, "DELETE FROM bale_types WHERE id = $1", id)
return err
}
func (r *Repository) GetLineStages(ctx context.Context) ([]LineStage, error) {
rows, err := r.pool.Query(ctx, "SELECT id, name, description, stage_order, equipment, mqtt_topic FROM line_stages ORDER BY stage_order")
if err != nil {
return nil, err
}
defer rows.Close()
var stages []LineStage
for rows.Next() {
var s LineStage
if err := rows.Scan(&s.ID, &s.Name, &s.Description, &s.Order, &s.Equipment, &s.MQTTTopic); err != nil {
return nil, err
}
stages = append(stages, s)
}
return stages, nil
}
func (r *Repository) GetLineStageByID(ctx context.Context, id int) (*LineStage, error) {
var s LineStage
err := r.pool.QueryRow(ctx, "SELECT id, name, description, stage_order, equipment, mqtt_topic FROM line_stages WHERE id = $1", id).Scan(&s.ID, &s.Name, &s.Description, &s.Order, &s.Equipment, &s.MQTTTopic)
if err != nil {
return nil, err
}
return &s, nil
}
func (r *Repository) CreateLineStage(ctx context.Context, input LineStage) (*LineStage, error) {
var s LineStage
err := r.pool.QueryRow(ctx, `
INSERT INTO line_stages (name, description, stage_order, equipment, mqtt_topic)
VALUES ($1, $2, $3, $4, $5)
RETURNING id, name, description, stage_order, equipment, mqtt_topic`, input.Name, input.Description, input.Order, input.Equipment, input.MQTTTopic).Scan(&s.ID, &s.Name, &s.Description, &s.Order, &s.Equipment, &s.MQTTTopic)
if err != nil {
return nil, err
}
return &s, nil
}
func (r *Repository) UpdateLineStage(ctx context.Context, id int, input LineStage) (*LineStage, error) {
var s LineStage
err := r.pool.QueryRow(ctx, `
UPDATE line_stages SET name = $1, description = $2, stage_order = $3, equipment = $4, mqtt_topic = $5 WHERE id = $6
RETURNING id, name, description, stage_order, equipment, mqtt_topic`, input.Name, input.Description, input.Order, input.Equipment, input.MQTTTopic, id).Scan(&s.ID, &s.Name, &s.Description, &s.Order, &s.Equipment, &s.MQTTTopic)
if err != nil {
return nil, err
}
return &s, nil
}
func (r *Repository) DeleteLineStage(ctx context.Context, id int) error {
_, err := r.pool.Exec(ctx, "DELETE FROM line_stages WHERE id = $1", id)
return err
}
func (r *Repository) CreateSensorReading(ctx context.Context, input SensorReading) (*SensorReading, error) {
var s SensorReading
err := r.pool.QueryRow(ctx, `
INSERT INTO sensor_readings (stage_id, sensor, value, unit, timestamp)
VALUES ($1, $2, $3, $4, $5)
RETURNING id, stage_id, sensor, value, unit, timestamp`, input.StageID, input.Sensor, input.Value, input.Unit, input.Timestamp).Scan(&s.ID, &s.StageID, &s.Sensor, &s.Value, &s.Unit, &s.Timestamp)
if err != nil {
return nil, err
}
return &s, nil
}
func (r *Repository) GetSensorReadingsByStage(ctx context.Context, stageID int) ([]SensorReading, error) {
rows, err := r.pool.Query(ctx, "SELECT id, stage_id, sensor, value, unit, timestamp FROM sensor_readings WHERE stage_id = $1 ORDER BY timestamp DESC LIMIT 100", stageID)
if err != nil {
return nil, err
}
defer rows.Close()
var readings []SensorReading
for rows.Next() {
var r SensorReading
if err := rows.Scan(&r.ID, &r.StageID, &r.Sensor, &r.Value, &r.Unit, &r.Timestamp); err != nil {
return nil, err
}
readings = append(readings, r)
}
return readings, nil
}
func (r *Repository) CreateProductionEvent(ctx context.Context, input ProductionEvent) (*ProductionEvent, error) {
var e ProductionEvent
err := r.pool.QueryRow(ctx, `
INSERT INTO production_events (stage_id, event_type, data, timestamp)
VALUES ($1, $2, $3, $4)
RETURNING id, stage_id, event_type, data, timestamp`, input.StageID, input.EventType, input.Data, input.Timestamp).Scan(&e.ID, &e.StageID, &e.EventType, &e.Data, &e.Timestamp)
if err != nil {
return nil, err
}
return &e, nil
}
func (r *Repository) GetProductionEventsByStage(ctx context.Context, stageID int) ([]ProductionEvent, error) {
rows, err := r.pool.Query(ctx, "SELECT id, stage_id, event_type, data, timestamp FROM production_events WHERE stage_id = $1 ORDER BY timestamp DESC LIMIT 100", stageID)
if err != nil {
return nil, err
}
defer rows.Close()
var events []ProductionEvent
for rows.Next() {
var e ProductionEvent
if err := rows.Scan(&e.ID, &e.StageID, &e.EventType, &e.Data, &e.Timestamp); err != nil {
return nil, err
}
events = append(events, e)
}
return events, nil
}
func (r *Repository) GetLineStats(ctx context.Context) (*LineStats, error) {
var stats LineStats
err := r.pool.QueryRow(ctx, `
SELECT
COUNT(CASE WHEN pe.event_type = 'item_processed' THEN 1 END) as total_items,
COUNT(CASE WHEN pe.event_type = 'item_rejected' THEN 1 END) as rejected_items,
COALESCE(AVG(sr.value) FILTER (WHERE sr.sensor = 'conveyor_speed'), 0) as avg_speed,
COALESCE((SELECT ls.name FROM line_stages ls ORDER BY ls.stage_order LIMIT 1), '') as current_stage,
'running' as status,
NOW() as last_update_time
FROM production_events pe
LEFT JOIN sensor_readings sr ON pe.stage_id = sr.stage_id
`).Scan(&stats.TotalItems, &stats.RejectedItems, &stats.AvgSpeed, &stats.CurrentStage, &stats.Status, &stats.LastUpdateTime)
if err != nil {
return nil, err
}
return &stats, nil
}
+45 -2
View File
@@ -24,6 +24,49 @@ type Bale struct {
type User struct {
ID int `json:"id"`
Username string `json:"username"`
Password string `json:"password"`
Username string `json:"username"`
Password string `json:"password"`
}
// LineStage Этап производственной линии
// @Description Этап производственной линии переработки
type LineStage struct {
ID int `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
Order int `json:"order"`
Equipment string `json:"equipment"`
MQTTTopic string `json:"mqtt_topic"`
}
// SensorReading Показание датчика
// @Description Показание датчика на этапе линии
type SensorReading struct {
ID int `json:"id"`
StageID int `json:"stage_id"`
Sensor string `json:"sensor"`
Value float64 `json:"value"`
Unit string `json:"unit"`
Timestamp time.Time `json:"timestamp"`
}
// ProductionEvent Событие на линии
// @Description Событие, произошедшее на этапе производственной линии
type ProductionEvent struct {
ID int `json:"id"`
StageID int `json:"stage_id"`
EventType string `json:"event_type"`
Data string `json:"data"`
Timestamp time.Time `json:"timestamp"`
}
// LineStats Статистика линии
// @Description Сводная статистика работы производственной линии
type LineStats struct {
TotalItems int `json:"total_items"`
RejectedItems int `json:"rejected_items"`
AvgSpeed float64 `json:"avg_speed"`
CurrentStage string `json:"current_stage"`
Status string `json:"status"`
LastUpdateTime time.Time `json:"last_update_time"`
}