- 将 admin 相关服务移动到 internal/service/admin 目录下 - 更新控制器中的服务导入路径引用 - 移除已合并的服务文件 - 添加统一工作约定文档 - 更新 API 接口定义的包路径
99 lines
4.1 KiB
Go
99 lines
4.1 KiB
Go
package cmd
|
||
|
||
import (
|
||
"context"
|
||
|
||
"github.com/gogf/gf/v2/frame/g"
|
||
"github.com/gogf/gf/v2/net/ghttp"
|
||
"github.com/gogf/gf/v2/os/gcfg"
|
||
"github.com/gogf/gf/v2/os/gcmd"
|
||
"github.com/gogf/gf/v2/os/genv"
|
||
|
||
adminctl "service.xpcool.com/internal/controller/admin"
|
||
"service.xpcool.com/internal/controller/hello"
|
||
openctl "service.xpcool.com/internal/controller/open"
|
||
userctl "service.xpcool.com/internal/controller/user"
|
||
"service.xpcool.com/internal/library/jwt"
|
||
"service.xpcool.com/internal/middleware"
|
||
"service.xpcool.com/internal/service/admin/admin"
|
||
"service.xpcool.com/internal/service/admin/base/log"
|
||
adminaudit "service.xpcool.com/internal/service/admin/system/audit"
|
||
adminauth "service.xpcool.com/internal/service/admin/system/auth"
|
||
adminmenu "service.xpcool.com/internal/service/admin/system/menu"
|
||
"service.xpcool.com/internal/service/admin/system/menu_manage"
|
||
"service.xpcool.com/internal/service/admin/system/role"
|
||
userauth "service.xpcool.com/internal/service/user/auth"
|
||
)
|
||
|
||
// injectEnv 手动把关键环境变量写入配置系统。
|
||
// 注意:gf v2.10.2 起配置不再自动替换 ${ENV} 占位符,需在此显式注入,
|
||
// 否则 config.dev.yaml 中的 ${DB_DSN}/${JWT_SECRET} 会原样传给数据库与 JWT。
|
||
func injectEnv(ctx context.Context) {
|
||
adapter, ok := g.Cfg().GetAdapter().(*gcfg.AdapterFile)
|
||
if !ok {
|
||
return
|
||
}
|
||
if v := genv.Get("DB_DSN"); !v.IsEmpty() {
|
||
_ = adapter.Set("database.default.link", v.String())
|
||
}
|
||
if v := genv.Get("JWT_SECRET"); !v.IsEmpty() {
|
||
_ = adapter.Set("jwt.secret", v.String())
|
||
}
|
||
}
|
||
|
||
var (
|
||
Main = gcmd.Command{
|
||
Name: "main",
|
||
Usage: "main",
|
||
Brief: "start http server",
|
||
Func: func(ctx context.Context, parser *gcmd.Parser) (err error) {
|
||
injectEnv(ctx)
|
||
s := g.Server()
|
||
tokens := jwt.New(ctx)
|
||
userauth.RegisterUserAuth(userauth.NewUserAuth(tokens, nil, nil))
|
||
adminauth.RegisterAdminAuth(adminauth.NewAdminAuth(tokens))
|
||
adminmenu.RegisterAdminMenu(adminmenu.NewAdminMenu())
|
||
admin.RegisterAdminManage(admin.NewAdminManage())
|
||
role.RegisterRoleManage(role.NewRoleManage())
|
||
menu_manage.RegisterMenuManage(menu_manage.NewMenuManage())
|
||
log.RegisterLogManage(log.NewLogManage())
|
||
adminaudit.RegisterAdminAudit(adminaudit.NewAdminAudit())
|
||
s.Group("/", func(group *ghttp.RouterGroup) {
|
||
group.Middleware(middleware.Recover, middleware.CORS)
|
||
group.Middleware(ghttp.MiddlewareHandlerResponse)
|
||
group.Bind(
|
||
hello.NewV1(),
|
||
)
|
||
})
|
||
s.Group("/api/open/v1", func(group *ghttp.RouterGroup) {
|
||
group.Middleware(middleware.Recover, middleware.CORS, ghttp.MiddlewareHandlerResponse)
|
||
group.Bind(openctl.New()) // Open tools API for frontends, no auth required.
|
||
})
|
||
s.Group("/api/v1", func(group *ghttp.RouterGroup) {
|
||
group.Middleware(middleware.Recover, middleware.CORS, ghttp.MiddlewareHandlerResponse)
|
||
group.Bind(userctl.New()) // Login and refresh routes are public.
|
||
group.Group("/", func(protected *ghttp.RouterGroup) { protected.Middleware(middleware.UserAuth(tokens)) })
|
||
})
|
||
s.Group("/admin/v1", func(group *ghttp.RouterGroup) {
|
||
group.Middleware(middleware.Recover, middleware.CORS, ghttp.MiddlewareHandlerResponse)
|
||
group.Bind(adminctl.NewAuth()) // Public: login only.
|
||
group.Group("/", func(profile *ghttp.RouterGroup) {
|
||
// Login-only endpoints: own profile / access codes / menu routes.
|
||
profile.Middleware(middleware.AdminAuthOnly(tokens))
|
||
profile.Bind(adminctl.NewProfile())
|
||
})
|
||
group.Group("/", func(protected *ghttp.RouterGroup) {
|
||
// Permission-protected endpoints: RBAC management, logs, ...
|
||
// 权限由后端按「方法+路径」自动匹配,无需前端传 X-Permission。
|
||
protected.Middleware(middleware.AdminAuth(tokens, adminauth.AdminAuth().PermissionForPath, adminauth.AdminAuth().HasPermission, func(ctx context.Context, id uint64, permission, method, path, ip, param string, duration, status int) {
|
||
adminaudit.AdminAudit().Record(ctx, adminaudit.AuditEvent{AdminID: id, Permission: permission, Method: method, Path: path, IP: ip, Param: param, DurationMS: duration, StatusCode: status})
|
||
}))
|
||
protected.Bind(adminctl.New())
|
||
})
|
||
})
|
||
s.Run()
|
||
return nil
|
||
},
|
||
}
|
||
)
|