This commit is contained in:
2024-12-17 22:28:48 +08:00
commit 754e1ae43c
50 changed files with 2969 additions and 0 deletions

52
lightCore/Config.go Normal file
View File

@ -0,0 +1,52 @@
package lightCore
var ConfigValue = &Config{}
type Config struct {
App AppConfigModel `mapstructure:"app" yaml:"app"`
Server ServerConfigModel `mapstructure:"server" yaml:"server"`
Database DatabaseConfigModel `mapstructure:"database" yaml:"database"`
Redis RedisConfigModel `mapstructure:"redis" yaml:"redis"`
Admin AdminConfigModel `mapstructure:"admin" yaml:"admin"`
}
func (t *Config) IsRelease() bool {
return t.Server.RunMode == "release"
}
type AppConfigModel struct {
JwtSecret string `mapstructure:"jwt_secret" yaml:"jwt_secret"`
AliOssSign string `mapstructure:"ali_oss_sign" yaml:"ali_oss_sign"`
}
type AdminConfigModel struct {
JwtSecret string `mapstructure:"jwt_secret" yaml:"jwt_secret"`
JwtExpires int `mapstructure:"jwt_expires" yaml:"jwt_expires"`
ApiPath string `mapstructure:"api_path" yaml:"api_path"`
}
type ServerConfigModel struct {
RunMode string `mapstructure:"run_mode" yaml:"run_mode"`
HttpPort int `mapstructure:"http_port" yaml:"http_port"`
ReadTimeout int `mapstructure:"read_timeout" yaml:"read_timeout"`
WriteTimeout int `mapstructure:"write_timeout" yaml:"write_timeout"`
}
type DatabaseConfigModel struct {
Type string `mapstructure:"type" yaml:"type"`
User string `mapstructure:"user" yaml:"user"`
Password string `mapstructure:"password" yaml:"password"`
Host string `mapstructure:"host" yaml:"host"`
Name string `mapstructure:"name" yaml:"name"`
Charset string `mapstructure:"charset" yaml:"charset"`
TablePrefix string `mapstructure:"table_prefix" yaml:"table_prefix"`
LogLevel string `mapstructure:"log_level" yaml:"log_level"`
}
type RedisConfigModel struct {
Host string `mapstructure:"host" yaml:"host"`
Password string `mapstructure:"password" yaml:"password"`
MaxIdle string `mapstructure:"max_idle" yaml:"max_idle"`
MaxActive string `mapstructure:"max_active" yaml:"max_active"`
IdleTimeout string `mapstructure:"idle_timeout" yaml:"idle_timeout"`
}

21
lightCore/Db.go Normal file
View File

@ -0,0 +1,21 @@
package lightCore
import (
"code.zhecent.com/gopkg/light-core/pkg/myGorm"
"gorm.io/gorm"
)
var DBEngine *gorm.DB
func InitDB() {
orm := myGorm.NewSimpleORM(
ConfigValue.Database.User,
ConfigValue.Database.Password,
ConfigValue.Database.Host,
ConfigValue.Database.Name,
ConfigValue.Database.Charset,
ConfigValue.Server.RunMode,
)
orm.SetLoggerLevel(ConfigValue.Database.LogLevel)
DBEngine = orm.ConnectMysql()
}

7
lightCore/Fairing.go Normal file
View File

@ -0,0 +1,7 @@
package lightCore
import "github.com/gin-gonic/gin"
type Fairing interface {
OnRequest(c *gin.Context) error
}

11
lightCore/GromAdapter.go Normal file
View File

@ -0,0 +1,11 @@
package lightCore
import "gorm.io/gorm"
type GormAdapter struct {
*gorm.DB
}
func NewGormAdapter(db *gorm.DB) *GormAdapter {
return &GormAdapter{DB: db}
}

24
lightCore/IClass.go Normal file
View File

@ -0,0 +1,24 @@
package lightCore
import "github.com/gin-gonic/gin"
type IClass interface {
Build(core *LightCore)
}
type ClassMounts struct {
handles []IClass
errorHandler []gin.HandlerFunc
}
func NewClassMounts(handles []IClass, errorHandler []gin.HandlerFunc) *ClassMounts {
return &ClassMounts{handles: handles, errorHandler: errorHandler}
}
func (t *ClassMounts) Handles() []IClass {
return t.handles
}
func (t *ClassMounts) ErrorHandler() []gin.HandlerFunc {
return t.errorHandler
}

10
lightCore/IRouters.go Normal file
View File

@ -0,0 +1,10 @@
package lightCore
type Routers struct {
groupPath string
cs *ClassMounts
}
func NewRouters(groupPath string, cs *ClassMounts) *Routers {
return &Routers{groupPath: groupPath, cs: cs}
}

135
lightCore/LightCore.go Normal file
View File

