84 lines
3.3 KiB
Go
84 lines
3.3 KiB
Go
package user
|
||
|
||
import (
|
||
"context"
|
||
"strings"
|
||
|
||
"hyapp/pkg/xerr"
|
||
userdomain "hyapp/services/user-service/internal/domain/user"
|
||
)
|
||
|
||
const (
|
||
defaultContentBlacklistPageSize int32 = 50
|
||
maxContentBlacklistPageSize int32 = 200
|
||
maxContentBlacklistReasonRunes = 255
|
||
)
|
||
|
||
// UserContentBlacklistCommand 是后台增加/移除运营内容屏蔽的治理命令。
|
||
// 时间由 user-service owner 生成,不能信任后台进程或客户端传入的时钟。
|
||
type UserContentBlacklistCommand struct {
|
||
UserID int64
|
||
OperatorAdminID int64
|
||
Reason string
|
||
NowMs int64
|
||
}
|
||
|
||
// ListUserContentBlacklist 分页读取当前 active 屏蔽用户。
|
||
func (s *Service) ListUserContentBlacklist(ctx context.Context, page int32, pageSize int32) ([]userdomain.ContentBlacklistEntry, int64, error) {
|
||
if s.contentBlacklistRepository == nil {
|
||
return nil, 0, xerr.New(xerr.Unavailable, "content blacklist repository is not configured")
|
||
}
|
||
if page < 1 {
|
||
page = 1
|
||
}
|
||
if pageSize <= 0 {
|
||
pageSize = defaultContentBlacklistPageSize
|
||
}
|
||
if pageSize > maxContentBlacklistPageSize {
|
||
pageSize = maxContentBlacklistPageSize
|
||
}
|
||
return s.contentBlacklistRepository.ListUserContentBlacklist(ctx, page, pageSize)
|
||
}
|
||
|
||
// AdminAddUserContentBlacklist 启用指定用户的运营内容屏蔽。
|
||
// 重复添加保持单行当前态并更新操作者和原因,不会把账号状态改成 banned/disabled。
|
||
func (s *Service) AdminAddUserContentBlacklist(ctx context.Context, command UserContentBlacklistCommand) (userdomain.ContentBlacklistEntry, error) {
|
||
if s.contentBlacklistRepository == nil {
|
||
return userdomain.ContentBlacklistEntry{}, xerr.New(xerr.Unavailable, "content blacklist repository is not configured")
|
||
}
|
||
normalized, err := s.normalizeUserContentBlacklistCommand(command)
|
||
if err != nil {
|
||
return userdomain.ContentBlacklistEntry{}, err
|
||
}
|
||
return s.contentBlacklistRepository.AddUserContentBlacklist(ctx, normalized)
|
||
}
|
||
|
||
// AdminRemoveUserContentBlacklist 关闭指定用户的运营内容屏蔽。
|
||
// 已经移除时返回 removed=false,允许后台重试同一个操作而不产生错误。
|
||
func (s *Service) AdminRemoveUserContentBlacklist(ctx context.Context, command UserContentBlacklistCommand) (bool, error) {
|
||
if s.contentBlacklistRepository == nil {
|
||
return false, xerr.New(xerr.Unavailable, "content blacklist repository is not configured")
|
||
}
|
||
normalized, err := s.normalizeUserContentBlacklistCommand(command)
|
||
if err != nil {
|
||
return false, err
|
||
}
|
||
return s.contentBlacklistRepository.RemoveUserContentBlacklist(ctx, normalized)
|
||
}
|
||
|
||
func (s *Service) normalizeUserContentBlacklistCommand(command UserContentBlacklistCommand) (UserContentBlacklistCommand, error) {
|
||
if command.UserID <= 0 {
|
||
return UserContentBlacklistCommand{}, xerr.New(xerr.InvalidArgument, "user_id is required")
|
||
}
|
||
if command.OperatorAdminID <= 0 {
|
||
return UserContentBlacklistCommand{}, xerr.New(xerr.InvalidArgument, "operator_admin_id is required")
|
||
}
|
||
command.Reason = strings.TrimSpace(command.Reason)
|
||
if len([]rune(command.Reason)) > maxContentBlacklistReasonRunes {
|
||
return UserContentBlacklistCommand{}, xerr.New(xerr.InvalidArgument, "reason is too long")
|
||
}
|
||
// user-service 的 UTC 时钟是持久事实时间源,后台 RequestMeta.sent_at_ms 只用于链路追踪。
|
||
command.NowMs = s.now().UTC().UnixMilli()
|
||
return command, nil
|
||
}
|