Skip to content

Commit

Permalink
feat(plugin): comment
Browse files Browse the repository at this point in the history
  • Loading branch information
Matrix-X committed May 30, 2024
1 parent e4077d4 commit d527cf8
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 5 deletions.
1 change: 1 addition & 0 deletions cmd/ctl/database/migrate/powerx.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"PowerX/internal/model"
"PowerX/internal/model/crm/customerdomain"
"PowerX/internal/model/crm/market"
"PowerX/internal/model/crm/operation"
"PowerX/internal/model/crm/product"
"PowerX/internal/model/crm/trade"
infoorganizatoin "PowerX/internal/model/infoorganization"
Expand Down
1 change: 1 addition & 0 deletions cmd/ctl/database/seed/datadictionary/membershipstatus.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package datadictionary

import (
"PowerX/internal/model"
"PowerX/internal/model/crm/operation"
)

func defaultMembershipStatusDataDictionary() *model.DataDictionaryType {
Expand Down
1 change: 1 addition & 0 deletions cmd/ctl/database/seed/datadictionary/membershiptype.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package datadictionary

import (
"PowerX/internal/model"
"PowerX/internal/model/crm/operation"
)

func defaultMembershipTypeDataDictionary() *model.DataDictionaryType {
Expand Down
28 changes: 25 additions & 3 deletions cmd/server/powerx.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,48 +21,70 @@ import (
"github.com/zeromicro/go-zero/core/conf"
)

// 定义了一个全局变量 configFile,用于指定配置文件的路径,默认为 etc/powerx.yaml。
var configFile = flag.String("f", "etc/powerx.yaml", "the config file")

// 在 main() 函数中,首先解析命令行参数,加载配置文件,然后初始化 Gin 框架,并设置为发布模式。
func main() {
// 解析命令行参数
flag.Parse()

// ---------- 加载配置文件 ----------
var c config.Config
conf.MustLoad(*configFile, &c)

// 设置配置文件目录
c.EtcDir = filepath.Dir(*configFile)

// ---------- 设置 Gin 框架为发布模式 ----------
gin.SetMode(gin.ReleaseMode)
// 创建 Gin 路由实例
r := zgin.NewRouter()

// 创建 Go-Zero REST 服务器实例
server := rest.MustNewServer(c.Server, rest.WithRouter(r))

// 设置跨域配置
runOpt := config.SetupCors(&c)
if runOpt == nil {
server = rest.MustNewServer(c.Server)
} else {
server = rest.MustNewServer(c.Server, runOpt)
}
// 确保服务器关闭
defer server.Stop()

// ---------- 设置日志 ----------
zerox.MustSetupLog(c.Log)

// ---------- 创建插件管理器实例 ----------
plugin := pluginx.NewManager(context.Background(), r, fmt.Sprintf("%s:%d", "127.0.0.1", c.Server.Port))
// 创建服务上下文
ctx := svc.NewServiceContext(c, svc.WithPlugin(plugin))

// 启动插件
go func() {
plugin.Start()
}()
// 确保插件关闭
defer ctx.Plugin.Close()

// ---------- 注册业务处理函数 ----------
handler.RegisterHandlers(server, ctx)
// ---------- 注册 Webhook 处理函数 ----------
handler.RegisterWebhookHandlers(server, ctx)

// ---------- 注册静态资源处理函数 ----------
handler.RegisterStaticHandlers(server, ctx)

// error 5xx
// ---------- 添加恢复中间件 ----------
server.Use(recovery.RecoverMiddleware())

// 设置自定义错误处理逻辑 3xx 4xx default: 400
// ---------- 设置自定义错误处理逻辑 ----------
// 3xx 4xx default: 400
httpx.SetErrorHandler(handler.ErrorHandle)
httpx.SetErrorHandlerCtx(handler.ErrorHandleCtx)

// ---------- 启动服务器 ----------
fmt.Printf("Starting server at %s:%d...\n", c.Server.Host, c.Server.Port)
server.Start()
}
2 changes: 1 addition & 1 deletion internal/model/origanzation/employee.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func VerifyPassword(hashedPwd string, pwd string) bool {
}

func (e *Employee) TableName() string {
return `employees`
return `users`
}

func (e *Employee) Action(db *gorm.DB, employees []*Employee) {
Expand Down
1 change: 1 addition & 0 deletions pkg/pluginx/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ type BuildPluginFrontendOptions struct {
ReDownload bool
}

// BuildPluginFrontend 构建插件前端
func (l *Loader) BuildPluginFrontend(opts BuildPluginFrontendOptions) error {
// 检查是否workdir是否存在.download文件夹
isFirstDownload := false
Expand Down
16 changes: 15 additions & 1 deletion pkg/pluginx/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"strings"
)

// Manager 管理插件的加载、启动和关闭
type Manager struct {
r httpx.Router

Expand All @@ -32,6 +33,7 @@ type Manager struct {
frontendServer *PluginFrontendServer
}

// NewManager 创建一个新的插件管理器实例
func NewManager(ctx context.Context, route httpx.Router, mainHost string) *Manager {
manager := &Manager{
r: route,
Expand All @@ -44,16 +46,19 @@ func NewManager(ctx context.Context, route httpx.Router, mainHost string) *Manag
return manager
}

// ProxyHandleFunc 返回处理代理请求的 HTTP 处理函数
func (m *Manager) ProxyHandleFunc() http.HandlerFunc {
return func(writer http.ResponseWriter, request *http.Request) {
const prefix = "/api/plugin"
const unknownError = `{"error": "plugin backend request failed"}`

// 如果请求路径不以指定前缀开头,则返回未知错误
if !strings.HasPrefix(request.URL.Path, prefix) {
http.Error(writer, unknownError, http.StatusInternalServerError)
return
}

// 根据路径分割获取插件名称和路径
splitPaths := strings.Split(request.URL.Path, "/")
if len(splitPaths) < 4 {
http.Error(writer, unknownError, http.StatusInternalServerError)
Expand All @@ -63,25 +68,30 @@ func (m *Manager) ProxyHandleFunc() http.HandlerFunc {
name := splitPaths[3]
pluginPath := strings.Join(splitPaths[4:], "/")

// 根据插件名称查找插件
plugin, ok := m.pluginMap[name]
if !ok || !plugin.IsReady() {
logx.Errorf("Plugin %s not found", name)
http.Error(writer, unknownError, http.StatusInternalServerError)
return
}

// 构建目标 URL
targetURL := fmt.Sprintf("http://%s/%s", plugin.PluginHost, pluginPath)
fmt.Println(targetURL)
if request.URL.RawQuery != "" {
targetURL = targetURL + "?" + request.URL.RawQuery
}

// 读取请求体
var buf bytes.Buffer
if _, err := io.Copy(&buf, request.Body); err != nil {
logx.Errorf("Error reading request body: %v", err)
http.Error(writer, "Error reading request body", http.StatusInternalServerError)
return
}

// 创建代理请求
proxyReq, err := http.NewRequest(request.Method, targetURL, &buf)

if err != nil {
Expand All @@ -90,8 +100,9 @@ func (m *Manager) ProxyHandleFunc() http.HandlerFunc {
return
}

// 复制请求头
copyHeaders(request.Header, proxyReq.Header)

// 发送代理请求
resp, err := http.DefaultClient.Do(proxyReq)
if err != nil {
logx.Errorf("Error sending proxy request: %v", err)
Expand All @@ -100,9 +111,11 @@ func (m *Manager) ProxyHandleFunc() http.HandlerFunc {
}
defer resp.Body.Close()

// 复制响应头
copyHeaders(resp.Header, writer.Header())
writer.WriteHeader(resp.StatusCode)

// 发送代理响应
if _, err = io.Copy(writer, resp.Body); err != nil {
logx.Errorf("Error sending proxy request: %v", err)
http.Error(writer, "Error sending proxy request", http.StatusBadGateway)
Expand Down Expand Up @@ -156,6 +169,7 @@ func (m *Manager) SetupPluginManager() {
return
}

// 定义重新构建插件的函数
rebuild := func() {
loader := NewLoader("./plugins", &BuildLoaderConfig{
MainAPIEndpoint: "/api/plugin",
Expand Down

0 comments on commit d527cf8

Please sign in to comment.