spark-server/internal/module/group/model/group_member.go
2026-09-20 17:49:09 +08:00

125 lines
3.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package model
import (
"context"
"time"
"spark-server/internal/module/group/entity"
"spark-server/internal/pkg/errs"
)
// GroupMember maps table group_members.
type GroupMember struct {
ID int64 `gorm:"column:id;primaryKey;autoIncrement;comment:行 id,表内自增,仅内部用;业务唯一键是 (group_id, user_id)"`
GroupID int64 `gorm:"column:group_id;comment:群号,groups.id"`
UserID int64 `gorm:"column:user_id;comment:成员 user_id"`
Role int `gorm:"column:role;comment:1=群主 2=管理员 3=普通成员"`
Nickname string `gorm:"column:nickname;comment:群内昵称,空则用用户昵称"`
Remark string `gorm:"column:remark;comment:成员对该群的备注,仅自己可见"`
SpeakMuted int `gorm:"column:speak_muted;comment:0=未禁言 1=被单独禁言"`
JoinedAt time.Time `gorm:"column:joined_at;comment:入群时间"`
}
func (GroupMember) TableName() string { return "group_members" }
func (r *GroupMember) entity() *entity.Member {
if r == nil {
return nil
}
m := &entity.Member{
GroupID: r.GroupID, UserID: r.UserID, Role: entity.Role(r.Role),
Nickname: r.Nickname, Remark: r.Remark, JoinedAtMS: r.JoinedAt.UnixMilli(),
}
m.SpeakMuted = r.SpeakMuted != 0
return m
}
func memberRow(m *entity.Member) *GroupMember {
row := &GroupMember{
GroupID: m.GroupID, UserID: m.UserID, Role: int(m.Role),
Nickname: m.Nickname, Remark: m.Remark, JoinedAt: msTime(m.JoinedAtMS),
}
if m.SpeakMuted {
row.SpeakMuted = 1
}
if row.Role == 0 {
row.Role = int(entity.RoleMember)
}
return row
}
func (m *Repo) GetMember(ctx context.Context, groupID, userID int64) (*entity.Member, error) {
if groupID <= 0 || userID <= 0 {
return nil, errs.ErrInvalidArgument
}
db, err := m.session(ctx)
if err != nil {
return nil, err
}
var row GroupMember
if err := db.Where("group_id = ? AND user_id = ?", groupID, userID).Take(&row).Error; err != nil {
return nil, mapDBErr(err)
}
return row.entity(), nil
}
func (m *Repo) ListMembers(ctx context.Context, groupID int64, limit int) ([]*entity.Member, error) {
if groupID <= 0 {
return nil, errs.ErrInvalidArgument
}
db, err := m.session(ctx)
if err != nil {
return nil, err
}
limit = entity.ClampMemberLimit(limit)
var rows []GroupMember
err = db.Where("group_id = ?", groupID).Order("role ASC, joined_at ASC, id ASC").Limit(limit).Find(&rows).Error
if err != nil {
return nil, mapDBErr(err)
}
out := make([]*entity.Member, 0, len(rows))
for i := range rows {
out = append(out, rows[i].entity())
}
return out, nil
}
func (m *Repo) ListMemberIDs(ctx context.Context, groupID int64) ([]int64, error) {
if groupID <= 0 {
return nil, errs.ErrInvalidArgument
}
db, err := m.session(ctx)
if err != nil {
return nil, err
}
var ids []int64
err = db.Model(&GroupMember{}).Where("group_id = ?", groupID).Order("joined_at ASC").Pluck("user_id", &ids).Error
if err != nil {
return nil, mapDBErr(err)
}
return ids, nil
}
func (m *Repo) UpdateMember(ctx context.Context, mem *entity.Member) error {
if mem == nil || mem.GroupID <= 0 || mem.UserID <= 0 {
return errs.ErrInvalidArgument
}
db, err := m.session(ctx)
if err != nil {
return err
}
res := db.Model(&GroupMember{}).Where("group_id = ? AND user_id = ?", mem.GroupID, mem.UserID).Updates(map[string]any{
"role": mem.Role,
"nickname": mem.Nickname,
"remark": mem.Remark,
"speak_muted": boolInt(mem.SpeakMuted),
})
if res.Error != nil {
return mapDBErr(res.Error)
}
if res.RowsAffected == 0 {
return errs.ErrNotFound
}
return nil
}