@ -0,0 +1,135 @@
package lightCore
import (
"fmt"
"github.com/gin-gonic/gin"
"net/http"
"reflect"
)
type LightCore struct {
gin *gin.Engine
g *gin.RouterGroup
props []interface{}
}
func StartEngine() *LightCore {
gin.SetMode(ConfigValue.Server.RunMode)
g := &LightCore{gin: gin.New(), props: make([]interface{}, 0)}
g.gin.Use(gin.Logger(), gin.Recovery())
return g
}
func (t *LightCore) GetGin() *gin.Engine {
return t.gin
}
func (t *LightCore) Launch() {
err := t.gin.Run(fmt.Sprintf(":%d", ConfigValue.Server.HttpPort))
if err != nil {
panic("Gin Launch Error")
}
//server := &http.Server{
// Addr: fmt.Sprintf(":%d", addr),
// Handler: t,
// MaxHeaderBytes: 1 << 20,
//}
//err := server.ListenAndServe()
//if err != nil {
// panic("Gin Launch Error")
//}
}
func (t *LightCore) Attach(f Fairing) *LightCore {
t.gin.Use(func(context *gin.Context) {
err := f.OnRequest(context)
if err != nil {
context.AbortWithStatusJSON(http.StatusOK, gin.H{"error": "onRequest"})
} else {
context.Next()
}
})
return t
}
func (t *LightCore) LoadHtml(path string) *LightCore {
t.gin.LoadHTMLGlob(path)
return t
}
func (t *LightCore) StaticFS(path string, fs http.FileSystem) *LightCore {
t.gin.StaticFS(path, fs)
return t
}
func (t *LightCore) Beans(beans ...interface{}) *LightCore {
t.props = append(t.props, beans...)
return t
}
func (t *LightCore) Handle(httpMethod, relativePath string, handler interface{}, mids ...gin.HandlerFunc) *LightCore {
if h := Convert(handler); h != nil {
if len(mids) > 0 {
mids = append(mids, h)
t.g.Handle(httpMethod, relativePath, mids...)
} else {
t.g.Handle(httpMethod, relativePath, h)
}
}
return t
}
func (t *LightCore) MountRaw(f func(s *gin.Engine)) *LightCore {
f(t.GetGin())
return t
}
func (t *LightCore) Mount(group string, errorHandlerFunc []gin.HandlerFunc, classes ...IClass) *LightCore {
t.g = t.gin.Group(group)
if len(errorHandlerFunc) > 0 {
t.g.Use(errorHandlerFunc...)
}
for _, class := range classes {
class.Build(t)
//其实就是找到相同类型的数据就赋值上去
t.setProp(class)
}
return t
}
func (t *LightCore) Mounts(routers []*Routers) *LightCore {
for _, router := range routers {
t.Mount(router.groupPath, router.cs.errorHandler, router.cs.Handles()...)
}
return t
}
func (t *LightCore) SetNoRoute(f func(context *gin.Context)) *LightCore {
t.gin.NoRoute(f)
return t
}
// 查找对应名字的属性
func (t *LightCore) getProp(tp reflect.Type) interface{} {
for _, p := range t.props {
if tp == reflect.TypeOf(p) {
return p
}
}
return nil
}
func (t *LightCore) setProp(class IClass) {
vClass := reflect.ValueOf(class).Elem()
for i := 0; i < vClass.NumField(); i++ {
f := vClass.Field(i)
if !f.IsNil() || f.Kind() != reflect.Ptr {
//已经赋值了,不需要初始化了。
continue
}
if p := t.getProp(f.Type()); p != nil {
f.Set(reflect.New(f.Type().Elem()))
f.Elem().Set(reflect.ValueOf(p).Elem())
}
}
}

5
lightCore/Model.go Normal file
View File

@ -0,0 +1,5 @@
package lightCore
type Model interface {
IsLightModel()
}

162
lightCore/Responder.go Normal file
View File

