🎨 更新项目版本

This commit is contained in:
2025-09-03 01:45:01 +08:00
parent f928348284
commit 5496bdaa94
130 changed files with 9397 additions and 1816 deletions

View File

@@ -53,7 +53,7 @@ func (e *ensureTables) MigrateTable(ctx context.Context) (context.Context, error
sysModel.Condition{},
sysModel.JoinTemplate{},
sysModel.SysParams{},
sysModel.SysVersion{},
adapter.CasbinRule{},
example.ExaFile{},

View File

@@ -1,7 +1,6 @@
package initialize
import (
"git.echol.cn/loser/lckt/model/app"
"os"
"git.echol.cn/loser/lckt/global"
@@ -57,15 +56,13 @@ func RegisterTables() {
system.Condition{},
system.JoinTemplate{},
system.SysParams{},
system.SysVersion{},
example.ExaFile{},
example.ExaCustomer{},
example.ExaFileChunk{},
example.ExaFileUploadAndDownload{},
example.ExaAttachmentCategory{},
app.Banner{},
app.Order{},
)
if err != nil {
global.GVA_LOG.Error("register table failed", zap.Error(err))

View File

@@ -2,24 +2,11 @@ package initialize
import (
"git.echol.cn/loser/lckt/global"
"git.echol.cn/loser/lckt/model/article"
"git.echol.cn/loser/lckt/model/bot"
"git.echol.cn/loser/lckt/model/category"
"git.echol.cn/loser/lckt/model/notice"
"git.echol.cn/loser/lckt/model/user"
"git.echol.cn/loser/lckt/model/vip"
)
func bizModel() error {
db := global.GVA_DB
err := db.AutoMigrate(
category.Category{},
bot.Bot{},
article.Article{},
user.User{},
vip.Vip{},
notice.Notice{},
)
err := db.AutoMigrate()
if err != nil {
return err
}

View File

@@ -28,7 +28,9 @@ func GormMssql() *gorm.DB {
DSN: m.Dsn(), // DSN data source name
DefaultStringSize: 191, // string 类型字段的默认长度
}
if db, err := gorm.Open(sqlserver.New(mssqlConfig), internal.Gorm.Config(m.Prefix, m.Singular)); err != nil {
// 数据库配置
general := m.GeneralDB
if db, err := gorm.Open(sqlserver.New(mssqlConfig), internal.Gorm.Config(general)); err != nil {
return nil
} else {
db.InstanceSet("gorm:table_options", "ENGINE="+m.Engine)
@@ -48,7 +50,9 @@ func GormMssqlByConfig(m config.Mssql) *gorm.DB {
DSN: m.Dsn(), // DSN data source name
DefaultStringSize: 191, // string 类型字段的默认长度
}
if db, err := gorm.Open(sqlserver.New(mssqlConfig), internal.Gorm.Config(m.Prefix, m.Singular)); err != nil {
// 数据库配置
general := m.GeneralDB
if db, err := gorm.Open(sqlserver.New(mssqlConfig), internal.Gorm.Config(general)); err != nil {
panic(err)
} else {
db.InstanceSet("gorm:table_options", "ENGINE=InnoDB")

View File

@@ -12,18 +12,32 @@ import (
// GormMysql 初始化Mysql数据库
// Author [piexlmax](https://github.com/piexlmax)
// Author [SliverHorn](https://github.com/SliverHorn)
// Author [ByteZhou-2018](https://github.com/ByteZhou-2018)
func GormMysql() *gorm.DB {
m := global.GVA_CONFIG.Mysql
return initMysqlDatabase(m)
}
// GormMysqlByConfig 通过传入配置初始化Mysql数据库
func GormMysqlByConfig(m config.Mysql) *gorm.DB {
return initMysqlDatabase(m)
}
// initMysqlDatabase 初始化Mysql数据库的辅助函数
func initMysqlDatabase(m config.Mysql) *gorm.DB {
if m.Dbname == "" {
return nil
}
mysqlConfig := mysql.Config{
DSN: m.Dsn(), // DSN data source name
DefaultStringSize: 191, // string 类型字段的默认长度
SkipInitializeWithVersion: false, // 根据版本自动配置
}
if db, err := gorm.Open(mysql.New(mysqlConfig), internal.Gorm.Config(m.Prefix, m.Singular)); err != nil {
return nil
// 数据库配置
general := m.GeneralDB
if db, err := gorm.Open(mysql.New(mysqlConfig), internal.Gorm.Config(general)); err != nil {
panic(err)
} else {
db.InstanceSet("gorm:table_options", "ENGINE="+m.Engine)
sqlDB, _ := db.DB()
@@ -32,24 +46,3 @@ func GormMysql() *gorm.DB {
return db
}
}
// GormMysqlByConfig 初始化Mysql数据库用过传入配置
func GormMysqlByConfig(m config.Mysql) *gorm.DB {
if m.Dbname == "" {
return nil
}
mysqlConfig := mysql.Config{
DSN: m.Dsn(), // DSN data source name
DefaultStringSize: 191, // string 类型字段的默认长度
SkipInitializeWithVersion: false, // 根据版本自动配置
}
if db, err := gorm.Open(mysql.New(mysqlConfig), internal.Gorm.Config(m.Prefix, m.Singular)); err != nil {
panic(err)
} else {
db.InstanceSet("gorm:table_options", "ENGINE=InnoDB")
sqlDB, _ := db.DB()
sqlDB.SetMaxIdleConns(m.MaxIdleConns)
sqlDB.SetMaxOpenConns(m.MaxOpenConns)
return db
}
}

View File

@@ -1,47 +1,32 @@
package initialize
import (
//"github.com/dzwvip/oracle"
"git.echol.cn/loser/lckt/config"
"git.echol.cn/loser/lckt/global"
"git.echol.cn/loser/lckt/initialize/internal"
//_ "github.com/godror/godror"
"gorm.io/driver/mysql"
oracle "github.com/dzwvip/gorm-oracle"
"gorm.io/gorm"
)
// GormOracle 初始化oracle数据库
// 如果需要Oracle库 放开import里的注释 把下方 mysql.Config 改为 oracle.Config ; mysql.New 改为 oracle.New
func GormOracle() *gorm.DB {
m := global.GVA_CONFIG.Oracle
if m.Dbname == "" {
return nil
}
oracleConfig := mysql.Config{
DSN: m.Dsn(), // DSN data source name
DefaultStringSize: 191, // string 类型字段的默认长度
}
if db, err := gorm.Open(mysql.New(oracleConfig), internal.Gorm.Config(m.Prefix, m.Singular)); err != nil {
panic(err)
} else {
sqlDB, _ := db.DB()
sqlDB.SetMaxIdleConns(m.MaxIdleConns)
sqlDB.SetMaxOpenConns(m.MaxOpenConns)
return db
}
return initOracleDatabase(m)
}
// GormOracleByConfig 初始化Oracle数据库用过传入配置
func GormOracleByConfig(m config.Oracle) *gorm.DB {
return initOracleDatabase(m)
}
// initOracleDatabase 初始化Oracle数据库的辅助函数
func initOracleDatabase(m config.Oracle) *gorm.DB {
if m.Dbname == "" {
return nil
}
oracleConfig := mysql.Config{
DSN: m.Dsn(), // DSN data source name
DefaultStringSize: 191, // string 类型字段的默认长度
}
if db, err := gorm.Open(mysql.New(oracleConfig), internal.Gorm.Config(m.Prefix, m.Singular)); err != nil {
// 数据库配置
general := m.GeneralDB
if db, err := gorm.Open(oracle.Open(m.Dsn()), internal.Gorm.Config(general)); err != nil {
panic(err)
} else {
sqlDB, _ := db.DB()

View File

@@ -13,25 +13,16 @@ import (
// Author [SliverHorn](https://github.com/SliverHorn)
func GormPgSql() *gorm.DB {
p := global.GVA_CONFIG.Pgsql
if p.Dbname == "" {
return nil
}
pgsqlConfig := postgres.Config{
DSN: p.Dsn(), // DSN data source name
PreferSimpleProtocol: false,
}
if db, err := gorm.Open(postgres.New(pgsqlConfig), internal.Gorm.Config(p.Prefix, p.Singular)); err != nil {
return nil
} else {
sqlDB, _ := db.DB()
sqlDB.SetMaxIdleConns(p.MaxIdleConns)
sqlDB.SetMaxOpenConns(p.MaxOpenConns)
return db
}
return initPgSqlDatabase(p)
}
// GormPgSqlByConfig 初始化 Postgresql 数据库 通过参数
// GormPgSqlByConfig 初始化 Postgresql 数据库 通过指定参数
func GormPgSqlByConfig(p config.Pgsql) *gorm.DB {
return initPgSqlDatabase(p)
}
// initPgSqlDatabase 初始化 Postgresql 数据库的辅助函数
func initPgSqlDatabase(p config.Pgsql) *gorm.DB {
if p.Dbname == "" {
return nil
}
@@ -39,7 +30,9 @@ func GormPgSqlByConfig(p config.Pgsql) *gorm.DB {
DSN: p.Dsn(), // DSN data source name
PreferSimpleProtocol: false,
}
if db, err := gorm.Open(postgres.New(pgsqlConfig), internal.Gorm.Config(p.Prefix, p.Singular)); err != nil {
// 数据库配置
general := p.GeneralDB
if db, err := gorm.Open(postgres.New(pgsqlConfig), internal.Gorm.Config(general)); err != nil {
panic(err)
} else {
sqlDB, _ := db.DB()

View File

@@ -11,27 +11,23 @@ import (
// GormSqlite 初始化Sqlite数据库
func GormSqlite() *gorm.DB {
s := global.GVA_CONFIG.Sqlite
if s.Dbname == "" {
return nil
}
if db, err := gorm.Open(sqlite.Open(s.Dsn()), internal.Gorm.Config(s.Prefix, s.Singular)); err != nil {
panic(err)
} else {
sqlDB, _ := db.DB()
sqlDB.SetMaxIdleConns(s.MaxIdleConns)
sqlDB.SetMaxOpenConns(s.MaxOpenConns)
return db
}
return initSqliteDatabase(s)
}
// GormSqliteByConfig 初始化Sqlite数据库用过传入配置
func GormSqliteByConfig(s config.Sqlite) *gorm.DB {
return initSqliteDatabase(s)
}
// initSqliteDatabase 初始化Sqlite数据库辅助函数
func initSqliteDatabase(s config.Sqlite) *gorm.DB {
if s.Dbname == "" {
return nil
}
if db, err := gorm.Open(sqlite.Open(s.Dsn()), internal.Gorm.Config(s.Prefix, s.Singular)); err != nil {
// 数据库配置
general := s.GeneralDB
if db, err := gorm.Open(sqlite.Open(s.Dsn()), internal.Gorm.Config(general)); err != nil {
panic(err)
} else {
sqlDB, _ := db.DB()

15
initialize/init.go Normal file
View File

@@ -0,0 +1,15 @@
// 假设这是初始化逻辑的一部分
package initialize
import (
"git.echol.cn/loser/lckt/utils"
)
// 初始化全局函数
func SetupHandlers() {
// 注册系统重载处理函数
utils.GlobalSystemEvents.RegisterReloadHandler(func() error {
return Reload()
})
}

View File

@@ -1,12 +1,12 @@
package internal
import (
"time"
"git.echol.cn/loser/lckt/config"
"git.echol.cn/loser/lckt/global"
"gorm.io/gorm"
"gorm.io/gorm/logger"
"gorm.io/gorm/schema"
"time"
)
var Gorm = new(_gorm)
@@ -15,22 +15,7 @@ type _gorm struct{}
// Config gorm 自定义配置
// Author [SliverHorn](https://github.com/SliverHorn)
func (g *_gorm) Config(prefix string, singular bool) *gorm.Config {
var general config.GeneralDB
switch global.GVA_CONFIG.System.DbType {
case "mysql":
general = global.GVA_CONFIG.Mysql.GeneralDB
case "pgsql":
general = global.GVA_CONFIG.Pgsql.GeneralDB
case "oracle":
general = global.GVA_CONFIG.Oracle.GeneralDB
case "sqlite":
general = global.GVA_CONFIG.Sqlite.GeneralDB
case "mssql":
general = global.GVA_CONFIG.Mssql.GeneralDB
default:
general = global.GVA_CONFIG.Mysql.GeneralDB
}
func (g *_gorm) Config(general config.GeneralDB) *gorm.Config {
return &gorm.Config{
Logger: logger.New(NewWriter(general), logger.Config{
SlowThreshold: 200 * time.Millisecond,
@@ -38,8 +23,8 @@ func (g *_gorm) Config(prefix string, singular bool) *gorm.Config {
Colorful: true,
}),
NamingStrategy: schema.NamingStrategy{
TablePrefix: prefix,
SingularTable: singular,
TablePrefix: general.Prefix,
SingularTable: general.Singular,
},
DisableForeignKeyConstraintWhenMigrating: true,
}

25
initialize/mcp.go Normal file
View File

@@ -0,0 +1,25 @@
package initialize
import (
"git.echol.cn/loser/lckt/global"
mcpTool "git.echol.cn/loser/lckt/mcp"
"github.com/mark3labs/mcp-go/server"
)
func McpRun() *server.SSEServer {
config := global.GVA_CONFIG.MCP
s := server.NewMCPServer(
config.Name,
config.Version,
)
global.GVA_MCP_SERVER = s
mcpTool.RegisterAllTools(s)
return server.NewSSEServer(s,
server.WithSSEEndpoint(config.SSEPath),
server.WithMessageEndpoint(config.MessagePath),
server.WithBaseURL(config.UrlPrefix))
}

View File

@@ -2,6 +2,7 @@ package initialize
import (
"fmt"
"git.echol.cn/loser/lckt/global"
"git.echol.cn/loser/lckt/plugin/email"
"git.echol.cn/loser/lckt/utils/plugin"
@@ -29,6 +30,7 @@ func bizPluginV1(group ...*gin.RouterGroup) {
global.GVA_CONFIG.Email.Nickname,
global.GVA_CONFIG.Email.Port,
global.GVA_CONFIG.Email.IsSSL,
global.GVA_CONFIG.Email.IsLoginAuth,
))
holder(public, private)
}

45
initialize/reload.go Normal file
View File

@@ -0,0 +1,45 @@
package initialize
import (
"git.echol.cn/loser/lckt/global"
"go.uber.org/zap"
)
// Reload 优雅地重新加载系统配置
func Reload() error {
global.GVA_LOG.Info("正在重新加载系统配置...")
// 重新加载配置文件
if err := global.GVA_VP.ReadInConfig(); err != nil {
global.GVA_LOG.Error("重新读取配置文件失败!", zap.Error(err))
return err
}
// 重新初始化数据库连接
if global.GVA_DB != nil {
db, _ := global.GVA_DB.DB()
err := db.Close()
if err != nil {
global.GVA_LOG.Error("关闭原数据库连接失败!", zap.Error(err))
return err
}
}
// 重新建立数据库连接
global.GVA_DB = Gorm()
// 重新初始化其他配置
OtherInit()
DBList()
if global.GVA_DB != nil {
// 确保数据库表结构是最新的
RegisterTables()
}
// 重新初始化定时任务
Timer()
global.GVA_LOG.Info("系统配置重新加载完成")
return nil
}

View File

@@ -1,19 +1,16 @@
package initialize
import (
"net/http"
"os"
"git.echol.cn/loser/lckt/docs"
"git.echol.cn/loser/lckt/global"
"git.echol.cn/loser/lckt/middleware"
"git.echol.cn/loser/lckt/plugin/customerservice"
"git.echol.cn/loser/lckt/plugin/picturelibrary"
"git.echol.cn/loser/lckt/router"
gc "github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
swaggerFiles "github.com/swaggo/files"
ginSwagger "github.com/swaggo/gin-swagger"
"net/http"
"os"
"time"
)
type justFilesFilesystem struct {
@@ -39,21 +36,21 @@ func (fs justFilesFilesystem) Open(name string) (http.File, error) {
func Routers() *gin.Engine {
Router := gin.New()
Router.Use(gin.Recovery())
Router.Use(middleware.AllCors())
Router.Use(gc.New(gc.Config{
AllowAllOrigins: true, // 允许所有来源
AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
AllowHeaders: []string{"*"}, // 允许所有自定义header
ExposeHeaders: []string{"Content-Length", "Content-Type"},
AllowCredentials: true,
MaxAge: 12 * time.Hour,
}))
if gin.Mode() == gin.DebugMode {
Router.Use(gin.Logger())
}
sseServer := McpRun()
// 注册mcp服务
Router.GET(global.GVA_CONFIG.MCP.SSEPath, func(c *gin.Context) {
sseServer.SSEHandler().ServeHTTP(c.Writer, c.Request)
})
Router.POST(global.GVA_CONFIG.MCP.MessagePath, func(c *gin.Context) {
sseServer.MessageHandler().ServeHTTP(c.Writer, c.Request)
})
systemRouter := router.RouterGroupApp.System
exampleRouter := router.RouterGroupApp.Example
appRouter := router.RouterGroupApp.APP
@@ -61,13 +58,13 @@ func Routers() *gin.Engine {
// VUE_APP_BASE_API = /
// VUE_APP_BASE_PATH = http://localhost
// 然后执行打包命令 npm run build。在打开下面3行注释
// Router.Static("/favicon.ico", "./dist/favicon.ico")
// Router.StaticFile("/favicon.ico", "./dist/favicon.ico")
// Router.Static("/assets", "./dist/assets") // dist里面的静态资源
// Router.StaticFile("/", "./dist/index.html") // 前端网页入口页面
Router.StaticFS(global.GVA_CONFIG.Local.StorePath, justFilesFilesystem{http.Dir(global.GVA_CONFIG.Local.StorePath)}) // Router.Use(middleware.LoadTls()) // 如果需要使用https 请打开此中间件 然后前往 core/server.go 将启动模式 更变为 Router.RunTLS("端口","你的cre/pem文件","你的key文件")
// 跨域,如需跨域可以打开下面的注释
// Router.Use(middleware.AllCors()) // 直接放行全部跨域请求
// Router.Use(middleware.Cors()) // 直接放行全部跨域请求
// Router.Use(middleware.CorsByRules()) // 按照配置的规则放行跨域请求
// global.GVA_LOG.Info("use middleware cors")
docs.SwaggerInfo.BasePath = global.GVA_CONFIG.System.RouterPrefix
@@ -76,13 +73,13 @@ func Routers() *gin.Engine {
// 方便统一添加路由组前缀 多服务器上线使用
PublicGroup := Router.Group(global.GVA_CONFIG.System.RouterPrefix)
PublicGroup.Use(middleware.AllCors()) // 直接放行全部跨域请求
PublicGroup.Use(middleware.Cors()) // 直接放行全部跨域请求
PrivateGroup := Router.Group(global.GVA_CONFIG.System.RouterPrefix)
PrivateGroup.Use(middleware.JWTAuth()).Use(middleware.CasbinHandler()).Use(middleware.AllCors())
PrivateGroup.Use(middleware.JWTAuth()).Use(middleware.CasbinHandler()).Use(middleware.Cors())
AppAuthGroup := Router.Group(global.GVA_CONFIG.System.RouterPrefix)
//AppAuthGroup.Use(middleware.AllCors())
AppAuthGroup.Use(middleware.UserJWTAuth()).Use(middleware.AllCors())
AppAuthGroup.Use(middleware.UserJWTAuth()).Use(middleware.Cors())
{
// 健康监测
PublicGroup.GET("/health", func(c *gin.Context) {
@@ -100,6 +97,7 @@ func Routers() *gin.Engine {
systemRouter.InitUserRouter(PrivateGroup) // 注册用户路由
systemRouter.InitMenuRouter(PrivateGroup) // 注册menu路由
systemRouter.InitSystemRouter(PrivateGroup) // system相关路由
systemRouter.InitSysVersionRouter(PrivateGroup) // 发版相关路由
systemRouter.InitCasbinRouter(PrivateGroup) // 权限相关路由
systemRouter.InitAutoCodeRouter(PrivateGroup, PublicGroup) // 创建自动化代码
systemRouter.InitAuthorityRouter(PrivateGroup) // 注册角色路由
@@ -128,9 +126,6 @@ func Routers() *gin.Engine {
// 注册业务路由
initBizRouter(PrivateGroup, PublicGroup, AppAuthGroup)
PluginInit(PublicGroup, customerservice.CreateCustomerServicePlug())
PluginInit(PrivateGroup, picturelibrary.CreatePictureLibraryPlug())
global.GVA_ROUTERS = Router.Routes()
global.GVA_LOG.Info("router register success")

View File

@@ -5,10 +5,12 @@ import (
"github.com/gin-gonic/gin"
)
// 占位方法保证文件可以正确加载避免go空变量检测报错请勿删除。
func holder(routers ...*gin.RouterGroup) {
_ = routers
_ = router.RouterGroupApp
}
func initBizRouter(routers ...*gin.RouterGroup) {
privateGroup := routers[0]
publicGroup := routers[1]