Files
aiops/backend/repository/repo.go
T
Logan.Li 83662487cb fix: 接通服务器V2排序链路
- 将排序参数从V2 Handler传递至Service与Repository

- 增加仓储分页排序与参数白名单测试
2026-07-26 23:38:06 +08:00

251 lines
6.8 KiB
Go

// Package repository 提供数据访问层 — 所有 DB 操作集中在此
// Handler / Service 不直接操作 *gorm.DB
package repository
import (
"ezops/model"
"gorm.io/gorm"
)
// ━━━ Server Repository ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
type ServerRepository struct {
db *gorm.DB
}
func NewServerRepository(db *gorm.DB) *ServerRepository {
return &ServerRepository{db: db}
}
func (r *ServerRepository) DB() *gorm.DB {
return r.db
}
// List 分页查询服务器列表
func (r *ServerRepository) List(keyword, status, regionID, sortField, sortOrder string, page, pageSize int) ([]model.Server, int64, error) {
q := r.db.Model(&model.Server{})
if keyword != "" {
q = q.Where("hostname LIKE ? OR ip LIKE ? OR public_ip LIKE ?",
"%"+keyword+"%", "%"+keyword+"%", "%"+keyword+"%")
}
if status != "" {
q = q.Where("status = ?", status)
}
if regionID != "" {
q = q.Where("region_id = ?", regionID)
}
var total int64
q.Count(&total)
var list []model.Server
err := q.Preload("Region").Preload("Cloud").
Offset((page - 1) * pageSize).Limit(pageSize).
Order(serverOrderClause(sortField, sortOrder)).Find(&list).Error
return list, total, err
}
// serverOrderClause 返回服务器列表允许使用的排序表达式,避免直接拼接请求参数。 // Logan.Li
func serverOrderClause(sortField, sortOrder string) string {
if sortField != "hostname" {
return "created_at DESC"
}
if sortOrder == "desc" {
return "LOWER(hostname) DESC, id DESC"
}
return "LOWER(hostname) ASC, id ASC"
}
// GetByID 根据 ID 获取服务器
func (r *ServerRepository) GetByID(id uint) (*model.Server, error) {
var s model.Server
err := r.db.Preload("Region").Preload("Cloud").First(&s, id).Error
if err != nil {
return nil, err
}
return &s, nil
}
// Create 创建服务器
func (r *ServerRepository) Create(s *model.Server) error {
return r.db.Create(s).Error
}
// Update 更新服务器 (全量)
func (r *ServerRepository) Update(s *model.Server) error {
return r.db.Save(s).Error
}
// UpdateFields 部分更新
func (r *ServerRepository) UpdateFields(id uint, updates map[string]interface{}) error {
return r.db.Model(&model.Server{}).Where("id = ?", id).Updates(updates).Error
}
// Delete 删除服务器
func (r *ServerRepository) Delete(id uint) error {
return r.db.Delete(&model.Server{}, id).Error
}
// CountByStatus 按状态统计
func (r *ServerRepository) CountByStatus(status string) int64 {
var c int64
r.db.Model(&model.Server{}).Where("status = ?", status).Count(&c)
return c
}
// AvgMetric 获取平均指标
func (r *ServerRepository) AvgMetric(field string) float64 {
var v float64
r.db.Model(&model.Server{}).Select("AVG(" + field + ")").Scan(&v)
return v
}
// ━━━ Credential Repository ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
type CredentialRepository struct {
db *gorm.DB
}
func NewCredentialRepository(db *gorm.DB) *CredentialRepository {
return &CredentialRepository{db: db}
}
// List 分页查询凭据
func (r *CredentialRepository) List(keyword, secretType string, page, pageSize int) ([]model.Credential, int64, error) {
q := r.db.Model(&model.Credential{})
if keyword != "" {
q = q.Where("name LIKE ?", "%"+keyword+"%")
}
if secretType != "" {
q = q.Where("secret_type = ?", secretType)
}
var total int64
q.Count(&total)
var list []model.Credential
err := q.Offset((page - 1) * pageSize).Limit(pageSize).
Order("created_at DESC").Find(&list).Error
return list, total, err
}
// GetByID 根据 ID 获取凭据
func (r *CredentialRepository) GetByID(id uint) (*model.Credential, error) {
var c model.Credential
err := r.db.First(&c, id).Error
if err != nil {
return nil, err
}
return &c, nil
}
// Create 创建凭据
func (r *CredentialRepository) Create(c *model.Credential) error {
return r.db.Create(c).Error
}
// Update 全量更新凭据
func (r *CredentialRepository) Update(c *model.Credential) error {
return r.db.Save(c).Error
}
// UpdateFields 部分更新
func (r *CredentialRepository) UpdateFields(id uint, updates map[string]interface{}) error {
return r.db.Model(&model.Credential{}).Where("id = ?", id).Updates(updates).Error
}
// Delete 删除凭据
func (r *CredentialRepository) Delete(id uint) error {
return r.db.Delete(&model.Credential{}, id).Error
}
// ━━━ Alert Contact Repository ━━━━━━━━━━━━━━━━━━━━━━━━━━━
type AlertContactRepository struct {
db *gorm.DB
}
func NewAlertContactRepository(db *gorm.DB) *AlertContactRepository {
return &AlertContactRepository{db: db}
}
func (r *AlertContactRepository) List(keyword string, page, pageSize int) ([]model.AlertContact, int64, error) {
q := r.db.Model(&model.AlertContact{})
if keyword != "" {
q = q.Where("name LIKE ?", "%"+keyword+"%")
}
var total int64
q.Count(&total)
var list []model.AlertContact
err := q.Offset((page - 1) * pageSize).Limit(pageSize).
Order("created_at DESC").Find(&list).Error
return list, total, err
}
func (r *AlertContactRepository) GetByID(id uint) (*model.AlertContact, error) {
var c model.AlertContact
err := r.db.First(&c, id).Error
if err != nil {
return nil, err
}
return &c, nil
}
func (r *AlertContactRepository) Create(c *model.AlertContact) error {
return r.db.Create(c).Error
}
func (r *AlertContactRepository) Update(c *model.AlertContact) error {
return r.db.Save(c).Error
}
func (r *AlertContactRepository) Delete(id uint) error {
return r.db.Delete(&model.AlertContact{}, id).Error
}
// AlertContactGroup Repository
type AlertContactGroupRepository struct {
db *gorm.DB
}
func NewAlertContactGroupRepository(db *gorm.DB) *AlertContactGroupRepository {
return &AlertContactGroupRepository{db: db}
}
func (r *AlertContactGroupRepository) List(keyword string, page, pageSize int) ([]model.AlertContactGroup, int64, error) {
q := r.db.Model(&model.AlertContactGroup{})
if keyword != "" {
q = q.Where("group_name LIKE ?", "%"+keyword+"%")
}
var total int64
q.Count(&total)
var list []model.AlertContactGroup
err := q.Offset((page - 1) * pageSize).Limit(pageSize).
Order("created_at DESC").Find(&list).Error
return list, total, err
}
func (r *AlertContactGroupRepository) GetByID(id uint) (*model.AlertContactGroup, error) {
var g model.AlertContactGroup
err := r.db.First(&g, id).Error
if err != nil {
return nil, err
}
return &g, nil
}
func (r *AlertContactGroupRepository) Create(g *model.AlertContactGroup) error {
return r.db.Create(g).Error
}
func (r *AlertContactGroupRepository) UpdateFields(id uint, updates map[string]interface{}) error {
return r.db.Model(&model.AlertContactGroup{}).Where("id = ?", id).Updates(updates).Error
}
func (r *AlertContactGroupRepository) Delete(id uint) error {
return r.db.Delete(&model.AlertContactGroup{}, id).Error
}