service.xpcool.com/internal/cmd/cmd.go

133 lines
6.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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"
housectl "service.xpcool.com/internal/controller/house"
openctl "service.xpcool.com/internal/controller/open"
recruitmentctl "service.xpcool.com/internal/controller/recruitment"
serversecurityctl "service.xpcool.com/internal/controller/serversecurity"
userctl "service.xpcool.com/internal/controller/user"
"service.xpcool.com/internal/library/jwt"
"service.xpcool.com/internal/middleware"
admin "service.xpcool.com/internal/service/admin/admin/admin"
adminauth "service.xpcool.com/internal/service/admin/admin/login"
log "service.xpcool.com/internal/service/admin/base/log"
adminaudit "service.xpcool.com/internal/service/admin/system/log"
adminloginlog "service.xpcool.com/internal/service/admin/system/login_log"
adminmenu "service.xpcool.com/internal/service/admin/system/menu"
menu_manage "service.xpcool.com/internal/service/admin/system/menu_manage"
role "service.xpcool.com/internal/service/admin/system/role"
userauth "service.xpcool.com/internal/service/user/auth"
housecommunity "service.xpcool.com/internal/service/house/community"
housedashboard "service.xpcool.com/internal/service/house/dashboard"
houselisting "service.xpcool.com/internal/service/house/listing"
housetransaction "service.xpcool.com/internal/service/house/transaction"
housepresale "service.xpcool.com/internal/service/house/presale"
recruitmentsvc "service.xpcool.com/internal/service/recruitment"
serversecuritysvc "service.xpcool.com/internal/service/serversecurity"
)
// 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())
}
// 招聘模块独立数据库与 Bark 推送配置(自建 Bark 服务)。
if v := genv.Get("RECRUITMENT_DB_DSN"); !v.IsEmpty() {
_ = adapter.Set("database.recruitment.link", v.String())
}
if v := genv.Get("BARK_BASE_URL"); !v.IsEmpty() {
_ = adapter.Set("bark.baseUrl", v.String())
}
if v := genv.Get("BARK_DEVICE_KEY"); !v.IsEmpty() {
_ = adapter.Set("bark.deviceKey", v.String())
}
if v := genv.Get("BARK_PUSH_TIME"); !v.IsEmpty() {
_ = adapter.Set("bark.pushTime", v.String())
}
// 服务器安全日志上报令牌(宿主机采集脚本携带,接口侧校验)。
if v := genv.Get("INTERNAL_TOKEN"); !v.IsEmpty() {
_ = adapter.Set("internalToken", 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())
adminloginlog.RegisterAdminLoginLog(adminloginlog.NewAdminLoginLog())
housecommunity.RegisterCommunity(housecommunity.NewCommunity())
houselisting.RegisterListing(houselisting.NewListing())
housedashboard.RegisterDashboard(housedashboard.NewDashboard())
housetransaction.RegisterTransaction(housetransaction.NewTransaction())
housepresale.RegisterPresale(housepresale.NewPresale())
recruitmentsvc.RegisterRecruitment(recruitmentsvc.New())
serversecuritysvc.RegisterServerSecurity(serversecuritysvc.New())
s.Group("/api/service/open", func(group *ghttp.RouterGroup) {
group.Middleware(middleware.Recover, middleware.CORS, ghttp.MiddlewareHandlerResponse)
group.Bind(openctl.New()) // Open tools API for frontends, no auth required.
group.Bind(serversecurityctl.NewReport()) // 安全日志上报(宿主机脚本,内部令牌校验)。
})
s.Group("/api/service/user", 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("/api/service/admin", 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) {
// 仅登录端点:个人资料 / 权限码 / 菜单路由。
profile.Middleware(middleware.AdminAuthOnly(tokens))
profile.Bind(adminctl.NewProfile())
})
group.Group("/", func(protected *ghttp.RouterGroup) {
// 受权限保护端点RBAC 管理、日志等。
// 权限由后端按「方法+路径」自动匹配,无需前端传 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, userAgent, errorMessage string) {
adminaudit.AdminAudit().Record(ctx, adminaudit.AuditEvent{AdminID: id, Permission: permission, Method: method, Path: path, IP: ip, Param: param, DurationMS: duration, StatusCode: status, ErrorMessage: errorMessage, UserAgent: userAgent})
}))
protected.Bind(adminctl.New())
protected.Bind(housectl.New())
protected.Bind(recruitmentctl.New())
protected.Bind(serversecurityctl.NewManage())
})
})
// 启动招聘模块定时任务(每日增量抓取 + 早报推送)。
recruitmentsvc.StartScheduler(ctx)
s.Run()
return nil
},
}
)