refactor: cleanup unused code and simplify internal packages
Some checks failed
Build Backend / build (push) Successful in 1m56s
Build Backend / build-docker (push) Has been cancelled

This commit performs a significant cleanup of the codebase by removing unused functions, methods, and entire files across various internal modules. This reduces technical debt and simplifies the project structure.

Key changes include:
- **cache**: Removed unused cache key generators and metrics snapshots.
- **dto**: Removed redundant converter functions and segment creation helpers.
- **middleware**: Deleted the unused `logger.go` middleware and simplified `ratelimit.go` and `casbin.go`.
- **model**: Removed unused ID helpers, database closing functions, and batch decryption logic.
- **pkg**: Cleaned up unused utility functions in `circuitbreaker`, `crypto`, `cursor`, `hook`, and `utils`.
- **service**: Deleted `account_cleanup_service.go` and removed unused helper functions in `log_cleanup_service.go` and `sensitive_service.go`.
- **repository**: Removed unused private loading methods in `comment_repo.go`.
This commit is contained in:
2026-05-14 02:24:30 +08:00
parent d2894066f8
commit 9a1851f023
36 changed files with 0 additions and 1449 deletions

View File

@@ -22,15 +22,6 @@ type Config struct {
Name string // 熔断器名称,用于日志
}
func DefaultConfig(name string) Config {
return Config{
FailureThreshold: 5,
SuccessThreshold: 3,
Timeout: 30 * time.Second,
Name: name,
}
}
type Breaker struct {
cfg Config
mu sync.Mutex

View File

@@ -1,7 +1,6 @@
package crypto
import (
"encoding/json"
"sync"
)
@@ -75,35 +74,3 @@ func (e *MessageEncryptor) BatchDecrypt(ciphertexts []string, workerCount int) [
return results
}
// DecryptMessageSegments 解密消息段 JSON
// 这是一个便捷方法,直接返回解析后的 MessageSegments
func (e *MessageEncryptor) DecryptMessageSegments(ciphertext string) ([]byte, error) {
if e == nil || ciphertext == "" {
return nil, nil
}
return e.Decrypt(ciphertext)
}
// TryParseMessageSegments 尝试解析消息段
// 先尝试解密,如果失败则尝试直接解析(兼容未加密的旧数据)
func TryParseMessageSegments(ciphertext string, segments any) error {
if ciphertext == "" {
return nil
}
encryptor := GetMessageEncryptor()
if encryptor == nil {
// 加密器未初始化,直接解析
return json.Unmarshal([]byte(ciphertext), segments)
}
// 尝试解密
plaintext, err := encryptor.Decrypt(ciphertext)
if err != nil {
// 解密失败,可能是未加密的旧数据,尝试直接解析
return json.Unmarshal([]byte(ciphertext), segments)
}
// 解析解密后的数据
return json.Unmarshal(plaintext, segments)
}

View File

@@ -167,7 +167,3 @@ func (e *MessageEncryptor) RotateKey(newKey string, newVersion int) error {
return nil
}
// IsInitialized 检查加密器是否已初始化
func IsInitialized() bool {
return globalEncryptor != nil
}

View File

@@ -64,19 +64,6 @@ func (b *CursorBuilder) WithPageSize(size int) *CursorBuilder {
return b
}
// WithDirection 设置分页方向
func (b *CursorBuilder) WithDirection(direction Direction) *CursorBuilder {
if b.err != nil {
return b
}
if direction == "" {
b.direction = Forward
} else {
b.direction = direction
}
return b
}
// Error 返回构建过程中的错误
func (b *CursorBuilder) Error() error {
@@ -166,79 +153,11 @@ func HasMore(itemsLen int, pageSize int) bool {
return itemsLen > pageSize
}
// TrimItems 裁剪结果到实际页面大小
func TrimItems(itemsLen int, pageSize int) int {
if itemsLen > pageSize {
return pageSize
}
return itemsLen
}
// BuildResponse 从结果构建响应
// items: 结果切片(需要是切片类型)
// getSortValue: 获取排序字段值的函数
// getID: 获取ID的函数
func BuildResponse[T any](items []T, order SortOrder, pageSize int, getSortValue func(T) string, getID func(T) string) *PageResponse {
hasMore := len(items) > pageSize
// 裁剪到实际页面大小
if hasMore {
items = items[:pageSize]
}
var nextCursor, prevCursor string
// 生成下一页游标
if hasMore && len(items) > 0 {
lastItem := items[len(items)-1]
nextCursor = NewCursor(getSortValue(lastItem), getID(lastItem), order).Encode()
}
return &PageResponse{
Items: items,
NextCursor: nextCursor,
PrevCursor: prevCursor,
HasMore: hasMore,
}
}
// BuildResponseWithPrev 从结果构建响应(包含上一页游标)
func BuildResponseWithPrev[T any](items []T, order SortOrder, pageSize int, getSortValue func(T) string, getID func(T) string) *PageResponse {
hasMore := len(items) > pageSize
// 裁剪到实际页面大小
if hasMore {
items = items[:pageSize]
}
var nextCursor, prevCursor string
// 生成下一页游标
if hasMore && len(items) > 0 {
lastItem := items[len(items)-1]
nextCursor = NewCursor(getSortValue(lastItem), getID(lastItem), order).Encode()
}
// 生成上一页游标
if len(items) > 0 {
firstItem := items[0]
prevCursor = NewCursor(getSortValue(firstItem), getID(firstItem), order).Encode()
}
return &PageResponse{
Items: items,
NextCursor: nextCursor,
PrevCursor: prevCursor,
HasMore: hasMore,
}
}
// FormatTime 格式化时间为字符串(用于游标)
func FormatTime(t time.Time) string {
return t.Format(time.RFC3339Nano)
}
// ParseTime 解析时间字符串(从游标)
func ParseTime(s string) (time.Time, error) {
return time.Parse(time.RFC3339Nano, s)
}

View File

@@ -99,15 +99,6 @@ type PageResponse struct {
HasMore bool `json:"has_more"`
}
// NewPageResponse 创建分页响应
func NewPageResponse(items any, nextCursor, prevCursor string, hasMore bool) *PageResponse {
return &PageResponse{
Items: items,
NextCursor: nextCursor,
PrevCursor: prevCursor,
HasMore: hasMore,
}
}
// CursorPageResult 游标分页结果(泛型版本,供内部使用)
type CursorPageResult[T any] struct {

View File

@@ -187,11 +187,6 @@ func WithAsync() HookOption {
}
}
func WithTimeout(timeout time.Duration) HookOption {
return func(h *Hook) {
h.Timeout = timeout
}
}
func (m *Manager) Trigger(ctx context.Context, hookType HookType, userID uint, data any) error {
return m.TriggerWithMetadata(ctx, hookType, userID, data, nil)

View File

@@ -1,8 +1,6 @@
package hook
import (
"context"
"go.uber.org/zap"
)
@@ -196,144 +194,3 @@ func (b *BuiltinHooks) registerLoggingHooks() {
func (b *BuiltinHooks) registerCacheInvalidationHooks() {
}
type HookTriggerHelper struct {
manager *Manager
}
func NewHookTriggerHelper(manager *Manager) *HookTriggerHelper {
return &HookTriggerHelper{manager: manager}
}
func (h *HookTriggerHelper) TriggerPostCreated(ctx context.Context, userID uint, data *PostHookData) {
h.manager.Trigger(ctx, HookPostCreated, userID, data)
}
func (h *HookTriggerHelper) TriggerPostUpdated(ctx context.Context, userID uint, data *PostHookData) {
h.manager.Trigger(ctx, HookPostUpdated, userID, data)
}
func (h *HookTriggerHelper) TriggerPostDeleted(ctx context.Context, userID uint, postID uint) {
h.manager.Trigger(ctx, HookPostDeleted, userID, postID)
}
func (h *HookTriggerHelper) TriggerCommentCreated(ctx context.Context, userID uint, data *CommentHookData) {
h.manager.Trigger(ctx, HookCommentCreated, userID, data)
}
func (h *HookTriggerHelper) TriggerCommentDeleted(ctx context.Context, userID uint, commentID uint) {
h.manager.Trigger(ctx, HookCommentDeleted, userID, commentID)
}
func (h *HookTriggerHelper) TriggerUserCreated(ctx context.Context, data *UserHookData) {
h.manager.Trigger(ctx, HookUserCreated, data.UserID, data)
}
func (h *HookTriggerHelper) TriggerUserUpdated(ctx context.Context, userID uint, data *UserHookData) {
h.manager.Trigger(ctx, HookUserUpdated, userID, data)
}
func (h *HookTriggerHelper) TriggerUserDeleted(ctx context.Context, userID uint) {
h.manager.Trigger(ctx, HookUserDeleted, userID, userID)
}
func (h *HookTriggerHelper) TriggerUserLogin(ctx context.Context, userID uint, data *UserHookData) {
h.manager.Trigger(ctx, HookUserLogin, userID, data)
}
func (h *HookTriggerHelper) TriggerUserLogout(ctx context.Context, userID uint) {
h.manager.Trigger(ctx, HookUserLogout, userID, userID)
}
func (h *HookTriggerHelper) TriggerGroupCreated(ctx context.Context, userID uint, data *GroupHookData) {
h.manager.Trigger(ctx, HookGroupCreated, userID, data)
}
func (h *HookTriggerHelper) TriggerGroupUpdated(ctx context.Context, userID uint, data *GroupHookData) {
h.manager.Trigger(ctx, HookGroupUpdated, userID, data)
}
func (h *HookTriggerHelper) TriggerGroupDeleted(ctx context.Context, userID uint, groupID uint) {
h.manager.Trigger(ctx, HookGroupDeleted, userID, groupID)
}
func (h *HookTriggerHelper) TriggerGroupJoined(ctx context.Context, userID uint, groupID uint) {
h.manager.Trigger(ctx, HookGroupJoined, userID, groupID)
}
func (h *HookTriggerHelper) TriggerGroupLeft(ctx context.Context, userID uint, groupID uint) {
h.manager.Trigger(ctx, HookGroupLeft, userID, groupID)
}
func (h *HookTriggerHelper) TriggerMessageSent(ctx context.Context, userID uint, data *MessageHookData) {
h.manager.Trigger(ctx, HookMessageSent, userID, data)
}
func (h *HookTriggerHelper) TriggerMessageRead(ctx context.Context, userID uint, messageID uint) {
h.manager.Trigger(ctx, HookMessageRead, userID, messageID)
}
func (h *HookTriggerHelper) TriggerNotificationSent(ctx context.Context, userID uint, data *NotificationHookData) {
h.manager.Trigger(ctx, HookNotificationSent, userID, data)
}
func (h *HookTriggerHelper) TriggerVoteCreated(ctx context.Context, userID uint, data *VoteHookData) {
h.manager.Trigger(ctx, HookVoteCreated, userID, data)
}
func (h *HookTriggerHelper) TriggerVoteUpdated(ctx context.Context, userID uint, data *VoteHookData) {
h.manager.Trigger(ctx, HookVoteUpdated, userID, data)
}
func (h *HookTriggerHelper) TriggerFileUploaded(ctx context.Context, userID uint, data *FileHookData) {
h.manager.Trigger(ctx, HookFileUploaded, userID, data)
}
func (h *HookTriggerHelper) TriggerPostPreModerate(ctx context.Context, userID uint, data *PostModerateHookData, result *ModerationResult) {
h.manager.TriggerWithMetadata(ctx, HookPostPreModerate, userID, data, map[string]any{
"result": result,
})
}
func (h *HookTriggerHelper) TriggerPostModerated(ctx context.Context, userID uint, data *PostModeratedHookData) {
h.manager.Trigger(ctx, HookPostModerated, userID, data)
}
func (h *HookTriggerHelper) TriggerCommentPreModerate(ctx context.Context, userID uint, data *CommentModerateHookData, result *ModerationResult) {
h.manager.TriggerWithMetadata(ctx, HookCommentPreModerate, userID, data, map[string]any{
"result": result,
})
}
func (h *HookTriggerHelper) TriggerCommentModerated(ctx context.Context, userID uint, data *CommentModeratedHookData) {
h.manager.Trigger(ctx, HookCommentModerated, userID, data)
}
func (h *HookTriggerHelper) TriggerUserAvatarPreModerate(ctx context.Context, userID uint, data *UserAvatarModerateHookData, result *ModerationResult) {
h.manager.TriggerWithMetadata(ctx, HookUserAvatarPreModerate, userID, data, map[string]any{
"result": result,
})
}
func (h *HookTriggerHelper) TriggerUserAvatarModerated(ctx context.Context, userID uint, data *UserAvatarModeratedHookData) {
h.manager.Trigger(ctx, HookUserAvatarModerated, userID, data)
}
func (h *HookTriggerHelper) TriggerUserCoverPreModerate(ctx context.Context, userID uint, data *UserCoverModerateHookData, result *ModerationResult) {
h.manager.TriggerWithMetadata(ctx, HookUserCoverPreModerate, userID, data, map[string]any{
"result": result,
})
}
func (h *HookTriggerHelper) TriggerUserCoverModerated(ctx context.Context, userID uint, data *UserCoverModeratedHookData) {
h.manager.Trigger(ctx, HookUserCoverModerated, userID, data)
}
func (h *HookTriggerHelper) TriggerUserBioPreModerate(ctx context.Context, userID uint, data *UserBioModerateHookData, result *ModerationResult) {
h.manager.TriggerWithMetadata(ctx, HookUserBioPreModerate, userID, data, map[string]any{
"result": result,
})
}
func (h *HookTriggerHelper) TriggerUserBioModerated(ctx context.Context, userID uint, data *UserBioModeratedHookData) {
h.manager.Trigger(ctx, HookUserBioModerated, userID, data)
}

View File

@@ -111,21 +111,6 @@ func Paginated(c *gin.Context, list any, total int64, page, pageSize int) {
})
}
// HandleServiceError 统一处理 Service 错误
// 如果 err 是 *apperrors.AppError返回对应的业务错误码和消息
// 如果 err 是其他错误,返回 false调用方应处理通用错误
// 返回 true 表示错误已处理false 表示需要调用方继续处理
func HandleServiceError(c *gin.Context, err error) bool {
if err == nil {
return false
}
if se, ok := apperrors.As(err); ok {
statusCode := statusCodeFromAppErrorCode(se.Code)
ErrorWithStringCode(c, statusCode, se.Code, se.Message)
return true
}
return false
}
// HandleError 统一处理错误(带默认消息)
// 如果 err 是 *apperrors.AppError返回对应的业务错误码和消息

View File

@@ -46,13 +46,3 @@ type tencentAPIResponse struct {
} `json:"Response"`
}
func ConfigFromAppConfig(cfg *Config) Config {
return Config{
Enabled: cfg.Enabled,
SecretID: cfg.SecretID,
SecretKey: cfg.SecretKey,
Region: cfg.Region,
BizType: cfg.BizType,
Timeout: cfg.Timeout,
}
}

View File

@@ -15,6 +15,3 @@ func GetAvatarOrDefault(username, nickname, avatar string) string {
return DefaultAvatarURL
}
func GetAvatarOrDefaultFromInfo(info AvatarInfo) string {
return GetAvatarOrDefault(info.Username, info.Nickname, info.Avatar)
}

View File

@@ -61,12 +61,6 @@ var (
globalSnowflakeErr error
)
// InitSnowflake 初始化全局雪花算法实例
// nodeID: 机器ID范围0-1023可以通过环境变量 NODE_ID 配置
func InitSnowflake(nodeID int64) error {
globalSnowflake, globalSnowflakeErr = NewSnowflake(nodeID)
return globalSnowflakeErr
}
// GetSnowflake 获取全局雪花算法实例
// 如果未初始化,会自动使用默认配置初始化
@@ -191,71 +185,12 @@ func (s *Snowflake) waitNextMillis(timestamp int64) int64 {
return now
}
// ParseID 解析雪花算法ID提取其中的信息
// id: 要解析的雪花算法ID
// 返回值包含时间戳、机器ID、序列号的结构体
func ParseID(id int64) *IDInfo {
// 提取序列号低12位
sequence := id & maxSequence
// 提取机器ID中间10位
nodeID := (id >> nodeIDShift) & maxNodeID
// 提取时间戳高41位
timestamp := (id >> timestampShift) + customEpoch
return &IDInfo{
Timestamp: timestamp,
NodeID: nodeID,
Sequence: sequence,
}
}
// currentTimestamp 获取当前时间戳(毫秒)
func currentTimestamp() int64 {
return time.Now().UnixNano() / 1e6
}
// GetNodeID 获取当前机器ID
func (s *Snowflake) GetNodeID() int64 {
return s.nodeID
}
// GetCustomEpoch 获取自定义纪元时间
func GetCustomEpoch() int64 {
return customEpoch
}
// IDToTime 将雪花算法ID转换为生成时间
// 这是一个便捷方法,等价于 ParseID(id).Timestamp
func IDToTime(id int64) time.Time {
info := ParseID(id)
return time.Unix(0, info.Timestamp*1e6) // 毫秒转纳秒
}
// ValidateID 验证ID是否为有效的雪花算法ID
// 检查时间戳是否在合理范围内
func ValidateID(id int64) bool {
if id <= 0 {
return false
}
info := ParseID(id)
// 检查时间戳是否在合理范围内
// 不能早于纪元时间不能晚于当前时间太多允许1分钟的时钟偏差
now := currentTimestamp()
if info.Timestamp < customEpoch || info.Timestamp > now+60000 {
return false
}
// 检查机器ID和序列号是否在有效范围内
if info.NodeID < 0 || info.NodeID > maxNodeID {
return false
}
if info.Sequence < 0 || info.Sequence > maxSequence {
return false
}
return true
}

View File

@@ -2,7 +2,6 @@ package utils
import (
"regexp"
"strings"
)
// ValidateEmail 验证邮箱
@@ -43,39 +42,6 @@ func ValidatePassword(password string) bool {
return hasUpper && hasLower && hasDigit
}
// ValidatePasswordWithDetail 验证密码强度并返回详细信息
func ValidatePasswordWithDetail(password string) (bool, string) {
if len(password) < 8 {
return false, "密码长度至少8位"
}
if len(password) > 50 {
return false, "密码长度不能超过50位"
}
var hasUpper, hasLower, hasDigit bool
for _, c := range password {
switch {
case 'A' <= c && c <= 'Z':
hasUpper = true
case 'a' <= c && c <= 'z':
hasLower = true
case '0' <= c && c <= '9':
hasDigit = true
}
}
if !hasUpper {
return false, "密码必须包含大写字母"
}
if !hasLower {
return false, "密码必须包含小写字母"
}
if !hasDigit {
return false, "密码必须包含数字"
}
return true, ""
}
// ValidatePhone 验证手机号
func ValidatePhone(phone string) bool {
@@ -84,13 +50,3 @@ func ValidatePhone(phone string) bool {
return matched
}
// SanitizeHTML 清理HTML防止XSS攻击
func SanitizeHTML(input string) string {
input = strings.ReplaceAll(input, "&", "&amp;")
input = strings.ReplaceAll(input, "<", "&lt;")
input = strings.ReplaceAll(input, ">", "&gt;")
input = strings.ReplaceAll(input, "\"", "&quot;")
input = strings.ReplaceAll(input, "'", "&#x27;")
input = strings.ReplaceAll(input, "/", "&#x2F;")
return input
}