125 lines
3.5 KiB
Go
125 lines
3.5 KiB
Go
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{
|
|
ID: r.ID, ConversationID: r.ConversationID, Name: r.Name, Avatar: r.Avatar,
|
|
OwnerID: r.OwnerID, MutedAll: r.MutedAll, MemberCount: r.MemberCount, Status: r.Status,
|
|
CreatedAt: r.CreatedAt, UpdatedAt: r.UpdatedAt,
|
|
}
|
|
}
|
|
|
|
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("`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 _, r := range rows {
|
|
out = append(out, groupScanToRow(r))
|
|
}
|
|
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("`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("`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 group_members m
|
|
LEFT JOIN users u ON u.id = m.user_id
|
|
LEFT JOIN 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 _, r := range rows {
|
|
out = append(out, GroupMemberRow{
|
|
UserID: r.UserID, Role: r.Role, Nickname: r.Nickname, Email: r.Email, UNick: r.UNick,
|
|
})
|
|
}
|
|
return out, nil
|
|
}
|