后端重构
This commit is contained in:
+284
-11
@@ -1,7 +1,10 @@
|
||||
package data
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"kra/internal/biz/example"
|
||||
"kra/internal/conf"
|
||||
dataexample "kra/internal/data/example"
|
||||
@@ -9,17 +12,24 @@ import (
|
||||
pkgcasbin "kra/pkg/casbin"
|
||||
|
||||
"github.com/casbin/casbin/v2"
|
||||
oracle "github.com/dzwvip/gorm-oracle"
|
||||
"github.com/glebarez/sqlite"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/google/wire"
|
||||
"github.com/redis/go-redis/v9"
|
||||
"gorm.io/driver/mysql"
|
||||
"gorm.io/driver/postgres"
|
||||
"gorm.io/driver/sqlserver"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
||||
"gorm.io/gorm/schema"
|
||||
)
|
||||
|
||||
// ProviderSet is data providers.
|
||||
var ProviderSet = wire.NewSet(
|
||||
NewDB,
|
||||
NewData,
|
||||
NewRedisClient,
|
||||
NewCasbinEnforcer,
|
||||
NewOssUploader,
|
||||
NewDataAuthorityProvider,
|
||||
@@ -41,6 +51,8 @@ var ProviderSet = wire.NewSet(
|
||||
datasystem.NewAutoCodeRepo,
|
||||
datasystem.NewAutoCodeHistoryRepo,
|
||||
datasystem.NewAutoCodePackageRepo,
|
||||
datasystem.NewAutoCodeTemplateRepo,
|
||||
datasystem.NewAutoCodePluginRepo,
|
||||
// Example
|
||||
dataexample.NewFileUploadRepo,
|
||||
dataexample.NewCustomerRepo,
|
||||
@@ -50,34 +62,295 @@ var ProviderSet = wire.NewSet(
|
||||
|
||||
// Data 数据层包装器
|
||||
type Data struct {
|
||||
db *gorm.DB
|
||||
db *gorm.DB
|
||||
redis redis.UniversalClient
|
||||
}
|
||||
|
||||
// NewData 创建数据层包装器
|
||||
func NewData(db *gorm.DB) (*Data, func(), error) {
|
||||
func NewData(db *gorm.DB, redisClient redis.UniversalClient) (*Data, func(), error) {
|
||||
cleanup := func() {
|
||||
// 关闭数据库连接
|
||||
sqlDB, err := db.DB()
|
||||
if err == nil {
|
||||
sqlDB.Close()
|
||||
if db != nil {
|
||||
sqlDB, err := db.DB()
|
||||
if err == nil {
|
||||
sqlDB.Close()
|
||||
}
|
||||
}
|
||||
// 关闭Redis连接
|
||||
if redisClient != nil {
|
||||
redisClient.Close()
|
||||
}
|
||||
}
|
||||
return &Data{db: db}, cleanup, nil
|
||||
return &Data{db: db, redis: redisClient}, cleanup, nil
|
||||
}
|
||||
|
||||
// NewDB 创建数据库连接
|
||||
func NewDB(c *conf.Mysql) (*gorm.DB, error) {
|
||||
// DB 获取数据库连接
|
||||
func (d *Data) DB() *gorm.DB {
|
||||
return d.db
|
||||
}
|
||||
|
||||
// Redis 获取Redis客户端
|
||||
func (d *Data) Redis() redis.UniversalClient {
|
||||
return d.redis
|
||||
}
|
||||
|
||||
// NewDB 创建数据库连接(根据配置的数据库类型)
|
||||
func NewDB(system *conf.System, mysqlCfg *conf.Mysql, pgsqlCfg *conf.Pgsql, sqliteCfg *conf.Sqlite, mssqlCfg *conf.Mssql, oracleCfg *conf.Oracle) (*gorm.DB, error) {
|
||||
dbType := "mysql"
|
||||
if system != nil && system.DbType != "" {
|
||||
dbType = system.DbType
|
||||
}
|
||||
|
||||
switch dbType {
|
||||
case "mysql":
|
||||
return NewMysqlDB(mysqlCfg)
|
||||
case "pgsql":
|
||||
return NewPgsqlDB(pgsqlCfg)
|
||||
case "sqlite":
|
||||
return NewSqliteDB(sqliteCfg)
|
||||
case "mssql":
|
||||
return NewMssqlDB(mssqlCfg)
|
||||
case "oracle":
|
||||
return NewOracleDB(oracleCfg)
|
||||
default:
|
||||
return NewMysqlDB(mysqlCfg)
|
||||
}
|
||||
}
|
||||
|
||||
// NewMysqlDB 创建MySQL数据库连接
|
||||
func NewMysqlDB(c *conf.Mysql) (*gorm.DB, error) {
|
||||
if c == nil || c.DbName == "" {
|
||||
return nil, fmt.Errorf("mysql config is empty")
|
||||
}
|
||||
|
||||
dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?%s",
|
||||
c.Username, c.Password, c.Path, c.Port, c.DbName, c.Config)
|
||||
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
|
||||
Logger: logger.Default.LogMode(logger.Info),
|
||||
})
|
||||
|
||||
gormConfig := newGormConfig(c.Prefix, c.Singular, c.LogMode)
|
||||
|
||||
db, err := gorm.Open(mysql.New(mysql.Config{
|
||||
DSN: dsn,
|
||||
DefaultStringSize: 191,
|
||||
SkipInitializeWithVersion: false,
|
||||
}), gormConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if c.Engine != "" {
|
||||
db.InstanceSet("gorm:table_options", "ENGINE="+c.Engine)
|
||||
}
|
||||
|
||||
sqlDB, err := db.DB()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sqlDB.SetMaxIdleConns(int(c.MaxIdleConns))
|
||||
sqlDB.SetMaxOpenConns(int(c.MaxOpenConns))
|
||||
|
||||
return db, nil
|
||||
}
|
||||
|
||||
// NewPgsqlDB 创建PostgreSQL数据库连接
|
||||
func NewPgsqlDB(c *conf.Pgsql) (*gorm.DB, error) {
|
||||
if c == nil || c.DbName == "" {
|
||||
return nil, fmt.Errorf("pgsql config is empty")
|
||||
}
|
||||
|
||||
dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%s %s",
|
||||
c.Path, c.Username, c.Password, c.DbName, c.Port, c.Config)
|
||||
|
||||
gormConfig := newGormConfig(c.Prefix, c.Singular, c.LogMode)
|
||||
|
||||
db, err := gorm.Open(postgres.New(postgres.Config{
|
||||
DSN: dsn,
|
||||
PreferSimpleProtocol: false,
|
||||
}), gormConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sqlDB, err := db.DB()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sqlDB.SetMaxIdleConns(int(c.MaxIdleConns))
|
||||
sqlDB.SetMaxOpenConns(int(c.MaxOpenConns))
|
||||
|
||||
return db, nil
|
||||
}
|
||||
|
||||
// NewSqliteDB 创建SQLite数据库连接
|
||||
func NewSqliteDB(c *conf.Sqlite) (*gorm.DB, error) {
|
||||
if c == nil || c.DbName == "" {
|
||||
return nil, fmt.Errorf("sqlite config is empty")
|
||||
}
|
||||
|
||||
dsn := c.DbName
|
||||
if c.Path != "" {
|
||||
dsn = fmt.Sprintf("%s/%s", c.Path, c.DbName)
|
||||
}
|
||||
|
||||
gormConfig := newGormConfig(c.Prefix, c.Singular, c.LogMode)
|
||||
|
||||
db, err := gorm.Open(sqlite.Open(dsn), gormConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sqlDB, err := db.DB()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sqlDB.SetMaxIdleConns(int(c.MaxIdleConns))
|
||||
sqlDB.SetMaxOpenConns(int(c.MaxOpenConns))
|
||||
|
||||
return db, nil
|
||||
}
|
||||
|
||||
// NewMssqlDB 创建MSSQL数据库连接
|
||||
func NewMssqlDB(c *conf.Mssql) (*gorm.DB, error) {
|
||||
if c == nil || c.DbName == "" {
|
||||
return nil, fmt.Errorf("mssql config is empty")
|
||||
}
|
||||
|
||||
dsn := fmt.Sprintf("sqlserver://%s:%s@%s:%s?database=%s&%s",
|
||||
c.Username, c.Password, c.Path, c.Port, c.DbName, c.Config)
|
||||
|
||||
gormConfig := newGormConfig(c.Prefix, c.Singular, c.LogMode)
|
||||
|
||||
db, err := gorm.Open(sqlserver.New(sqlserver.Config{
|
||||
DSN: dsn,
|
||||
DefaultStringSize: 191,
|
||||
}), gormConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if c.Engine != "" {
|
||||
db.InstanceSet("gorm:table_options", "ENGINE="+c.Engine)
|
||||
}
|
||||
|
||||
sqlDB, err := db.DB()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sqlDB.SetMaxIdleConns(int(c.MaxIdleConns))
|
||||
sqlDB.SetMaxOpenConns(int(c.MaxOpenConns))
|
||||
|
||||
return db, nil
|
||||
}
|
||||
|
||||
// NewOracleDB 创建Oracle数据库连接
|
||||
func NewOracleDB(c *conf.Oracle) (*gorm.DB, error) {
|
||||
if c == nil || c.DbName == "" {
|
||||
return nil, fmt.Errorf("oracle config is empty")
|
||||
}
|
||||
|
||||
dsn := fmt.Sprintf("oracle://%s:%s@%s:%s/%s?%s",
|
||||
c.Username, c.Password, c.Path, c.Port, c.DbName, c.Config)
|
||||
|
||||
gormConfig := newGormConfig(c.Prefix, c.Singular, c.LogMode)
|
||||
|
||||
db, err := gorm.Open(oracle.Open(dsn), gormConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sqlDB, err := db.DB()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sqlDB.SetMaxIdleConns(int(c.MaxIdleConns))
|
||||
sqlDB.SetMaxOpenConns(int(c.MaxOpenConns))
|
||||
|
||||
return db, nil
|
||||
}
|
||||
|
||||
// newGormConfig 创建GORM配置
|
||||
func newGormConfig(prefix string, singular bool, logMode string) *gorm.Config {
|
||||
return &gorm.Config{
|
||||
Logger: logger.New(
|
||||
&gormLogWriter{},
|
||||
logger.Config{
|
||||
SlowThreshold: 200 * time.Millisecond,
|
||||
LogLevel: parseLogLevel(logMode),
|
||||
Colorful: true,
|
||||
},
|
||||
),
|
||||
NamingStrategy: schema.NamingStrategy{
|
||||
TablePrefix: prefix,
|
||||
SingularTable: singular,
|
||||
},
|
||||
DisableForeignKeyConstraintWhenMigrating: true,
|
||||
}
|
||||
}
|
||||
|
||||
// gormLogWriter GORM日志写入器
|
||||
type gormLogWriter struct{}
|
||||
|
||||
func (w *gormLogWriter) Printf(format string, args ...interface{}) {
|
||||
fmt.Printf(format+"\n", args...)
|
||||
}
|
||||
|
||||
// parseLogLevel 解析日志级别
|
||||
func parseLogLevel(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.Info
|
||||
}
|
||||
}
|
||||
|
||||
// NewRedisClient 创建Redis客户端
|
||||
func NewRedisClient(c *conf.Redis, system *conf.System) (redis.UniversalClient, error) {
|
||||
// 如果不使用Redis,返回nil
|
||||
if system != nil && !system.UseRedis {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if c == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var client redis.UniversalClient
|
||||
|
||||
// 使用集群模式
|
||||
if c.UseCluster {
|
||||
client = redis.NewClusterClient(&redis.ClusterOptions{
|
||||
Addrs: c.ClusterAddrs,
|
||||
Password: c.Password,
|
||||
})
|
||||
} else {
|
||||
// 使用单例模式
|
||||
client = redis.NewClient(&redis.Options{
|
||||
Addr: c.Addr,
|
||||
Password: c.Password,
|
||||
DB: int(c.Db),
|
||||
})
|
||||
}
|
||||
|
||||
// 测试连接
|
||||
_, err := client.Ping(context.Background()).Result()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("redis connect ping failed: %v", err)
|
||||
}
|
||||
|
||||
return client, nil
|
||||
}
|
||||
|
||||
// NewCasbinEnforcer 创建Casbin Enforcer
|
||||
func NewCasbinEnforcer(db *gorm.DB) (*casbin.SyncedCachedEnforcer, error) {
|
||||
return pkgcasbin.InitCasbin(db, "")
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package query
|
||||
|
||||
// 运行 go generate ./... 时会自动执行 GORM Gen 代码生成
|
||||
// 这会读取数据库中的所有表并生成对应的查询代码
|
||||
//go:generate go run ../../../cmd/gen/main.go
|
||||
@@ -4,21 +4,37 @@ import (
|
||||
"context"
|
||||
|
||||
"kra/internal/biz/system"
|
||||
"kra/internal/conf"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type autoCodeRepo struct {
|
||||
db *gorm.DB
|
||||
db *gorm.DB
|
||||
dbName string
|
||||
conf *conf.Bootstrap
|
||||
}
|
||||
|
||||
// NewAutoCodeRepo 创建自动代码仓储
|
||||
func NewAutoCodeRepo(db *gorm.DB) system.AutoCodeRepo {
|
||||
return &autoCodeRepo{db: db}
|
||||
func NewAutoCodeRepo(db *gorm.DB, conf *conf.Bootstrap) system.AutoCodeRepo {
|
||||
// 获取默认数据库名
|
||||
dbName := ""
|
||||
if conf.Mysql != nil && conf.Mysql.DbName != "" {
|
||||
dbName = conf.Mysql.DbName
|
||||
} else if conf.Pgsql != nil && conf.Pgsql.DbName != "" {
|
||||
dbName = conf.Pgsql.DbName
|
||||
} else if conf.Sqlite != nil && conf.Sqlite.DbName != "" {
|
||||
dbName = conf.Sqlite.DbName
|
||||
}
|
||||
return &autoCodeRepo{
|
||||
db: db,
|
||||
dbName: dbName,
|
||||
conf: conf,
|
||||
}
|
||||
}
|
||||
|
||||
// GetDB 获取所有数据库
|
||||
func (r *autoCodeRepo) GetDB(ctx context.Context) ([]system.Db, error) {
|
||||
func (r *autoCodeRepo) GetDB(ctx context.Context, businessDB string) ([]system.Db, error) {
|
||||
var entities []system.Db
|
||||
sql := "SELECT SCHEMA_NAME AS `database` FROM INFORMATION_SCHEMA.SCHEMATA;"
|
||||
err := r.db.WithContext(ctx).Raw(sql).Scan(&entities).Error
|
||||
@@ -26,7 +42,7 @@ func (r *autoCodeRepo) GetDB(ctx context.Context) ([]system.Db, error) {
|
||||
}
|
||||
|
||||
// GetTables 获取指定数据库的所有表
|
||||
func (r *autoCodeRepo) GetTables(ctx context.Context, dbName string) ([]system.Table, error) {
|
||||
func (r *autoCodeRepo) GetTables(ctx context.Context, businessDB, dbName string) ([]system.Table, error) {
|
||||
var entities []system.Table
|
||||
sql := `SELECT table_name AS table_name FROM information_schema.tables WHERE table_schema = ?`
|
||||
err := r.db.WithContext(ctx).Raw(sql, dbName).Scan(&entities).Error
|
||||
@@ -34,7 +50,7 @@ func (r *autoCodeRepo) GetTables(ctx context.Context, dbName string) ([]system.T
|
||||
}
|
||||
|
||||
// GetColumn 获取指定表的所有列
|
||||
func (r *autoCodeRepo) GetColumn(ctx context.Context, tableName, dbName string) ([]system.Column, error) {
|
||||
func (r *autoCodeRepo) GetColumn(ctx context.Context, businessDB, tableName, dbName string) ([]system.Column, error) {
|
||||
var entities []system.Column
|
||||
sql := `
|
||||
SELECT
|
||||
@@ -69,3 +85,40 @@ func (r *autoCodeRepo) GetColumn(ctx context.Context, tableName, dbName string)
|
||||
err := r.db.WithContext(ctx).Raw(sql, tableName, dbName).Scan(&entities).Error
|
||||
return entities, err
|
||||
}
|
||||
|
||||
// GetDBList 获取配置的数据库列表
|
||||
func (r *autoCodeRepo) GetDBList() []system.DBInfo {
|
||||
// 目前KRA只支持单数据库配置,返回主数据库信息
|
||||
var dbList []system.DBInfo
|
||||
if r.conf.Mysql != nil && r.conf.Mysql.DbName != "" {
|
||||
dbList = append(dbList, system.DBInfo{
|
||||
AliasName: "",
|
||||
DBName: r.conf.Mysql.DbName,
|
||||
Disable: false,
|
||||
DBType: "mysql",
|
||||
})
|
||||
}
|
||||
if r.conf.Pgsql != nil && r.conf.Pgsql.DbName != "" {
|
||||
dbList = append(dbList, system.DBInfo{
|
||||
AliasName: "",
|
||||
DBName: r.conf.Pgsql.DbName,
|
||||
Disable: false,
|
||||
DBType: "pgsql",
|
||||
})
|
||||
}
|
||||
if r.conf.Sqlite != nil && r.conf.Sqlite.DbName != "" {
|
||||
dbList = append(dbList, system.DBInfo{
|
||||
AliasName: "",
|
||||
DBName: r.conf.Sqlite.DbName,
|
||||
Disable: false,
|
||||
DBType: "sqlite",
|
||||
})
|
||||
}
|
||||
return dbList
|
||||
}
|
||||
|
||||
// GetActiveDBName 获取当前活动的数据库名
|
||||
func (r *autoCodeRepo) GetActiveDBName(businessDB string) string {
|
||||
// 目前KRA只支持单数据库,直接返回配置的数据库名
|
||||
return r.dbName
|
||||
}
|
||||
|
||||
@@ -66,3 +66,18 @@ func (r *autoCodeHistoryRepo) DropTable(ctx context.Context, businessDB, tableNa
|
||||
// 注意:这里简化处理,实际应该支持多数据库
|
||||
return r.db.WithContext(ctx).Exec("DROP TABLE IF EXISTS " + tableName).Error
|
||||
}
|
||||
|
||||
// Create 创建历史记录
|
||||
func (r *autoCodeHistoryRepo) Create(ctx context.Context, history *system.SysAutoCodeHistory) error {
|
||||
return r.db.WithContext(ctx).Create(history).Error
|
||||
}
|
||||
|
||||
// Repeat 检测重复
|
||||
func (r *autoCodeHistoryRepo) Repeat(ctx context.Context, businessDB, structName, abbreviation, pkg string) bool {
|
||||
var count int64
|
||||
r.db.WithContext(ctx).Model(&system.SysAutoCodeHistory{}).
|
||||
Where("business_db = ? AND struct_name = ? AND abbreviation = ? AND package = ?",
|
||||
businessDB, structName, abbreviation, pkg).
|
||||
Count(&count)
|
||||
return count > 0
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,38 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"kra/internal/biz/system"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type autoCodePluginRepo struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
// NewAutoCodePluginRepo 创建插件仓储
|
||||
func NewAutoCodePluginRepo(db *gorm.DB) system.AutoCodePluginRepo {
|
||||
return &autoCodePluginRepo{db: db}
|
||||
}
|
||||
|
||||
// GetMenusByIDs 根据ID列表获取菜单
|
||||
func (r *autoCodePluginRepo) GetMenusByIDs(ctx context.Context, ids []uint) ([]system.SysBaseMenu, error) {
|
||||
var menus []system.SysBaseMenu
|
||||
if len(ids) == 0 {
|
||||
return menus, nil
|
||||
}
|
||||
err := r.db.WithContext(ctx).Where("id IN ?", ids).Find(&menus).Error
|
||||
return menus, err
|
||||
}
|
||||
|
||||
// GetApisByIDs 根据ID列表获取API
|
||||
func (r *autoCodePluginRepo) GetApisByIDs(ctx context.Context, ids []uint) ([]system.SysApi, error) {
|
||||
var apis []system.SysApi
|
||||
if len(ids) == 0 {
|
||||
return apis, nil
|
||||
}
|
||||
err := r.db.WithContext(ctx).Where("id IN ?", ids).Find(&apis).Error
|
||||
return apis, err
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"kra/internal/biz/system"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type autoCodeTemplateRepo struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
// NewAutoCodeTemplateRepo 创建自动代码模板仓储
|
||||
func NewAutoCodeTemplateRepo(db *gorm.DB) system.AutoCodeTemplateRepo {
|
||||
return &autoCodeTemplateRepo{db: db}
|
||||
}
|
||||
|
||||
// GetPackageByName 根据包名获取包信息
|
||||
func (r *autoCodeTemplateRepo) GetPackageByName(ctx context.Context, packageName string) (*system.SysAutoCodePackage, error) {
|
||||
var entity system.SysAutoCodePackage
|
||||
err := r.db.WithContext(ctx).Where("package_name = ?", packageName).First(&entity).Error
|
||||
return &entity, err
|
||||
}
|
||||
|
||||
// CreateApis 批量创建API
|
||||
func (r *autoCodeTemplateRepo) CreateApis(ctx context.Context, apis []system.SysApi) ([]uint, error) {
|
||||
if len(apis) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
err := r.db.WithContext(ctx).Create(&apis).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ids := make([]uint, len(apis))
|
||||
for i, api := range apis {
|
||||
ids[i] = api.ID
|
||||
}
|
||||
return ids, nil
|
||||
}
|
||||
|
||||
// GetMenuByName 根据名称获取菜单
|
||||
func (r *autoCodeTemplateRepo) GetMenuByName(ctx context.Context, name string) (*system.SysBaseMenu, error) {
|
||||
var entity system.SysBaseMenu
|
||||
err := r.db.WithContext(ctx).Where("name = ?", name).First(&entity).Error
|
||||
return &entity, err
|
||||
}
|
||||
|
||||
// CreateMenu 创建菜单
|
||||
func (r *autoCodeTemplateRepo) CreateMenu(ctx context.Context, menu *system.SysBaseMenu) error {
|
||||
return r.db.WithContext(ctx).Create(menu).Error
|
||||
}
|
||||
|
||||
// CreateExportTemplate 创建导出模板
|
||||
func (r *autoCodeTemplateRepo) CreateExportTemplate(ctx context.Context, tpl *system.SysExportTemplate) error {
|
||||
return r.db.WithContext(ctx).Create(tpl).Error
|
||||
}
|
||||
|
||||
// Repeat 检查是否重复创建
|
||||
func (r *autoCodeTemplateRepo) Repeat(ctx context.Context, businessDB, structName, abbreviation, pkg string) bool {
|
||||
var count int64
|
||||
r.db.WithContext(ctx).Model(&system.SysAutoCodeHistory{}).
|
||||
Where("struct_name = ? AND package = ?", structName, pkg).
|
||||
Or("abbreviation = ? AND package = ?", abbreviation, pkg).
|
||||
Count(&count)
|
||||
return count > 0
|
||||
}
|
||||
@@ -108,3 +108,13 @@ func (r *casbinRepo) UpdateCasbin(adminAuthorityID, authorityId uint, casbinInfo
|
||||
func (r *casbinRepo) RemoveFilteredPolicy(authorityId string) error {
|
||||
return r.db.Delete(&gormadapter.CasbinRule{}, "v0 = ?", authorityId).Error
|
||||
}
|
||||
|
||||
// SyncPolicy 同步策略(先删除再添加)
|
||||
func (r *casbinRepo) SyncPolicy(authorityId string, rules [][]string) error {
|
||||
// 先删除旧策略
|
||||
if err := r.RemoveFilteredPolicy(authorityId); err != nil {
|
||||
return err
|
||||
}
|
||||
// 再添加新策略
|
||||
return r.AddPolicies(rules)
|
||||
}
|
||||
|
||||
@@ -2,22 +2,40 @@ package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"kra/internal/biz/system"
|
||||
"kra/internal/data/model"
|
||||
"kra/internal/data/query"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type jwtBlacklistRepo struct {
|
||||
db *gorm.DB
|
||||
db *gorm.DB
|
||||
redisClient redis.UniversalClient
|
||||
expiresTime time.Duration
|
||||
}
|
||||
|
||||
// NewJwtBlacklistRepo 创建JWT黑名单仓储
|
||||
func NewJwtBlacklistRepo(db *gorm.DB) system.JwtBlacklistRepo {
|
||||
query.SetDefault(db)
|
||||
return &jwtBlacklistRepo{db: db}
|
||||
return &jwtBlacklistRepo{
|
||||
db: db,
|
||||
redisClient: nil, // 默认不使用Redis
|
||||
expiresTime: 7 * 24 * time.Hour,
|
||||
}
|
||||
}
|
||||
|
||||
// NewJwtBlacklistRepoWithRedis 创建带Redis的JWT黑名单仓储
|
||||
func NewJwtBlacklistRepoWithRedis(db *gorm.DB, redisClient redis.UniversalClient, expiresTime time.Duration) system.JwtBlacklistRepo {
|
||||
query.SetDefault(db)
|
||||
return &jwtBlacklistRepo{
|
||||
db: db,
|
||||
redisClient: redisClient,
|
||||
expiresTime: expiresTime,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *jwtBlacklistRepo) Create(ctx context.Context, jwt string) error {
|
||||
@@ -35,3 +53,19 @@ func (r *jwtBlacklistRepo) LoadAll(ctx context.Context) ([]string, error) {
|
||||
err := r.db.WithContext(ctx).Model(&model.JwtBlacklist{}).Pluck("jwt", &jwts).Error
|
||||
return jwts, err
|
||||
}
|
||||
|
||||
// GetRedisJWT 从Redis获取JWT
|
||||
func (r *jwtBlacklistRepo) GetRedisJWT(ctx context.Context, username string) (string, error) {
|
||||
if r.redisClient == nil {
|
||||
return "", redis.Nil
|
||||
}
|
||||
return r.redisClient.Get(ctx, "jwt:"+username).Result()
|
||||
}
|
||||
|
||||
// SetRedisJWT 设置Redis JWT
|
||||
func (r *jwtBlacklistRepo) SetRedisJWT(ctx context.Context, token, username string) error {
|
||||
if r.redisClient == nil {
|
||||
return nil
|
||||
}
|
||||
return r.redisClient.Set(ctx, "jwt:"+username, token, r.expiresTime).Err()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user