@ -0,0 +1,162 @@
package lightCore
import (
"code.zhecent.com/gopkg/light-core/pkg/myAes"
"github.com/gin-gonic/gin"
"google.golang.org/protobuf/proto"
"net/http"
"reflect"
)
var RespondList []Responder
func init() {
RespondList = []Responder{
new(EmptyResponder),
new(StringResponder),
new(ModelResponder),
new(SuccessResponder),
new(JsonErrorResponder),
new(ViewResponder),
new(ProtobufResponder),
new(ProtobufAesResponder),
new(RedirectResponder),
}
}
type Responder interface {
RespondTo() gin.HandlerFunc
}
func Convert(handler interface{}) gin.HandlerFunc {
hRef := reflect.ValueOf(handler)
for _, r := range RespondList {
rRef := reflect.ValueOf(r).Elem()
if hRef.Type().ConvertibleTo(rRef.Type()) {
rRef.Set(hRef)
return rRef.Interface().(Responder).RespondTo()
}
}
return nil
}
type StringResponder func(*gin.Context) string
func (t StringResponder) RespondTo() gin.HandlerFunc {
return func(context *gin.Context) {
context.String(http.StatusOK, t(context))
}
}
type ModelResponder func(*gin.Context) Model
func (t ModelResponder) RespondTo() gin.HandlerFunc {
return func(context *gin.Context) {
context.JSON(http.StatusOK, gin.H{
"code": 200,
"msg": "",
"data": t(context),
})
}
}
type JsonSuccess string
type SuccessResponder func(*gin.Context) JsonSuccess
func (t SuccessResponder) RespondTo() gin.HandlerFunc {
return func(context *gin.Context) {
context.JSON(http.StatusOK, gin.H{
"code": 200,
"msg": string(t(context)),
"data": []int{},
})
}
}
type JsonError error
type JsonErrorResponder func(*gin.Context) JsonError
func (t JsonErrorResponder) RespondTo() gin.HandlerFunc {
return func(context *gin.Context) {
err := t(context)
if err != nil {
context.JSON(http.StatusOK, gin.H{
"code": 400,
"msg": err.Error(),
"data": []int{},
})
} else {
context.JSON(http.StatusOK, gin.H{
"code": 200,
"msg": "success",
"data": []int{},
})
}
}
}
type EmptyResponder func(*gin.Context)
func (t EmptyResponder) RespondTo() gin.HandlerFunc {
//func(c *gin.Context)其实就是reply
//t,提示就是方法本身其实就是reply
return func(context *gin.Context) {
//context是gin给的全新的没有任何资料的
//t(context)其实就是运行reply
t(context)
//fmt.Println("========================")
//fmt.Println(context.Writer)
//fmt.Println("========================")
}
}
type View string
type ViewResponder func(*gin.Context) View
func (t ViewResponder) RespondTo() gin.HandlerFunc {
return func(context *gin.Context) {
context.HTML(http.StatusOK, string(t(context))+".html", context.Keys)
}
}
type Protobuf proto.Message
type ProtobufResponder func(*gin.Context) Protobuf
func (t ProtobufResponder) RespondTo() gin.HandlerFunc {
return func(context *gin.Context) {
context.ProtoBuf(http.StatusOK, t(context))
}
}
type ProtobufAes proto.Message
type ProtobufAesResponder func(*gin.Context) ProtobufAes
func (t ProtobufAesResponder) RespondTo() gin.HandlerFunc {
return func(context *gin.Context) {
str, err := proto.Marshal(t(context))
if err != nil {
context.String(http.StatusBadRequest, err.Error())
} else {
decrypt, err := myAes.AesTool(context.GetString("LightAppKey"), context.GetString("LightAppIv")).Encrypt(string(str))
if err != nil {
context.String(http.StatusBadRequest, err.Error())
} else {
context.String(http.StatusOK, string(decrypt))
}
}
}
}
type Redirect string
type RedirectResponder func(*gin.Context) Redirect
func (t RedirectResponder) RespondTo() gin.HandlerFunc {
return func(context *gin.Context) {
context.Redirect(http.StatusFound, string(t(context)))
}
}

33
lightCore/Start.go Normal file
View File

@ -0,0 +1,33 @@
package lightCore
import "code.zhecent.com/gopkg/light-core/pkg/myViper"
type Start struct {
config *Config
}
func NewByConfig(config *Config) *Start {
return &Start{config: config}
}
func NewByYAML(fileName string, path string) *Start {
c := &Config{}
myViper.NewSimpleViper(c, "yaml", fileName, path).Apply()
return &Start{config: c}
}
func (t *Start) Start() {
//校验配置
if t.config.App.JwtSecret == "" {
panic("App JwtSecret Empty")
}
if t.config.Server.RunMode == "" || t.config.Server.HttpPort == 0 {
panic("Server Config Error")
}
ConfigValue = t.config
//初始化数据库
InitDB()
}

76
lightCore/Task.go Normal file
View File

@ -0,0 +1,76 @@
package lightCore
import (
"fmt"
"sync"
)
type TaskFunc func()
var taskList chan *TaskExecutor //任务列表
var once sync.Once
func getTaskList() chan *TaskExecutor {
once.Do(func() {
taskList = make(chan *TaskExecutor, 0)
})
return taskList
}
func init() {
chList := getTaskList() //得到任务列表
go func() {
for t := range chList {
doTask(t)
}
}()
}
func doTask(t *TaskExecutor) {
go func() {
defer func() {
if t.callback != nil {
t.callback()
}
}()
t.Exec()
}()
}
type TaskExecutor struct {
f TaskFunc
callback func()
}
func NewTaskExecutor(f TaskFunc, callback func()) *TaskExecutor {
return &TaskExecutor{f: f, callback: callback}
}
func (t *TaskExecutor) Exec() {
t.f()
}
func Task(f TaskFunc, callBack func()) {
if f == nil {
return
}
newF := func() {
defer func() {
if e := recover(); e != nil {
if err, ok := e.(string); ok {
fmt.Println("===================================")
fmt.Println(fmt.Sprintf("协程运行错误:%s", err))
fmt.Println("===================================")
} else {
fmt.Println("===================================")
fmt.Println(fmt.Sprintf("协程运行错误:%s", "未知"))
fmt.Println("===================================")
}
}
}()
f()
}
go func() {
getTaskList() <- NewTaskExecutor(newF, callBack) //添加任务队列
}()
}