package model import ( "context" "strconv" "strings" "time" groupentity "spark-server/internal/module/group/entity" "spark-server/internal/pkg/errs" ) type groupScanRow struct { ID int64 `gorm:"column:id"` ConversationID int64 `gorm:"column:conversation_id"` Name string `gorm:"column:name"` Avatar string `gorm:"column:avatar"` OwnerID int64 `gorm:"column:owner_id"` MutedAll int `gorm:"column:muted_all"` MemberCount int `gorm:"column:member_count"` Status int `gorm:"column:status"` CreatedAt time.Time `gorm:"column:created_at"` UpdatedAt time.Time `gorm:"column:updated_at"` } func groupScanToRow(r *groupScanRow) GroupRow { return GroupRow(*r) } func (m *Repo) ListGroups(ctx context.Context, q string) ([]GroupRow, error) { db, err := m.session(ctx) if err != nil { return nil, err } query := db.Table("`t_groups`").Where("status = ?", int(groupentity.StatusActive)) q = strings.TrimSpace(q) if q != "" { like := "%" + q + "%" if id, e := strconv.ParseInt(q, 10, 64); e == nil { query = query.Where("id = ? OR name LIKE ?", id, like) } else { query = query.Where("name LIKE ?", like) } } var rows []groupScanRow if err := query.Order("updated_at DESC").Limit(200).Find(&rows).Error; err != nil { return nil, mapDBErr(err) } out := make([]GroupRow, 0, len(rows)) for i := range rows { out = append(out, groupScanToRow(&rows[i])) } return out, nil } func (m *Repo) GroupByID(ctx context.Context, groupID int64) (*GroupRow, error) { db, err := m.session(ctx) if err != nil { return nil, err } var r groupScanRow if err := db.Table("`t_groups`").Where("id = ?", groupID).Take(&r).Error; err != nil { return nil, mapDBErr(err) } row := groupScanToRow(&r) return &row, nil } func (m *Repo) ActiveGroupOwner(ctx context.Context, groupID int64) (int64, error) { db, err := m.session(ctx) if err != nil { return 0, err } var r struct { OwnerID int64 `gorm:"column:owner_id"` } err = db.Table("`t_groups`").Select("owner_id"). Where("id = ? AND status = ?", groupID, int(groupentity.StatusActive)). Take(&r).Error if err != nil { return 0, mapDBErr(err) } if r.OwnerID <= 0 { return 0, errs.ErrNotFound } return r.OwnerID, nil } func (m *Repo) ListGroupMembers(ctx context.Context, groupID int64) ([]GroupMemberRow, error) { db, err := m.session(ctx) if err != nil { return nil, err } type scanRow struct { UserID int64 `gorm:"column:user_id"` Role int `gorm:"column:role"` Nickname string `gorm:"column:nickname"` Email string `gorm:"column:email"` UNick string `gorm:"column:u_nickname"` } var rows []scanRow err = db.Raw(` SELECT m.user_id, m.role, m.nickname, COALESCE(e.email,'') AS email, COALESCE(u.nickname,'') AS u_nickname FROM t_group_members m LEFT JOIN t_users u ON u.id = m.user_id LEFT JOIN t_user_emails e ON e.user_id = m.user_id WHERE m.group_id = ? ORDER BY m.role ASC, m.joined_at ASC LIMIT 500`, groupID).Scan(&rows).Error if err != nil { return nil, mapDBErr(err) } out := make([]GroupMemberRow, 0, len(rows)) for i := range rows { out = append(out, GroupMemberRow(rows[i])) } return out, nil }