Files
backend/internal/model/init.go
lan ae5b997924 feat(auth): add Casbin RBAC and user activity tracking
Integrate Casbin for role-based access control with admin routes for role management. Add user activity logging service to track login and refresh events. Refactor audit service to use AI-based content moderation.
2026-03-14 02:09:38 +08:00

167 lines
3.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package model
import (
"fmt"
"log"
"os"
"time"
"gorm.io/driver/postgres"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
"gorm.io/gorm/logger"
"carrot_bbs/internal/config"
)
// NewDB 创建数据库连接(用于 Wire 依赖注入)
func NewDB(cfg *config.DatabaseConfig) (*gorm.DB, error) {
var err error
var db *gorm.DB
gormLogger := logger.New(
log.New(os.Stdout, "\r\n", log.LstdFlags),
logger.Config{
SlowThreshold: time.Duration(cfg.SlowThresholdMs) * time.Millisecond,
LogLevel: parseGormLogLevel(cfg.LogLevel),
IgnoreRecordNotFoundError: cfg.IgnoreRecordNotFound,
ParameterizedQueries: cfg.ParameterizedQueries,
Colorful: false,
},
)
// 根据数据库类型选择驱动
switch cfg.Type {
case "sqlite":
db, err = gorm.Open(sqlite.Open(cfg.SQLite.Path), &gorm.Config{
Logger: gormLogger,
})
case "postgres", "postgresql":
dsn := cfg.Postgres.DSN()
db, err = gorm.Open(postgres.Open(dsn), &gorm.Config{
Logger: gormLogger,
})
default:
// 默认使用PostgreSQL
dsn := cfg.Postgres.DSN()
db, err = gorm.Open(postgres.Open(dsn), &gorm.Config{
Logger: gormLogger,
})
}
if err != nil {
return nil, fmt.Errorf("failed to connect to database: %w", err)
}
// 配置连接池SQLite不支持连接池配置跳过
if cfg.Type != "sqlite" {
sqlDB, err := db.DB()
if err != nil {
return nil, fmt.Errorf("failed to get database instance: %w", err)
}
sqlDB.SetMaxIdleConns(cfg.MaxIdleConns)
sqlDB.SetMaxOpenConns(cfg.MaxOpenConns)
}
// 自动迁移
if err := autoMigrate(db); err != nil {
return nil, fmt.Errorf("failed to auto migrate: %w", err)
}
log.Printf("Database connected (%s) and migrated successfully", cfg.Type)
return db, nil
}
func parseGormLogLevel(level string) logger.LogLevel {
switch level {
case "silent":
return logger.Silent
case "error":
return logger.Error
case "warn":
return logger.Warn
case "info":
return logger.Info
default:
return logger.Warn
}
}
// autoMigrate 自动迁移数据库表
func autoMigrate(db *gorm.DB) error {
err := db.AutoMigrate(
// 用户相关
&User{},
// 帖子相关
&Post{},
&PostImage{},
// 评论相关
&Comment{},
&CommentLike{},
// 消息相关使用雪花算法ID和seq机制
// 已读位置存储在 ConversationParticipant.LastReadSeq 中
&Conversation{},
&ConversationParticipant{},
&Message{},
// 系统通知(独立表,每个用户只能看到自己的通知)
&SystemNotification{},
// 通知
&Notification{},
// 推送中心相关
&PushRecord{}, // 推送记录
&DeviceToken{}, // 设备Token
// 社交
&Follow{},
&UserBlock{},
&PostLike{},
&Favorite{},
// 投票
&VoteOption{},
&UserVote{},
// 敏感词和审核
&SensitiveWord{},
&AuditLog{},
// 群组相关
&Group{},
&GroupMember{},
&GroupAnnouncement{},
&GroupJoinRequest{},
// 自定义表情
&UserSticker{},
// 课表
&ScheduleCourse{},
// 用户活跃相关
&UserActiveLog{},
&UserActivityStat{},
// 角色和权限相关
&Role{},
&UserRole{},
&CasbinRule{},
)
if err != nil {
return err
}
return nil
}
// CloseDB 关闭数据库连接
func CloseDB(db *gorm.DB) {
if sqlDB, err := db.DB(); err == nil {
sqlDB.Close()
}
}