Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
FLIPPED-AURORA
gin-vue-admin
提交
461e01cb
G
gin-vue-admin
项目概览
FLIPPED-AURORA
/
gin-vue-admin
大约 1 年 前同步成功
通知
333
Star
18155
Fork
5506
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
G
gin-vue-admin
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
461e01cb
编写于
8月 20, 2021
作者:
S
songzhibin97
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat:插件模式尝鲜
上级
964dd1f2
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
159 addition
and
28 deletion
+159
-28
server/main.go
server/main.go
+33
-28
server/router/example/plugin.go
server/router/example/plugin.go
+16
-0
server/utils/plugin/plugin.go
server/utils/plugin/plugin.go
+41
-0
server/utils/plugin/plugin_uinx.go
server/utils/plugin/plugin_uinx.go
+69
-0
未找到文件。
server/main.go
浏览文件 @
461e01cb
package
main
import
(
"gin-vue-admin/core"
"gin-vue-admin/global"
"gin-vue-admin/initialize"
)
//import (
// "gin-vue-admin/core"
// "gin-vue-admin/global"
// "gin-vue-admin/initialize"
//)
//
////go:generate go env -w GO111MODULE=on
////go:generate go env -w GOPROXY=https://goproxy.cn,direct
////go:generate go mod tidy
////go:generate go mod download
//
//// @title Swagger Example API
//// @version 0.0.1
//// @description This is a sample Server pets
//// @securityDefinitions.apikey ApiKeyAuth
//// @in header
//// @name x-token
//// @BasePath /
//func main() {
// global.GVA_VP = core.Viper() // 初始化Viper
// global.GVA_LOG = core.Zap() // 初始化zap日志库
// global.GVA_DB = initialize.Gorm() // gorm连接数据库
// initialize.Timer()
// if global.GVA_DB != nil {
// initialize.MysqlTables(global.GVA_DB) // 初始化表
// // 程序结束前关闭数据库链接
// db, _ := global.GVA_DB.DB()
// defer db.Close()
// }
// core.RunWindowsServer()
//}
//go:generate go env -w GO111MODULE=on
//go:generate go env -w GOPROXY=https://goproxy.cn,direct
//go:generate go mod tidy
//go:generate go mod download
var
Plugin
plugin
// @title Swagger Example API
// @version 0.0.1
// @description This is a sample Server pets
// @securityDefinitions.apikey ApiKeyAuth
// @in header
// @name x-token
// @BasePath /
func
main
()
{
global
.
GVA_VP
=
core
.
Viper
()
// 初始化Viper
global
.
GVA_LOG
=
core
.
Zap
()
// 初始化zap日志库
global
.
GVA_DB
=
initialize
.
Gorm
()
// gorm连接数据库
initialize
.
Timer
()
if
global
.
GVA_DB
!=
nil
{
initialize
.
MysqlTables
(
global
.
GVA_DB
)
// 初始化表
// 程序结束前关闭数据库链接
db
,
_
:=
global
.
GVA_DB
.
DB
()
defer
db
.
Close
()
}
core
.
RunWindowsServer
()
type
plugin
struct
{
}
server/router/example/plugin.go
0 → 100644
浏览文件 @
461e01cb
package
example
import
"github.com/gin-gonic/gin"
type
Plugin
struct
{
}
func
(
*
Plugin
)
Register
(
group
*
gin
.
RouterGroup
)
{
group
.
GET
(
"hello"
,
func
(
context
*
gin
.
Context
)
{
context
.
JSON
(
200
,
"hello world"
)
})
}
func
(
*
Plugin
)
RouterPath
()
string
{
return
"group"
}
server/utils/plugin/plugin.go
0 → 100644
浏览文件 @
461e01cb
package
plugin
import
(
"plugin"
"sync"
"github.com/gin-gonic/gin"
)
const
(
OnlyFuncName
=
"Plugin"
)
var
ManagementPlugin
=
managementPlugin
{
mp
:
make
(
map
[
string
]
*
plugin
.
Plugin
)}
type
managementPlugin
struct
{
mp
map
[
string
]
*
plugin
.
Plugin
sync
.
Mutex
}
func
(
m
*
managementPlugin
)
SetPlugin
(
key
string
,
p
*
plugin
.
Plugin
)
{
m
.
Lock
()
defer
m
.
Unlock
()
m
.
mp
[
key
]
=
p
}
func
(
m
*
managementPlugin
)
GetPlugin
(
key
string
)
(
p
*
plugin
.
Plugin
,
ok
bool
)
{
m
.
Lock
()
defer
m
.
Unlock
()
p
,
ok
=
m
.
mp
[
key
]
return
}
// Plugin 插件模式接口化
type
Plugin
interface
{
// Register 注册路由
Register
(
group
*
gin
.
RouterGroup
)
// RouterPath 用户返回注册路由
RouterPath
()
string
}
server/utils/plugin/plugin_uinx.go
0 → 100644
浏览文件 @
461e01cb
//+build !windows
package
plugin
import
(
"errors"
"fmt"
"io/fs"
"io/ioutil"
"os"
"path/filepath"
"plugin"
)
// LoadPlugin 加载插件 传入path
func
LoadPlugin
(
path
string
)
error
{
path
,
err
:=
filepath
.
Abs
(
path
)
if
err
!=
nil
{
return
err
}
fileInfo
,
err
:=
os
.
Stat
(
path
)
if
err
!=
nil
{
return
err
}
if
fileInfo
.
IsDir
()
{
fileSlice
,
err
:=
ioutil
.
ReadDir
(
path
)
if
err
!=
nil
{
return
err
}
for
_
,
ff
:=
range
fileSlice
{
if
!
ff
.
IsDir
()
&&
filepath
.
Ext
(
ff
.
Name
())
==
".so"
{
if
err
=
loadPlugin
(
path
,
ff
);
err
!=
nil
{
return
err
}
}
else
if
ff
.
IsDir
()
{
_
=
LoadPlugin
(
filepath
.
Join
(
path
,
ff
.
Name
()))
}
}
return
nil
}
else
{
return
loadPlugin
(
path
,
fileInfo
)
}
}
func
loadPlugin
(
path
string
,
f
fs
.
FileInfo
)
error
{
if
filepath
.
Ext
(
f
.
Name
())
==
".so"
{
fPath
:=
filepath
.
Join
(
path
,
f
.
Name
())
// 加载插件
p
,
err
:=
plugin
.
Open
(
fPath
)
if
err
!=
nil
{
fmt
.
Println
(
"loadPlugin err "
,
err
)
return
err
}
// 判断是否满足协议
// 要满足 OnlyFuncName && 实现 Plugin 接口
if
v
,
err
:=
p
.
Lookup
(
OnlyFuncName
);
err
!=
nil
{
fmt
.
Println
(
"loadPlugin err "
,
err
)
return
err
}
else
if
_
,
ok
:=
v
.
(
Plugin
);
!
ok
{
fmt
.
Println
(
"loadPlugin err "
,
fmt
.
Sprintf
(
"path:%s 没有实现 %s 接口"
,
filepath
.
Base
(
fPath
),
OnlyFuncName
))
return
errors
.
New
(
"没有实现指定接口"
)
}
else
{
}
fmt
.
Println
(
"loadPlugin add "
,
filepath
.
Base
(
fPath
))
ManagementPlugin
.
SetPlugin
(
filepath
.
Base
(
fPath
),
p
)
}
return
nil
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录