后端功能首次提交

This commit is contained in:
qian committed 2026-05-10 12:21:27 +08:00
1 parent 5b38e1b567
commit 3405280224
1136 files changed
+96170 -1

No files matched your search

+22
View File
@@ -0,0 +1,22 @@
package hooks
import (
"context"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/glog"
"github.com/qianfree/team-api/internal/plugin"
)
// RelayBeforeRequest 记录 relay 请求日志。
func RelayBeforeRequest(ctx context.Context, payload plugin.HookPayload) (plugin.HookResult, error) {
glog.Infof(ctx, "[example plugin] relay before request: model=%v", payload.Data["model"])
return plugin.HookResult{Data: g.Map{}}, nil
}
// RelayAfterResponse 记录 relay 响应日志。
func RelayAfterResponse(ctx context.Context, payload plugin.HookPayload) (plugin.HookResult, error) {
glog.Info(ctx, "[example plugin] relay after response")
return plugin.HookResult{Data: g.Map{}}, nil
}
+161
View File
@@ -0,0 +1,161 @@
package example
import (
"context"
"fmt"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/os/glog"
"github.com/qianfree/team-api/internal/plugin"
"github.com/qianfree/team-api/plugins/example/hooks"
)
type examplePlugin struct{}
func init() {
plugin.Register(&examplePlugin{})
}
// Info 实现 Plugin 基础接口
func (p *examplePlugin) Info() plugin.PluginInfo {
return plugin.PluginInfo{
Name: "example",
Label: "功能示例",
Description: "插件系统功能示例,展示所有扩展接口的用法",
Author: "team-api",
Version: "1.0.0",
Category: "extension",
}
}
// Init 实现 Plugin 基础接口
func (p *examplePlugin) Init(ctx context.Context, app *plugin.App) error {
glog.Info(ctx, "example plugin initialized")
return nil
}
// Destroy 实现 Plugin 基础接口
func (p *examplePlugin) Destroy(ctx context.Context) error {
glog.Info(ctx, "example plugin destroyed")
return nil
}
// Install 建表
func (p *examplePlugin) Install(ctx context.Context) error {
_, err := g.DB().Exec(ctx, `
CREATE TABLE IF NOT EXISTS plg_example_logs (
id BIGSERIAL PRIMARY KEY,
tenant_id BIGINT NOT NULL,
action VARCHAR(64) NOT NULL,
detail TEXT DEFAULT '',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
COMMENT ON TABLE plg_example_logs IS '示例插件-操作日志';
CREATE INDEX IF NOT EXISTS idx_plg_example_logs_tenant_id ON plg_example_logs (tenant_id);
CREATE INDEX IF NOT EXISTS idx_plg_example_logs_created_at ON plg_example_logs USING BRIN (created_at);
`)
return err
}
// Upgrade 增量迁移
func (p *examplePlugin) Upgrade(ctx context.Context) error {
return nil
}
// Uninstall 清理数据
func (p *examplePlugin) Uninstall(ctx context.Context) error {
_, err := g.DB().Exec(ctx, `DROP TABLE IF EXISTS plg_example_logs`)
return err
}
// --- 可选接口实现 ---
// Hooks 实现 Hookable 接口
func (p *examplePlugin) Hooks() []plugin.HookBinding {
return []plugin.HookBinding{
{
Event: plugin.HookRelayBeforeRequest,
Priority: 100,
Handler: hooks.RelayBeforeRequest,
},
{
Event: plugin.HookRelayAfterResponse,
Priority: 100,
Handler: hooks.RelayAfterResponse,
},
}
}
// Routes 实现 Routable 接口
func (p *examplePlugin) Routes(ctx context.Context, server *ghttp.Server) error {
// 示例:注册插件自定义路由
// 实际使用时可以绑定到 admin 或 tenant 路由组
return nil
}
// CronJobs 实现 Cronable 接口
func (p *examplePlugin) CronJobs() []plugin.CronJobDef {
return []plugin.CronJobDef{
{
Name: "example_daily_cleanup",
CronExpr: "0 3 * * *",
Handler: p.dailyCleanup,
Singleton: true,
},
}
}
func (p *examplePlugin) dailyCleanup(ctx context.Context) {
glog.Info(ctx, "[example plugin] running daily cleanup")
_, err := g.DB().Exec(ctx, fmt.Sprintf(
`DELETE FROM plg_example_logs WHERE created_at < NOW() - INTERVAL '%d days'`, 30,
))
if err != nil {
glog.Warningf(ctx, "[example plugin] cleanup failed: %v", err)
}
}
// ConfigSchema 实现 Configurable 接口
func (p *examplePlugin) ConfigSchema() []plugin.ConfigFieldDef {
return []plugin.ConfigFieldDef{
{
Key: "max_log_retention_days",
Label: "日志保留天数",
Type: "int",
Default: 30,
Required: false,
Description: "操作日志保留天数,超过此天数自动清理",
},
{
Key: "enable_detailed_logging",
Label: "详细日志",
Type: "bool",
Default: false,
Required: false,
Description: "是否记录详细的请求/响应内容",
},
{
Key: "log_level",
Label: "日志级别",
Type: "select",
Default: "info",
Options: []string{"debug", "info", "warn", "error"},
Required: false,
Description: "插件日志级别",
},
}
}
// OnTenantEnable 实现 TenantAware 接口
func (p *examplePlugin) OnTenantEnable(ctx context.Context, tenantID int64) error {
glog.Infof(ctx, "[example plugin] enabled for tenant %d", tenantID)
return nil
}
// OnTenantDisable 实现 TenantAware 接口
func (p *examplePlugin) OnTenantDisable(ctx context.Context, tenantID int64) error {
glog.Infof(ctx, "[example plugin] disabled for tenant %d", tenantID)
return nil
}
+7
View File
@@ -0,0 +1,7 @@
package plugins
// 插件导入中心。每新增一个插件,在这里加一行 blank import。
//
import (
_ "github.com/qianfree/team-api/plugins/example"
)