feat(ECR-025): OpsCMS FeedSlot 只读并 Closed

栏目位目录(ops_feed_slots + /cms),复用 admin.cms.read。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
jackyu66git
2026-08-08 03:08:40 +08:00
co-authored by Cursor
parent f51b2524c5
commit e32466357d
26 changed files with 661 additions and 4 deletions
+51
View File
@@ -65,3 +65,54 @@ func (r *AdminRepo) GetBanner(ctx context.Context, id uuid.UUID) (*BannerRow, er
}
return &b, nil
}
// FeedSlotRow is OpsCMS FeedSlot catalog row.
type FeedSlotRow struct {
ID uuid.UUID `json:"id"`
Code string `json:"code"`
Title string `json:"title"`
SlotKey string `json:"slot_key"`
Placement string `json:"placement"`
Active bool `json:"active"`
System bool `json:"system"`
UpdatedAt time.Time `json:"updated_at"`
}
// ListFeedSlots returns feed slot catalog.
func (r *AdminRepo) ListFeedSlots(ctx context.Context) ([]FeedSlotRow, error) {
rows, err := r.Pool.Query(ctx, `
SELECT id, code, title, slot_key, placement, active, system, updated_at
FROM ops_feed_slots
ORDER BY active DESC, code ASC`)
if err != nil {
return nil, err
}
defer rows.Close()
var out []FeedSlotRow
for rows.Next() {
var s FeedSlotRow
if err := rows.Scan(
&s.ID, &s.Code, &s.Title, &s.SlotKey, &s.Placement, &s.Active, &s.System, &s.UpdatedAt,
); err != nil {
return nil, err
}
out = append(out, s)
}
return out, rows.Err()
}
// GetFeedSlot loads one feed slot by id.
func (r *AdminRepo) GetFeedSlot(ctx context.Context, id uuid.UUID) (*FeedSlotRow, error) {
var s FeedSlotRow
err := r.Pool.QueryRow(ctx, `
SELECT id, code, title, slot_key, placement, active, system, updated_at
FROM ops_feed_slots WHERE id=$1`, id,
).Scan(&s.ID, &s.Code, &s.Title, &s.SlotKey, &s.Placement, &s.Active, &s.System, &s.UpdatedAt)
if errors.Is(err, pgx.ErrNoRows) {
return nil, err
}
if err != nil {
return nil, err
}
return &s, nil
}