合并 origin/main 设备注册后,纳入本地 music 模块、seed 命令与 popadmin 相关路由/文档;music migration 编号为 0020 以避免与 0019_devices 冲突。 Co-authored-by: Cursor <cursoragent@cursor.com>
101 lines
2.5 KiB
Go
101 lines
2.5 KiB
Go
package logic
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
|
|
userentity "spark-server/internal/module/user/entity"
|
|
"spark-server/internal/pkg/errs"
|
|
)
|
|
|
|
func (s *Service) ensureBots(ctx context.Context) ([]*userentity.User, error) {
|
|
out := make([]*userentity.User, 0, userentity.BotCount)
|
|
for i := 1; i <= userentity.BotCount; i++ {
|
|
u, err := s.ensureBot(ctx, i)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("bot %d: %w", i, err)
|
|
}
|
|
out = append(out, u)
|
|
}
|
|
return out, nil
|
|
}
|
|
|
|
func (s *Service) ensureBot(ctx context.Context, index int) (*userentity.User, error) {
|
|
email := userentity.BotEmail(index)
|
|
if u, err := s.users.GetByEmail(ctx, email); err == nil {
|
|
return u, nil
|
|
} else if !errors.Is(err, errs.ErrNotFound) {
|
|
return nil, err
|
|
}
|
|
id, err := s.ids.NextID()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
nick := nicknameForBot(index)
|
|
qr, err := userentity.NewQRCode()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
now := time.Now()
|
|
u := &userentity.User{
|
|
ID: id, SparkID: userentity.BotSparkID(index), Nickname: nick,
|
|
Avatar: userentity.LetterAvatarDataURI(nick), Gender: userentity.GenderUnknown,
|
|
Status: userentity.StatusActive, QRCode: qr,
|
|
CreatedAt: now, UpdatedAt: now, LastActiveAt: now,
|
|
}
|
|
if err := s.users.CreateWithEmail(ctx, u, email); err != nil {
|
|
if errors.Is(err, errs.ErrDuplicate) {
|
|
return s.users.GetByEmail(ctx, email)
|
|
}
|
|
return nil, err
|
|
}
|
|
return u, nil
|
|
}
|
|
|
|
func (s *Service) ensureTestUsers(ctx context.Context) error {
|
|
for i := 1; i <= 10; i++ {
|
|
email := fmt.Sprintf("test%02d@spark.com", i)
|
|
if _, err := s.users.GetByEmail(ctx, email); err == nil {
|
|
continue
|
|
} else if !errors.Is(err, errs.ErrNotFound) {
|
|
return err
|
|
}
|
|
if _, err := s.createPlainUser(ctx, email); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (s *Service) createPlainUser(ctx context.Context, email string) (*userentity.User, error) {
|
|
id, err := s.ids.NextID()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
qr, err := userentity.NewQRCode()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
local, _, _ := strings.Cut(email, "@")
|
|
if local == "" {
|
|
local = "user"
|
|
}
|
|
now := time.Now()
|
|
u := &userentity.User{
|
|
ID: id, SparkID: userentity.DefaultSparkID(id), Nickname: local,
|
|
Avatar: userentity.LetterAvatarDataURI(local), Gender: userentity.GenderUnknown,
|
|
Status: userentity.StatusActive, QRCode: qr,
|
|
CreatedAt: now, UpdatedAt: now, LastActiveAt: now,
|
|
}
|
|
if err := s.users.CreateWithEmail(ctx, u, email); err != nil {
|
|
if errors.Is(err, errs.ErrDuplicate) {
|
|
return s.users.GetByEmail(ctx, email)
|
|
}
|
|
return nil, err
|
|
}
|
|
return u, nil
|
|
}
|