package repository import ( "database/sql" "github.com/wmms/wmms/internal/model" "github.com/wmms/wmms/pkg/database" ) type WarehouseRepository struct{} func NewWarehouseRepository() *WarehouseRepository { return &WarehouseRepository{} } func (r *WarehouseRepository) List(organizationID int64) ([]model.Warehouse, error) { rows, err := database.DB.Query(`SELECT w.id, w.organization_id, w.code, w.name, w.status, l.id, l.code, l.name, l.status FROM warehouses w LEFT JOIN warehouse_locations l ON l.warehouse_id = w.id WHERE w.organization_id = ? ORDER BY w.code, l.code`, organizationID) if err != nil { return nil, err } defer rows.Close() items := make([]model.Warehouse, 0) index := make(map[int64]int) for rows.Next() { var warehouse model.Warehouse var locationID sql.NullInt64 var locationCode, locationName, locationStatus sql.NullString if err := rows.Scan(&warehouse.ID, &warehouse.OrganizationID, &warehouse.Code, &warehouse.Name, &warehouse.Status, &locationID, &locationCode, &locationName, &locationStatus); err != nil { return nil, err } position, exists := index[warehouse.ID] if !exists { warehouse.Locations = []model.WarehouseLocation{} items = append(items, warehouse) position = len(items) - 1 index[warehouse.ID] = position } if locationID.Valid { items[position].Locations = append(items[position].Locations, model.WarehouseLocation{ID: locationID.Int64, WarehouseID: warehouse.ID, Code: locationCode.String, Name: locationName.String, Status: locationStatus.String}) } } return items, rows.Err() } func (r *WarehouseRepository) Create(item *model.Warehouse) error { result, err := database.DB.Exec(`INSERT INTO warehouses (organization_id, code, name, status) VALUES (?, ?, ?, ?)`, item.OrganizationID, item.Code, item.Name, item.Status) if err != nil { return err } item.ID, err = result.LastInsertId() return err } func (r *WarehouseRepository) Update(item *model.Warehouse) error { return execExpectingRow(`UPDATE warehouses SET name = ?, status = ? WHERE id = ? AND organization_id = ?`, item.Name, item.Status, item.ID, item.OrganizationID) } func (r *WarehouseRepository) CreateLocation(item *model.WarehouseLocation, organizationID int64) error { result, err := database.DB.Exec(`INSERT INTO warehouse_locations (warehouse_id, code, name, status) SELECT id, ?, ?, ? FROM warehouses WHERE id = ? AND organization_id = ?`, item.Code, item.Name, item.Status, item.WarehouseID, organizationID) if err != nil { return err } item.ID, err = result.LastInsertId() return err } func (r *WarehouseRepository) UpdateLocation(item *model.WarehouseLocation, organizationID int64) error { // JOIN 形式的 UPDATE 同样受 clientFoundRows 影响,影响 0 行也代表库位不存在 // 或不属于该组织(已实测)。 return execExpectingRow(`UPDATE warehouse_locations l JOIN warehouses w ON w.id = l.warehouse_id SET l.name = ?, l.status = ? WHERE l.id = ? AND w.organization_id = ?`, item.Name, item.Status, item.ID, organizationID) }