package repository import ( "context" "errors" "fmt" v1 "github.com/go-nunu/nunu-layout-advanced/api/v1" "github.com/go-nunu/nunu-layout-advanced/internal/model" "gorm.io/gorm" "math" "strings" ) type GatewayGroupRepository interface { GetGatewayGroup(ctx context.Context, id int64) (*model.GatewayGroup, error) AddGatewayGroup(ctx context.Context, req *model.GatewayGroup) error EditGatewayGroup(ctx context.Context, req *model.GatewayGroup) error DeleteGatewayGroup(ctx context.Context, id int) error GetGatewayGroupWhereHostIdNull(ctx context.Context, req v1.GlobalLimitRequireResponse) (int, error) GetGatewayGroupByHostId(ctx context.Context, hostId int64) (*model.GatewayGroup, error) GetGatewayGroupList(ctx context.Context,req v1.SearchGatewayGroupParams) (*v1.PaginatedResponse[model.GatewayGroup], error) EditGatewayGroupById(ctx context.Context, req *model.GatewayGroup) error } func NewGatewayGroupRepository( repository *Repository, ) GatewayGroupRepository { return &gatewayGroupRepository{ Repository: repository, } } type gatewayGroupRepository struct { *Repository } func (r *gatewayGroupRepository) GetGatewayGroup(ctx context.Context, id int64) (*model.GatewayGroup, error) { var gatewayGroup model.GatewayGroup return &gatewayGroup, nil } func (r *gatewayGroupRepository) AddGatewayGroup(ctx context.Context, req *model.GatewayGroup) error { if err := r.DB(ctx).Create(req).Error; err != nil { return err } return nil } func (r *gatewayGroupRepository) EditGatewayGroup(ctx context.Context, req *model.GatewayGroup) error { if err := r.DB(ctx).Model(&model.GatewayGroup{}).Where("id = ?", req.Id).Updates(req).Error; err != nil { return err } return nil } func (r *gatewayGroupRepository) DeleteGatewayGroup(ctx context.Context, id int) error { if err := r.DB(ctx).Model(&model.GatewayGroup{}).Where("id = ?", id).Delete(&model.GatewayGroup{}).Error; err != nil { return err } return nil } func (r *gatewayGroupRepository) GetGatewayGroupWhereHostIdNull(ctx context.Context,req v1.GlobalLimitRequireResponse) (int, error) { var id int subQuery := r.DB(ctx).Model(&model.GateWayGroupIp{}). Select("gateway_group_id"). Group("gateway_group_id"). Having("COUNT(*) = ?", req.IpCount) err := r.DB(ctx).Model(&model.GatewayGroup{}). Where("operator = ?", req.Operator). Where("ban_udp", req.IsBanUdp). Where("ban_overseas", req.IsBanOverseas). Where("id IN (?)", subQuery). Where("host_id = ?", 0). Select("id").First(&id).Error if err != nil { if errors.Is(err, gorm.ErrRecordNotFound){ return 0, fmt.Errorf("库存不足,请联系客服补充网关组库存") } return 0, err } return id, nil } func (r *gatewayGroupRepository) GetGatewayGroupByHostId(ctx context.Context, hostId int64) (*model.GatewayGroup, error) { res := model.GatewayGroup{} if err := r.DB(ctx).Where("host_id = ?", hostId).Find(&res).Error; err != nil { return nil, err } return &res, nil } func (r *gatewayGroupRepository) GetGatewayGroupList(ctx context.Context,req v1.SearchGatewayGroupParams) (*v1.PaginatedResponse[model.GatewayGroup], error) { var res []model.GatewayGroup var total int64 query := r.Db.WithContext(ctx).Model(&model.GatewayGroup{}) if req.Name != "" { // 去除后所有的空白字符(包括空格、制表符\t、换行符等) trimmedName := strings.TrimSpace(req.Name) // 使用 LIKE 进行模糊匹配 query = query.Where("name LIKE CONCAT('%', ?, '%')", trimmedName) } // 如果 HostId 被提供了,添加一个精确匹配条件 if req.HostId != 0 { query = query.Where("host_id = ?", req.HostId) } // 如果 RuleId 被提供了 if req.RuleId != 0 { query = query.Where("rule_id = ?", req.RuleId) } // 如果 Operator 被提供了 if req.Operator != 0 { query = query.Where("operator = ?", req.Operator) } if req.Column != "" { if req.Column == "createTime" { query = query.Order("created_at" + " " + req.Order) } } if err := query.Count(&total).Error; err != nil { // 如果连计数都失败了,直接返回错误 return nil, err } page := req.Current pageSize := req.PageSize if page <= 0 { page = 1 } if pageSize <= 0 { pageSize = 10 // 默认每页 10 条 } else if pageSize > 100 { pageSize = 100 // 每页最多 100 条 } // 计算 offset (偏移量) // 例如,第 1 页,offset = (1-1)*10 = 0 (从第0条开始) // 第 2 页,offset = (2-1)*10 = 10 (从第10条开始) offset := (page - 1) * pageSize // 3. 执行最终的查询 // 在所有条件都添加完毕后,再执行 .Find() result := query.Offset(offset).Limit(pageSize).Find(&res) if result.Error != nil { // 这里的错误可能是数据库连接问题等,而不是“未找到记录” return nil, result.Error } return &v1.PaginatedResponse[model.GatewayGroup]{ Records: res, Page: page, PageSize: pageSize, Total: total, TotalPages: int(math.Ceil(float64(total) / float64(pageSize))), }, nil } func (r *gatewayGroupRepository) EditGatewayGroupById(ctx context.Context, req *model.GatewayGroup) error { if err := r.DB(ctx).Model(&model.GatewayGroup{}).Where("id = ?", req.Id).Updates(req).Error; err != nil { return err } return nil }