2025-12-02 17:50:52 +08:00
|
|
|
// Package service 定义业务逻辑层接口
|
|
|
|
|
package service
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"carrotskin/internal/model"
|
|
|
|
|
"carrotskin/pkg/storage"
|
|
|
|
|
"context"
|
2025-12-02 22:52:33 +08:00
|
|
|
"time"
|
2025-12-02 17:50:52 +08:00
|
|
|
|
|
|
|
|
"go.uber.org/zap"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// UserService 用户服务接口
|
|
|
|
|
type UserService interface {
|
|
|
|
|
// 用户认证
|
2025-12-02 22:52:33 +08:00
|
|
|
Register(ctx context.Context, username, password, email, avatar string) (*model.User, string, error)
|
|
|
|
|
Login(ctx context.Context, usernameOrEmail, password, ipAddress, userAgent string) (*model.User, string, error)
|
|
|
|
|
|
2025-12-02 17:50:52 +08:00
|
|
|
// 用户查询
|
2025-12-02 22:52:33 +08:00
|
|
|
GetByID(ctx context.Context, id int64) (*model.User, error)
|
|
|
|
|
GetByEmail(ctx context.Context, email string) (*model.User, error)
|
2026-01-10 03:52:35 +08:00
|
|
|
GetByUsername(ctx context.Context, username string) (*model.User, error)
|
2025-12-02 22:52:33 +08:00
|
|
|
|
2025-12-02 17:50:52 +08:00
|
|
|
// 用户更新
|
2025-12-02 22:52:33 +08:00
|
|
|
UpdateInfo(ctx context.Context, user *model.User) error
|
|
|
|
|
UpdateAvatar(ctx context.Context, userID int64, avatarURL string) error
|
|
|
|
|
ChangePassword(ctx context.Context, userID int64, oldPassword, newPassword string) error
|
|
|
|
|
ResetPassword(ctx context.Context, email, newPassword string) error
|
|
|
|
|
ChangeEmail(ctx context.Context, userID int64, newEmail string) error
|
|
|
|
|
|
2025-12-08 15:40:28 +08:00
|
|
|
// 头像上传
|
|
|
|
|
UploadAvatar(ctx context.Context, userID int64, fileData []byte, fileName string) (string, error)
|
|
|
|
|
|
2025-12-02 17:50:52 +08:00
|
|
|
// URL验证
|
2025-12-02 22:52:33 +08:00
|
|
|
ValidateAvatarURL(ctx context.Context, avatarURL string) error
|
|
|
|
|
|
2025-12-02 17:50:52 +08:00
|
|
|
// 配置获取
|
|
|
|
|
GetMaxProfilesPerUser() int
|
|
|
|
|
GetMaxTexturesPerUser() int
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ProfileService 档案服务接口
|
|
|
|
|
type ProfileService interface {
|
|
|
|
|
// 档案CRUD
|
2025-12-02 22:52:33 +08:00
|
|
|
Create(ctx context.Context, userID int64, name string) (*model.Profile, error)
|
|
|
|
|
GetByUUID(ctx context.Context, uuid string) (*model.Profile, error)
|
|
|
|
|
GetByUserID(ctx context.Context, userID int64) ([]*model.Profile, error)
|
|
|
|
|
Update(ctx context.Context, uuid string, userID int64, name *string, skinID, capeID *int64) (*model.Profile, error)
|
|
|
|
|
Delete(ctx context.Context, uuid string, userID int64) error
|
|
|
|
|
|
2025-12-02 17:50:52 +08:00
|
|
|
// 档案状态
|
2025-12-02 22:52:33 +08:00
|
|
|
CheckLimit(ctx context.Context, userID int64, maxProfiles int) error
|
|
|
|
|
|
2025-12-02 17:50:52 +08:00
|
|
|
// 批量查询
|
2025-12-02 22:52:33 +08:00
|
|
|
GetByNames(ctx context.Context, names []string) ([]*model.Profile, error)
|
|
|
|
|
GetByProfileName(ctx context.Context, name string) (*model.Profile, error)
|
2025-12-02 17:50:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TextureService 材质服务接口
|
|
|
|
|
type TextureService interface {
|
|
|
|
|
// 材质CRUD
|
2025-12-08 15:40:28 +08:00
|
|
|
UploadTexture(ctx context.Context, uploaderID int64, name, description, textureType string, fileData []byte, fileName string, isPublic, isSlim bool) (*model.Texture, error)
|
2025-12-02 22:52:33 +08:00
|
|
|
GetByID(ctx context.Context, id int64) (*model.Texture, error)
|
2025-12-03 10:58:39 +08:00
|
|
|
GetByHash(ctx context.Context, hash string) (*model.Texture, error)
|
2025-12-02 22:52:33 +08:00
|
|
|
GetByUserID(ctx context.Context, uploaderID int64, page, pageSize int) ([]*model.Texture, int64, error)
|
|
|
|
|
Search(ctx context.Context, keyword string, textureType model.TextureType, publicOnly bool, page, pageSize int) ([]*model.Texture, int64, error)
|
|
|
|
|
Update(ctx context.Context, textureID, uploaderID int64, name, description string, isPublic *bool) (*model.Texture, error)
|
|
|
|
|
Delete(ctx context.Context, textureID, uploaderID int64) error
|
|
|
|
|
|
2025-12-02 17:50:52 +08:00
|
|
|
// 收藏
|
2025-12-02 22:52:33 +08:00
|
|
|
ToggleFavorite(ctx context.Context, userID, textureID int64) (bool, error)
|
|
|
|
|
GetUserFavorites(ctx context.Context, userID int64, page, pageSize int) ([]*model.Texture, int64, error)
|
|
|
|
|
|
2025-12-02 17:50:52 +08:00
|
|
|
// 限制检查
|
2025-12-02 22:52:33 +08:00
|
|
|
CheckUploadLimit(ctx context.Context, uploaderID int64, maxTextures int) error
|
2025-12-02 17:50:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TokenService 令牌服务接口
|
|
|
|
|
type TokenService interface {
|
|
|
|
|
// 令牌管理
|
2025-12-02 22:52:33 +08:00
|
|
|
Create(ctx context.Context, userID int64, uuid, clientToken string) (*model.Profile, []*model.Profile, string, string, error)
|
|
|
|
|
Validate(ctx context.Context, accessToken, clientToken string) bool
|
|
|
|
|
Refresh(ctx context.Context, accessToken, clientToken, selectedProfileID string) (string, string, error)
|
|
|
|
|
Invalidate(ctx context.Context, accessToken string)
|
|
|
|
|
InvalidateUserTokens(ctx context.Context, userID int64)
|
|
|
|
|
|
2025-12-02 17:50:52 +08:00
|
|
|
// 令牌查询
|
2025-12-02 22:52:33 +08:00
|
|
|
GetUUIDByAccessToken(ctx context.Context, accessToken string) (string, error)
|
|
|
|
|
GetUserIDByAccessToken(ctx context.Context, accessToken string) (int64, error)
|
2025-12-02 17:50:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// VerificationService 验证码服务接口
|
|
|
|
|
type VerificationService interface {
|
|
|
|
|
SendCode(ctx context.Context, email, codeType string) error
|
|
|
|
|
VerifyCode(ctx context.Context, email, code, codeType string) error
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// CaptchaService 滑动验证码服务接口
|
|
|
|
|
type CaptchaService interface {
|
|
|
|
|
Generate(ctx context.Context) (masterImg, tileImg, captchaID string, y int, err error)
|
|
|
|
|
Verify(ctx context.Context, dx int, captchaID string) (bool, error)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// YggdrasilService Yggdrasil服务接口
|
|
|
|
|
type YggdrasilService interface {
|
|
|
|
|
// 用户认证
|
2025-12-02 22:52:33 +08:00
|
|
|
GetUserIDByEmail(ctx context.Context, email string) (int64, error)
|
|
|
|
|
VerifyPassword(ctx context.Context, password string, userID int64) error
|
|
|
|
|
|
2025-12-02 17:50:52 +08:00
|
|
|
// 会话管理
|
2025-12-02 22:52:33 +08:00
|
|
|
JoinServer(ctx context.Context, serverID, accessToken, selectedProfile, ip string) error
|
|
|
|
|
HasJoinedServer(ctx context.Context, serverID, username, ip string) error
|
|
|
|
|
|
2025-12-02 17:50:52 +08:00
|
|
|
// 密码管理
|
2025-12-02 22:52:33 +08:00
|
|
|
ResetYggdrasilPassword(ctx context.Context, userID int64) (string, error)
|
|
|
|
|
|
2025-12-02 17:50:52 +08:00
|
|
|
// 序列化
|
2025-12-02 22:52:33 +08:00
|
|
|
SerializeProfile(ctx context.Context, profile model.Profile) map[string]interface{}
|
|
|
|
|
SerializeUser(ctx context.Context, user *model.User, uuid string) map[string]interface{}
|
|
|
|
|
|
2025-12-02 17:50:52 +08:00
|
|
|
// 证书
|
2025-12-02 22:52:33 +08:00
|
|
|
GeneratePlayerCertificate(ctx context.Context, uuid string) (map[string]interface{}, error)
|
|
|
|
|
GetPublicKey(ctx context.Context) (string, error)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SecurityService 安全服务接口
|
|
|
|
|
type SecurityService interface {
|
|
|
|
|
// 登录安全
|
|
|
|
|
CheckLoginLocked(ctx context.Context, identifier string) (bool, time.Duration, error)
|
|
|
|
|
RecordLoginFailure(ctx context.Context, identifier string) (int, error)
|
|
|
|
|
ClearLoginAttempts(ctx context.Context, identifier string) error
|
|
|
|
|
GetRemainingLoginAttempts(ctx context.Context, identifier string) (int, error)
|
|
|
|
|
|
|
|
|
|
// 验证码安全
|
|
|
|
|
CheckVerifyLocked(ctx context.Context, email, codeType string) (bool, time.Duration, error)
|
|
|
|
|
RecordVerifyFailure(ctx context.Context, email, codeType string) (int, error)
|
|
|
|
|
ClearVerifyAttempts(ctx context.Context, email, codeType string) error
|
2025-12-02 17:50:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Services 服务集合
|
|
|
|
|
type Services struct {
|
|
|
|
|
User UserService
|
|
|
|
|
Profile ProfileService
|
|
|
|
|
Texture TextureService
|
|
|
|
|
Token TokenService
|
|
|
|
|
Verification VerificationService
|
|
|
|
|
Captcha CaptchaService
|
|
|
|
|
Yggdrasil YggdrasilService
|
2025-12-02 22:52:33 +08:00
|
|
|
Security SecurityService
|
2025-12-02 17:50:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ServiceDeps 服务依赖
|
|
|
|
|
type ServiceDeps struct {
|
|
|
|
|
Logger *zap.Logger
|
|
|
|
|
Storage *storage.StorageClient
|
|
|
|
|
}
|