Go workspace (go.work) with 5 microservices + shared library: - gateway (8080), auth-service (8081), purchaser-service (8082) - textile-service (8083), washing-service (8084) - shared: proto definitions, common packages Infrastructure: docker-compose for local dev, K8s manifests for K3s cluster deployment (mysql/redis/etcd + traefik ingress). Frontend (iloom-flatten) added as git submodule. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
103 lines
3.2 KiB
Go
103 lines
3.2 KiB
Go
package repository
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"time"
|
|
)
|
|
|
|
type PlanSummary struct {
|
|
ID string `json:"id"`
|
|
PlanCode string `json:"plan_code"`
|
|
ProductName string `json:"product_name"`
|
|
FabricCode string `json:"fabric_code"`
|
|
Color string `json:"color"`
|
|
ColorCode string `json:"color_code"`
|
|
TargetQuantity float64 `json:"target_quantity"`
|
|
CompletedQuantity float64 `json:"completed_quantity"`
|
|
Status string `json:"status"`
|
|
Remark *string `json:"remark,omitempty"`
|
|
StartTime *time.Time `json:"start_time,omitempty"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
FactoryID string `json:"factory_id"`
|
|
}
|
|
|
|
type PlanRepo struct {
|
|
db *sql.DB
|
|
}
|
|
|
|
func NewPlanRepo(db *sql.DB) *PlanRepo {
|
|
return &PlanRepo{db: db}
|
|
}
|
|
|
|
func (r *PlanRepo) ListByFactory(ctx context.Context, factoryCompanyID string) ([]PlanSummary, error) {
|
|
query := `
|
|
SELECT pp.id, pp.plan_code, pp.product_name, pp.fabric_code,
|
|
pp.color, pp.color_code, pp.target_quantity, pp.completed_quantity,
|
|
pp.status, pp.remark, pp.start_time, pp.created_at, pp.updated_at,
|
|
pf.factory_id
|
|
FROM ilm_production_plan pp
|
|
JOIN ilm_plan_factory pf ON pp.id = pf.plan_id
|
|
WHERE pf.factory_id = ? AND pf.factory_type = 'textile'
|
|
ORDER BY pp.created_at DESC`
|
|
|
|
rows, err := r.db.QueryContext(ctx, query, factoryCompanyID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
|
|
var plans []PlanSummary
|
|
for rows.Next() {
|
|
var p PlanSummary
|
|
if err := rows.Scan(
|
|
&p.ID, &p.PlanCode, &p.ProductName, &p.FabricCode,
|
|
&p.Color, &p.ColorCode, &p.TargetQuantity, &p.CompletedQuantity,
|
|
&p.Status, &p.Remark, &p.StartTime, &p.CreatedAt, &p.UpdatedAt,
|
|
&p.FactoryID,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
plans = append(plans, p)
|
|
}
|
|
return plans, rows.Err()
|
|
}
|
|
|
|
func (r *PlanRepo) GetByID(ctx context.Context, planID string) (*PlanSummary, error) {
|
|
query := `
|
|
SELECT pp.id, pp.plan_code, pp.product_name, pp.fabric_code,
|
|
pp.color, pp.color_code, pp.target_quantity, pp.completed_quantity,
|
|
pp.status, pp.remark, pp.start_time, pp.created_at, pp.updated_at,
|
|
COALESCE(pf.factory_id, '')
|
|
FROM ilm_production_plan pp
|
|
LEFT JOIN ilm_plan_factory pf ON pp.id = pf.plan_id AND pf.factory_type = 'textile'
|
|
WHERE pp.id = ?`
|
|
|
|
var p PlanSummary
|
|
err := r.db.QueryRowContext(ctx, query, planID).Scan(
|
|
&p.ID, &p.PlanCode, &p.ProductName, &p.FabricCode,
|
|
&p.Color, &p.ColorCode, &p.TargetQuantity, &p.CompletedQuantity,
|
|
&p.Status, &p.Remark, &p.StartTime, &p.CreatedAt, &p.UpdatedAt,
|
|
&p.FactoryID,
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &p, nil
|
|
}
|
|
|
|
func (r *PlanRepo) CountByFactory(ctx context.Context, factoryCompanyID string) (total, active, completed int, err error) {
|
|
query := `
|
|
SELECT
|
|
COUNT(*),
|
|
SUM(CASE WHEN pp.status IN ('pending', 'in_progress') THEN 1 ELSE 0 END),
|
|
SUM(CASE WHEN pp.status = 'completed' THEN 1 ELSE 0 END)
|
|
FROM ilm_production_plan pp
|
|
JOIN ilm_plan_factory pf ON pp.id = pf.plan_id
|
|
WHERE pf.factory_id = ? AND pf.factory_type = 'textile'`
|
|
|
|
err = r.db.QueryRowContext(ctx, query, factoryCompanyID).Scan(&total, &active, &completed)
|
|
return
|
|
}
|