125 lines
3.5 KiB
Go
125 lines
3.5 KiB
Go
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 "t_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
|
||
}
|