diff --git a/frontend/package.json b/frontend/package.json index ab503a53..a781763f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -19,7 +19,7 @@ "crypto-js": "^4.2.0", "dayjs": "^1.11.13", "echarts": "^5.5.1", - "element-plus": "^2.9.0", + "element-plus": "^2.9.1", "js-base64": "^3.7.7", "jsencrypt": "^3.3.2", "lodash": "^4.17.21", diff --git a/server/initialize/router.go b/server/initialize/router.go index cfbb8a2d..37427eef 100644 --- a/server/initialize/router.go +++ b/server/initialize/router.go @@ -4,23 +4,19 @@ import ( "fmt" "io/fs" "mayfly-go/pkg/config" + "mayfly-go/pkg/ioc" "mayfly-go/pkg/middleware" + "mayfly-go/pkg/req" "mayfly-go/static" "net/http" + "reflect" "github.com/gin-gonic/gin" ) -// 初始化路由函数 -type InitRouterFunc func(router *gin.RouterGroup) - -var ( - initRouterFuncs = make([]InitRouterFunc, 0) -) - -// 添加初始化路由函数,由各个默认自行添加 -func AddInitRouterFunc(initRouterFunc InitRouterFunc) { - initRouterFuncs = append(initRouterFuncs, initRouterFunc) +type RouterApi interface { + // ReqConfs 获取请求配置信息 + ReqConfs() *req.Confs } func InitRouter() *gin.Engine { @@ -46,11 +42,17 @@ func InitRouter() *gin.Engine { // 设置路由组 api := router.Group(serverConfig.ContextPath + "/api") - // 调用所有模块注册的初始化路由函数 - for _, initRouterFunc := range initRouterFuncs { - initRouterFunc(api) + + // 获取所有实现了RouterApi接口的实例,并注册对应路由 + ras := ioc.GetBeansByType[RouterApi](reflect.TypeOf((*RouterApi)(nil)).Elem()) + for _, ra := range ras { + confs := ra.ReqConfs() + if group := confs.Group; group != "" { + req.BatchSetGroup(api.Group(group), confs.Confs) + } else { + req.BatchSetGroup(api, confs.Confs) + } } - initRouterFuncs = nil return router } diff --git a/server/internal/auth/api/account_login.go b/server/internal/auth/api/account_login.go index ecac3c68..9e599863 100644 --- a/server/internal/auth/api/account_login.go +++ b/server/internal/auth/api/account_login.go @@ -8,7 +8,6 @@ import ( "mayfly-go/internal/auth/imsg" "mayfly-go/internal/auth/pkg/captcha" "mayfly-go/internal/auth/pkg/otp" - msgapp "mayfly-go/internal/msg/application" sysapp "mayfly-go/internal/sys/application" sysentity "mayfly-go/internal/sys/domain/entity" "mayfly-go/pkg/biz" @@ -24,8 +23,24 @@ import ( ) type AccountLogin struct { - AccountApp sysapp.Account `inject:""` - MsgApp msgapp.Msg `inject:""` + accountApp sysapp.Account `inject:"T"` +} + +func (a *AccountLogin) ReqConfs() *req.Confs { + reqs := [...]*req.Conf{ + // 用户账号密码登录 + req.NewPost("/login", a.Login).Log(req.NewLogSaveI(imsg.LogAccountLogin)).DontNeedToken(), + + req.NewGet("/refreshToken", a.RefreshToken).DontNeedToken(), + + // 用户退出登录 + req.NewPost("/logout", a.Logout), + + // 用户otp双因素校验 + req.NewPost("/otp-verify", a.OtpVerify).DontNeedToken(), + } + + return req.NewConfs("/auth/accounts", reqs[:]...) } /** 用户账号密码登录 **/ @@ -51,7 +66,7 @@ func (a *AccountLogin) Login(rc *req.Ctx) { biz.ErrIsNilAppendErr(err, "decryption password error: %s") account := &sysentity.Account{Username: username} - err = a.AccountApp.GetByCond(model.NewModelCond(account).Columns("Id", "Name", "Username", "Password", "Status", "LastLoginTime", "LastLoginIp", "OtpSecret")) + err = a.accountApp.GetByCond(model.NewModelCond(account).Columns("Id", "Name", "Username", "Password", "Status", "LastLoginTime", "LastLoginIp", "OtpSecret")) failCountKey := fmt.Sprintf("account:login:failcount:%s", username) nowFailCount := cache.GetInt(failCountKey) @@ -109,7 +124,7 @@ func (a *AccountLogin) OtpVerify(rc *req.Ctx) { update := &sysentity.Account{OtpSecret: otpSecret} update.Id = accountId biz.ErrIsNil(update.OtpSecretEncrypt()) - biz.ErrIsNil(a.AccountApp.Update(context.Background(), update)) + biz.ErrIsNil(a.accountApp.Update(context.Background(), update)) } la := &sysentity.Account{Username: otpInfo.Username} diff --git a/server/internal/auth/api/api.go b/server/internal/auth/api/api.go new file mode 100644 index 00000000..9febb7ed --- /dev/null +++ b/server/internal/auth/api/api.go @@ -0,0 +1,10 @@ +package api + +import "mayfly-go/pkg/ioc" + +func InitIoc() { + ioc.Register(new(AccountLogin)) + ioc.Register(new(LdapLogin)) + ioc.Register(new(Oauth2Login)) + ioc.Register(new(Captcha)) +} diff --git a/server/internal/auth/api/captcha.go b/server/internal/auth/api/captcha.go index c515d749..b33a9e3f 100644 --- a/server/internal/auth/api/captcha.go +++ b/server/internal/auth/api/captcha.go @@ -7,7 +7,18 @@ import ( "mayfly-go/pkg/utils/collx" ) -func GenerateCaptcha(rc *req.Ctx) { +type Captcha struct { +} + +func (c *Captcha) ReqConfs() *req.Confs { + reqs := [...]*req.Conf{ + req.NewGet("", c.GenerateCaptcha).DontNeedToken(), + } + + return req.NewConfs("/sys/captcha", reqs[:]...) +} + +func (c *Captcha) GenerateCaptcha(rc *req.Ctx) { id, image, err := captcha.Generate() biz.ErrIsNilAppendErr(err, "failed to generate the CAPTCHA: %s") rc.ResData = collx.M{"base64Captcha": image, "cid": id} diff --git a/server/internal/auth/api/ldap_login.go b/server/internal/auth/api/ldap_login.go index 27b56fbc..382523ac 100644 --- a/server/internal/auth/api/ldap_login.go +++ b/server/internal/auth/api/ldap_login.go @@ -8,7 +8,6 @@ import ( "mayfly-go/internal/auth/config" "mayfly-go/internal/auth/imsg" "mayfly-go/internal/auth/pkg/captcha" - msgapp "mayfly-go/internal/msg/application" sysapp "mayfly-go/internal/sys/application" sysentity "mayfly-go/internal/sys/domain/entity" "mayfly-go/pkg/biz" @@ -28,8 +27,16 @@ import ( ) type LdapLogin struct { - AccountApp sysapp.Account `inject:""` - MsgApp msgapp.Msg `inject:""` + accountApp sysapp.Account `inject:"T"` +} + +func (l *LdapLogin) ReqConfs() *req.Confs { + reqs := [...]*req.Conf{ + req.NewGet("/enabled", l.GetLdapEnabled).DontNeedToken(), + req.NewPost("/login", l.Login).Log(req.NewLogSaveI(imsg.LogLdapLogin)).DontNeedToken(), + } + + return req.NewConfs("/auth/ldap", reqs[:]...) } // @router /auth/ldap/enabled [get] @@ -80,7 +87,7 @@ func (a *LdapLogin) Login(rc *req.Ctx) { func (a *LdapLogin) getUser(userName string, cols ...string) (*sysentity.Account, error) { account := &sysentity.Account{Username: userName} - if err := a.AccountApp.GetByCond(model.NewModelCond(account).Columns(cols...)); err != nil { + if err := a.accountApp.GetByCond(model.NewModelCond(account).Columns(cols...)); err != nil { return nil, err } return account, nil @@ -90,10 +97,10 @@ func (a *LdapLogin) createUser(userName, displayName string) { account := &sysentity.Account{Username: userName} account.FillBaseInfo(model.IdGenTypeNone, nil) account.Name = displayName - biz.ErrIsNil(a.AccountApp.Create(context.TODO(), account)) + biz.ErrIsNil(a.accountApp.Create(context.TODO(), account)) // 将 LADP 用户本地密码设置为空,不允许本地登录 account.Password = cryptox.PwdHash("") - biz.ErrIsNil(a.AccountApp.Update(context.TODO(), account)) + biz.ErrIsNil(a.accountApp.Update(context.TODO(), account)) } func (a *LdapLogin) getOrCreateUserWithLdap(ctx context.Context, userName string, password string, cols ...string) (*sysentity.Account, error) { diff --git a/server/internal/auth/api/oauth2_login.go b/server/internal/auth/api/oauth2_login.go index 369e2bc2..25952ac8 100644 --- a/server/internal/auth/api/oauth2_login.go +++ b/server/internal/auth/api/oauth2_login.go @@ -9,7 +9,6 @@ import ( "mayfly-go/internal/auth/config" "mayfly-go/internal/auth/domain/entity" "mayfly-go/internal/auth/imsg" - msgapp "mayfly-go/internal/msg/application" sysapp "mayfly-go/internal/sys/application" sysentity "mayfly-go/internal/sys/domain/entity" "mayfly-go/pkg/biz" @@ -29,9 +28,28 @@ import ( ) type Oauth2Login struct { - Oauth2App application.Oauth2 `inject:""` - AccountApp sysapp.Account `inject:""` - MsgApp msgapp.Msg `inject:""` + oauth2App application.Oauth2 `inject:"T"` + accountApp sysapp.Account `inject:"T"` +} + +func (o *Oauth2Login) ReqConfs() *req.Confs { + reqs := [...]*req.Conf{ + req.NewGet("/config", o.Oauth2Config).DontNeedToken(), + + // oauth2登录 + req.NewGet("/login", o.OAuth2Login).DontNeedToken(), + + req.NewGet("/bind", o.OAuth2Bind), + + // oauth2回调地址 + req.NewGet("/callback", o.OAuth2Callback).Log(req.NewLogSaveI(imsg.LogOauth2Callback)).DontNeedToken(), + + req.NewGet("/status", o.Oauth2Status), + + req.NewGet("/unbind", o.Oauth2Unbind).Log(req.NewLogSaveI(imsg.LogOauth2Unbind)), + } + + return req.NewConfs("/auth/oauth2", reqs[:]...) } func (a *Oauth2Login) OAuth2Login(rc *req.Ctx) { @@ -100,22 +118,22 @@ func (a *Oauth2Login) OAuth2Callback(rc *req.Ctx) { account := new(sysentity.Account) account.Id = accountId - err = a.AccountApp.GetByCond(model.NewModelCond(account).Columns("username")) + err = a.accountApp.GetByCond(model.NewModelCond(account).Columns("username")) biz.ErrIsNilAppendErr(err, "this account does not exist") rc.ReqParam = collx.Kvs("username", account.Username, "type", "bind") - err = a.Oauth2App.GetOAuthAccount(&entity.Oauth2Account{ + err = a.oauth2App.GetOAuthAccount(&entity.Oauth2Account{ AccountId: accountId, }, "account_id", "identity") biz.IsTrue(err != nil, "the account has been linked by another user") - err = a.Oauth2App.GetOAuthAccount(&entity.Oauth2Account{ + err = a.oauth2App.GetOAuthAccount(&entity.Oauth2Account{ Identity: userId, }, "account_id", "identity") biz.IsTrue(err != nil, "you are bound to another account") now := time.Now() - err = a.Oauth2App.BindOAuthAccount(&entity.Oauth2Account{ + err = a.oauth2App.BindOAuthAccount(&entity.Oauth2Account{ AccountId: accountId, Identity: userId, CreateTime: &now, @@ -136,7 +154,7 @@ func (a *Oauth2Login) OAuth2Callback(rc *req.Ctx) { func (a *Oauth2Login) doLoginAction(rc *req.Ctx, userId string, oauth *config.Oauth2Login) { // 查询用户是否存在 oauthAccount := &entity.Oauth2Account{Identity: userId} - err := a.Oauth2App.GetOAuthAccount(oauthAccount, "account_id", "identity") + err := a.oauth2App.GetOAuthAccount(oauthAccount, "account_id", "identity") ctx := rc.MetaCtx var accountId uint64 isFirst := false @@ -156,9 +174,9 @@ func (a *Oauth2Login) doLoginAction(rc *req.Ctx, userId string, oauth *config.Oa Name: userId, Username: userId, } - biz.ErrIsNil(a.AccountApp.Create(context.TODO(), account)) + biz.ErrIsNil(a.accountApp.Create(context.TODO(), account)) // 绑定 - err := a.Oauth2App.BindOAuthAccount(&entity.Oauth2Account{ + err := a.oauth2App.BindOAuthAccount(&entity.Oauth2Account{ AccountId: account.Id, Identity: oauthAccount.Identity, CreateTime: &now, @@ -172,7 +190,7 @@ func (a *Oauth2Login) doLoginAction(rc *req.Ctx, userId string, oauth *config.Oa } // 进行登录 - account, err := a.AccountApp.GetById(accountId, "Id", "Name", "Username", "Password", "Status", "LastLoginTime", "LastLoginIp", "OtpSecret") + account, err := a.accountApp.GetById(accountId, "Id", "Name", "Username", "Password", "Status", "LastLoginTime", "LastLoginIp", "OtpSecret") biz.ErrIsNilAppendErr(err, "get user info error: %s") clientIp := getIpAndRegion(rc) @@ -207,7 +225,7 @@ func (a *Oauth2Login) Oauth2Status(ctx *req.Ctx) { oauth2LoginConfig := config.GetOauth2Login() res.Enable = oauth2LoginConfig.Enable if res.Enable { - err := a.Oauth2App.GetOAuthAccount(&entity.Oauth2Account{ + err := a.oauth2App.GetOAuthAccount(&entity.Oauth2Account{ AccountId: ctx.GetLoginAccount().Id, }, "account_id", "identity") res.Bind = err == nil @@ -217,7 +235,7 @@ func (a *Oauth2Login) Oauth2Status(ctx *req.Ctx) { } func (a *Oauth2Login) Oauth2Unbind(rc *req.Ctx) { - a.Oauth2App.Unbind(rc.GetLoginAccount().Id) + a.oauth2App.Unbind(rc.GetLoginAccount().Id) } // 获取oauth2登录配置信息,因为有些字段是敏感字段,故单独使用接口获取 diff --git a/server/internal/auth/application/oauth2.go b/server/internal/auth/application/oauth2.go index cd0cb3d6..297423ee 100644 --- a/server/internal/auth/application/oauth2.go +++ b/server/internal/auth/application/oauth2.go @@ -16,20 +16,20 @@ type Oauth2 interface { } type oauth2AppImpl struct { - Oauth2AccountRepo repository.Oauth2Account `inject:""` + oauth2AccountRepo repository.Oauth2Account `inject:"T"` } func (a *oauth2AppImpl) GetOAuthAccount(condition *entity.Oauth2Account, cols ...string) error { - return a.Oauth2AccountRepo.GetByCond(model.NewModelCond(condition).Columns(cols...)) + return a.oauth2AccountRepo.GetByCond(model.NewModelCond(condition).Columns(cols...)) } func (a *oauth2AppImpl) BindOAuthAccount(e *entity.Oauth2Account) error { if e.Id == 0 { - return a.Oauth2AccountRepo.Insert(context.Background(), e) + return a.oauth2AccountRepo.Insert(context.Background(), e) } - return a.Oauth2AccountRepo.UpdateById(context.Background(), e) + return a.oauth2AccountRepo.UpdateById(context.Background(), e) } func (a *oauth2AppImpl) Unbind(accountId uint64) { - a.Oauth2AccountRepo.DeleteByCond(context.Background(), &entity.Oauth2Account{AccountId: accountId}) + a.oauth2AccountRepo.DeleteByCond(context.Background(), &entity.Oauth2Account{AccountId: accountId}) } diff --git a/server/internal/auth/init/init.go b/server/internal/auth/init/init.go index d4c46453..3bb7a4cb 100644 --- a/server/internal/auth/init/init.go +++ b/server/internal/auth/init/init.go @@ -2,15 +2,15 @@ package init import ( "mayfly-go/initialize" + "mayfly-go/internal/auth/api" "mayfly-go/internal/auth/application" "mayfly-go/internal/auth/infrastructure/persistence" - "mayfly-go/internal/auth/router" ) func init() { initialize.AddInitIocFunc(func() { persistence.InitIoc() application.InitIoc() + api.InitIoc() }) - initialize.AddInitRouterFunc(router.Init) } diff --git a/server/internal/auth/router/account.go b/server/internal/auth/router/account.go deleted file mode 100644 index e29a64ee..00000000 --- a/server/internal/auth/router/account.go +++ /dev/null @@ -1,37 +0,0 @@ -package router - -import ( - "mayfly-go/internal/auth/api" - "mayfly-go/internal/auth/imsg" - "mayfly-go/pkg/biz" - "mayfly-go/pkg/ioc" - "mayfly-go/pkg/req" - - "github.com/gin-gonic/gin" -) - -func InitAccount(router *gin.RouterGroup) { - accountLogin := new(api.AccountLogin) - biz.ErrIsNil(ioc.Inject(accountLogin)) - - ldapLogin := new(api.LdapLogin) - biz.ErrIsNil(ioc.Inject(ldapLogin)) - - rg := router.Group("/auth/accounts") - - reqs := [...]*req.Conf{ - - // 用户账号密码登录 - req.NewPost("/login", accountLogin.Login).Log(req.NewLogSaveI(imsg.LogAccountLogin)).DontNeedToken(), - - req.NewGet("/refreshToken", accountLogin.RefreshToken).DontNeedToken(), - - // 用户退出登录 - req.NewPost("/logout", accountLogin.Logout), - - // 用户otp双因素校验 - req.NewPost("/otp-verify", accountLogin.OtpVerify).DontNeedToken(), - } - - req.BatchSetGroup(rg, reqs[:]) -} diff --git a/server/internal/auth/router/captcha.go b/server/internal/auth/router/captcha.go deleted file mode 100644 index 6d807d25..00000000 --- a/server/internal/auth/router/captcha.go +++ /dev/null @@ -1,15 +0,0 @@ -package router - -import ( - "mayfly-go/internal/auth/api" - "mayfly-go/pkg/req" - - "github.com/gin-gonic/gin" -) - -func InitCaptcha(router *gin.RouterGroup) { - captcha := router.Group("sys/captcha") - { - req.NewGet("", api.GenerateCaptcha).DontNeedToken().Group(captcha) - } -} diff --git a/server/internal/auth/router/ldap.go b/server/internal/auth/router/ldap.go deleted file mode 100644 index 84db5d95..00000000 --- a/server/internal/auth/router/ldap.go +++ /dev/null @@ -1,25 +0,0 @@ -package router - -import ( - "mayfly-go/internal/auth/api" - "mayfly-go/internal/auth/imsg" - "mayfly-go/pkg/biz" - "mayfly-go/pkg/ioc" - "mayfly-go/pkg/req" - - "github.com/gin-gonic/gin" -) - -func InitLdap(router *gin.RouterGroup) { - ldapLogin := new(api.LdapLogin) - biz.ErrIsNil(ioc.Inject(ldapLogin)) - - rg := router.Group("/auth/ldap") - - reqs := [...]*req.Conf{ - req.NewGet("/enabled", ldapLogin.GetLdapEnabled).DontNeedToken(), - req.NewPost("/login", ldapLogin.Login).Log(req.NewLogSaveI(imsg.LogLdapLogin)).DontNeedToken(), - } - - req.BatchSetGroup(rg, reqs[:]) -} diff --git a/server/internal/auth/router/oauth2.go b/server/internal/auth/router/oauth2.go deleted file mode 100644 index ebfe58dd..00000000 --- a/server/internal/auth/router/oauth2.go +++ /dev/null @@ -1,37 +0,0 @@ -package router - -import ( - "mayfly-go/internal/auth/api" - "mayfly-go/internal/auth/imsg" - "mayfly-go/pkg/biz" - "mayfly-go/pkg/ioc" - "mayfly-go/pkg/req" - - "github.com/gin-gonic/gin" -) - -func InitOauth2(router *gin.RouterGroup) { - oauth2Login := new(api.Oauth2Login) - biz.ErrIsNil(ioc.Inject(oauth2Login)) - - rg := router.Group("/auth/oauth2") - - reqs := [...]*req.Conf{ - - req.NewGet("/config", oauth2Login.Oauth2Config).DontNeedToken(), - - // oauth2登录 - req.NewGet("/login", oauth2Login.OAuth2Login).DontNeedToken(), - - req.NewGet("/bind", oauth2Login.OAuth2Bind), - - // oauth2回调地址 - req.NewGet("/callback", oauth2Login.OAuth2Callback).Log(req.NewLogSaveI(imsg.LogOauth2Callback)).DontNeedToken(), - - req.NewGet("/status", oauth2Login.Oauth2Status), - - req.NewGet("/unbind", oauth2Login.Oauth2Unbind).Log(req.NewLogSaveI(imsg.LogOauth2Unbind)), - } - - req.BatchSetGroup(rg, reqs[:]) -} diff --git a/server/internal/auth/router/router.go b/server/internal/auth/router/router.go deleted file mode 100644 index a350e09a..00000000 --- a/server/internal/auth/router/router.go +++ /dev/null @@ -1,10 +0,0 @@ -package router - -import "github.com/gin-gonic/gin" - -func Init(router *gin.RouterGroup) { - InitCaptcha(router) - InitAccount(router) - InitOauth2(router) - InitLdap(router) -} diff --git a/server/internal/common/api/api.go b/server/internal/common/api/api.go new file mode 100644 index 00000000..54855a54 --- /dev/null +++ b/server/internal/common/api/api.go @@ -0,0 +1,7 @@ +package api + +import "mayfly-go/pkg/ioc" + +func InitIoc() { + ioc.Register(new(Common)) +} diff --git a/server/internal/common/api/common.go b/server/internal/common/api/common.go index febc5456..a85bba39 100644 --- a/server/internal/common/api/common.go +++ b/server/internal/common/api/common.go @@ -9,8 +9,17 @@ import ( type Common struct { } +func (c *Common) ReqConfs() *req.Confs { + reqs := [...]*req.Conf{ + // 获取公钥 + req.NewGet("/public-key", c.RasPublicKey).DontNeedToken(), + } + + return req.NewConfs("/common", reqs[:]...) +} + func (i *Common) RasPublicKey(rc *req.Ctx) { publicKeyStr, err := cryptox.GetRsaPublicKey() - biz.ErrIsNilAppendErr(err, "rsa生成公私钥失败") + biz.ErrIsNilAppendErr(err, "rsa - failed to genenrate public key") rc.ResData = publicKeyStr } diff --git a/server/internal/common/init/init.go b/server/internal/common/init/init.go index 49d0628f..819b1130 100644 --- a/server/internal/common/init/init.go +++ b/server/internal/common/init/init.go @@ -2,9 +2,11 @@ package init import ( "mayfly-go/initialize" - "mayfly-go/internal/common/router" + "mayfly-go/internal/common/api" ) func init() { - initialize.AddInitRouterFunc(router.Init) + initialize.AddInitIocFunc(func() { + api.InitIoc() + }) } diff --git a/server/internal/common/router/common.go b/server/internal/common/router/common.go deleted file mode 100644 index ee7030ab..00000000 --- a/server/internal/common/router/common.go +++ /dev/null @@ -1,17 +0,0 @@ -package router - -import ( - "mayfly-go/internal/common/api" - "mayfly-go/pkg/req" - - "github.com/gin-gonic/gin" -) - -func InitCommonRouter(router *gin.RouterGroup) { - common := router.Group("common") - c := &api.Common{} - { - // 获取公钥 - req.NewGet("public-key", c.RasPublicKey).DontNeedToken().Group(common) - } -} diff --git a/server/internal/common/router/router.go b/server/internal/common/router/router.go deleted file mode 100644 index ce6d6a23..00000000 --- a/server/internal/common/router/router.go +++ /dev/null @@ -1,7 +0,0 @@ -package router - -import "github.com/gin-gonic/gin" - -func Init(router *gin.RouterGroup) { - InitCommonRouter(router) -} diff --git a/server/internal/db/api/api.go b/server/internal/db/api/api.go new file mode 100644 index 00000000..ca10b1e1 --- /dev/null +++ b/server/internal/db/api/api.go @@ -0,0 +1,13 @@ +package api + +import "mayfly-go/pkg/ioc" + +func InitIoc() { + ioc.Register(new(Dashbord)) + ioc.Register(new(Db)) + ioc.Register(new(Instance)) + ioc.Register(new(DbSqlExec)) + ioc.Register(new(DbSql)) + ioc.Register(new(DataSyncTask)) + ioc.Register(new(DbTransferTask)) +} diff --git a/server/internal/db/api/dashbord.go b/server/internal/db/api/dashbord.go index 3bad29cb..79f79a06 100644 --- a/server/internal/db/api/dashbord.go +++ b/server/internal/db/api/dashbord.go @@ -1,7 +1,6 @@ package api import ( - "mayfly-go/internal/db/application" tagapp "mayfly-go/internal/tag/application" tagentity "mayfly-go/internal/tag/domain/entity" "mayfly-go/pkg/req" @@ -9,14 +8,21 @@ import ( ) type Dashbord struct { - TagTreeApp tagapp.TagTree `inject:""` - DbApp application.Db `inject:""` + tagTreeApp tagapp.TagTree `inject:"T"` +} + +func (d *Dashbord) ReqConfs() *req.Confs { + reqs := [...]*req.Conf{ + req.NewGet("dashbord", d.Dashbord), + } + + return req.NewConfs("/dbs", reqs[:]...) } func (m *Dashbord) Dashbord(rc *req.Ctx) { accountId := rc.GetLoginAccount().Id - tagCodePaths := m.TagTreeApp.GetAccountTags(accountId, &tagentity.TagTreeQuery{Types: collx.AsArray(tagentity.TagTypeDb)}).GetCodePaths() + tagCodePaths := m.tagTreeApp.GetAccountTags(accountId, &tagentity.TagTreeQuery{Types: collx.AsArray(tagentity.TagTypeDb)}).GetCodePaths() rc.ResData = collx.M{ "dbNum": len(tagCodePaths), diff --git a/server/internal/db/api/db.go b/server/internal/db/api/db.go index eec1a604..03291d3e 100644 --- a/server/internal/db/api/db.go +++ b/server/internal/db/api/db.go @@ -33,11 +33,46 @@ import ( ) type Db struct { - InstanceApp application.Instance `inject:"DbInstanceApp"` - DbApp application.Db `inject:""` - DbSqlExecApp application.DbSqlExec `inject:""` - MsgApp msgapp.Msg `inject:""` - TagApp tagapp.TagTree `inject:"TagTreeApp"` + instanceApp application.Instance `inject:"T"` + dbApp application.Db `inject:"T"` + dbSqlExecApp application.DbSqlExec `inject:"T"` + msgApp msgapp.Msg `inject:"T"` + tagApp tagapp.TagTree `inject:"T"` +} + +func (d *Db) ReqConfs() *req.Confs { + reqs := [...]*req.Conf{ + // 获取数据库列表 + req.NewGet("", d.Dbs), + + req.NewPost("", d.Save).Log(req.NewLogSaveI(imsg.LogDbSave)), + + req.NewDelete(":dbId", d.DeleteDb).Log(req.NewLogSaveI(imsg.LogDbDelete)), + + req.NewGet(":dbId/t-create-ddl", d.GetTableDDL), + + req.NewGet(":dbId/version", d.GetVersion), + + req.NewGet(":dbId/pg/schemas", d.GetSchemas), + + req.NewPost(":dbId/exec-sql", d.ExecSql).Log(req.NewLogI(imsg.LogDbRunSql)), + + req.NewPost(":dbId/exec-sql-file", d.ExecSqlFile).Log(req.NewLogSaveI(imsg.LogDbRunSqlFile)).RequiredPermissionCode("db:sqlscript:run"), + + req.NewGet(":dbId/dump", d.DumpSql).Log(req.NewLogSaveI(imsg.LogDbDump)).NoRes(), + + req.NewGet(":dbId/t-infos", d.TableInfos), + + req.NewGet(":dbId/t-index", d.TableIndex), + + req.NewGet(":dbId/c-metadata", d.ColumnMA), + + req.NewGet(":dbId/hint-tables", d.HintTables), + + req.NewPost(":dbId/copy-table", d.CopyTable), + } + + return req.NewConfs("/dbs", reqs[:]...) } // @router /api/dbs [get] @@ -45,7 +80,7 @@ func (d *Db) Dbs(rc *req.Ctx) { queryCond, page := req.BindQueryAndPage[*entity.DbQuery](rc, new(entity.DbQuery)) // 不存在可访问标签id,即没有可操作数据 - tags := d.TagApp.GetAccountTags(rc.GetLoginAccount().Id, &tagentity.TagTreeQuery{ + tags := d.tagApp.GetAccountTags(rc.GetLoginAccount().Id, &tagentity.TagTreeQuery{ TypePaths: collx.AsArray(tagentity.NewTypePaths(tagentity.TagTypeDbInstance, tagentity.TagTypeAuthCert, tagentity.TagTypeDb)), CodePathLikes: collx.AsArray(queryCond.TagPath), }) @@ -56,10 +91,10 @@ func (d *Db) Dbs(rc *req.Ctx) { queryCond.Codes = tags.GetCodes() var dbvos []*vo.DbListVO - res, err := d.DbApp.GetPageList(queryCond, page, &dbvos) + res, err := d.dbApp.GetPageList(queryCond, page, &dbvos) biz.ErrIsNil(err) - instances, _ := d.InstanceApp.GetByIds(collx.ArrayMap(dbvos, func(i *vo.DbListVO) uint64 { + instances, _ := d.instanceApp.GetByIds(collx.ArrayMap(dbvos, func(i *vo.DbListVO) uint64 { return i.InstanceId })) instancesMap := collx.ArrayToMap(instances, func(i *entity.DbInstance) uint64 { @@ -84,7 +119,7 @@ func (d *Db) Save(rc *req.Ctx) { rc.ReqParam = form - biz.ErrIsNil(d.DbApp.SaveDb(rc.MetaCtx, db)) + biz.ErrIsNil(d.dbApp.SaveDb(rc.MetaCtx, db)) } func (d *Db) DeleteDb(rc *req.Ctx) { @@ -94,7 +129,7 @@ func (d *Db) DeleteDb(rc *req.Ctx) { ctx := rc.MetaCtx for _, v := range ids { - biz.ErrIsNil(d.DbApp.Delete(ctx, cast.ToUint64(v))) + biz.ErrIsNil(d.dbApp.Delete(ctx, cast.ToUint64(v))) } } @@ -104,9 +139,9 @@ func (d *Db) ExecSql(rc *req.Ctx) { form := req.BindJsonAndValid(rc, new(form.DbSqlExecForm)) dbId := getDbId(rc) - dbConn, err := d.DbApp.GetDbConn(dbId, form.Db) + dbConn, err := d.dbApp.GetDbConn(dbId, form.Db) biz.ErrIsNil(err) - biz.ErrIsNilAppendErr(d.TagApp.CanAccess(rc.GetLoginAccount().Id, dbConn.Info.CodePath...), "%s") + biz.ErrIsNilAppendErr(d.tagApp.CanAccess(rc.GetLoginAccount().Id, dbConn.Info.CodePath...), "%s") global.EventBus.Publish(rc.MetaCtx, event.EventTopicResourceOp, dbConn.Info.CodePath[0]) sqlStr, err := cryptox.AesDecryptByLa(form.Sql, rc.GetLoginAccount()) @@ -127,7 +162,7 @@ func (d *Db) ExecSql(rc *req.Ctx) { ctx, cancel := context.WithTimeout(rc.MetaCtx, time.Duration(config.GetDbms().SqlExecTl)*time.Second) defer cancel() - execRes, err := d.DbSqlExecApp.Exec(ctx, execReq) + execRes, err := d.dbSqlExecApp.Exec(ctx, execReq) biz.ErrIsNil(err) rc.ResData = execRes } @@ -155,12 +190,12 @@ func (d *Db) ExecSqlFile(rc *req.Ctx) { dbName := getDbName(rc) clientId := rc.Query("clientId") - dbConn, err := d.DbApp.GetDbConn(dbId, dbName) + dbConn, err := d.dbApp.GetDbConn(dbId, dbName) biz.ErrIsNil(err) - biz.ErrIsNilAppendErr(d.TagApp.CanAccess(rc.GetLoginAccount().Id, dbConn.Info.CodePath...), "%s") + biz.ErrIsNilAppendErr(d.tagApp.CanAccess(rc.GetLoginAccount().Id, dbConn.Info.CodePath...), "%s") rc.ReqParam = fmt.Sprintf("filename: %s -> %s", filename, dbConn.Info.GetLogDesc()) - biz.ErrIsNil(d.DbSqlExecApp.ExecReader(rc.MetaCtx, &dto.SqlReaderExec{ + biz.ErrIsNil(d.dbSqlExecApp.ExecReader(rc.MetaCtx, &dto.SqlReaderExec{ Reader: file, Filename: filename, DbConn: dbConn, @@ -188,9 +223,9 @@ func (d *Db) DumpSql(rc *req.Ctx) { needData := dumpType == "2" || dumpType == "3" la := rc.GetLoginAccount() - dbConn, err := d.DbApp.GetDbConn(dbId, dbName) + dbConn, err := d.dbApp.GetDbConn(dbId, dbName) biz.ErrIsNil(err) - biz.ErrIsNilAppendErr(d.TagApp.CanAccess(la.Id, dbConn.Info.CodePath...), "%s") + biz.ErrIsNilAppendErr(d.tagApp.CanAccess(la.Id, dbConn.Info.CodePath...), "%s") now := time.Now() filename := fmt.Sprintf("%s-%s.%s.sql%s", dbConn.Info.Name, dbName, now.Format("20060102150405"), extName) @@ -210,11 +245,11 @@ func (d *Db) DumpSql(rc *req.Ctx) { if len(msg) > 0 { msg = "DB dump error: " + msg rc.GetWriter().Write([]byte(msg)) - d.MsgApp.CreateAndSend(la, msgdto.ErrSysMsg(i18n.T(imsg.DbDumpErr), msg)) + d.msgApp.CreateAndSend(la, msgdto.ErrSysMsg(i18n.T(imsg.DbDumpErr), msg)) } }() - biz.ErrIsNil(d.DbApp.DumpDb(rc.MetaCtx, &dto.DumpDb{ + biz.ErrIsNil(d.dbApp.DumpDb(rc.MetaCtx, &dto.DumpDb{ DbId: dbId, DbName: dbName, Tables: tables, @@ -316,7 +351,7 @@ func (d *Db) CopyTable(rc *req.Ctx) { form := &form.DbCopyTableForm{} copy := req.BindJsonAndCopyTo[*dbi.DbCopyTable](rc, form, new(dbi.DbCopyTable)) - conn, err := d.DbApp.GetDbConn(form.Id, form.Db) + conn, err := d.dbApp.GetDbConn(form.Id, form.Db) biz.ErrIsNilAppendErr(err, "copy table error: %s") err = conn.GetDialect().CopyTable(copy) @@ -339,7 +374,7 @@ func getDbName(rc *req.Ctx) string { } func (d *Db) getDbConn(rc *req.Ctx) *dbi.DbConn { - dc, err := d.DbApp.GetDbConn(getDbId(rc), getDbName(rc)) + dc, err := d.dbApp.GetDbConn(getDbId(rc), getDbName(rc)) biz.ErrIsNil(err) return dc } diff --git a/server/internal/db/api/db_data_sync.go b/server/internal/db/api/db_data_sync.go index dc934b03..8c426cd9 100644 --- a/server/internal/db/api/db_data_sync.go +++ b/server/internal/db/api/db_data_sync.go @@ -5,6 +5,7 @@ import ( "mayfly-go/internal/db/api/vo" "mayfly-go/internal/db/application" "mayfly-go/internal/db/domain/entity" + "mayfly-go/internal/db/imsg" "mayfly-go/pkg/biz" "mayfly-go/pkg/req" "mayfly-go/pkg/utils/cryptox" @@ -15,19 +16,48 @@ import ( ) type DataSyncTask struct { - DataSyncTaskApp application.DataSyncTask `inject:"DbDataSyncTaskApp"` + dataSyncTaskApp application.DataSyncTask `inject:"T"` +} + +func (d *DataSyncTask) ReqConfs() *req.Confs { + reqs := [...]*req.Conf{ + // 获取任务列表 /datasync + req.NewGet("", d.Tasks), + + req.NewGet(":taskId/logs", d.Logs).RequiredPermissionCode("db:sync:log"), + + // 保存任务 /datasync/save + req.NewPost("save", d.SaveTask).Log(req.NewLogSaveI(imsg.LogDataSyncSave)).RequiredPermissionCode("db:sync:save"), + + // 获取单个详情 /datasync/:taskId + req.NewGet(":taskId", d.GetTask), + + // 删除任务 /datasync/:taskId/del + req.NewDelete(":taskId/del", d.DeleteTask).Log(req.NewLogSaveI(imsg.LogDataSyncDelete)).RequiredPermissionCode("db:sync:del"), + + // 启停用任务 /datasync/status + req.NewPost(":taskId/status", d.ChangeStatus).Log(req.NewLogSaveI(imsg.LogDataSyncChangeStatus)).RequiredPermissionCode("db:sync:status"), + + // 立即执行任务 /datasync/run + req.NewPost(":taskId/run", d.Run), + + // 停止正在执行中的任务 + req.NewPost(":taskId/stop", d.Stop), + } + + return req.NewConfs("/datasync/tasks", reqs[:]...) } func (d *DataSyncTask) Tasks(rc *req.Ctx) { queryCond, page := req.BindQueryAndPage[*entity.DataSyncTaskQuery](rc, new(entity.DataSyncTaskQuery)) - res, err := d.DataSyncTaskApp.GetPageList(queryCond, page, new([]vo.DataSyncTaskListVO)) + res, err := d.dataSyncTaskApp.GetPageList(queryCond, page, new([]vo.DataSyncTaskListVO)) biz.ErrIsNil(err) rc.ResData = res } func (d *DataSyncTask) Logs(rc *req.Ctx) { queryCond, page := req.BindQueryAndPage[*entity.DataSyncLogQuery](rc, new(entity.DataSyncLogQuery)) - res, err := d.DataSyncTaskApp.GetTaskLogList(queryCond, page, new([]vo.DataSyncLogListVO)) + res, err := d.dataSyncTaskApp.GetTaskLogList(queryCond, page, new([]vo.DataSyncLogListVO)) biz.ErrIsNil(err) rc.ResData = res } @@ -44,7 +74,7 @@ func (d *DataSyncTask) SaveTask(rc *req.Ctx) { form.DataSql = sql rc.ReqParam = form - biz.ErrIsNil(d.DataSyncTaskApp.Save(rc.MetaCtx, task)) + biz.ErrIsNil(d.dataSyncTaskApp.Save(rc.MetaCtx, task)) } func (d *DataSyncTask) DeleteTask(rc *req.Ctx) { @@ -53,21 +83,21 @@ func (d *DataSyncTask) DeleteTask(rc *req.Ctx) { ids := strings.Split(taskId, ",") for _, v := range ids { - biz.ErrIsNil(d.DataSyncTaskApp.Delete(rc.MetaCtx, cast.ToUint64(v))) + biz.ErrIsNil(d.dataSyncTaskApp.Delete(rc.MetaCtx, cast.ToUint64(v))) } } func (d *DataSyncTask) ChangeStatus(rc *req.Ctx) { form := &form.DataSyncTaskStatusForm{} task := req.BindJsonAndCopyTo[*entity.DataSyncTask](rc, form, new(entity.DataSyncTask)) - _ = d.DataSyncTaskApp.UpdateById(rc.MetaCtx, task) + _ = d.dataSyncTaskApp.UpdateById(rc.MetaCtx, task) if task.Status == entity.DataSyncTaskStatusEnable { - task, err := d.DataSyncTaskApp.GetById(task.Id) + task, err := d.dataSyncTaskApp.GetById(task.Id) biz.ErrIsNil(err, "task not found") - d.DataSyncTaskApp.AddCronJob(rc.MetaCtx, task) + d.dataSyncTaskApp.AddCronJob(rc.MetaCtx, task) } else { - d.DataSyncTaskApp.RemoveCronJobById(task.Id) + d.dataSyncTaskApp.RemoveCronJobById(task.Id) } // 记录请求日志 rc.ReqParam = form @@ -76,7 +106,7 @@ func (d *DataSyncTask) ChangeStatus(rc *req.Ctx) { func (d *DataSyncTask) Run(rc *req.Ctx) { taskId := d.getTaskId(rc) rc.ReqParam = taskId - _ = d.DataSyncTaskApp.RunCronJob(rc.MetaCtx, taskId) + _ = d.dataSyncTaskApp.RunCronJob(rc.MetaCtx, taskId) } func (d *DataSyncTask) Stop(rc *req.Ctx) { @@ -86,12 +116,12 @@ func (d *DataSyncTask) Stop(rc *req.Ctx) { task := new(entity.DataSyncTask) task.Id = taskId task.RunningState = entity.DataSyncTaskRunStateStop - _ = d.DataSyncTaskApp.UpdateById(rc.MetaCtx, task) + _ = d.dataSyncTaskApp.UpdateById(rc.MetaCtx, task) } func (d *DataSyncTask) GetTask(rc *req.Ctx) { taskId := d.getTaskId(rc) - dbEntity, _ := d.DataSyncTaskApp.GetById(taskId) + dbEntity, _ := d.dataSyncTaskApp.GetById(taskId) rc.ResData = dbEntity } diff --git a/server/internal/db/api/db_instance.go b/server/internal/db/api/db_instance.go index 984f337f..5ba2268a 100644 --- a/server/internal/db/api/db_instance.go +++ b/server/internal/db/api/db_instance.go @@ -7,6 +7,7 @@ import ( "mayfly-go/internal/db/application" "mayfly-go/internal/db/application/dto" "mayfly-go/internal/db/domain/entity" + "mayfly-go/internal/db/imsg" tagapp "mayfly-go/internal/tag/application" tagentity "mayfly-go/internal/tag/domain/entity" @@ -20,10 +21,35 @@ import ( ) type Instance struct { - InstanceApp application.Instance `inject:"DbInstanceApp"` - DbApp application.Db `inject:""` - ResourceAuthCertApp tagapp.ResourceAuthCert `inject:""` - TagApp tagapp.TagTree `inject:"TagTreeApp"` + instanceApp application.Instance `inject:"T"` + dbApp application.Db `inject:"T"` + resourceAuthCertApp tagapp.ResourceAuthCert `inject:"T"` + tagApp tagapp.TagTree `inject:"T"` +} + +func (d *Instance) ReqConfs() *req.Confs { + reqs := [...]*req.Conf{ + // 获取数据库列表 + req.NewGet("", d.Instances), + + req.NewPost("/test-conn", d.TestConn), + + req.NewPost("", d.SaveInstance).Log(req.NewLogSaveI(imsg.LogDbInstSave)), + + req.NewGet(":instanceId", d.GetInstance), + + // 获取数据库实例的所有数据库名 + req.NewPost("/databases", d.GetDatabaseNames), + + // 根据授权凭证名获取其所有库名 + req.NewGet("/databases/:ac", d.GetDatabaseNamesByAc), + + req.NewGet(":instanceId/server-info", d.GetDbServer), + + req.NewDelete(":instanceId", d.DeleteInstance).Log(req.NewLogSaveI(imsg.LogDbInstDelete)), + } + + return req.NewConfs("/instances", reqs[:]...) } // Instances 获取数据库实例信息 @@ -31,7 +57,7 @@ type Instance struct { func (d *Instance) Instances(rc *req.Ctx) { queryCond, page := req.BindQueryAndPage[*entity.InstanceQuery](rc, new(entity.InstanceQuery)) - tags := d.TagApp.GetAccountTags(rc.GetLoginAccount().Id, &tagentity.TagTreeQuery{ + tags := d.tagApp.GetAccountTags(rc.GetLoginAccount().Id, &tagentity.TagTreeQuery{ TypePaths: collx.AsArray(tagentity.NewTypePaths(tagentity.TagTypeDbInstance, tagentity.TagTypeAuthCert)), CodePathLikes: collx.AsArray(queryCond.TagPath), }) @@ -46,16 +72,16 @@ func (d *Instance) Instances(rc *req.Ctx) { queryCond.Codes = dbInstCodes var instvos []*vo.InstanceListVO - res, err := d.InstanceApp.GetPageList(queryCond, page, &instvos) + res, err := d.instanceApp.GetPageList(queryCond, page, &instvos) biz.ErrIsNil(err) // 填充授权凭证信息 - d.ResourceAuthCertApp.FillAuthCertByAcNames(tagentity.GetCodesByCodePaths(tagentity.TagTypeAuthCert, tagCodePaths...), collx.ArrayMap(instvos, func(vos *vo.InstanceListVO) tagentity.IAuthCert { + d.resourceAuthCertApp.FillAuthCertByAcNames(tagentity.GetCodesByCodePaths(tagentity.TagTypeAuthCert, tagCodePaths...), collx.ArrayMap(instvos, func(vos *vo.InstanceListVO) tagentity.IAuthCert { return vos })...) // 填充标签信息 - d.TagApp.FillTagInfo(tagentity.TagType(consts.ResourceTypeDbInstance), collx.ArrayMap(instvos, func(insvo *vo.InstanceListVO) tagentity.ITagResource { + d.tagApp.FillTagInfo(tagentity.TagType(consts.ResourceTypeDbInstance), collx.ArrayMap(instvos, func(insvo *vo.InstanceListVO) tagentity.ITagResource { return insvo })...) @@ -66,7 +92,7 @@ func (d *Instance) TestConn(rc *req.Ctx) { form := &form.InstanceForm{} instance := req.BindJsonAndCopyTo[*entity.DbInstance](rc, form, new(entity.DbInstance)) - biz.ErrIsNil(d.InstanceApp.TestConn(instance, form.AuthCerts[0])) + biz.ErrIsNil(d.instanceApp.TestConn(instance, form.AuthCerts[0])) } // SaveInstance 保存数据库实例信息 @@ -76,7 +102,7 @@ func (d *Instance) SaveInstance(rc *req.Ctx) { instance := req.BindJsonAndCopyTo[*entity.DbInstance](rc, form, new(entity.DbInstance)) rc.ReqParam = form - id, err := d.InstanceApp.SaveDbInstance(rc.MetaCtx, &dto.SaveDbInstance{ + id, err := d.instanceApp.SaveDbInstance(rc.MetaCtx, &dto.SaveDbInstance{ DbInstance: instance, AuthCerts: form.AuthCerts, TagCodePaths: form.TagCodePaths, @@ -89,7 +115,7 @@ func (d *Instance) SaveInstance(rc *req.Ctx) { // @router /api/instances/:instance [GET] func (d *Instance) GetInstance(rc *req.Ctx) { dbId := getInstanceId(rc) - dbEntity, err := d.InstanceApp.GetById(dbId) + dbEntity, err := d.instanceApp.GetById(dbId) biz.ErrIsNilAppendErr(err, "get db instance failed: %s") rc.ResData = dbEntity } @@ -102,7 +128,7 @@ func (d *Instance) DeleteInstance(rc *req.Ctx) { ids := strings.Split(idsStr, ",") for _, v := range ids { - biz.ErrIsNilAppendErr(d.InstanceApp.Delete(rc.MetaCtx, cast.ToUint64(v)), "delete db instance failed: %s") + biz.ErrIsNilAppendErr(d.instanceApp.Delete(rc.MetaCtx, cast.ToUint64(v)), "delete db instance failed: %s") } } @@ -110,13 +136,13 @@ func (d *Instance) DeleteInstance(rc *req.Ctx) { func (d *Instance) GetDatabaseNames(rc *req.Ctx) { form := &form.InstanceDbNamesForm{} instance := req.BindJsonAndCopyTo[*entity.DbInstance](rc, form, new(entity.DbInstance)) - res, err := d.InstanceApp.GetDatabases(instance, form.AuthCert) + res, err := d.instanceApp.GetDatabases(instance, form.AuthCert) biz.ErrIsNil(err) rc.ResData = res } func (d *Instance) GetDatabaseNamesByAc(rc *req.Ctx) { - res, err := d.InstanceApp.GetDatabasesByAc(rc.PathParam("ac")) + res, err := d.instanceApp.GetDatabasesByAc(rc.PathParam("ac")) biz.ErrIsNil(err) rc.ResData = res } @@ -124,7 +150,7 @@ func (d *Instance) GetDatabaseNamesByAc(rc *req.Ctx) { // 获取数据库实例server信息 func (d *Instance) GetDbServer(rc *req.Ctx) { instanceId := getInstanceId(rc) - conn, err := d.DbApp.GetDbConnByInstanceId(instanceId) + conn, err := d.dbApp.GetDbConnByInstanceId(instanceId) biz.ErrIsNil(err) res, err := conn.GetMetadata().GetDbServer() biz.ErrIsNil(err) diff --git a/server/internal/db/api/db_sql.go b/server/internal/db/api/db_sql.go index c58f4e55..42ffdf5a 100644 --- a/server/internal/db/api/db_sql.go +++ b/server/internal/db/api/db_sql.go @@ -10,7 +10,22 @@ import ( ) type DbSql struct { - DbSqlApp application.DbSql `inject:""` + dbSqlApp application.DbSql `inject:"T"` +} + +func (d *DbSql) ReqConfs() *req.Confs { + reqs := [...]*req.Conf{ + // 用户sql相关 + req.NewPost(":dbId/sql", d.SaveSql), + + req.NewGet(":dbId/sql", d.GetSql), + + req.NewDelete(":dbId/sql", d.DeleteSql), + + req.NewGet(":dbId/sql-names", d.GetSqlNames), + } + + return req.NewConfs("/dbs", reqs[:]...) } // @router /api/db/:dbId/sql [post] @@ -25,14 +40,14 @@ func (d *DbSql) SaveSql(rc *req.Ctx) { // 获取用于是否有该dbsql的保存记录,有则更改,否则新增 dbSql := &entity.DbSql{Type: dbSqlForm.Type, DbId: dbId, Name: dbSqlForm.Name, Db: dbSqlForm.Db} dbSql.CreatorId = account.Id - e := d.DbSqlApp.GetByCond(dbSql) + e := d.dbSqlApp.GetByCond(dbSql) // 更新sql信息 dbSql.Sql = dbSqlForm.Sql if e == nil { - d.DbSqlApp.UpdateById(rc.MetaCtx, dbSql) + d.dbSqlApp.UpdateById(rc.MetaCtx, dbSql) } else { - d.DbSqlApp.Insert(rc.MetaCtx, dbSql) + d.dbSqlApp.Insert(rc.MetaCtx, dbSql) } } @@ -43,7 +58,7 @@ func (d *DbSql) GetSqlNames(rc *req.Ctx) { // 获取用于是否有该dbsql的保存记录,有则更改,否则新增 dbSql := &entity.DbSql{Type: 1, DbId: dbId, Db: dbName} dbSql.CreatorId = rc.GetLoginAccount().Id - sqls, _ := d.DbSqlApp.ListByCond(model.NewModelCond(dbSql).Columns("id", "name")) + sqls, _ := d.dbSqlApp.ListByCond(model.NewModelCond(dbSql).Columns("id", "name")) rc.ResData = sqls } @@ -55,7 +70,7 @@ func (d *DbSql) DeleteSql(rc *req.Ctx) { dbSql.Name = rc.Query("name") dbSql.Db = rc.Query("db") - biz.ErrIsNil(d.DbSqlApp.DeleteByCond(rc.MetaCtx, dbSql)) + biz.ErrIsNil(d.dbSqlApp.DeleteByCond(rc.MetaCtx, dbSql)) } // @router /api/db/:dbId/sql [get] @@ -67,7 +82,7 @@ func (d *DbSql) GetSql(rc *req.Ctx) { dbSql.CreatorId = rc.GetLoginAccount().Id dbSql.Name = rc.Query("name") - e := d.DbSqlApp.GetByCond(dbSql) + e := d.dbSqlApp.GetByCond(dbSql) if e != nil { return } diff --git a/server/internal/db/api/db_sql_exec.go b/server/internal/db/api/db_sql_exec.go index 797dc54f..ad358619 100644 --- a/server/internal/db/api/db_sql_exec.go +++ b/server/internal/db/api/db_sql_exec.go @@ -13,7 +13,16 @@ import ( ) type DbSqlExec struct { - DbSqlExecApp application.DbSqlExec `inject:""` + dbSqlExecApp application.DbSqlExec `inject:"T"` +} + +func (d *DbSqlExec) ReqConfs() *req.Confs { + reqs := [...]*req.Conf{ + // 获取所有数据库sql执行记录列表 + req.NewGet("/sql-execs", d.DbSqlExecs), + } + + return req.NewConfs("/dbs", reqs[:]...) } func (d *DbSqlExec) DbSqlExecs(rc *req.Ctx) { @@ -24,7 +33,7 @@ func (d *DbSqlExec) DbSqlExecs(rc *req.Ctx) { return cast.ToInt8(val) }) } - res, err := d.DbSqlExecApp.GetPageList(queryCond, page, new([]entity.DbSqlExec)) + res, err := d.dbSqlExecApp.GetPageList(queryCond, page, new([]entity.DbSqlExec)) biz.ErrIsNil(err) rc.ResData = res } diff --git a/server/internal/db/api/db_transfer.go b/server/internal/db/api/db_transfer.go index 05d6e89a..1e3c0b47 100644 --- a/server/internal/db/api/db_transfer.go +++ b/server/internal/db/api/db_transfer.go @@ -7,8 +7,8 @@ import ( "mayfly-go/internal/db/application" "mayfly-go/internal/db/application/dto" "mayfly-go/internal/db/domain/entity" + "mayfly-go/internal/db/imsg" fileapp "mayfly-go/internal/file/application" - msgapp "mayfly-go/internal/msg/application" tagapp "mayfly-go/internal/tag/application" "mayfly-go/pkg/biz" "mayfly-go/pkg/req" @@ -19,25 +19,56 @@ import ( ) type DbTransferTask struct { - DbTransferTask application.DbTransferTask `inject:"DbTransferTaskApp"` - DbTransferFile application.DbTransferFile `inject:"DbTransferFileApp"` - DbApp application.Db `inject:""` - TagApp tagapp.TagTree `inject:"TagTreeApp"` - MsgApp msgapp.Msg `inject:""` - DbSqlExecApp application.DbSqlExec `inject:""` - FileApp fileapp.File `inject:""` + dbTransferTask application.DbTransferTask `inject:"T"` + dbTransferFile application.DbTransferFile `inject:"T"` + dbApp application.Db `inject:"T"` + tagApp tagapp.TagTree `inject:"T"` + dbSqlExecApp application.DbSqlExec `inject:"T"` + fileApp fileapp.File `inject:"T"` +} + +func (d *DbTransferTask) ReqConfs() *req.Confs { + reqs := [...]*req.Conf{ + // 获取任务列表 + req.NewGet("", d.Tasks), + + // 保存任务 + req.NewPost("save", d.SaveTask).Log(req.NewLogSaveI(imsg.LogDtsSave)).RequiredPermissionCode("db:transfer:save"), + + // 删除任务 + req.NewDelete(":taskId/del", d.DeleteTask).Log(req.NewLogSaveI(imsg.LogDtsDelete)).RequiredPermissionCode("db:transfer:del"), + + // 启停用任务 + req.NewPost(":taskId/status", d.ChangeStatus).Log(req.NewLogSaveI(imsg.LogDtsChangeStatus)).RequiredPermissionCode("db:transfer:status"), + + // 立即执行任务 + req.NewPost(":taskId/run", d.Run).Log(req.NewLogI(imsg.LogDtsRun)).RequiredPermissionCode("db:transfer:run"), + + // 停止正在执行中的任务 + req.NewPost(":taskId/stop", d.Stop).Log(req.NewLogSaveI(imsg.LogDtsStop)).RequiredPermissionCode("db:transfer:run"), + + // 导出文件管理-列表 + req.NewGet("/files/:taskId", d.Files), + + // 导出文件管理-删除 + req.NewPost("/files/del/:fileId", d.FileDel).Log(req.NewLogSaveI(imsg.LogDtsDeleteFile)).RequiredPermissionCode("db:transfer:files:del"), + + req.NewPost("/files/run", d.FileRun).Log(req.NewLogSaveI(imsg.LogDtsRunSqlFile)).RequiredPermissionCode("db:transfer:files:run"), + } + + return req.NewConfs("/dbTransfer", reqs[:]...) } func (d *DbTransferTask) Tasks(rc *req.Ctx) { queryCond, page := req.BindQueryAndPage[*entity.DbTransferTaskQuery](rc, new(entity.DbTransferTaskQuery)) - res, err := d.DbTransferTask.GetPageList(queryCond, page, new([]vo.DbTransferTaskListVO)) + res, err := d.dbTransferTask.GetPageList(queryCond, page, new([]vo.DbTransferTaskListVO)) biz.ErrIsNil(err) if res.List != nil { list := res.List.(*[]vo.DbTransferTaskListVO) for _, item := range *list { item.RunningState = entity.DbTransferTaskRunStateSuccess - if d.DbTransferTask.IsRunning(item.Id) { + if d.dbTransferTask.IsRunning(item.Id) { item.RunningState = entity.DbTransferTaskRunStateRunning } } @@ -51,7 +82,7 @@ func (d *DbTransferTask) SaveTask(rc *req.Ctx) { task := req.BindJsonAndCopyTo[*entity.DbTransferTask](rc, reqForm, new(entity.DbTransferTask)) rc.ReqParam = reqForm - biz.ErrIsNil(d.DbTransferTask.Save(rc.MetaCtx, task)) + biz.ErrIsNil(d.dbTransferTask.Save(rc.MetaCtx, task)) } func (d *DbTransferTask) DeleteTask(rc *req.Ctx) { @@ -63,17 +94,17 @@ func (d *DbTransferTask) DeleteTask(rc *req.Ctx) { return cast.ToUint64(val) }) - biz.ErrIsNil(d.DbTransferTask.DeleteById(rc.MetaCtx, uids...)) + biz.ErrIsNil(d.dbTransferTask.DeleteById(rc.MetaCtx, uids...)) } func (d *DbTransferTask) ChangeStatus(rc *req.Ctx) { form := &form.DbTransferTaskStatusForm{} task := req.BindJsonAndCopyTo[*entity.DbTransferTask](rc, form, new(entity.DbTransferTask)) - _ = d.DbTransferTask.UpdateById(rc.MetaCtx, task) + _ = d.dbTransferTask.UpdateById(rc.MetaCtx, task) - task, err := d.DbTransferTask.GetById(task.Id) + task, err := d.dbTransferTask.GetById(task.Id) biz.ErrIsNil(err, "task not found") - d.DbTransferTask.AddCronJob(rc.MetaCtx, task) + d.dbTransferTask.AddCronJob(rc.MetaCtx, task) // 记录请求日志 rc.ReqParam = form @@ -81,18 +112,18 @@ func (d *DbTransferTask) ChangeStatus(rc *req.Ctx) { func (d *DbTransferTask) Run(rc *req.Ctx) { taskId := uint64(rc.PathParamInt("taskId")) - logId, _ := d.DbTransferTask.CreateLog(rc.MetaCtx, taskId) - go d.DbTransferTask.Run(rc.MetaCtx, taskId, logId) + logId, _ := d.dbTransferTask.CreateLog(rc.MetaCtx, taskId) + go d.dbTransferTask.Run(rc.MetaCtx, taskId, logId) rc.ResData = logId } func (d *DbTransferTask) Stop(rc *req.Ctx) { - biz.ErrIsNil(d.DbTransferTask.Stop(rc.MetaCtx, uint64(rc.PathParamInt("taskId")))) + biz.ErrIsNil(d.dbTransferTask.Stop(rc.MetaCtx, uint64(rc.PathParamInt("taskId")))) } func (d *DbTransferTask) Files(rc *req.Ctx) { queryCond, page := req.BindQueryAndPage[*entity.DbTransferFileQuery](rc, new(entity.DbTransferFileQuery)) - res, err := d.DbTransferFile.GetPageList(queryCond, page, new([]vo.DbTransferFileListVO)) + res, err := d.dbTransferFile.GetPageList(queryCond, page, new([]vo.DbTransferFileListVO)) biz.ErrIsNil(err) rc.ResData = res } @@ -106,7 +137,7 @@ func (d *DbTransferTask) FileDel(rc *req.Ctx) { for _, v := range ids { uIds = append(uIds, cast.ToUint64(v)) } - biz.ErrIsNil(d.DbTransferFile.Delete(rc.MetaCtx, uIds...)) + biz.ErrIsNil(d.dbTransferFile.Delete(rc.MetaCtx, uIds...)) } func (d *DbTransferTask) FileRun(rc *req.Ctx) { @@ -114,22 +145,21 @@ func (d *DbTransferTask) FileRun(rc *req.Ctx) { rc.ReqParam = fm - tFile, err := d.DbTransferFile.GetById(fm.Id) + tFile, err := d.dbTransferFile.GetById(fm.Id) biz.IsTrue(tFile != nil && err == nil, "file not found") - targetDbConn, err := d.DbApp.GetDbConn(fm.TargetDbId, fm.TargetDbName) + targetDbConn, err := d.dbApp.GetDbConn(fm.TargetDbId, fm.TargetDbName) biz.ErrIsNilAppendErr(err, "failed to connect to the target database: %s") - biz.ErrIsNilAppendErr(d.TagApp.CanAccess(rc.GetLoginAccount().Id, targetDbConn.Info.CodePath...), "%s") + biz.ErrIsNilAppendErr(d.tagApp.CanAccess(rc.GetLoginAccount().Id, targetDbConn.Info.CodePath...), "%s") - filename, reader, err := d.FileApp.GetReader(context.TODO(), tFile.FileKey) + filename, reader, err := d.fileApp.GetReader(context.TODO(), tFile.FileKey) biz.ErrIsNil(err) go func() { - biz.ErrIsNil(d.DbSqlExecApp.ExecReader(rc.MetaCtx, &dto.SqlReaderExec{ + biz.ErrIsNil(d.dbSqlExecApp.ExecReader(rc.MetaCtx, &dto.SqlReaderExec{ Reader: reader, Filename: filename, DbConn: targetDbConn, ClientId: fm.ClientId, })) }() - } diff --git a/server/internal/db/application/db.go b/server/internal/db/application/db.go index 43d6706c..cf8ddd9f 100644 --- a/server/internal/db/application/db.go +++ b/server/internal/db/application/db.go @@ -52,20 +52,15 @@ type Db interface { type dbAppImpl struct { base.AppImpl[*entity.Db, repository.Db] - dbSqlRepo repository.DbSql `inject:"DbSqlRepo"` - dbInstanceApp Instance `inject:"DbInstanceApp"` - dbSqlExecApp DbSqlExec `inject:"DbSqlExecApp"` - tagApp tagapp.TagTree `inject:"TagTreeApp"` - resourceAuthCertApp tagapp.ResourceAuthCert `inject:"ResourceAuthCertApp"` + dbSqlRepo repository.DbSql `inject:"T"` + dbInstanceApp Instance `inject:"T"` + dbSqlExecApp DbSqlExec `inject:"T"` + tagApp tagapp.TagTree `inject:"T"` + resourceAuthCertApp tagapp.ResourceAuthCert `inject:"T"` } var _ (Db) = (*dbAppImpl)(nil) -// 注入DbRepo -func (d *dbAppImpl) InjectDbRepo(repo repository.Db) { - d.Repo = repo -} - // 分页获取数据库信息列表 func (d *dbAppImpl) GetPageList(condition *entity.DbQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) { return d.GetRepo().GetDbList(condition, pageParam, toEntity, orderBy...) diff --git a/server/internal/db/application/db_data_sync.go b/server/internal/db/application/db_data_sync.go index e9792da6..1bd25e1b 100644 --- a/server/internal/db/application/db_data_sync.go +++ b/server/internal/db/application/db_data_sync.go @@ -47,15 +47,13 @@ type DataSyncTask interface { type dataSyncAppImpl struct { base.AppImpl[*entity.DataSyncTask, repository.DataSyncTask] - dbDataSyncLogRepo repository.DataSyncLog `inject:"DbDataSyncLogRepo"` + dbDataSyncLogRepo repository.DataSyncLog `inject:"T"` - dbApp Db `inject:"DbApp"` + dbApp Db `inject:"T"` } var ( - dateTimeReg = regexp.MustCompile(`^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$`) - dateTimeIsoReg = regexp.MustCompile(`^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.*$`) - whereReg = regexp.MustCompile(`(?i)where`) + whereReg = regexp.MustCompile(`(?i)where`) ) func (app *dataSyncAppImpl) InjectDbDataSyncTaskRepo(repo repository.DataSyncTask) { diff --git a/server/internal/db/application/db_instance.go b/server/internal/db/application/db_instance.go index 6d7e23b7..1ef50f36 100644 --- a/server/internal/db/application/db_instance.go +++ b/server/internal/db/application/db_instance.go @@ -47,18 +47,13 @@ type Instance interface { type instanceAppImpl struct { base.AppImpl[*entity.DbInstance, repository.Instance] - tagApp tagapp.TagTree `inject:"TagTreeApp"` - resourceAuthCertApp tagapp.ResourceAuthCert `inject:"ResourceAuthCertApp"` - dbApp Db `inject:"DbApp"` + tagApp tagapp.TagTree `inject:"T"` + resourceAuthCertApp tagapp.ResourceAuthCert `inject:"T"` + dbApp Db `inject:"T"` } var _ (Instance) = (*instanceAppImpl)(nil) -// 注入DbInstanceRepo -func (app *instanceAppImpl) InjectDbInstanceRepo(repo repository.Instance) { - app.Repo = repo -} - // GetPageList 分页获取数据库实例 func (app *instanceAppImpl) GetPageList(condition *entity.InstanceQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) { return app.GetRepo().GetInstanceList(condition, pageParam, toEntity, orderBy...) diff --git a/server/internal/db/application/db_sql.go b/server/internal/db/application/db_sql.go index 6b2db4c9..69eaf1c6 100644 --- a/server/internal/db/application/db_sql.go +++ b/server/internal/db/application/db_sql.go @@ -13,8 +13,3 @@ type DbSql interface { type dbSqlAppImpl struct { base.AppImpl[*entity.DbSql, repository.DbSql] } - -// 注入DbSqlRepo -func (d *dbSqlAppImpl) InjectDbSqlRepo(repo repository.DbSql) { - d.Repo = repo -} diff --git a/server/internal/db/application/db_sql_exec.go b/server/internal/db/application/db_sql_exec.go index b3eee6d1..08d96d8c 100644 --- a/server/internal/db/application/db_sql_exec.go +++ b/server/internal/db/application/db_sql_exec.go @@ -65,11 +65,11 @@ type DbSqlExec interface { } type dbSqlExecAppImpl struct { - dbApp Db `inject:"DbApp"` - dbSqlExecRepo repository.DbSqlExec `inject:"DbSqlExecRepo"` + dbApp Db `inject:"T"` + dbSqlExecRepo repository.DbSqlExec `inject:"T"` - flowProcdefApp flowapp.Procdef `inject:"ProcdefApp"` - msgApp msgapp.Msg `inject:"MsgApp"` + flowProcdefApp flowapp.Procdef `inject:"T"` + msgApp msgapp.Msg `inject:"T"` } func createSqlExecRecord(ctx context.Context, execSqlReq *dto.DbSqlExecReq, sql string) *entity.DbSqlExec { diff --git a/server/internal/db/application/db_transfer.go b/server/internal/db/application/db_transfer.go index 866a9b69..d5083cc5 100644 --- a/server/internal/db/application/db_transfer.go +++ b/server/internal/db/application/db_transfer.go @@ -61,14 +61,10 @@ type DbTransferTask interface { type dbTransferAppImpl struct { base.AppImpl[*entity.DbTransferTask, repository.DbTransferTask] - dbApp Db `inject:"DbApp"` - logApp sysapp.Syslog `inject:"SyslogApp"` - transferFileApp DbTransferFile `inject:"DbTransferFileApp"` - fileApp fileapp.File `inject:"FileApp"` -} - -func (app *dbTransferAppImpl) InjectDbTransferTaskRepo(repo repository.DbTransferTask) { - app.Repo = repo + dbApp Db `inject:"T"` + logApp sysapp.Syslog `inject:"T"` + transferFileApp DbTransferFile `inject:"T"` + fileApp fileapp.File `inject:"T"` } func (app *dbTransferAppImpl) GetPageList(condition *entity.DbTransferTaskQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) { diff --git a/server/internal/db/application/db_transfer_file.go b/server/internal/db/application/db_transfer_file.go index de16accb..421505a6 100644 --- a/server/internal/db/application/db_transfer_file.go +++ b/server/internal/db/application/db_transfer_file.go @@ -25,11 +25,7 @@ var _ DbTransferFile = (*dbTransferFileAppImpl)(nil) type dbTransferFileAppImpl struct { base.AppImpl[*entity.DbTransferFile, repository.DbTransferFile] - fileApp fileapp.File `inject:"FileApp"` -} - -func (app *dbTransferFileAppImpl) InjectDbTransferFileRepo(repo repository.DbTransferFile) { - app.Repo = repo + fileApp fileapp.File `inject:"T"` } func (app *dbTransferFileAppImpl) GetPageList(condition *entity.DbTransferFileQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) { diff --git a/server/internal/db/init/init.go b/server/internal/db/init/init.go index 058f1d9c..36609137 100644 --- a/server/internal/db/init/init.go +++ b/server/internal/db/init/init.go @@ -2,18 +2,18 @@ package init import ( "mayfly-go/initialize" + "mayfly-go/internal/db/api" "mayfly-go/internal/db/application" "mayfly-go/internal/db/infrastructure/persistence" - "mayfly-go/internal/db/router" ) func init() { initialize.AddInitIocFunc(func() { persistence.InitIoc() application.InitIoc() + api.InitIoc() }) - initialize.AddInitRouterFunc(router.Init) initialize.AddInitFunc(application.Init) initialize.AddTerminateFunc(Terminate) } diff --git a/server/internal/db/router/db.go b/server/internal/db/router/db.go deleted file mode 100644 index 0060c9ae..00000000 --- a/server/internal/db/router/db.go +++ /dev/null @@ -1,57 +0,0 @@ -package router - -import ( - "mayfly-go/internal/db/api" - "mayfly-go/internal/db/imsg" - "mayfly-go/pkg/biz" - "mayfly-go/pkg/ioc" - "mayfly-go/pkg/req" - - "github.com/gin-gonic/gin" -) - -func InitDbRouter(router *gin.RouterGroup) { - db := router.Group("dbs") - - d := new(api.Db) - biz.ErrIsNil(ioc.Inject(d)) - - dashbord := new(api.Dashbord) - biz.ErrIsNil(ioc.Inject(dashbord)) - - reqs := [...]*req.Conf{ - req.NewGet("dashbord", dashbord.Dashbord), - - // 获取数据库列表 - req.NewGet("", d.Dbs), - - req.NewPost("", d.Save).Log(req.NewLogSaveI(imsg.LogDbSave)), - - req.NewDelete(":dbId", d.DeleteDb).Log(req.NewLogSaveI(imsg.LogDbDelete)), - - req.NewGet(":dbId/t-create-ddl", d.GetTableDDL), - - req.NewGet(":dbId/version", d.GetVersion), - - req.NewGet(":dbId/pg/schemas", d.GetSchemas), - - req.NewPost(":dbId/exec-sql", d.ExecSql).Log(req.NewLogI(imsg.LogDbRunSql)), - - req.NewPost(":dbId/exec-sql-file", d.ExecSqlFile).Log(req.NewLogSaveI(imsg.LogDbRunSqlFile)).RequiredPermissionCode("db:sqlscript:run"), - - req.NewGet(":dbId/dump", d.DumpSql).Log(req.NewLogSaveI(imsg.LogDbDump)).NoRes(), - - req.NewGet(":dbId/t-infos", d.TableInfos), - - req.NewGet(":dbId/t-index", d.TableIndex), - - req.NewGet(":dbId/c-metadata", d.ColumnMA), - - req.NewGet(":dbId/hint-tables", d.HintTables), - - req.NewPost(":dbId/copy-table", d.CopyTable), - } - - req.BatchSetGroup(db, reqs[:]) - -} diff --git a/server/internal/db/router/db_backup.go b/server/internal/db/router/db_backup.go deleted file mode 100644 index 0874d553..00000000 --- a/server/internal/db/router/db_backup.go +++ /dev/null @@ -1,45 +0,0 @@ -package router - -import ( - "mayfly-go/internal/db/api" - "mayfly-go/pkg/biz" - "mayfly-go/pkg/ioc" - "mayfly-go/pkg/req" - - "github.com/gin-gonic/gin" -) - -func InitDbBackupRouter(router *gin.RouterGroup) { - dbs := router.Group("/dbs") - - d := &api.DbBackup{} - biz.ErrIsNil(ioc.Inject(d)) - - reqs := []*req.Conf{ - // 获取数据库备份任务 - req.NewGet(":dbId/backups", d.GetPageList), - // 创建数据库备份任务 - req.NewPost(":dbId/backups", d.Create).Log(req.NewLogSave("db-创建数据库备份任务")), - // 保存数据库备份任务 - req.NewPut(":dbId/backups/:backupId", d.Update).Log(req.NewLogSave("db-保存数据库备份任务")), - // 启用数据库备份任务 - req.NewPut(":dbId/backups/:backupId/enable", d.Enable).Log(req.NewLogSave("db-启用数据库备份任务")), - // 禁用数据库备份任务 - req.NewPut(":dbId/backups/:backupId/disable", d.Disable).Log(req.NewLogSave("db-禁用数据库备份任务")), - // 立即启动数据库备份任务 - req.NewPut(":dbId/backups/:backupId/start", d.Start).Log(req.NewLogSave("db-立即启动数据库备份任务")), - // 删除数据库备份任务 - req.NewDelete(":dbId/backups/:backupId", d.Delete), - // 获取未配置定时备份的数据库名称 - req.NewGet(":dbId/db-names-without-backup", d.GetDbNamesWithoutBackup), - - // 获取数据库备份历史 - req.NewGet(":dbId/backup-histories/", d.GetHistoryPageList), - // 从数据库备份历史中恢复数据库 - req.NewPost(":dbId/backup-histories/:backupHistoryId/restore", d.RestoreHistories), - // 删除数据库备份历史 - req.NewDelete(":dbId/backup-histories/:backupHistoryId", d.DeleteHistories), - } - - req.BatchSetGroup(dbs, reqs) -} diff --git a/server/internal/db/router/db_data_sync.go b/server/internal/db/router/db_data_sync.go deleted file mode 100644 index 0a4a2ddf..00000000 --- a/server/internal/db/router/db_data_sync.go +++ /dev/null @@ -1,45 +0,0 @@ -package router - -import ( - "mayfly-go/internal/db/api" - "mayfly-go/internal/db/imsg" - "mayfly-go/pkg/biz" - "mayfly-go/pkg/ioc" - "mayfly-go/pkg/req" - - "github.com/gin-gonic/gin" -) - -func InitDbDataSyncRouter(router *gin.RouterGroup) { - instances := router.Group("/datasync/tasks") - - d := new(api.DataSyncTask) - biz.ErrIsNil(ioc.Inject(d)) - - reqs := [...]*req.Conf{ - // 获取任务列表 /datasync - req.NewGet("", d.Tasks), - - req.NewGet(":taskId/logs", d.Logs).RequiredPermissionCode("db:sync:log"), - - // 保存任务 /datasync/save - req.NewPost("save", d.SaveTask).Log(req.NewLogSaveI(imsg.LogDataSyncSave)).RequiredPermissionCode("db:sync:save"), - - // 获取单个详情 /datasync/:taskId - req.NewGet(":taskId", d.GetTask), - - // 删除任务 /datasync/:taskId/del - req.NewDelete(":taskId/del", d.DeleteTask).Log(req.NewLogSaveI(imsg.LogDataSyncDelete)).RequiredPermissionCode("db:sync:del"), - - // 启停用任务 /datasync/status - req.NewPost(":taskId/status", d.ChangeStatus).Log(req.NewLogSaveI(imsg.LogDataSyncChangeStatus)).RequiredPermissionCode("db:sync:status"), - - // 立即执行任务 /datasync/run - req.NewPost(":taskId/run", d.Run), - - // 停止正在执行中的任务 - req.NewPost(":taskId/stop", d.Stop), - } - - req.BatchSetGroup(instances, reqs[:]) -} diff --git a/server/internal/db/router/db_restore.go b/server/internal/db/router/db_restore.go deleted file mode 100644 index cc68e668..00000000 --- a/server/internal/db/router/db_restore.go +++ /dev/null @@ -1,39 +0,0 @@ -package router - -import ( - "mayfly-go/internal/db/api" - "mayfly-go/pkg/biz" - "mayfly-go/pkg/ioc" - "mayfly-go/pkg/req" - - "github.com/gin-gonic/gin" -) - -func InitDbRestoreRouter(router *gin.RouterGroup) { - dbs := router.Group("/dbs") - - d := &api.DbRestore{} - biz.ErrIsNil(ioc.Inject(d)) - - reqs := []*req.Conf{ - // 获取数据库备份任务 - req.NewGet(":dbId/restores", d.GetPageList), - // 创建数据库备份任务 - req.NewPost(":dbId/restores", d.Create).Log(req.NewLogSave("db-创建数据库恢复任务")), - // 保存数据库备份任务 - req.NewPut(":dbId/restores/:restoreId", d.Update).Log(req.NewLogSave("db-保存数据库恢复任务")), - // 启用数据库备份任务 - req.NewPut(":dbId/restores/:restoreId/enable", d.Enable).Log(req.NewLogSave("db-启用数据库恢复任务")), - // 禁用数据库备份任务 - req.NewPut(":dbId/restores/:restoreId/disable", d.Disable).Log(req.NewLogSave("db-禁用数据库恢复任务")), - // 删除数据库备份任务 - req.NewDelete(":dbId/restores/:restoreId", d.Delete), - // 获取未配置定时恢复的数据库名称 - req.NewGet(":dbId/db-names-without-restore", d.GetDbNamesWithoutRestore), - - // 获取数据库备份历史 - req.NewGet(":dbId/restores/:restoreId/histories", d.GetHistoryPageList), - } - - req.BatchSetGroup(dbs, reqs) -} diff --git a/server/internal/db/router/db_sql.go b/server/internal/db/router/db_sql.go deleted file mode 100644 index d74bb3d4..00000000 --- a/server/internal/db/router/db_sql.go +++ /dev/null @@ -1,32 +0,0 @@ -package router - -import ( - "mayfly-go/internal/db/api" - "mayfly-go/pkg/biz" - "mayfly-go/pkg/ioc" - "mayfly-go/pkg/req" - - "github.com/gin-gonic/gin" -) - -func InitDbSqlRouter(router *gin.RouterGroup) { - db := router.Group("dbs") - - dbSql := new(api.DbSql) - biz.ErrIsNil(ioc.Inject(dbSql)) - - reqs := [...]*req.Conf{ - - // 用户sql相关 - req.NewPost(":dbId/sql", dbSql.SaveSql), - - req.NewGet(":dbId/sql", dbSql.GetSql), - - req.NewDelete(":dbId/sql", dbSql.DeleteSql), - - req.NewGet(":dbId/sql-names", dbSql.GetSqlNames), - } - - req.BatchSetGroup(db, reqs[:]) - -} diff --git a/server/internal/db/router/db_sql_exec.go b/server/internal/db/router/db_sql_exec.go deleted file mode 100644 index 7981d124..00000000 --- a/server/internal/db/router/db_sql_exec.go +++ /dev/null @@ -1,21 +0,0 @@ -package router - -import ( - "mayfly-go/internal/db/api" - "mayfly-go/pkg/biz" - "mayfly-go/pkg/ioc" - "mayfly-go/pkg/req" - - "github.com/gin-gonic/gin" -) - -func InitDbSqlExecRouter(router *gin.RouterGroup) { - db := router.Group("/dbs/sql-execs") - - d := new(api.DbSqlExec) - biz.ErrIsNil(ioc.Inject(d)) - - // 获取所有数据库sql执行记录列表 - req.NewGet("", d.DbSqlExecs).Group(db) - -} diff --git a/server/internal/db/router/db_transfer.go b/server/internal/db/router/db_transfer.go deleted file mode 100644 index 0ccf8479..00000000 --- a/server/internal/db/router/db_transfer.go +++ /dev/null @@ -1,48 +0,0 @@ -package router - -import ( - "mayfly-go/internal/db/api" - "mayfly-go/internal/db/imsg" - "mayfly-go/pkg/biz" - "mayfly-go/pkg/ioc" - "mayfly-go/pkg/req" - - "github.com/gin-gonic/gin" -) - -func InitDbTransferRouter(router *gin.RouterGroup) { - instances := router.Group("/dbTransfer") - - d := new(api.DbTransferTask) - biz.ErrIsNil(ioc.Inject(d)) - - reqs := [...]*req.Conf{ - // 获取任务列表 /datasync - req.NewGet("", d.Tasks), - - // 保存任务 /datasync/save - req.NewPost("save", d.SaveTask).Log(req.NewLogSaveI(imsg.LogDtsSave)).RequiredPermissionCode("db:transfer:save"), - - // 删除任务 /datasync/:taskId/del - req.NewDelete(":taskId/del", d.DeleteTask).Log(req.NewLogSaveI(imsg.LogDtsDelete)).RequiredPermissionCode("db:transfer:del"), - - // 启停用任务 /datasync/status - req.NewPost(":taskId/status", d.ChangeStatus).Log(req.NewLogSaveI(imsg.LogDtsChangeStatus)).RequiredPermissionCode("db:transfer:status"), - - // 立即执行任务 /datasync/run - req.NewPost(":taskId/run", d.Run).Log(req.NewLogI(imsg.LogDtsRun)).RequiredPermissionCode("db:transfer:run"), - - // 停止正在执行中的任务 - req.NewPost(":taskId/stop", d.Stop).Log(req.NewLogSaveI(imsg.LogDtsStop)).RequiredPermissionCode("db:transfer:run"), - - // 导出文件管理-列表 - req.NewGet("/files/:taskId", d.Files), - - // 导出文件管理-删除 - req.NewPost("/files/del/:fileId", d.FileDel).Log(req.NewLogSaveI(imsg.LogDtsDeleteFile)).RequiredPermissionCode("db:transfer:files:del"), - - req.NewPost("/files/run", d.FileRun).Log(req.NewLogSaveI(imsg.LogDtsRunSqlFile)).RequiredPermissionCode("db:transfer:files:run"), - } - - req.BatchSetGroup(instances, reqs[:]) -} diff --git a/server/internal/db/router/instance.go b/server/internal/db/router/instance.go deleted file mode 100644 index 35055e65..00000000 --- a/server/internal/db/router/instance.go +++ /dev/null @@ -1,41 +0,0 @@ -package router - -import ( - "mayfly-go/internal/db/api" - "mayfly-go/internal/db/imsg" - "mayfly-go/pkg/biz" - "mayfly-go/pkg/ioc" - "mayfly-go/pkg/req" - - "github.com/gin-gonic/gin" -) - -func InitInstanceRouter(router *gin.RouterGroup) { - instances := router.Group("/instances") - - d := new(api.Instance) - biz.ErrIsNil(ioc.Inject(d)) - - reqs := [...]*req.Conf{ - // 获取数据库列表 - req.NewGet("", d.Instances), - - req.NewPost("/test-conn", d.TestConn), - - req.NewPost("", d.SaveInstance).Log(req.NewLogSaveI(imsg.LogDbInstSave)), - - req.NewGet(":instanceId", d.GetInstance), - - // 获取数据库实例的所有数据库名 - req.NewPost("/databases", d.GetDatabaseNames), - - // 根据授权凭证名获取其所有库名 - req.NewGet("/databases/:ac", d.GetDatabaseNamesByAc), - - req.NewGet(":instanceId/server-info", d.GetDbServer), - - req.NewDelete(":instanceId", d.DeleteInstance).Log(req.NewLogSaveI(imsg.LogDbInstDelete)), - } - - req.BatchSetGroup(instances, reqs[:]) -} diff --git a/server/internal/db/router/router.go b/server/internal/db/router/router.go deleted file mode 100644 index 8fcee56a..00000000 --- a/server/internal/db/router/router.go +++ /dev/null @@ -1,14 +0,0 @@ -package router - -import "github.com/gin-gonic/gin" - -func Init(router *gin.RouterGroup) { - InitInstanceRouter(router) - InitDbRouter(router) - InitDbSqlRouter(router) - InitDbSqlExecRouter(router) - InitDbBackupRouter(router) - InitDbRestoreRouter(router) - InitDbDataSyncRouter(router) - InitDbTransferRouter(router) -} diff --git a/server/internal/file/api/api.go b/server/internal/file/api/api.go new file mode 100644 index 00000000..80b83614 --- /dev/null +++ b/server/internal/file/api/api.go @@ -0,0 +1,7 @@ +package api + +import "mayfly-go/pkg/ioc" + +func InitIoc() { + ioc.Register(new(File)) +} diff --git a/server/internal/file/api/file.go b/server/internal/file/api/file.go index 243b4f63..4f171878 100644 --- a/server/internal/file/api/file.go +++ b/server/internal/file/api/file.go @@ -10,7 +10,21 @@ import ( ) type File struct { - FileApp application.File `inject:""` + fileApp application.File `inject:"T"` +} + +func (f *File) ReqConfs() *req.Confs { + reqs := [...]*req.Conf{ + req.NewGet("/detail/:keys", f.GetFileByKeys).DontNeedToken(), + + req.NewGet("/:key", f.GetFileContent).DontNeedToken().NoRes(), + + req.NewPost("/upload", f.Upload).Log(req.NewLogSave("file-文件上传")), + + req.NewDelete("/:key", f.Remove).Log(req.NewLogSave("file-文件删除")), + } + + return req.NewConfs("/sys/files", reqs[:]...) } func (f *File) GetFileByKeys(rc *req.Ctx) { @@ -18,7 +32,7 @@ func (f *File) GetFileByKeys(rc *req.Ctx) { biz.NotEmpty(keysStr, "keys cannot be empty") var files []vo.SimpleFile - err := f.FileApp.ListByCondToAny(model.NewCond().In("file_key", strings.Split(keysStr, ",")), &files) + err := f.fileApp.ListByCondToAny(model.NewCond().In("file_key", strings.Split(keysStr, ",")), &files) biz.ErrIsNil(err) rc.ResData = files } @@ -27,7 +41,7 @@ func (f *File) GetFileContent(rc *req.Ctx) { key := rc.PathParam("key") biz.NotEmpty(key, "key cannot be empty") - filename, reader, err := f.FileApp.GetReader(rc.MetaCtx, key) + filename, reader, err := f.fileApp.GetReader(rc.MetaCtx, key) if err != nil { rc.GetWriter().Write([]byte(err.Error())) return @@ -43,11 +57,11 @@ func (f *File) Upload(rc *req.Ctx) { biz.ErrIsNilAppendErr(err, "read file error: %s") defer file.Close() - fileKey, err := f.FileApp.Upload(rc.MetaCtx, rc.Query("fileKey"), file.FileName(), file) + fileKey, err := f.fileApp.Upload(rc.MetaCtx, rc.Query("fileKey"), file.FileName(), file) biz.ErrIsNil(err) rc.ResData = fileKey } func (f *File) Remove(rc *req.Ctx) { - biz.ErrIsNil(f.FileApp.Remove(rc.MetaCtx, rc.PathParam("key"))) + biz.ErrIsNil(f.fileApp.Remove(rc.MetaCtx, rc.PathParam("key"))) } diff --git a/server/internal/file/init/init.go b/server/internal/file/init/init.go index d525f232..19311c23 100644 --- a/server/internal/file/init/init.go +++ b/server/internal/file/init/init.go @@ -2,15 +2,15 @@ package init import ( "mayfly-go/initialize" + "mayfly-go/internal/file/api" "mayfly-go/internal/file/application" "mayfly-go/internal/file/infrastructure/persistence" - "mayfly-go/internal/file/router" ) func init() { initialize.AddInitIocFunc(func() { persistence.InitIoc() application.InitIoc() + api.InitIoc() }) - initialize.AddInitRouterFunc(router.Init) } diff --git a/server/internal/file/router/file.go b/server/internal/file/router/file.go deleted file mode 100644 index 28ce087a..00000000 --- a/server/internal/file/router/file.go +++ /dev/null @@ -1,29 +0,0 @@ -package router - -import ( - "mayfly-go/internal/file/api" - "mayfly-go/pkg/biz" - "mayfly-go/pkg/ioc" - "mayfly-go/pkg/req" - - "github.com/gin-gonic/gin" -) - -func InitFileRouter(router *gin.RouterGroup) { - file := router.Group("sys/files") - f := new(api.File) - biz.ErrIsNil(ioc.Inject(f)) - - reqs := [...]*req.Conf{ - - req.NewGet("/detail/:keys", f.GetFileByKeys).DontNeedToken(), - - req.NewGet("/:key", f.GetFileContent).DontNeedToken().NoRes(), - - req.NewPost("/upload", f.Upload).Log(req.NewLogSave("file-文件上传")), - - req.NewDelete("/:key", f.Remove).Log(req.NewLogSave("file-文件删除")), - } - - req.BatchSetGroup(file, reqs[:]) -} diff --git a/server/internal/file/router/router.go b/server/internal/file/router/router.go deleted file mode 100644 index cd1af4c1..00000000 --- a/server/internal/file/router/router.go +++ /dev/null @@ -1,9 +0,0 @@ -package router - -import ( - "github.com/gin-gonic/gin" -) - -func Init(router *gin.RouterGroup) { - InitFileRouter(router) -} diff --git a/server/internal/flow/api/api.go b/server/internal/flow/api/api.go new file mode 100644 index 00000000..091b948e --- /dev/null +++ b/server/internal/flow/api/api.go @@ -0,0 +1,8 @@ +package api + +import "mayfly-go/pkg/ioc" + +func InitIoc() { + ioc.Register(new(Procdef)) + ioc.Register(new(Procinst)) +} diff --git a/server/internal/flow/api/procdef.go b/server/internal/flow/api/procdef.go index 53c99e99..cefd7ad4 100644 --- a/server/internal/flow/api/procdef.go +++ b/server/internal/flow/api/procdef.go @@ -6,6 +6,7 @@ import ( "mayfly-go/internal/flow/application" "mayfly-go/internal/flow/application/dto" "mayfly-go/internal/flow/domain/entity" + "mayfly-go/internal/flow/imsg" tagapp "mayfly-go/internal/tag/application" tagentity "mayfly-go/internal/tag/domain/entity" "mayfly-go/pkg/biz" @@ -17,17 +18,31 @@ import ( ) type Procdef struct { - ProcdefApp application.Procdef `inject:""` - TagTreeRelateApp tagapp.TagTreeRelate `inject:"TagTreeRelateApp"` + procdefApp application.Procdef `inject:"T"` + tagTreeRelateApp tagapp.TagTreeRelate `inject:"T"` +} + +func (p *Procdef) ReqConfs() *req.Confs { + reqs := [...]*req.Conf{ + req.NewGet("", p.GetProcdefPage), + + req.NewGet("/:resourceType/:resourceCode", p.GetProcdef), + + req.NewPost("", p.Save).Log(req.NewLogSaveI(imsg.LogProcdefSave)).RequiredPermissionCode("flow:procdef:save"), + + req.NewDelete(":id", p.Delete).Log(req.NewLogSaveI(imsg.LogProcdefDelete)).RequiredPermissionCode("flow:procdef:del"), + } + + return req.NewConfs("/flow/procdefs", reqs[:]...) } func (p *Procdef) GetProcdefPage(rc *req.Ctx) { cond, page := req.BindQueryAndPage(rc, new(entity.Procdef)) var procdefs []*vo.Procdef - res, err := p.ProcdefApp.GetPageList(cond, page, &procdefs) + res, err := p.procdefApp.GetPageList(cond, page, &procdefs) biz.ErrIsNil(err) - p.TagTreeRelateApp.FillTagInfo(tagentity.TagRelateTypeFlowDef, collx.ArrayMap(procdefs, func(mvo *vo.Procdef) tagentity.IRelateTag { + p.tagTreeRelateApp.FillTagInfo(tagentity.TagRelateTypeFlowDef, collx.ArrayMap(procdefs, func(mvo *vo.Procdef) tagentity.IRelateTag { return mvo })...) @@ -37,14 +52,14 @@ func (p *Procdef) GetProcdefPage(rc *req.Ctx) { func (p *Procdef) GetProcdef(rc *req.Ctx) { resourceType := rc.PathParamInt("resourceType") resourceCode := rc.PathParam("resourceCode") - rc.ResData = p.ProcdefApp.GetProcdefByResource(rc.MetaCtx, int8(resourceType), resourceCode) + rc.ResData = p.procdefApp.GetProcdefByResource(rc.MetaCtx, int8(resourceType), resourceCode) } func (a *Procdef) Save(rc *req.Ctx) { form := &form.Procdef{} procdef := req.BindJsonAndCopyTo(rc, form, new(entity.Procdef)) rc.ReqParam = form - biz.ErrIsNil(a.ProcdefApp.SaveProcdef(rc.MetaCtx, &dto.SaveProcdef{ + biz.ErrIsNil(a.procdefApp.SaveProcdef(rc.MetaCtx, &dto.SaveProcdef{ Procdef: procdef, CodePaths: form.CodePaths, })) @@ -56,6 +71,6 @@ func (p *Procdef) Delete(rc *req.Ctx) { ids := strings.Split(idsStr, ",") for _, v := range ids { - biz.ErrIsNilAppendErr(p.ProcdefApp.DeleteProcdef(rc.MetaCtx, cast.ToUint64(v)), "delete error: %s") + biz.ErrIsNilAppendErr(p.procdefApp.DeleteProcdef(rc.MetaCtx, cast.ToUint64(v)), "delete error: %s") } } diff --git a/server/internal/flow/api/procinst.go b/server/internal/flow/api/procinst.go index 58119715..45b0d521 100644 --- a/server/internal/flow/api/procinst.go +++ b/server/internal/flow/api/procinst.go @@ -9,6 +9,7 @@ import ( "mayfly-go/internal/flow/application/dto" "mayfly-go/internal/flow/domain/entity" "mayfly-go/internal/flow/domain/repository" + "mayfly-go/internal/flow/imsg" "mayfly-go/pkg/biz" "mayfly-go/pkg/req" "mayfly-go/pkg/utils/collx" @@ -17,10 +18,32 @@ import ( ) type Procinst struct { - ProcinstApp application.Procinst `inject:""` - ProcdefApp application.Procdef `inject:""` + procinstApp application.Procinst `inject:"T"` + procdefApp application.Procdef `inject:"T"` - ProcinstTaskRepo repository.ProcinstTask `inject:""` + procinstTaskRepo repository.ProcinstTask `inject:"T"` +} + +func (p *Procinst) ReqConfs() *req.Confs { + reqs := [...]*req.Conf{ + req.NewGet("", p.GetProcinstPage), + + req.NewGet("/:id", p.GetProcinstDetail), + + req.NewPost("/start", p.ProcinstStart).Log(req.NewLogSaveI(imsg.LogProcinstStart)), + + req.NewPost("/:id/cancel", p.ProcinstCancel).Log(req.NewLogSaveI(imsg.LogProcinstCancel)), + + req.NewGet("/tasks", p.GetTasks), + + req.NewPost("/tasks/complete", p.CompleteTask).Log(req.NewLogSaveI(imsg.LogCompleteTask)), + + req.NewPost("/tasks/reject", p.RejectTask).Log(req.NewLogSaveI(imsg.LogRejectTask)), + + req.NewPost("/tasks/back", p.BackTask).Log(req.NewLogSaveI(imsg.LogBackTask)), + } + + return req.NewConfs("/flow/procinsts", reqs[:]...) } func (p *Procinst) GetProcinstPage(rc *req.Ctx) { @@ -30,7 +53,7 @@ func (p *Procinst) GetProcinstPage(rc *req.Ctx) { cond.CreatorId = laId } - res, err := p.ProcinstApp.GetPageList(cond, page, new([]entity.Procinst)) + res, err := p.procinstApp.GetPageList(cond, page, new([]entity.Procinst)) biz.ErrIsNil(err) rc.ResData = res } @@ -38,7 +61,7 @@ func (p *Procinst) GetProcinstPage(rc *req.Ctx) { func (p *Procinst) ProcinstStart(rc *req.Ctx) { startForm := new(form.ProcinstStart) req.BindJsonAndValid(rc, startForm) - _, err := p.ProcinstApp.StartProc(rc.MetaCtx, startForm.ProcdefId, &dto.StarProc{ + _, err := p.procinstApp.StartProc(rc.MetaCtx, startForm.ProcdefId, &dto.StarProc{ BizType: startForm.BizType, BizForm: jsonx.ToStr(startForm.BizForm), Remark: startForm.Remark, @@ -49,21 +72,21 @@ func (p *Procinst) ProcinstStart(rc *req.Ctx) { func (p *Procinst) ProcinstCancel(rc *req.Ctx) { instId := uint64(rc.PathParamInt("id")) rc.ReqParam = instId - biz.ErrIsNil(p.ProcinstApp.CancelProc(rc.MetaCtx, instId)) + biz.ErrIsNil(p.procinstApp.CancelProc(rc.MetaCtx, instId)) } func (p *Procinst) GetProcinstDetail(rc *req.Ctx) { - pi, err := p.ProcinstApp.GetById(uint64(rc.PathParamInt("id"))) + pi, err := p.procinstApp.GetById(uint64(rc.PathParamInt("id"))) biz.ErrIsNil(err, "procinst not found") pivo := new(vo.ProcinstVO) structx.Copy(pivo, pi) // 流程定义信息 - procdef, _ := p.ProcdefApp.GetById(pi.ProcdefId) + procdef, _ := p.procdefApp.GetById(pi.ProcdefId) pivo.Procdef = procdef // 流程实例任务信息 - instTasks, err := p.ProcinstTaskRepo.SelectByCond(&entity.ProcinstTask{ProcinstId: pi.Id}) + instTasks, err := p.procinstTaskRepo.SelectByCond(&entity.ProcinstTask{ProcinstId: pi.Id}) biz.ErrIsNil(err) pivo.ProcinstTasks = instTasks @@ -78,11 +101,11 @@ func (p *Procinst) GetTasks(rc *req.Ctx) { } taskVos := new([]*vo.ProcinstTask) - res, err := p.ProcinstApp.GetProcinstTasks(instTaskQuery, page, taskVos) + res, err := p.procinstApp.GetProcinstTasks(instTaskQuery, page, taskVos) biz.ErrIsNil(err) instIds := collx.ArrayMap[*vo.ProcinstTask, uint64](*taskVos, func(val *vo.ProcinstTask) uint64 { return val.ProcinstId }) - insts, _ := p.ProcinstApp.GetByIds(instIds) + insts, _ := p.procinstApp.GetByIds(instIds) instId2Inst := collx.ArrayToMap[*entity.Procinst, uint64](insts, func(val *entity.Procinst) uint64 { return val.Id }) // 赋值任务对应的流程实例 @@ -95,17 +118,17 @@ func (p *Procinst) GetTasks(rc *req.Ctx) { func (p *Procinst) CompleteTask(rc *req.Ctx) { auditForm := req.BindJsonAndValid(rc, new(form.ProcinstTaskAudit)) rc.ReqParam = auditForm - biz.ErrIsNil(p.ProcinstApp.CompleteTask(rc.MetaCtx, auditForm.Id, auditForm.Remark)) + biz.ErrIsNil(p.procinstApp.CompleteTask(rc.MetaCtx, auditForm.Id, auditForm.Remark)) } func (p *Procinst) RejectTask(rc *req.Ctx) { auditForm := req.BindJsonAndValid(rc, new(form.ProcinstTaskAudit)) rc.ReqParam = auditForm - biz.ErrIsNil(p.ProcinstApp.RejectTask(rc.MetaCtx, auditForm.Id, auditForm.Remark)) + biz.ErrIsNil(p.procinstApp.RejectTask(rc.MetaCtx, auditForm.Id, auditForm.Remark)) } func (p *Procinst) BackTask(rc *req.Ctx) { auditForm := req.BindJsonAndValid(rc, new(form.ProcinstTaskAudit)) rc.ReqParam = auditForm - biz.ErrIsNil(p.ProcinstApp.BackTask(rc.MetaCtx, auditForm.Id, auditForm.Remark)) + biz.ErrIsNil(p.procinstApp.BackTask(rc.MetaCtx, auditForm.Id, auditForm.Remark)) } diff --git a/server/internal/flow/application/procdef.go b/server/internal/flow/application/procdef.go index 05fe7165..dd1dcc71 100644 --- a/server/internal/flow/application/procdef.go +++ b/server/internal/flow/application/procdef.go @@ -34,10 +34,10 @@ type Procdef interface { type procdefAppImpl struct { base.AppImpl[*entity.Procdef, repository.Procdef] - procinstApp Procinst `inject:"ProcinstApp"` + procinstApp Procinst `inject:"T"` - tagTreeApp tagapp.TagTree `inject:"TagTreeApp"` - tagTreeRelateApp tagapp.TagTreeRelate `inject:"TagTreeRelateApp"` + tagTreeApp tagapp.TagTree `inject:"T"` + tagTreeRelateApp tagapp.TagTreeRelate `inject:"T"` } var _ (Procdef) = (*procdefAppImpl)(nil) diff --git a/server/internal/flow/application/procinst.go b/server/internal/flow/application/procinst.go index 80d84e4e..67ad5dfa 100644 --- a/server/internal/flow/application/procinst.go +++ b/server/internal/flow/application/procinst.go @@ -45,8 +45,8 @@ type Procinst interface { type procinstAppImpl struct { base.AppImpl[*entity.Procinst, repository.Procinst] - procinstTaskRepo repository.ProcinstTask `inject:"ProcinstTaskRepo"` - procdefApp Procdef `inject:"ProcdefApp"` + procinstTaskRepo repository.ProcinstTask `inject:"T"` + procdefApp Procdef `inject:"T"` } var _ (Procinst) = (*procinstAppImpl)(nil) diff --git a/server/internal/flow/init/init.go b/server/internal/flow/init/init.go index 2e3ef3d6..a652156d 100644 --- a/server/internal/flow/init/init.go +++ b/server/internal/flow/init/init.go @@ -2,15 +2,15 @@ package init import ( "mayfly-go/initialize" + "mayfly-go/internal/flow/api" "mayfly-go/internal/flow/application" "mayfly-go/internal/flow/infrastructure/persistence" - "mayfly-go/internal/flow/router" ) func init() { initialize.AddInitIocFunc(func() { persistence.InitIoc() application.InitIoc() + api.InitIoc() }) - initialize.AddInitRouterFunc(router.Init) } diff --git a/server/internal/flow/router/procdef.go b/server/internal/flow/router/procdef.go deleted file mode 100644 index 397bc698..00000000 --- a/server/internal/flow/router/procdef.go +++ /dev/null @@ -1,31 +0,0 @@ -package router - -import ( - "mayfly-go/internal/flow/api" - "mayfly-go/internal/flow/imsg" - "mayfly-go/pkg/biz" - "mayfly-go/pkg/ioc" - "mayfly-go/pkg/req" - - "github.com/gin-gonic/gin" -) - -func InitProcdefouter(router *gin.RouterGroup) { - p := new(api.Procdef) - biz.ErrIsNil(ioc.Inject(p)) - - reqGroup := router.Group("/flow/procdefs") - { - reqs := [...]*req.Conf{ - req.NewGet("", p.GetProcdefPage), - - req.NewGet("/:resourceType/:resourceCode", p.GetProcdef), - - req.NewPost("", p.Save).Log(req.NewLogSaveI(imsg.LogProcdefSave)).RequiredPermissionCode("flow:procdef:save"), - - req.NewDelete(":id", p.Delete).Log(req.NewLogSaveI(imsg.LogProcdefDelete)).RequiredPermissionCode("flow:procdef:del"), - } - - req.BatchSetGroup(reqGroup, reqs[:]) - } -} diff --git a/server/internal/flow/router/procinst.go b/server/internal/flow/router/procinst.go deleted file mode 100644 index 4607f686..00000000 --- a/server/internal/flow/router/procinst.go +++ /dev/null @@ -1,39 +0,0 @@ -package router - -import ( - "mayfly-go/internal/flow/api" - "mayfly-go/internal/flow/imsg" - "mayfly-go/pkg/biz" - "mayfly-go/pkg/ioc" - "mayfly-go/pkg/req" - - "github.com/gin-gonic/gin" -) - -func InitProcinstRouter(router *gin.RouterGroup) { - p := new(api.Procinst) - biz.ErrIsNil(ioc.Inject(p)) - - reqGroup := router.Group("/flow/procinsts") - { - reqs := [...]*req.Conf{ - req.NewGet("", p.GetProcinstPage), - - req.NewGet("/:id", p.GetProcinstDetail), - - req.NewPost("/start", p.ProcinstStart).Log(req.NewLogSaveI(imsg.LogProcinstStart)), - - req.NewPost("/:id/cancel", p.ProcinstCancel).Log(req.NewLogSaveI(imsg.LogProcinstCancel)), - - req.NewGet("/tasks", p.GetTasks), - - req.NewPost("/tasks/complete", p.CompleteTask).Log(req.NewLogSaveI(imsg.LogCompleteTask)), - - req.NewPost("/tasks/reject", p.RejectTask).Log(req.NewLogSaveI(imsg.LogRejectTask)), - - req.NewPost("/tasks/back", p.BackTask).Log(req.NewLogSaveI(imsg.LogBackTask)), - } - - req.BatchSetGroup(reqGroup, reqs[:]) - } -} diff --git a/server/internal/flow/router/router.go b/server/internal/flow/router/router.go deleted file mode 100644 index 40606ccb..00000000 --- a/server/internal/flow/router/router.go +++ /dev/null @@ -1,8 +0,0 @@ -package router - -import "github.com/gin-gonic/gin" - -func Init(router *gin.RouterGroup) { - InitProcdefouter(router) - InitProcinstRouter(router) -} diff --git a/server/internal/machine/api/api.go b/server/internal/machine/api/api.go new file mode 100644 index 00000000..6baec5e9 --- /dev/null +++ b/server/internal/machine/api/api.go @@ -0,0 +1,12 @@ +package api + +import "mayfly-go/pkg/ioc" + +func InitIoc() { + ioc.Register(new(Dashbord)) + ioc.Register(new(Machine)) + ioc.Register(new(MachineFile)) + ioc.Register(new(MachineScript)) + ioc.Register(new(MachineCronJob)) + ioc.Register(new(MachineCmdConf)) +} diff --git a/server/internal/machine/api/dashbord.go b/server/internal/machine/api/dashbord.go index acf9538a..d1ca8d81 100644 --- a/server/internal/machine/api/dashbord.go +++ b/server/internal/machine/api/dashbord.go @@ -1,23 +1,28 @@ package api import ( - "mayfly-go/internal/machine/application" tagapp "mayfly-go/internal/tag/application" - "mayfly-go/internal/tag/domain/entity" tagentity "mayfly-go/internal/tag/domain/entity" "mayfly-go/pkg/req" "mayfly-go/pkg/utils/collx" ) type Dashbord struct { - TagTreeApp tagapp.TagTree `inject:""` - MachineApp application.Machine `inject:""` + tagTreeApp tagapp.TagTree `inject:"T"` +} + +func (d *Dashbord) ReqConfs() *req.Confs { + reqs := [...]*req.Conf{ + req.NewGet("/machines/dashbord", d.Dashbord), + } + + return req.NewConfs("", reqs[:]...) } func (m *Dashbord) Dashbord(rc *req.Ctx) { accountId := rc.GetLoginAccount().Id - tagCodePaths := m.TagTreeApp.GetAccountTags(accountId, &tagentity.TagTreeQuery{TypePaths: collx.AsArray(entity.NewTypePaths(tagentity.TagTypeMachine, tagentity.TagTypeAuthCert))}).GetCodePaths() + tagCodePaths := m.tagTreeApp.GetAccountTags(accountId, &tagentity.TagTreeQuery{TypePaths: collx.AsArray(tagentity.NewTypePaths(tagentity.TagTypeMachine, tagentity.TagTypeAuthCert))}).GetCodePaths() machineCodes := tagentity.GetCodesByCodePaths(tagentity.TagTypeMachine, tagCodePaths...) rc.ResData = collx.M{ diff --git a/server/internal/machine/api/machine.go b/server/internal/machine/api/machine.go index 7ab6fd6c..9a6728ed 100644 --- a/server/internal/machine/api/machine.go +++ b/server/internal/machine/api/machine.go @@ -28,22 +28,58 @@ import ( "strings" "time" - "github.com/gin-gonic/gin" "github.com/gorilla/websocket" "github.com/may-fly/cast" ) type Machine struct { - MachineApp application.Machine `inject:""` - MachineTermOpApp application.MachineTermOp `inject:""` - TagApp tagapp.TagTree `inject:"TagTreeApp"` - ResourceAuthCertApp tagapp.ResourceAuthCert `inject:""` + machineApp application.Machine `inject:"T"` + machineTermOpApp application.MachineTermOp `inject:"T"` + tagTreeApp tagapp.TagTree `inject:"T"` + resourceAuthCertApp tagapp.ResourceAuthCert `inject:"T"` +} + +func (m *Machine) ReqConfs() *req.Confs { + saveMachineP := req.NewPermission("machine:update") + + reqs := [...]*req.Conf{ + req.NewGet("", m.Machines), + + req.NewGet("/simple", m.SimpleMachieInfo), + + req.NewGet(":machineId/stats", m.MachineStats), + + req.NewGet(":machineId/process", m.GetProcess), + + req.NewGet(":machineId/users", m.GetUsers), + + req.NewGet(":machineId/groups", m.GetGroups), + + req.NewPost("", m.SaveMachine).Log(req.NewLogSaveI(imsg.LogMachineSave)).RequiredPermission(saveMachineP), + + req.NewDelete(":machineId", m.DeleteMachine).Log(req.NewLogSaveI(imsg.LogMachineSave)), + + req.NewPost("test-conn", m.TestConn), + + req.NewPut(":machineId/:status", m.ChangeStatus).Log(req.NewLogSaveI(imsg.LogMachineChangeStatus)).RequiredPermission(saveMachineP), + + req.NewDelete(":machineId/process", m.KillProcess).Log(req.NewLogSaveI(imsg.LogMachineKillProcess)).RequiredPermissionCode("machine:killprocess"), + + // 获取机器终端回放记录列表,目前具有保存机器信息的权限标识才有权限查看终端回放 + req.NewGet(":machineId/term-recs", m.MachineTermOpRecords).RequiredPermission(saveMachineP), + + // 终端操作 + req.NewGet("terminal/:ac", m.WsSSH), + req.NewGet("rdp/:ac", m.WsGuacamole), + } + + return req.NewConfs("machines", reqs[:]...) } func (m *Machine) Machines(rc *req.Ctx) { condition, pageParam := req.BindQueryAndPage(rc, new(entity.MachineQuery)) - tags := m.TagApp.GetAccountTags(rc.GetLoginAccount().Id, &tagentity.TagTreeQuery{ + tags := m.tagTreeApp.GetAccountTags(rc.GetLoginAccount().Id, &tagentity.TagTreeQuery{ TypePaths: collx.AsArray(tagentity.NewTypePaths(tagentity.TagTypeMachine, tagentity.TagTypeAuthCert)), CodePathLikes: collx.AsArray(condition.TagPath), }) @@ -58,7 +94,7 @@ func (m *Machine) Machines(rc *req.Ctx) { condition.Codes = collx.ArrayDeduplicate(machineCodes) var machinevos []*vo.MachineVO - res, err := m.MachineApp.GetMachineList(condition, pageParam, &machinevos) + res, err := m.machineApp.GetMachineList(condition, pageParam, &machinevos) biz.ErrIsNil(err) if res.Total == 0 { rc.ResData = res @@ -66,17 +102,17 @@ func (m *Machine) Machines(rc *req.Ctx) { } // 填充标签信息 - m.TagApp.FillTagInfo(tagentity.TagType(consts.ResourceTypeMachine), collx.ArrayMap(machinevos, func(mvo *vo.MachineVO) tagentity.ITagResource { + m.tagTreeApp.FillTagInfo(tagentity.TagType(consts.ResourceTypeMachine), collx.ArrayMap(machinevos, func(mvo *vo.MachineVO) tagentity.ITagResource { return mvo })...) // 填充授权凭证信息 - m.ResourceAuthCertApp.FillAuthCertByAcNames(tagentity.GetCodesByCodePaths(tagentity.TagTypeAuthCert, tagCodePaths...), collx.ArrayMap(machinevos, func(mvo *vo.MachineVO) tagentity.IAuthCert { + m.resourceAuthCertApp.FillAuthCertByAcNames(tagentity.GetCodesByCodePaths(tagentity.TagTypeAuthCert, tagCodePaths...), collx.ArrayMap(machinevos, func(mvo *vo.MachineVO) tagentity.IAuthCert { return mvo })...) for _, mv := range machinevos { - if machineStats, err := m.MachineApp.GetMachineStats(mv.Id); err == nil { + if machineStats, err := m.machineApp.GetMachineStats(mv.Id); err == nil { mv.Stat = collx.M{ "cpuIdle": machineStats.CPU.Idle, "memAvailable": machineStats.MemInfo.Available, @@ -93,12 +129,12 @@ func (m *Machine) SimpleMachieInfo(rc *req.Ctx) { biz.NotEmpty(machineCodesStr, "codes cannot be empty") var vos []vo.SimpleMachineVO - m.MachineApp.ListByCondToAny(model.NewCond().In("code", strings.Split(machineCodesStr, ",")), &vos) + m.machineApp.ListByCondToAny(model.NewCond().In("code", strings.Split(machineCodesStr, ",")), &vos) rc.ResData = vos } func (m *Machine) MachineStats(rc *req.Ctx) { - cli, err := m.MachineApp.GetCli(GetMachineId(rc)) + cli, err := m.machineApp.GetCli(GetMachineId(rc)) biz.ErrIsNilAppendErr(err, "connection error: %s") rc.ResData = cli.GetAllStats() } @@ -110,7 +146,7 @@ func (m *Machine) SaveMachine(rc *req.Ctx) { rc.ReqParam = machineForm - biz.ErrIsNil(m.MachineApp.SaveMachine(rc.MetaCtx, &dto.SaveMachine{ + biz.ErrIsNil(m.machineApp.SaveMachine(rc.MetaCtx, &dto.SaveMachine{ Machine: me, TagCodePaths: machineForm.TagCodePaths, AuthCerts: machineForm.AuthCerts, @@ -121,14 +157,14 @@ func (m *Machine) TestConn(rc *req.Ctx) { machineForm := new(form.MachineForm) me := req.BindJsonAndCopyTo(rc, machineForm, new(entity.Machine)) // 测试连接 - biz.ErrIsNilAppendErr(m.MachineApp.TestConn(me, machineForm.AuthCerts[0]), "connection error: %s") + biz.ErrIsNilAppendErr(m.machineApp.TestConn(me, machineForm.AuthCerts[0]), "connection error: %s") } func (m *Machine) ChangeStatus(rc *req.Ctx) { id := uint64(rc.PathParamInt("machineId")) status := int8(rc.PathParamInt("status")) rc.ReqParam = collx.Kvs("id", id, "status", status) - biz.ErrIsNil(m.MachineApp.ChangeStatus(rc.MetaCtx, id, status)) + biz.ErrIsNil(m.machineApp.ChangeStatus(rc.MetaCtx, id, status)) } func (m *Machine) DeleteMachine(rc *req.Ctx) { @@ -137,7 +173,7 @@ func (m *Machine) DeleteMachine(rc *req.Ctx) { ids := strings.Split(idsStr, ",") for _, v := range ids { - m.MachineApp.Delete(rc.MetaCtx, cast.ToUint64(v)) + m.machineApp.Delete(rc.MetaCtx, cast.ToUint64(v)) } } @@ -159,9 +195,9 @@ func (m *Machine) GetProcess(rc *req.Ctx) { count := rc.QueryIntDefault("count", 10) cmd += "| head -n " + fmt.Sprintf("%d", count) - cli, err := m.MachineApp.GetCli(GetMachineId(rc)) + cli, err := m.machineApp.GetCli(GetMachineId(rc)) biz.ErrIsNilAppendErr(err, "connection error: %s") - biz.ErrIsNilAppendErr(m.TagApp.CanAccess(rc.GetLoginAccount().Id, cli.Info.CodePath...), "%s") + biz.ErrIsNilAppendErr(m.tagTreeApp.CanAccess(rc.GetLoginAccount().Id, cli.Info.CodePath...), "%s") res, err := cli.Run(cmd) biz.ErrIsNil(err) @@ -173,16 +209,16 @@ func (m *Machine) KillProcess(rc *req.Ctx) { pid := rc.Query("pid") biz.NotEmpty(pid, "pid cannot be empty") - cli, err := m.MachineApp.GetCli(GetMachineId(rc)) + cli, err := m.machineApp.GetCli(GetMachineId(rc)) biz.ErrIsNilAppendErr(err, "connection error: %s") - biz.ErrIsNilAppendErr(m.TagApp.CanAccess(rc.GetLoginAccount().Id, cli.Info.CodePath...), "%s") + biz.ErrIsNilAppendErr(m.tagTreeApp.CanAccess(rc.GetLoginAccount().Id, cli.Info.CodePath...), "%s") res, err := cli.Run("sudo kill -9 " + pid) biz.ErrIsNil(err, "kill fail: %s", res) } func (m *Machine) GetUsers(rc *req.Ctx) { - cli, err := m.MachineApp.GetCli(GetMachineId(rc)) + cli, err := m.machineApp.GetCli(GetMachineId(rc)) biz.ErrIsNilAppendErr(err, "connection error: %s") res, err := cli.GetUsers() biz.ErrIsNil(err) @@ -190,15 +226,15 @@ func (m *Machine) GetUsers(rc *req.Ctx) { } func (m *Machine) GetGroups(rc *req.Ctx) { - cli, err := m.MachineApp.GetCli(GetMachineId(rc)) + cli, err := m.machineApp.GetCli(GetMachineId(rc)) biz.ErrIsNilAppendErr(err, "connection error: %s") res, err := cli.GetGroups() biz.ErrIsNil(err) rc.ResData = res } -func (m *Machine) WsSSH(g *gin.Context) { - wsConn, err := ws.Upgrader.Upgrade(g.Writer, g.Request, nil) +func (m *Machine) WsSSH(rc *req.Ctx) { + wsConn, err := ws.Upgrader.Upgrade(rc.GetWriter(), rc.GetRequest(), nil) defer func() { if wsConn != nil { if err := recover(); err != nil { @@ -211,15 +247,15 @@ func (m *Machine) WsSSH(g *gin.Context) { wsConn.WriteMessage(websocket.TextMessage, []byte("Connecting to host...")) // 权限校验 - rc := req.NewCtxWithGin(g).WithRequiredPermission(req.NewPermission("machine:terminal")) + rc = rc.WithRequiredPermission(req.NewPermission("machine:terminal")) if err = req.PermissionHandler(rc); err != nil { panic(errorx.NewBiz(mcm.GetErrorContentRn("You do not have permission to operate the machine terminal, please log in again and try again ~"))) } - cli, err := m.MachineApp.NewCli(GetMachineAc(rc)) + cli, err := m.machineApp.NewCli(GetMachineAc(rc)) biz.ErrIsNilAppendErr(err, mcm.GetErrorContentRn("connection error: %s")) defer cli.Close() - biz.ErrIsNilAppendErr(m.TagApp.CanAccess(rc.GetLoginAccount().Id, cli.Info.CodePath...), mcm.GetErrorContentRn("%s")) + biz.ErrIsNilAppendErr(m.tagTreeApp.CanAccess(rc.GetLoginAccount().Id, cli.Info.CodePath...), mcm.GetErrorContentRn("%s")) global.EventBus.Publish(rc.MetaCtx, event.EventTopicResourceOp, cli.Info.CodePath[0]) @@ -231,13 +267,13 @@ func (m *Machine) WsSSH(g *gin.Context) { rc.ReqParam = cli.Info req.LogHandler(rc) - err = m.MachineTermOpApp.TermConn(rc.MetaCtx, cli, wsConn, rows, cols) + err = m.machineTermOpApp.TermConn(rc.MetaCtx, cli, wsConn, rows, cols) biz.ErrIsNilAppendErr(err, mcm.GetErrorContentRn("connect fail: %s")) } func (m *Machine) MachineTermOpRecords(rc *req.Ctx) { mid := GetMachineId(rc) - res, err := m.MachineTermOpApp.GetPageList(&entity.MachineTermOp{MachineId: mid}, rc.GetPageParam(), new([]entity.MachineTermOp)) + res, err := m.machineTermOpApp.GetPageList(&entity.MachineTermOp{MachineId: mid}, rc.GetPageParam(), new([]entity.MachineTermOp)) biz.ErrIsNil(err) rc.ResData = res } @@ -253,7 +289,7 @@ var ( sessions = guac.NewMemorySessionStore() ) -func (m *Machine) WsGuacamole(g *gin.Context) { +func (m *Machine) WsGuacamole(rc *req.Ctx) { upgrader := websocket.Upgrader{ ReadBufferSize: websocketReadBufferSize, WriteBufferSize: websocketWriteBufferSize, @@ -261,17 +297,21 @@ func (m *Machine) WsGuacamole(g *gin.Context) { return true }, } - wsConn, err := upgrader.Upgrade(g.Writer, g.Request, nil) + + reqWriter := rc.GetWriter() + request := rc.GetRequest() + + wsConn, err := upgrader.Upgrade(reqWriter, request, nil) biz.ErrIsNil(err) - rc := req.NewCtxWithGin(g).WithRequiredPermission(req.NewPermission("machine:terminal")) + rc = rc.WithRequiredPermission(req.NewPermission("machine:terminal")) if err = req.PermissionHandler(rc); err != nil { panic(errorx.NewBiz(mcm.GetErrorContentRn("You do not have permission to operate the machine terminal, please log in again and try again ~"))) } ac := GetMachineAc(rc) - mi, err := m.MachineApp.ToMachineInfoByAc(ac) + mi, err := m.machineApp.ToMachineInfoByAc(ac) if err != nil { return } @@ -307,10 +347,9 @@ func (m *Machine) WsGuacamole(g *gin.Context) { } }() - query := g.Request.URL.Query() - if query.Get("force") != "" { + if rc.Query("force") != "" { // 判断是否强制连接,是的话,查询是否有正在连接的会话,有的话强制关闭 - if cast.ToBool(query.Get("force")) { + if cast.ToBool(rc.Query("force")) { tn := sessions.Get(ac) if tn != nil { _ = tn.Close() @@ -318,7 +357,7 @@ func (m *Machine) WsGuacamole(g *gin.Context) { } } - tunnel, err := guac.DoConnect(query, params, rc.GetLoginAccount().Username) + tunnel, err := guac.DoConnect(request.URL.Query(), params, rc.GetLoginAccount().Username) if err != nil { return } @@ -328,9 +367,9 @@ func (m *Machine) WsGuacamole(g *gin.Context) { } }() - sessions.Add(ac, wsConn, g.Request, tunnel) + sessions.Add(ac, wsConn, request, tunnel) - defer sessions.Delete(ac, wsConn, g.Request, tunnel) + defer sessions.Delete(ac, wsConn, request, tunnel) writer := tunnel.AcquireWriter() reader := tunnel.AcquireReader() diff --git a/server/internal/machine/api/machine_cmd_conf.go b/server/internal/machine/api/machine_cmd_conf.go index 610f5085..541f7578 100644 --- a/server/internal/machine/api/machine_cmd_conf.go +++ b/server/internal/machine/api/machine_cmd_conf.go @@ -6,6 +6,7 @@ import ( "mayfly-go/internal/machine/application" "mayfly-go/internal/machine/application/dto" "mayfly-go/internal/machine/domain/entity" + "mayfly-go/internal/machine/imsg" tagapp "mayfly-go/internal/tag/application" tagentity "mayfly-go/internal/tag/domain/entity" @@ -15,18 +16,30 @@ import ( ) type MachineCmdConf struct { - MachineCmdConfApp application.MachineCmdConf `inject:""` - TagTreeRelateApp tagapp.TagTreeRelate `inject:"TagTreeRelateApp"` + machineCmdConfApp application.MachineCmdConf `inject:"T"` + tagTreeRelateApp tagapp.TagTreeRelate `inject:"T"` +} + +func (mcc *MachineCmdConf) ReqConfs() *req.Confs { + reqs := [...]*req.Conf{ + req.NewGet("", mcc.MachineCmdConfs), + + req.NewPost("", mcc.Save).Log(req.NewLogSaveI(imsg.LogMachineSecurityCmdSave)).RequiredPermissionCode("cmdconf:save"), + + req.NewDelete(":id", mcc.Delete).Log(req.NewLogSaveI(imsg.LogMachineSecurityCmdDelete)).RequiredPermissionCode("cmdconf:del"), + } + + return req.NewConfs("machine/security/cmd-confs", reqs[:]...) } func (m *MachineCmdConf) MachineCmdConfs(rc *req.Ctx) { cond := req.BindQuery(rc, new(entity.MachineCmdConf)) var vos []*vo.MachineCmdConfVO - err := m.MachineCmdConfApp.ListByCondToAny(cond, &vos) + err := m.machineCmdConfApp.ListByCondToAny(cond, &vos) biz.ErrIsNil(err) - m.TagTreeRelateApp.FillTagInfo(tagentity.TagRelateTypeMachineCmd, collx.ArrayMap(vos, func(mvo *vo.MachineCmdConfVO) tagentity.IRelateTag { + m.tagTreeRelateApp.FillTagInfo(tagentity.TagRelateTypeMachineCmd, collx.ArrayMap(vos, func(mvo *vo.MachineCmdConfVO) tagentity.IRelateTag { return mvo })...) @@ -38,7 +51,7 @@ func (m *MachineCmdConf) Save(rc *req.Ctx) { mcj := req.BindJsonAndCopyTo[*entity.MachineCmdConf](rc, cmdForm, new(entity.MachineCmdConf)) rc.ReqParam = cmdForm - err := m.MachineCmdConfApp.SaveCmdConf(rc.MetaCtx, &dto.SaveMachineCmdConf{ + err := m.machineCmdConfApp.SaveCmdConf(rc.MetaCtx, &dto.SaveMachineCmdConf{ CmdConf: mcj, CodePaths: cmdForm.CodePaths, }) @@ -46,5 +59,5 @@ func (m *MachineCmdConf) Save(rc *req.Ctx) { } func (m *MachineCmdConf) Delete(rc *req.Ctx) { - m.MachineCmdConfApp.DeleteCmdConf(rc.MetaCtx, uint64(rc.PathParamInt("id"))) + m.machineCmdConfApp.DeleteCmdConf(rc.MetaCtx, uint64(rc.PathParamInt("id"))) } diff --git a/server/internal/machine/api/machine_cronjob.go b/server/internal/machine/api/machine_cronjob.go index 65b6fc6f..8809d598 100644 --- a/server/internal/machine/api/machine_cronjob.go +++ b/server/internal/machine/api/machine_cronjob.go @@ -6,6 +6,7 @@ import ( "mayfly-go/internal/machine/application" "mayfly-go/internal/machine/application/dto" "mayfly-go/internal/machine/domain/entity" + "mayfly-go/internal/machine/imsg" tagapp "mayfly-go/internal/tag/application" tagentity "mayfly-go/internal/tag/domain/entity" "strings" @@ -19,22 +20,39 @@ import ( ) type MachineCronJob struct { - MachineCronJobApp application.MachineCronJob `inject:""` - TagTreeRelateApp tagapp.TagTreeRelate `inject:"TagTreeRelateApp"` + machineCronJobApp application.MachineCronJob `inject:"T"` + tagTreeRelateApp tagapp.TagTreeRelate `inject:"T"` +} + +func (mcj *MachineCronJob) ReqConfs() *req.Confs { + reqs := [...]*req.Conf{ + // 获取机器任务列表 + req.NewGet("", mcj.MachineCronJobs), + + req.NewPost("", mcj.Save).Log(req.NewLogSaveI(imsg.LogMachineCronJobSave)), + + req.NewDelete(":ids", mcj.Delete).Log(req.NewLogSaveI(imsg.LogMachineCronJobDelete)), + + req.NewPost("/run/:key", mcj.RunCronJob).Log(req.NewLogSaveI(imsg.LogMachineCronJobRun)), + + req.NewGet("/execs", mcj.CronJobExecs), + } + + return req.NewConfs("machine-cronjobs", reqs[:]...) } func (m *MachineCronJob) MachineCronJobs(rc *req.Ctx) { cond, pageParam := req.BindQueryAndPage(rc, new(entity.MachineCronJob)) var vos []*vo.MachineCronJobVO - pageRes, err := m.MachineCronJobApp.GetPageList(cond, pageParam, &vos) + pageRes, err := m.machineCronJobApp.GetPageList(cond, pageParam, &vos) biz.ErrIsNil(err) for _, mcj := range vos { mcj.Running = scheduler.ExistKey(mcj.Key) } - m.TagTreeRelateApp.FillTagInfo(tagentity.TagRelateTypeMachineCronJob, collx.ArrayMap(vos, func(mvo *vo.MachineCronJobVO) tagentity.IRelateTag { + m.tagTreeRelateApp.FillTagInfo(tagentity.TagRelateTypeMachineCronJob, collx.ArrayMap(vos, func(mvo *vo.MachineCronJobVO) tagentity.IRelateTag { return mvo })...) @@ -46,7 +64,7 @@ func (m *MachineCronJob) Save(rc *req.Ctx) { mcj := req.BindJsonAndCopyTo[*entity.MachineCronJob](rc, jobForm, new(entity.MachineCronJob)) rc.ReqParam = jobForm - err := m.MachineCronJobApp.SaveMachineCronJob(rc.MetaCtx, &dto.SaveMachineCronJob{ + err := m.machineCronJobApp.SaveMachineCronJob(rc.MetaCtx, &dto.SaveMachineCronJob{ CronJob: mcj, CodePaths: jobForm.CodePaths, }) @@ -59,19 +77,19 @@ func (m *MachineCronJob) Delete(rc *req.Ctx) { ids := strings.Split(idsStr, ",") for _, v := range ids { - m.MachineCronJobApp.Delete(rc.MetaCtx, cast.ToUint64(v)) + m.machineCronJobApp.Delete(rc.MetaCtx, cast.ToUint64(v)) } } func (m *MachineCronJob) RunCronJob(rc *req.Ctx) { cronJobKey := rc.PathParam("key") biz.NotEmpty(cronJobKey, "cronJob key cannot be empty") - m.MachineCronJobApp.RunCronJob(cronJobKey) + m.machineCronJobApp.RunCronJob(cronJobKey) } func (m *MachineCronJob) CronJobExecs(rc *req.Ctx) { cond, pageParam := req.BindQueryAndPage[*entity.MachineCronJobExec](rc, new(entity.MachineCronJobExec)) - res, err := m.MachineCronJobApp.GetExecPageList(cond, pageParam, new([]entity.MachineCronJobExec)) + res, err := m.machineCronJobApp.GetExecPageList(cond, pageParam, new([]entity.MachineCronJobExec)) biz.ErrIsNil(err) rc.ResData = res } diff --git a/server/internal/machine/api/machine_file.go b/server/internal/machine/api/machine_file.go index b39a79bf..95ed41c1 100644 --- a/server/internal/machine/api/machine_file.go +++ b/server/internal/machine/api/machine_file.go @@ -34,9 +34,47 @@ import ( ) type MachineFile struct { - MachineApp application.Machine `inject:""` - MachineFileApp application.MachineFile `inject:""` - MsgApp msgapp.Msg `inject:""` + machineFileApp application.MachineFile `inject:"T"` + msgApp msgapp.Msg `inject:"T"` +} + +func (mf *MachineFile) ReqConfs() *req.Confs { + reqs := [...]*req.Conf{ + // 获取指定机器文件列表 + req.NewGet(":machineId/files", mf.MachineFiles), + + req.NewPost(":machineId/files", mf.SaveMachineFiles).Log(req.NewLogSaveI(imsg.LogMachineFileConfSave)).RequiredPermissionCode("machine:file:add"), + + req.NewDelete(":machineId/files/:fileId", mf.DeleteFile).Log(req.NewLogSaveI(imsg.LogMachineFileConfDelete)).RequiredPermissionCode("machine:file:del"), + + req.NewGet(":machineId/files/:fileId/read", mf.ReadFileContent).Log(req.NewLogSaveI(imsg.LogMachineFileRead)), + + req.NewGet(":machineId/files/:fileId/download", mf.DownloadFile).NoRes().Log(req.NewLogSaveI(imsg.LogMachineFileDownload)), + + req.NewGet(":machineId/files/:fileId/read-dir", mf.GetDirEntry), + + req.NewGet(":machineId/files/:fileId/dir-size", mf.GetDirSize), + + req.NewGet(":machineId/files/:fileId/file-stat", mf.GetFileStat), + + req.NewPost(":machineId/files/:fileId/write", mf.WriteFileContent).Log(req.NewLogSaveI(imsg.LogMachineFileModify)).RequiredPermissionCode("machine:file:write"), + + req.NewPost(":machineId/files/:fileId/create-file", mf.CreateFile).Log(req.NewLogSaveI(imsg.LogMachineFileCreate)), + + req.NewPost(":machineId/files/:fileId/upload", mf.UploadFile).Log(req.NewLogSaveI(imsg.LogMachineFileUpload)).RequiredPermissionCode("machine:file:upload"), + + req.NewPost(":machineId/files/:fileId/upload-folder", mf.UploadFolder).Log(req.NewLogSaveI(imsg.LogMachineFileUploadFolder)).RequiredPermissionCode("machine:file:upload"), + + req.NewPost(":machineId/files/:fileId/remove", mf.RemoveFile).Log(req.NewLogSaveI(imsg.LogMachineFileDelete)).RequiredPermissionCode("machine:file:rm"), + + req.NewPost(":machineId/files/:fileId/cp", mf.CopyFile).Log(req.NewLogSaveI(imsg.LogMachineFileCopy)).RequiredPermissionCode("machine:file:rm"), + + req.NewPost(":machineId/files/:fileId/mv", mf.MvFile).Log(req.NewLogSaveI(imsg.LogMachineFileMove)).RequiredPermissionCode("machine:file:rm"), + + req.NewPost(":machineId/files/:fileId/rename", mf.Rename).Log(req.NewLogSaveI(imsg.LogMachineFileRename)).RequiredPermissionCode("machine:file:write"), + } + + return req.NewConfs("machines", reqs[:]...) } const ( @@ -48,7 +86,7 @@ const ( func (m *MachineFile) MachineFiles(rc *req.Ctx) { condition := &entity.MachineFile{MachineId: GetMachineId(rc)} - res, err := m.MachineFileApp.GetPageList(condition, rc.GetPageParam(), new([]vo.MachineFileVO)) + res, err := m.machineFileApp.GetPageList(condition, rc.GetPageParam(), new([]vo.MachineFileVO)) biz.ErrIsNil(err) rc.ResData = res } @@ -58,11 +96,11 @@ func (m *MachineFile) SaveMachineFiles(rc *req.Ctx) { entity := req.BindJsonAndCopyTo[*entity.MachineFile](rc, fileForm, new(entity.MachineFile)) rc.ReqParam = fileForm - biz.ErrIsNil(m.MachineFileApp.Save(rc.MetaCtx, entity)) + biz.ErrIsNil(m.machineFileApp.Save(rc.MetaCtx, entity)) } func (m *MachineFile) DeleteFile(rc *req.Ctx) { - biz.ErrIsNil(m.MachineFileApp.DeleteById(rc.MetaCtx, GetMachineFileId(rc))) + biz.ErrIsNil(m.machineFileApp.DeleteById(rc.MetaCtx, GetMachineFileId(rc))) } /*** sftp相关操作 */ @@ -76,10 +114,10 @@ func (m *MachineFile) CreateFile(rc *req.Ctx) { var err error if opForm.Type == dir { attrs["type"] = "Folder" - mi, err = m.MachineFileApp.MkDir(rc.MetaCtx, opForm.MachineFileOp) + mi, err = m.machineFileApp.MkDir(rc.MetaCtx, opForm.MachineFileOp) } else { attrs["type"] = "File" - mi, err = m.MachineFileApp.CreateFile(rc.MetaCtx, opForm.MachineFileOp) + mi, err = m.machineFileApp.CreateFile(rc.MetaCtx, opForm.MachineFileOp) } attrs["machine"] = mi rc.ReqParam = attrs @@ -93,7 +131,7 @@ func (m *MachineFile) ReadFileContent(rc *req.Ctx) { // 特殊处理rdp文件 if opForm.Protocol == entity.MachineProtocolRdp { - path := m.MachineFileApp.GetRdpFilePath(rc.GetLoginAccount(), opForm.Path) + path := m.machineFileApp.GetRdpFilePath(rc.GetLoginAccount(), opForm.Path) fi, err := os.Stat(path) biz.ErrIsNil(err) biz.IsTrueI(ctx, fi.Size() < max_read_size, imsg.ErrFileTooLargeUseDownload) @@ -103,7 +141,7 @@ func (m *MachineFile) ReadFileContent(rc *req.Ctx) { return } - sftpFile, mi, err := m.MachineFileApp.ReadFile(rc.MetaCtx, opForm) + sftpFile, mi, err := m.machineFileApp.ReadFile(rc.MetaCtx, opForm) rc.ReqParam = collx.Kvs("machine", mi, "path", readPath) biz.ErrIsNil(err) defer sftpFile.Close() @@ -128,7 +166,7 @@ func (m *MachineFile) DownloadFile(rc *req.Ctx) { fileName := path[len(path)-1] if opForm.Protocol == entity.MachineProtocolRdp { - path := m.MachineFileApp.GetRdpFilePath(rc.GetLoginAccount(), opForm.Path) + path := m.machineFileApp.GetRdpFilePath(rc.GetLoginAccount(), opForm.Path) file, err := os.Open(path) if err != nil { return @@ -138,7 +176,7 @@ func (m *MachineFile) DownloadFile(rc *req.Ctx) { return } - sftpFile, mi, err := m.MachineFileApp.ReadFile(rc.MetaCtx, opForm) + sftpFile, mi, err := m.machineFileApp.ReadFile(rc.MetaCtx, opForm) rc.ReqParam = collx.Kvs("machine", mi, "path", readPath) biz.ErrIsNilAppendErr(err, "open file error: %s") defer sftpFile.Close() @@ -151,7 +189,7 @@ func (m *MachineFile) GetDirEntry(rc *req.Ctx) { readPath := opForm.Path rc.ReqParam = fmt.Sprintf("path: %s", readPath) - fis, err := m.MachineFileApp.ReadDir(rc.MetaCtx, opForm) + fis, err := m.machineFileApp.ReadDir(rc.MetaCtx, opForm) biz.ErrIsNilAppendErr(err, "read dir error: %s") fisVO := make([]vo.MachineFileInfo, 0) @@ -188,14 +226,14 @@ func (m *MachineFile) GetDirEntry(rc *req.Ctx) { func (m *MachineFile) GetDirSize(rc *req.Ctx) { opForm := req.BindQuery(rc, new(dto.MachineFileOp)) - size, err := m.MachineFileApp.GetDirSize(rc.MetaCtx, opForm) + size, err := m.machineFileApp.GetDirSize(rc.MetaCtx, opForm) biz.ErrIsNil(err) rc.ResData = size } func (m *MachineFile) GetFileStat(rc *req.Ctx) { opForm := req.BindQuery(rc, new(dto.MachineFileOp)) - res, err := m.MachineFileApp.FileStat(rc.MetaCtx, opForm) + res, err := m.machineFileApp.FileStat(rc.MetaCtx, opForm) biz.ErrIsNil(err, res) rc.ResData = res } @@ -204,7 +242,7 @@ func (m *MachineFile) WriteFileContent(rc *req.Ctx) { opForm := req.BindJsonAndValid(rc, new(form.WriteFileContentForm)) path := opForm.Path - mi, err := m.MachineFileApp.WriteFileContent(rc.MetaCtx, opForm.MachineFileOp, []byte(opForm.Content)) + mi, err := m.machineFileApp.WriteFileContent(rc.MetaCtx, opForm.MachineFileOp, []byte(opForm.Content)) rc.ReqParam = collx.Kvs("machine", mi, "path", path) biz.ErrIsNilAppendErr(err, "open file error: %s") } @@ -230,7 +268,7 @@ func (m *MachineFile) UploadFile(rc *req.Ctx) { defer func() { if anyx.ToString(recover()) != "" { logx.Errorf("upload file error: %s", err) - m.MsgApp.CreateAndSend(la, msgdto.ErrSysMsg(i18n.TC(ctx, imsg.ErrFileUploadFail), fmt.Sprintf("%s: \n<-e : %s", i18n.TC(ctx, imsg.ErrFileUploadFail), err))) + m.msgApp.CreateAndSend(la, msgdto.ErrSysMsg(i18n.TC(ctx, imsg.ErrFileUploadFail), fmt.Sprintf("%s: \n<-e : %s", i18n.TC(ctx, imsg.ErrFileUploadFail), err))) } }() @@ -241,11 +279,11 @@ func (m *MachineFile) UploadFile(rc *req.Ctx) { Path: path, } - mi, err := m.MachineFileApp.UploadFile(ctx, opForm, fileheader.Filename, file) + mi, err := m.machineFileApp.UploadFile(ctx, opForm, fileheader.Filename, file) rc.ReqParam = collx.Kvs("machine", mi, "path", fmt.Sprintf("%s/%s", path, fileheader.Filename)) biz.ErrIsNilAppendErr(err, "upload file error: %s") // 保存消息并发送文件上传成功通知 - m.MsgApp.CreateAndSend(la, msgdto.SuccessSysMsg(i18n.TC(ctx, imsg.MsgUploadFileSuccess), fmt.Sprintf("[%s] -> %s[%s:%s]", fileheader.Filename, mi.Name, mi.Ip, path))) + m.msgApp.CreateAndSend(la, msgdto.SuccessSysMsg(i18n.TC(ctx, imsg.MsgUploadFileSuccess), fmt.Sprintf("[%s] -> %s[%s:%s]", fileheader.Filename, mi.Name, mi.Ip, path))) } type FolderFile struct { @@ -282,12 +320,12 @@ func (m *MachineFile) UploadFolder(rc *req.Ctx) { } if protocol == entity.MachineProtocolRdp { - m.MachineFileApp.UploadFiles(ctx, opForm, basePath, fileheaders, paths) + m.machineFileApp.UploadFiles(ctx, opForm, basePath, fileheaders, paths) return } folderName := filepath.Dir(paths[0]) - mcli, err := m.MachineFileApp.GetMachineCli(authCertName) + mcli, err := m.machineFileApp.GetMachineCli(authCertName) biz.ErrIsNil(err) mi := mcli.Info @@ -331,7 +369,7 @@ func (m *MachineFile) UploadFolder(rc *req.Ctx) { logx.Errorf("upload file error: %s", err) switch t := err.(type) { case *errorx.BizError: - m.MsgApp.CreateAndSend(la, msgdto.ErrSysMsg(i18n.TC(ctx, imsg.ErrFileUploadFail), fmt.Sprintf("%s: \n<-e errCode: %d, errMsg: %s", i18n.TC(ctx, imsg.ErrFileUploadFail), t.Code(), t.Error()))) + m.msgApp.CreateAndSend(la, msgdto.ErrSysMsg(i18n.TC(ctx, imsg.ErrFileUploadFail), fmt.Sprintf("%s: \n<-e errCode: %d, errMsg: %s", i18n.TC(ctx, imsg.ErrFileUploadFail), t.Code(), t.Error()))) } } }() @@ -356,35 +394,35 @@ func (m *MachineFile) UploadFolder(rc *req.Ctx) { wg.Wait() if isSuccess { // 保存消息并发送文件上传成功通知 - m.MsgApp.CreateAndSend(la, msgdto.SuccessSysMsg(i18n.TC(ctx, imsg.MsgUploadFileSuccess), fmt.Sprintf("[%s] -> %s[%s:%s]", folderName, mi.Name, mi.Ip, basePath))) + m.msgApp.CreateAndSend(la, msgdto.SuccessSysMsg(i18n.TC(ctx, imsg.MsgUploadFileSuccess), fmt.Sprintf("[%s] -> %s[%s:%s]", folderName, mi.Name, mi.Ip, basePath))) } } func (m *MachineFile) RemoveFile(rc *req.Ctx) { opForm := req.BindJsonAndValid(rc, new(form.RemoveFileForm)) - mi, err := m.MachineFileApp.RemoveFile(rc.MetaCtx, opForm.MachineFileOp, opForm.Paths...) + mi, err := m.machineFileApp.RemoveFile(rc.MetaCtx, opForm.MachineFileOp, opForm.Paths...) rc.ReqParam = collx.Kvs("machine", mi, "path", opForm) biz.ErrIsNilAppendErr(err, "remove file error: %s") } func (m *MachineFile) CopyFile(rc *req.Ctx) { opForm := req.BindJsonAndValid(rc, new(form.CopyFileForm)) - mi, err := m.MachineFileApp.Copy(rc.MetaCtx, opForm.MachineFileOp, opForm.ToPath, opForm.Paths...) + mi, err := m.machineFileApp.Copy(rc.MetaCtx, opForm.MachineFileOp, opForm.ToPath, opForm.Paths...) biz.ErrIsNilAppendErr(err, "file copy error: %s") rc.ReqParam = collx.Kvs("machine", mi, "cp", opForm) } func (m *MachineFile) MvFile(rc *req.Ctx) { opForm := req.BindJsonAndValid(rc, new(form.CopyFileForm)) - mi, err := m.MachineFileApp.Mv(rc.MetaCtx, opForm.MachineFileOp, opForm.ToPath, opForm.Paths...) + mi, err := m.machineFileApp.Mv(rc.MetaCtx, opForm.MachineFileOp, opForm.ToPath, opForm.Paths...) rc.ReqParam = collx.Kvs("machine", mi, "mv", opForm) biz.ErrIsNilAppendErr(err, "file move error: %s") } func (m *MachineFile) Rename(rc *req.Ctx) { renameForm := req.BindJsonAndValid(rc, new(form.RenameForm)) - mi, err := m.MachineFileApp.Rename(rc.MetaCtx, renameForm.MachineFileOp, renameForm.Newname) + mi, err := m.machineFileApp.Rename(rc.MetaCtx, renameForm.MachineFileOp, renameForm.Newname) rc.ReqParam = collx.Kvs("machine", mi, "rename", renameForm) biz.ErrIsNilAppendErr(err, "file rename error: %s") } diff --git a/server/internal/machine/api/machine_script.go b/server/internal/machine/api/machine_script.go index 04b8abf3..28f09c57 100644 --- a/server/internal/machine/api/machine_script.go +++ b/server/internal/machine/api/machine_script.go @@ -17,14 +17,29 @@ import ( ) type MachineScript struct { - MachineScriptApp application.MachineScript `inject:""` - MachineApp application.Machine `inject:""` - TagApp tagapp.TagTree `inject:"TagTreeApp"` + machineScriptApp application.MachineScript `inject:"T"` + machineApp application.Machine `inject:"T"` + tagApp tagapp.TagTree `inject:"T"` +} + +func (ms *MachineScript) ReqConfs() *req.Confs { + reqs := [...]*req.Conf{ + // 获取指定机器脚本列表 + req.NewGet(":machineId/scripts", ms.MachineScripts), + + req.NewPost(":machineId/scripts", ms.SaveMachineScript).Log(req.NewLogSave("机器-保存脚本")).RequiredPermissionCode("machine:script:save"), + + req.NewDelete(":machineId/scripts/:scriptId", ms.DeleteMachineScript).Log(req.NewLogSave("机器-删除脚本")).RequiredPermissionCode("machine:script:del"), + + req.NewGet("scripts/:scriptId/:ac/run", ms.RunMachineScript).Log(req.NewLogSave("机器-执行脚本")).RequiredPermissionCode("machine:script:run"), + } + + return req.NewConfs("machines", reqs[:]...) } func (m *MachineScript) MachineScripts(rc *req.Ctx) { condition := &entity.MachineScript{MachineId: GetMachineId(rc)} - res, err := m.MachineScriptApp.GetPageList(condition, rc.GetPageParam(), new([]vo.MachineScriptVO)) + res, err := m.machineScriptApp.GetPageList(condition, rc.GetPageParam(), new([]vo.MachineScriptVO)) biz.ErrIsNil(err) rc.ResData = res } @@ -34,7 +49,7 @@ func (m *MachineScript) SaveMachineScript(rc *req.Ctx) { machineScript := req.BindJsonAndCopyTo(rc, form, new(entity.MachineScript)) rc.ReqParam = form - biz.ErrIsNil(m.MachineScriptApp.Save(rc.MetaCtx, machineScript)) + biz.ErrIsNil(m.machineScriptApp.Save(rc.MetaCtx, machineScript)) } func (m *MachineScript) DeleteMachineScript(rc *req.Ctx) { @@ -43,14 +58,14 @@ func (m *MachineScript) DeleteMachineScript(rc *req.Ctx) { ids := strings.Split(idsStr, ",") for _, v := range ids { - m.MachineScriptApp.Delete(rc.MetaCtx, cast.ToUint64(v)) + m.machineScriptApp.Delete(rc.MetaCtx, cast.ToUint64(v)) } } func (m *MachineScript) RunMachineScript(rc *req.Ctx) { scriptId := GetMachineScriptId(rc) ac := GetMachineAc(rc) - ms, err := m.MachineScriptApp.GetById(scriptId, "MachineId", "Name", "Script") + ms, err := m.machineScriptApp.GetById(scriptId, "MachineId", "Name", "Script") biz.ErrIsNil(err, "script not found") script := ms.Script @@ -59,9 +74,9 @@ func (m *MachineScript) RunMachineScript(rc *req.Ctx) { script, err = stringx.TemplateParse(ms.Script, jsonx.ToMap(params)) biz.ErrIsNilAppendErr(err, "failed to parse the script template parameter: %s") } - cli, err := m.MachineApp.GetCliByAc(ac) + cli, err := m.machineApp.GetCliByAc(ac) biz.ErrIsNilAppendErr(err, "connection error: %s") - biz.ErrIsNilAppendErr(m.TagApp.CanAccess(rc.GetLoginAccount().Id, cli.Info.CodePath...), "%s") + biz.ErrIsNilAppendErr(m.tagApp.CanAccess(rc.GetLoginAccount().Id, cli.Info.CodePath...), "%s") res, err := cli.Run(script) // 记录请求参数 diff --git a/server/internal/machine/application/machine.go b/server/internal/machine/application/machine.go index 32754705..3e07bccd 100644 --- a/server/internal/machine/application/machine.go +++ b/server/internal/machine/application/machine.go @@ -63,8 +63,8 @@ type Machine interface { type machineAppImpl struct { base.AppImpl[*entity.Machine, repository.Machine] - tagApp tagapp.TagTree `inject:"TagTreeApp"` - resourceAuthCertApp tagapp.ResourceAuthCert `inject:"ResourceAuthCertApp"` + tagApp tagapp.TagTree `inject:"T"` + resourceAuthCertApp tagapp.ResourceAuthCert `inject:"T"` } var _ (Machine) = (*machineAppImpl)(nil) diff --git a/server/internal/machine/application/machine_cmd_conf.go b/server/internal/machine/application/machine_cmd_conf.go index cfaed159..615354b7 100644 --- a/server/internal/machine/application/machine_cmd_conf.go +++ b/server/internal/machine/application/machine_cmd_conf.go @@ -31,7 +31,7 @@ type MachineCmdConf interface { type machineCmdConfAppImpl struct { base.AppImpl[*entity.MachineCmdConf, repository.MachineCmdConf] - tagTreeRelateApp tagapp.TagTreeRelate `inject:"TagTreeRelateApp"` + tagTreeRelateApp tagapp.TagTreeRelate `inject:"T"` } var _ (MachineCmdConf) = (*machineCmdConfAppImpl)(nil) diff --git a/server/internal/machine/application/machine_cronjob.go b/server/internal/machine/application/machine_cronjob.go index 239bb256..e5737a8e 100644 --- a/server/internal/machine/application/machine_cronjob.go +++ b/server/internal/machine/application/machine_cronjob.go @@ -42,11 +42,11 @@ type MachineCronJob interface { type machineCronJobAppImpl struct { base.AppImpl[*entity.MachineCronJob, repository.MachineCronJob] - machineCronJobExecRepo repository.MachineCronJobExec `inject:"MachineCronJobExecRepo"` - machineApp Machine `inject:"MachineApp"` + machineCronJobExecRepo repository.MachineCronJobExec `inject:"T"` + machineApp Machine `inject:"T"` - tagTreeApp tagapp.TagTree `inject:"TagTreeApp"` - tagTreeRelateApp tagapp.TagTreeRelate `inject:"TagTreeRelateApp"` + tagTreeApp tagapp.TagTree `inject:"T"` + tagTreeRelateApp tagapp.TagTreeRelate `inject:"T"` } var _ (MachineCronJob) = (*machineCronJobAppImpl)(nil) diff --git a/server/internal/machine/application/machine_file.go b/server/internal/machine/application/machine_file.go index edb4a9f7..8c5f8678 100644 --- a/server/internal/machine/application/machine_file.go +++ b/server/internal/machine/application/machine_file.go @@ -83,7 +83,7 @@ type MachineFile interface { type machineFileAppImpl struct { base.AppImpl[*entity.MachineFile, repository.MachineFile] - machineApp Machine `inject:"MachineApp"` + machineApp Machine `inject:"T"` } // 注入MachineFileRepo diff --git a/server/internal/machine/application/machine_script.go b/server/internal/machine/application/machine_script.go index 1a1d9d97..a4c06b2e 100644 --- a/server/internal/machine/application/machine_script.go +++ b/server/internal/machine/application/machine_script.go @@ -23,7 +23,7 @@ type MachineScript interface { type machineScriptAppImpl struct { base.AppImpl[*entity.MachineScript, repository.MachineScript] - machineApp Machine `inject:"MachineApp"` + machineApp Machine `inject:"T"` } const Common_Script_Machine_Id = 9999999 diff --git a/server/internal/machine/application/machine_term_op.go b/server/internal/machine/application/machine_term_op.go index 884e578e..ffefa154 100644 --- a/server/internal/machine/application/machine_term_op.go +++ b/server/internal/machine/application/machine_term_op.go @@ -38,8 +38,8 @@ type MachineTermOp interface { type machineTermOpAppImpl struct { base.AppImpl[*entity.MachineTermOp, repository.MachineTermOp] - machineCmdConfApp MachineCmdConf `inject:"MachineCmdConfApp"` - fileApp fileapp.File `inject:"FileApp"` + machineCmdConfApp MachineCmdConf `inject:"T"` + fileApp fileapp.File `inject:"T"` } func (m *machineTermOpAppImpl) TermConn(ctx context.Context, cli *mcm.Cli, wsConn *websocket.Conn, rows, cols int) error { diff --git a/server/internal/machine/imsg/en.go b/server/internal/machine/imsg/en.go index 909c80b7..18fa6712 100644 --- a/server/internal/machine/imsg/en.go +++ b/server/internal/machine/imsg/en.go @@ -31,6 +31,10 @@ var En = map[i18n.MsgId]string{ ErrFileUploadFail: "File upload failure", MsgUploadFileSuccess: "File uploaded successfully", + LogMachineCronJobSave: "Machine - save cronjob", + LogMachineCronJobDelete: "Machine - delete cronjob", + LogMachineCronJobRun: "Machine - run cronjob", + LogMachineSecurityCmdSave: "Machine - Security - Save command configuration", LogMachineSecurityCmdDelete: "Machine - Security - Delete command configuration", TerminalCmdDisable: "This command has been disabled...", diff --git a/server/internal/machine/imsg/imsg.go b/server/internal/machine/imsg/imsg.go index 109243d1..78edf4bb 100644 --- a/server/internal/machine/imsg/imsg.go +++ b/server/internal/machine/imsg/imsg.go @@ -39,6 +39,10 @@ const ( ErrFileUploadFail MsgUploadFileSuccess + LogMachineCronJobSave + LogMachineCronJobDelete + LogMachineCronJobRun + // security LogMachineSecurityCmdSave LogMachineSecurityCmdDelete diff --git a/server/internal/machine/imsg/zh_cn.go b/server/internal/machine/imsg/zh_cn.go index 40fdef46..0e735a84 100644 --- a/server/internal/machine/imsg/zh_cn.go +++ b/server/internal/machine/imsg/zh_cn.go @@ -31,6 +31,10 @@ var Zh_CN = map[i18n.MsgId]string{ ErrFileUploadFail: "文件上传失败", MsgUploadFileSuccess: "文件上传成功", + LogMachineCronJobSave: "机器-保存计划任务", + LogMachineCronJobDelete: "机器-删除计划任务", + LogMachineCronJobRun: "机器-执行计划任务", + LogMachineSecurityCmdSave: "机器-安全-保存命令配置", LogMachineSecurityCmdDelete: "机器-安全-删除命令配置", TerminalCmdDisable: "该命令已被禁用...", diff --git a/server/internal/machine/init/init.go b/server/internal/machine/init/init.go index faf2453b..f1dfc4fd 100644 --- a/server/internal/machine/init/init.go +++ b/server/internal/machine/init/init.go @@ -2,16 +2,17 @@ package init import ( "mayfly-go/initialize" + "mayfly-go/internal/machine/api" "mayfly-go/internal/machine/application" "mayfly-go/internal/machine/infrastructure/persistence" - "mayfly-go/internal/machine/router" ) func init() { initialize.AddInitIocFunc(func() { persistence.InitIoc() application.InitIoc() + api.InitIoc() }) - initialize.AddInitRouterFunc(router.Init) + initialize.AddInitFunc(application.Init) } diff --git a/server/internal/machine/router/machine.go b/server/internal/machine/router/machine.go deleted file mode 100644 index ab7b0a6d..00000000 --- a/server/internal/machine/router/machine.go +++ /dev/null @@ -1,61 +0,0 @@ -package router - -import ( - "mayfly-go/internal/machine/api" - "mayfly-go/internal/machine/imsg" - "mayfly-go/pkg/biz" - "mayfly-go/pkg/ioc" - "mayfly-go/pkg/req" - - "github.com/gin-gonic/gin" -) - -func InitMachineRouter(router *gin.RouterGroup) { - m := new(api.Machine) - biz.ErrIsNil(ioc.Inject(m)) - - dashbord := new(api.Dashbord) - biz.ErrIsNil(ioc.Inject(dashbord)) - - machines := router.Group("machines") - { - saveMachineP := req.NewPermission("machine:update") - - reqs := [...]*req.Conf{ - req.NewGet("dashbord", dashbord.Dashbord), - - req.NewGet("", m.Machines), - - req.NewGet("/simple", m.SimpleMachieInfo), - - req.NewGet(":machineId/stats", m.MachineStats), - - req.NewGet(":machineId/process", m.GetProcess), - - req.NewGet(":machineId/users", m.GetUsers), - - req.NewGet(":machineId/groups", m.GetGroups), - - req.NewPost("", m.SaveMachine).Log(req.NewLogSaveI(imsg.LogMachineSave)).RequiredPermission(saveMachineP), - - req.NewDelete(":machineId", m.DeleteMachine).Log(req.NewLogSaveI(imsg.LogMachineSave)), - - req.NewPost("test-conn", m.TestConn), - - req.NewPut(":machineId/:status", m.ChangeStatus).Log(req.NewLogSaveI(imsg.LogMachineChangeStatus)).RequiredPermission(saveMachineP), - - req.NewDelete(":machineId/process", m.KillProcess).Log(req.NewLogSaveI(imsg.LogMachineKillProcess)).RequiredPermissionCode("machine:killprocess"), - - // 获取机器终端回放记录列表,目前具有保存机器信息的权限标识才有权限查看终端回放 - req.NewGet(":machineId/term-recs", m.MachineTermOpRecords).RequiredPermission(saveMachineP), - } - - req.BatchSetGroup(machines, reqs[:]) - - // 终端连接 - machines.GET("terminal/:ac", m.WsSSH) - - // 终端连接 - machines.GET("rdp/:ac", m.WsGuacamole) - } -} diff --git a/server/internal/machine/router/machine_cmd_conf.go b/server/internal/machine/router/machine_cmd_conf.go deleted file mode 100644 index b8c03414..00000000 --- a/server/internal/machine/router/machine_cmd_conf.go +++ /dev/null @@ -1,28 +0,0 @@ -package router - -import ( - "mayfly-go/internal/machine/api" - "mayfly-go/internal/machine/imsg" - "mayfly-go/pkg/biz" - "mayfly-go/pkg/ioc" - "mayfly-go/pkg/req" - - "github.com/gin-gonic/gin" -) - -func InitMachineCmdConfRouter(router *gin.RouterGroup) { - mccs := router.Group("machine/security/cmd-confs") - - mcc := new(api.MachineCmdConf) - biz.ErrIsNil(ioc.Inject(mcc)) - - reqs := [...]*req.Conf{ - req.NewGet("", mcc.MachineCmdConfs), - - req.NewPost("", mcc.Save).Log(req.NewLogSaveI(imsg.LogMachineSecurityCmdSave)).RequiredPermissionCode("cmdconf:save"), - - req.NewDelete(":id", mcc.Delete).Log(req.NewLogSaveI(imsg.LogMachineSecurityCmdDelete)).RequiredPermissionCode("cmdconf:del"), - } - - req.BatchSetGroup(mccs, reqs[:]) -} diff --git a/server/internal/machine/router/machine_cronjob.go b/server/internal/machine/router/machine_cronjob.go deleted file mode 100644 index c1dab8e9..00000000 --- a/server/internal/machine/router/machine_cronjob.go +++ /dev/null @@ -1,32 +0,0 @@ -package router - -import ( - "mayfly-go/internal/machine/api" - "mayfly-go/pkg/biz" - "mayfly-go/pkg/ioc" - "mayfly-go/pkg/req" - - "github.com/gin-gonic/gin" -) - -func InitMachineCronJobRouter(router *gin.RouterGroup) { - cronjobs := router.Group("machine-cronjobs") - - cj := new(api.MachineCronJob) - biz.ErrIsNil(ioc.Inject(cj)) - - reqs := [...]*req.Conf{ - // 获取机器任务列表 - req.NewGet("", cj.MachineCronJobs), - - req.NewPost("", cj.Save).Log(req.NewLogSave("保存机器计划任务")), - - req.NewDelete(":ids", cj.Delete).Log(req.NewLogSave("删除机器计划任务")), - - req.NewPost("/run/:key", cj.RunCronJob).Log(req.NewLogSave("手动执行计划任务")), - - req.NewGet("/execs", cj.CronJobExecs), - } - - req.BatchSetGroup(cronjobs, reqs[:]) -} diff --git a/server/internal/machine/router/machine_file.go b/server/internal/machine/router/machine_file.go deleted file mode 100644 index 13ae7060..00000000 --- a/server/internal/machine/router/machine_file.go +++ /dev/null @@ -1,55 +0,0 @@ -package router - -import ( - "mayfly-go/internal/machine/api" - "mayfly-go/internal/machine/imsg" - "mayfly-go/pkg/biz" - "mayfly-go/pkg/ioc" - "mayfly-go/pkg/req" - - "github.com/gin-gonic/gin" -) - -func InitMachineFileRouter(router *gin.RouterGroup) { - machineFile := router.Group("machines") - - mf := new(api.MachineFile) - biz.ErrIsNil(ioc.Inject(mf)) - - reqs := [...]*req.Conf{ - // 获取指定机器文件列表 - req.NewGet(":machineId/files", mf.MachineFiles), - - req.NewPost(":machineId/files", mf.SaveMachineFiles).Log(req.NewLogSaveI(imsg.LogMachineFileConfSave)).RequiredPermissionCode("machine:file:add"), - - req.NewDelete(":machineId/files/:fileId", mf.DeleteFile).Log(req.NewLogSaveI(imsg.LogMachineFileConfDelete)).RequiredPermissionCode("machine:file:del"), - - req.NewGet(":machineId/files/:fileId/read", mf.ReadFileContent).Log(req.NewLogSaveI(imsg.LogMachineFileRead)), - - req.NewGet(":machineId/files/:fileId/download", mf.DownloadFile).NoRes().Log(req.NewLogSaveI(imsg.LogMachineFileDownload)), - - req.NewGet(":machineId/files/:fileId/read-dir", mf.GetDirEntry), - - req.NewGet(":machineId/files/:fileId/dir-size", mf.GetDirSize), - - req.NewGet(":machineId/files/:fileId/file-stat", mf.GetFileStat), - - req.NewPost(":machineId/files/:fileId/write", mf.WriteFileContent).Log(req.NewLogSaveI(imsg.LogMachineFileModify)).RequiredPermissionCode("machine:file:write"), - - req.NewPost(":machineId/files/:fileId/create-file", mf.CreateFile).Log(req.NewLogSaveI(imsg.LogMachineFileCreate)), - - req.NewPost(":machineId/files/:fileId/upload", mf.UploadFile).Log(req.NewLogSaveI(imsg.LogMachineFileUpload)).RequiredPermissionCode("machine:file:upload"), - - req.NewPost(":machineId/files/:fileId/upload-folder", mf.UploadFolder).Log(req.NewLogSaveI(imsg.LogMachineFileUploadFolder)).RequiredPermissionCode("machine:file:upload"), - - req.NewPost(":machineId/files/:fileId/remove", mf.RemoveFile).Log(req.NewLogSaveI(imsg.LogMachineFileDelete)).RequiredPermissionCode("machine:file:rm"), - - req.NewPost(":machineId/files/:fileId/cp", mf.CopyFile).Log(req.NewLogSaveI(imsg.LogMachineFileCopy)).RequiredPermissionCode("machine:file:rm"), - - req.NewPost(":machineId/files/:fileId/mv", mf.MvFile).Log(req.NewLogSaveI(imsg.LogMachineFileMove)).RequiredPermissionCode("machine:file:rm"), - - req.NewPost(":machineId/files/:fileId/rename", mf.Rename).Log(req.NewLogSaveI(imsg.LogMachineFileRename)).RequiredPermissionCode("machine:file:write"), - } - - req.BatchSetGroup(machineFile, reqs[:]) -} diff --git a/server/internal/machine/router/machine_script.go b/server/internal/machine/router/machine_script.go deleted file mode 100644 index 2543edfa..00000000 --- a/server/internal/machine/router/machine_script.go +++ /dev/null @@ -1,31 +0,0 @@ -package router - -import ( - "mayfly-go/internal/machine/api" - "mayfly-go/pkg/biz" - "mayfly-go/pkg/ioc" - "mayfly-go/pkg/req" - - "github.com/gin-gonic/gin" -) - -func InitMachineScriptRouter(router *gin.RouterGroup) { - machines := router.Group("machines") - - ms := new(api.MachineScript) - biz.ErrIsNil(ioc.Inject(ms)) - - reqs := [...]*req.Conf{ - // 获取指定机器脚本列表 - req.NewGet(":machineId/scripts", ms.MachineScripts), - - req.NewPost(":machineId/scripts", ms.SaveMachineScript).Log(req.NewLogSave("机器-保存脚本")).RequiredPermissionCode("machine:script:save"), - - req.NewDelete(":machineId/scripts/:scriptId", ms.DeleteMachineScript).Log(req.NewLogSave("机器-删除脚本")).RequiredPermissionCode("machine:script:del"), - - req.NewGet("scripts/:scriptId/:ac/run", ms.RunMachineScript).Log(req.NewLogSave("机器-执行脚本")).RequiredPermissionCode("machine:script:run"), - } - - req.BatchSetGroup(machines, reqs[:]) - -} diff --git a/server/internal/machine/router/router.go b/server/internal/machine/router/router.go deleted file mode 100644 index fe10ca19..00000000 --- a/server/internal/machine/router/router.go +++ /dev/null @@ -1,11 +0,0 @@ -package router - -import "github.com/gin-gonic/gin" - -func Init(router *gin.RouterGroup) { - InitMachineRouter(router) - InitMachineFileRouter(router) - InitMachineScriptRouter(router) - InitMachineCronJobRouter(router) - InitMachineCmdConfRouter(router) -} diff --git a/server/internal/mongo/api/api.go b/server/internal/mongo/api/api.go new file mode 100644 index 00000000..6c99d329 --- /dev/null +++ b/server/internal/mongo/api/api.go @@ -0,0 +1,8 @@ +package api + +import "mayfly-go/pkg/ioc" + +func InitIoc() { + ioc.Register(new(Mongo)) + ioc.Register(new(Dashbord)) +} diff --git a/server/internal/mongo/api/dashbord.go b/server/internal/mongo/api/dashbord.go index 5d53de9d..e5987b72 100644 --- a/server/internal/mongo/api/dashbord.go +++ b/server/internal/mongo/api/dashbord.go @@ -8,12 +8,20 @@ import ( ) type Dashbord struct { - TagTreeApp tagapp.TagTree `inject:""` + tagTreeApp tagapp.TagTree `inject:"T"` +} + +func (d *Dashbord) ReqConfs() *req.Confs { + reqs := [...]*req.Conf{ + req.NewGet("/mongos/dashbord", d.Dashbord), + } + + return req.NewConfs("", reqs[:]...) } func (m *Dashbord) Dashbord(rc *req.Ctx) { accountId := rc.GetLoginAccount().Id - mongoNum := len(m.TagTreeApp.GetAccountTags(accountId, &tagentity.TagTreeQuery{Types: []tagentity.TagType{ + mongoNum := len(m.tagTreeApp.GetAccountTags(accountId, &tagentity.TagTreeQuery{Types: []tagentity.TagType{ tagentity.TagTypeMongo, }})) diff --git a/server/internal/mongo/api/mongo.go b/server/internal/mongo/api/mongo.go index 5e859e7e..2a6bd7c2 100644 --- a/server/internal/mongo/api/mongo.go +++ b/server/internal/mongo/api/mongo.go @@ -8,6 +8,7 @@ import ( "mayfly-go/internal/mongo/api/vo" "mayfly-go/internal/mongo/application" "mayfly-go/internal/mongo/domain/entity" + "mayfly-go/internal/mongo/imsg" tagapp "mayfly-go/internal/tag/application" tagentity "mayfly-go/internal/tag/domain/entity" "mayfly-go/pkg/biz" @@ -25,15 +26,52 @@ import ( ) type Mongo struct { - MongoApp application.Mongo `inject:""` - TagApp tagapp.TagTree `inject:"TagTreeApp"` + mongoApp application.Mongo `inject:"T"` + tagTreeApp tagapp.TagTree `inject:"T"` +} + +func (ma *Mongo) ReqConfs() *req.Confs { + saveDataPerm := req.NewPermission("mongo:data:save") + + reqs := [...]*req.Conf{ + // 获取所有mongo列表 + req.NewGet("", ma.Mongos), + + req.NewPost("/test-conn", ma.TestConn), + + req.NewPost("", ma.Save).Log(req.NewLogSaveI(imsg.LogMongoSave)), + + req.NewDelete(":id", ma.DeleteMongo).Log(req.NewLogSaveI(imsg.LogMongoDelete)), + + // 获取mongo下的所有数据库 + req.NewGet(":id/databases", ma.Databases), + + // 获取mongo指定库的所有集合 + req.NewGet(":id/collections", ma.Collections), + + // mongo runCommand + req.NewPost(":id/run-command", ma.RunCommand).Log(req.NewLogSaveI(imsg.LogMongoRunCmd)), + + // 执行mongo find命令 + req.NewPost(":id/command/find", ma.FindCommand), + + req.NewPost(":id/command/update-by-id", ma.UpdateByIdCommand).RequiredPermission(saveDataPerm).Log(req.NewLogSaveI(imsg.LogUpdateDocs)), + + // 执行mongo delete by id命令 + req.NewPost(":id/command/delete-by-id", ma.DeleteByIdCommand).RequiredPermission(req.NewPermission("mongo:data:del")).Log(req.NewLogSaveI(imsg.LogDelDocs)), + + // 执行mongo insert 命令 + req.NewPost(":id/command/insert", ma.InsertOneCommand).RequiredPermission(saveDataPerm).Log(req.NewLogSaveI(imsg.LogInsertDocs)), + } + + return req.NewConfs("/mongos", reqs[:]...) } func (m *Mongo) Mongos(rc *req.Ctx) { queryCond, page := req.BindQueryAndPage[*entity.MongoQuery](rc, new(entity.MongoQuery)) // 不存在可访问标签id,即没有可操作数据 - tags := m.TagApp.GetAccountTags(rc.GetLoginAccount().Id, &tagentity.TagTreeQuery{ + tags := m.tagTreeApp.GetAccountTags(rc.GetLoginAccount().Id, &tagentity.TagTreeQuery{ TypePaths: collx.AsArray(tagentity.NewTypePaths(tagentity.TagTypeMongo)), CodePathLikes: []string{queryCond.TagPath}, }) @@ -44,11 +82,11 @@ func (m *Mongo) Mongos(rc *req.Ctx) { queryCond.Codes = tags.GetCodes() var mongovos []*vo.Mongo - res, err := m.MongoApp.GetPageList(queryCond, page, &mongovos) + res, err := m.mongoApp.GetPageList(queryCond, page, &mongovos) biz.ErrIsNil(err) // 填充标签信息 - m.TagApp.FillTagInfo(tagentity.TagType(consts.ResourceTypeMongo), collx.ArrayMap(mongovos, func(mvo *vo.Mongo) tagentity.ITagResource { + m.tagTreeApp.FillTagInfo(tagentity.TagType(consts.ResourceTypeMongo), collx.ArrayMap(mongovos, func(mvo *vo.Mongo) tagentity.ITagResource { return mvo })...) @@ -58,7 +96,7 @@ func (m *Mongo) Mongos(rc *req.Ctx) { func (m *Mongo) TestConn(rc *req.Ctx) { form := &form.Mongo{} mongo := req.BindJsonAndCopyTo[*entity.Mongo](rc, form, new(entity.Mongo)) - biz.ErrIsNilAppendErr(m.MongoApp.TestConn(mongo), "connection error: %s") + biz.ErrIsNilAppendErr(m.mongoApp.TestConn(mongo), "connection error: %s") } func (m *Mongo) Save(rc *req.Ctx) { @@ -72,7 +110,7 @@ func (m *Mongo) Save(rc *req.Ctx) { }(form.Uri) rc.ReqParam = form - biz.ErrIsNil(m.MongoApp.SaveMongo(rc.MetaCtx, mongo, form.TagCodePaths...)) + biz.ErrIsNil(m.mongoApp.SaveMongo(rc.MetaCtx, mongo, form.TagCodePaths...)) } func (m *Mongo) DeleteMongo(rc *req.Ctx) { @@ -81,12 +119,12 @@ func (m *Mongo) DeleteMongo(rc *req.Ctx) { ids := strings.Split(idsStr, ",") for _, v := range ids { - m.MongoApp.Delete(rc.MetaCtx, cast.ToUint64(v)) + m.mongoApp.Delete(rc.MetaCtx, cast.ToUint64(v)) } } func (m *Mongo) Databases(rc *req.Ctx) { - conn, err := m.MongoApp.GetMongoConn(m.GetMongoId(rc)) + conn, err := m.mongoApp.GetMongoConn(m.GetMongoId(rc)) biz.ErrIsNil(err) res, err := conn.Cli.ListDatabases(context.TODO(), bson.D{}) biz.ErrIsNilAppendErr(err, "get mongo dbs error: %s") @@ -94,7 +132,7 @@ func (m *Mongo) Databases(rc *req.Ctx) { } func (m *Mongo) Collections(rc *req.Ctx) { - conn, err := m.MongoApp.GetMongoConn(m.GetMongoId(rc)) + conn, err := m.mongoApp.GetMongoConn(m.GetMongoId(rc)) biz.ErrIsNil(err) global.EventBus.Publish(rc.MetaCtx, event.EventTopicResourceOp, conn.Info.CodePath[0]) @@ -111,7 +149,7 @@ func (m *Mongo) RunCommand(rc *req.Ctx) { commandForm := new(form.MongoRunCommand) req.BindJsonAndValid(rc, commandForm) - conn, err := m.MongoApp.GetMongoConn(m.GetMongoId(rc)) + conn, err := m.mongoApp.GetMongoConn(m.GetMongoId(rc)) biz.ErrIsNil(err) rc.ReqParam = collx.Kvs("mongo", conn.Info, "cmd", commandForm) @@ -140,7 +178,7 @@ func (m *Mongo) RunCommand(rc *req.Ctx) { func (m *Mongo) FindCommand(rc *req.Ctx) { commandForm := req.BindJsonAndValid(rc, new(form.MongoFindCommand)) - conn, err := m.MongoApp.GetMongoConn(m.GetMongoId(rc)) + conn, err := m.mongoApp.GetMongoConn(m.GetMongoId(rc)) biz.ErrIsNil(err) cli := conn.Cli @@ -174,7 +212,7 @@ func (m *Mongo) FindCommand(rc *req.Ctx) { func (m *Mongo) UpdateByIdCommand(rc *req.Ctx) { commandForm := req.BindJsonAndValid(rc, new(form.MongoUpdateByIdCommand)) - conn, err := m.MongoApp.GetMongoConn(m.GetMongoId(rc)) + conn, err := m.mongoApp.GetMongoConn(m.GetMongoId(rc)) biz.ErrIsNil(err) rc.ReqParam = collx.Kvs("mongo", conn.Info, "cmd", commandForm) @@ -197,7 +235,7 @@ func (m *Mongo) UpdateByIdCommand(rc *req.Ctx) { func (m *Mongo) DeleteByIdCommand(rc *req.Ctx) { commandForm := req.BindJsonAndValid(rc, new(form.MongoUpdateByIdCommand)) - conn, err := m.MongoApp.GetMongoConn(m.GetMongoId(rc)) + conn, err := m.mongoApp.GetMongoConn(m.GetMongoId(rc)) biz.ErrIsNil(err) rc.ReqParam = collx.Kvs("mongo", conn.Info, "cmd", commandForm) @@ -219,7 +257,7 @@ func (m *Mongo) DeleteByIdCommand(rc *req.Ctx) { func (m *Mongo) InsertOneCommand(rc *req.Ctx) { commandForm := req.BindJsonAndValid(rc, new(form.MongoInsertCommand)) - conn, err := m.MongoApp.GetMongoConn(m.GetMongoId(rc)) + conn, err := m.mongoApp.GetMongoConn(m.GetMongoId(rc)) biz.ErrIsNil(err) rc.ReqParam = collx.Kvs("mongo", conn.Info, "cmd", commandForm) diff --git a/server/internal/mongo/application/mongo.go b/server/internal/mongo/application/mongo.go index 87a7be64..703e6a05 100644 --- a/server/internal/mongo/application/mongo.go +++ b/server/internal/mongo/application/mongo.go @@ -37,7 +37,7 @@ type Mongo interface { type mongoAppImpl struct { base.AppImpl[*entity.Mongo, repository.Mongo] - tagApp tagapp.TagTree `inject:"TagTreeApp"` + tagTreeApp tagapp.TagTree `inject:"T"` } // 分页获取数据库信息列表 @@ -57,7 +57,7 @@ func (d *mongoAppImpl) Delete(ctx context.Context, id uint64) error { return d.DeleteById(ctx, id) }, func(ctx context.Context) error { - return d.tagApp.SaveResourceTag(ctx, &tagdto.SaveResourceTag{ResourceTag: &tagdto.ResourceTag{ + return d.tagTreeApp.SaveResourceTag(ctx, &tagdto.SaveResourceTag{ResourceTag: &tagdto.ResourceTag{ Type: tagentity.TagTypeMongo, Code: mongoEntity.Code, }}) @@ -87,7 +87,7 @@ func (d *mongoAppImpl) SaveMongo(ctx context.Context, m *entity.Mongo, tagCodePa return d.Tx(ctx, func(ctx context.Context) error { return d.Insert(ctx, m) }, func(ctx context.Context) error { - return d.tagApp.SaveResourceTag(ctx, &tagdto.SaveResourceTag{ + return d.tagTreeApp.SaveResourceTag(ctx, &tagdto.SaveResourceTag{ ResourceTag: &tagdto.ResourceTag{ Type: tagentity.TagTypeMongo, Code: m.Code, @@ -114,12 +114,12 @@ func (d *mongoAppImpl) SaveMongo(ctx context.Context, m *entity.Mongo, tagCodePa return d.UpdateById(ctx, m) }, func(ctx context.Context) error { if oldMongo.Name != m.Name { - if err := d.tagApp.UpdateTagName(ctx, tagentity.TagTypeMongo, oldMongo.Code, m.Name); err != nil { + if err := d.tagTreeApp.UpdateTagName(ctx, tagentity.TagTypeMongo, oldMongo.Code, m.Name); err != nil { return err } } - return d.tagApp.SaveResourceTag(ctx, &tagdto.SaveResourceTag{ + return d.tagTreeApp.SaveResourceTag(ctx, &tagdto.SaveResourceTag{ ResourceTag: &tagdto.ResourceTag{ Type: tagentity.TagTypeMongo, Code: oldMongo.Code, @@ -135,6 +135,6 @@ func (d *mongoAppImpl) GetMongoConn(id uint64) (*mgm.MongoConn, error) { if err != nil { return nil, errorx.NewBiz("mongo not found") } - return me.ToMongoInfo(d.tagApp.ListTagPathByTypeAndCode(consts.ResourceTypeMongo, me.Code)...), nil + return me.ToMongoInfo(d.tagTreeApp.ListTagPathByTypeAndCode(consts.ResourceTypeMongo, me.Code)...), nil }) } diff --git a/server/internal/mongo/init/init.go b/server/internal/mongo/init/init.go index 29fb7fe3..1bb6be62 100644 --- a/server/internal/mongo/init/init.go +++ b/server/internal/mongo/init/init.go @@ -2,15 +2,15 @@ package init import ( "mayfly-go/initialize" + "mayfly-go/internal/mongo/api" "mayfly-go/internal/mongo/application" "mayfly-go/internal/mongo/infrastructure/persistence" - "mayfly-go/internal/mongo/router" ) func init() { initialize.AddInitIocFunc(func() { persistence.InitIoc() application.InitIoc() + api.InitIoc() }) - initialize.AddInitRouterFunc(router.Init) } diff --git a/server/internal/mongo/router/mongo.go b/server/internal/mongo/router/mongo.go deleted file mode 100644 index e8f9965c..00000000 --- a/server/internal/mongo/router/mongo.go +++ /dev/null @@ -1,59 +0,0 @@ -package router - -import ( - "mayfly-go/internal/mongo/api" - "mayfly-go/internal/mongo/imsg" - "mayfly-go/pkg/biz" - "mayfly-go/pkg/ioc" - "mayfly-go/pkg/req" - - "github.com/gin-gonic/gin" -) - -func InitMongoRouter(router *gin.RouterGroup) { - m := router.Group("mongos") - - ma := new(api.Mongo) - biz.ErrIsNil(ioc.Inject(ma)) - - dashbord := new(api.Dashbord) - biz.ErrIsNil(ioc.Inject(dashbord)) - - saveDataPerm := req.NewPermission("mongo:data:save") - - reqs := [...]*req.Conf{ - req.NewGet("dashbord", dashbord.Dashbord), - - // 获取所有mongo列表 - req.NewGet("", ma.Mongos), - - req.NewPost("/test-conn", ma.TestConn), - - req.NewPost("", ma.Save).Log(req.NewLogSaveI(imsg.LogMongoSave)), - - req.NewDelete(":id", ma.DeleteMongo).Log(req.NewLogSaveI(imsg.LogMongoDelete)), - - // 获取mongo下的所有数据库 - req.NewGet(":id/databases", ma.Databases), - - // 获取mongo指定库的所有集合 - req.NewGet(":id/collections", ma.Collections), - - // mongo runCommand - req.NewPost(":id/run-command", ma.RunCommand).Log(req.NewLogSaveI(imsg.LogMongoRunCmd)), - - // 执行mongo find命令 - req.NewPost(":id/command/find", ma.FindCommand), - - req.NewPost(":id/command/update-by-id", ma.UpdateByIdCommand).RequiredPermission(saveDataPerm).Log(req.NewLogSaveI(imsg.LogUpdateDocs)), - - // 执行mongo delete by id命令 - req.NewPost(":id/command/delete-by-id", ma.DeleteByIdCommand).RequiredPermission(req.NewPermission("mongo:data:del")).Log(req.NewLogSaveI(imsg.LogDelDocs)), - - // 执行mongo insert 命令 - req.NewPost(":id/command/insert", ma.InsertOneCommand).RequiredPermission(saveDataPerm).Log(req.NewLogSaveI(imsg.LogInsertDocs)), - } - - req.BatchSetGroup(m, reqs[:]) - -} diff --git a/server/internal/mongo/router/router.go b/server/internal/mongo/router/router.go deleted file mode 100644 index 34c4b426..00000000 --- a/server/internal/mongo/router/router.go +++ /dev/null @@ -1,7 +0,0 @@ -package router - -import "github.com/gin-gonic/gin" - -func Init(router *gin.RouterGroup) { - InitMongoRouter(router) -} diff --git a/server/internal/msg/api/api.go b/server/internal/msg/api/api.go new file mode 100644 index 00000000..f9113efe --- /dev/null +++ b/server/internal/msg/api/api.go @@ -0,0 +1,7 @@ +package api + +import "mayfly-go/pkg/ioc" + +func InitIoc() { + ioc.Register(new(Msg)) +} diff --git a/server/internal/msg/api/msg.go b/server/internal/msg/api/msg.go index 7c797f59..7596cde9 100644 --- a/server/internal/msg/api/msg.go +++ b/server/internal/msg/api/msg.go @@ -8,7 +8,15 @@ import ( ) type Msg struct { - MsgApp application.Msg `inject:""` + msgApp application.Msg `inject:"T"` +} + +func (m *Msg) ReqConfs() *req.Confs { + reqs := [...]*req.Conf{ + req.NewGet("/self", m.GetMsgs), + } + + return req.NewConfs("/msgs", reqs[:]...) } // 获取账号接收的消息列表 @@ -16,7 +24,7 @@ func (m *Msg) GetMsgs(rc *req.Ctx) { condition := &entity.Msg{ RecipientId: int64(rc.GetLoginAccount().Id), } - res, err := m.MsgApp.GetPageList(condition, rc.GetPageParam(), new([]entity.Msg)) + res, err := m.msgApp.GetPageList(condition, rc.GetPageParam(), new([]entity.Msg)) biz.ErrIsNil(err) rc.ResData = res } diff --git a/server/internal/msg/application/msg.go b/server/internal/msg/application/msg.go index 160be20a..1aba98a2 100644 --- a/server/internal/msg/application/msg.go +++ b/server/internal/msg/application/msg.go @@ -20,20 +20,20 @@ type Msg interface { } type msgAppImpl struct { - MsgRepo repository.Msg `inject:""` + msgRepo repository.Msg `inject:"T"` } func (a *msgAppImpl) GetPageList(condition *entity.Msg, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) { - return a.MsgRepo.GetPageList(condition, pageParam, toEntity) + return a.msgRepo.GetPageList(condition, pageParam, toEntity) } func (a *msgAppImpl) Create(ctx context.Context, msg *entity.Msg) { - a.MsgRepo.Insert(ctx, msg) + a.msgRepo.Insert(ctx, msg) } func (a *msgAppImpl) CreateAndSend(la *model.LoginAccount, wmsg *dto.SysMsg) { now := time.Now() msg := &entity.Msg{Type: 2, Msg: wmsg.Msg, RecipientId: int64(la.Id), CreateTime: &now, CreatorId: la.Id, Creator: la.Username} - a.MsgRepo.Insert(context.TODO(), msg) + a.msgRepo.Insert(context.TODO(), msg) ws.SendJsonMsg(ws.UserId(la.Id), wmsg.ClientId, wmsg) } diff --git a/server/internal/msg/init/init.go b/server/internal/msg/init/init.go index 69322f9f..220d1457 100644 --- a/server/internal/msg/init/init.go +++ b/server/internal/msg/init/init.go @@ -2,15 +2,15 @@ package init import ( "mayfly-go/initialize" + "mayfly-go/internal/msg/api" "mayfly-go/internal/msg/application" "mayfly-go/internal/msg/infrastructure/persistence" - "mayfly-go/internal/msg/router" ) func init() { initialize.AddInitIocFunc(func() { persistence.InitIoc() application.InitIoc() + api.InitIoc() }) - initialize.AddInitRouterFunc(router.Init) } diff --git a/server/internal/msg/router/msg.go b/server/internal/msg/router/msg.go deleted file mode 100644 index 82e4f095..00000000 --- a/server/internal/msg/router/msg.go +++ /dev/null @@ -1,18 +0,0 @@ -package router - -import ( - "mayfly-go/internal/msg/api" - "mayfly-go/pkg/ioc" - "mayfly-go/pkg/req" - - "github.com/gin-gonic/gin" -) - -func InitMsgRouter(router *gin.RouterGroup) { - msg := router.Group("msgs") - - a := new(api.Msg) - ioc.Inject(a) - - req.NewGet("/self", a.GetMsgs).Group(msg) -} diff --git a/server/internal/msg/router/router.go b/server/internal/msg/router/router.go deleted file mode 100644 index 0cbfe7ec..00000000 --- a/server/internal/msg/router/router.go +++ /dev/null @@ -1,9 +0,0 @@ -package router - -import ( - "github.com/gin-gonic/gin" -) - -func Init(router *gin.RouterGroup) { - InitMsgRouter(router) -} diff --git a/server/internal/redis/api/api.go b/server/internal/redis/api/api.go new file mode 100644 index 00000000..4bb6215e --- /dev/null +++ b/server/internal/redis/api/api.go @@ -0,0 +1,8 @@ +package api + +import "mayfly-go/pkg/ioc" + +func InitIoc() { + ioc.Register(new(Redis)) + ioc.Register(new(Dashbord)) +} diff --git a/server/internal/redis/api/cmd.go b/server/internal/redis/api/cmd.go index 443de69c..755e4a06 100644 --- a/server/internal/redis/api/cmd.go +++ b/server/internal/redis/api/cmd.go @@ -16,12 +16,12 @@ func (r *Redis) RunCmd(rc *req.Ctx) { biz.IsTrue(len(cmdReq.Cmd) > 0, "redis cmd cannot be empty") redisConn := r.getRedisConn(rc) - biz.ErrIsNilAppendErr(r.TagApp.CanAccess(rc.GetLoginAccount().Id, redisConn.Info.CodePath...), "%s") + biz.ErrIsNilAppendErr(r.tagApp.CanAccess(rc.GetLoginAccount().Id, redisConn.Info.CodePath...), "%s") rc.ReqParam = collx.Kvs("redis", redisConn.Info, "cmd", cmdReq.Cmd) global.EventBus.Publish(rc.MetaCtx, event.EventTopicResourceOp, redisConn.Info.CodePath[0]) - res, err := r.RedisApp.RunCmd(rc.MetaCtx, redisConn, runCmdParam) + res, err := r.redisApp.RunCmd(rc.MetaCtx, redisConn, runCmdParam) biz.ErrIsNil(err) rc.ResData = res } diff --git a/server/internal/redis/api/dashbord.go b/server/internal/redis/api/dashbord.go index 3dc9b4b8..71f8177b 100644 --- a/server/internal/redis/api/dashbord.go +++ b/server/internal/redis/api/dashbord.go @@ -8,12 +8,20 @@ import ( ) type Dashbord struct { - TagTreeApp tagapp.TagTree `inject:""` + tagTreeApp tagapp.TagTree `inject:"T"` } -func (m *Dashbord) Dashbord(rc *req.Ctx) { +func (d *Dashbord) ReqConfs() *req.Confs { + reqs := [...]*req.Conf{ + req.NewGet("/redis/dashbord", d.Dashbord), + } + + return req.NewConfs("", reqs[:]...) +} + +func (d *Dashbord) Dashbord(rc *req.Ctx) { accountId := rc.GetLoginAccount().Id - redisNum := len(m.TagTreeApp.GetAccountTags(accountId, &tagentity.TagTreeQuery{ + redisNum := len(d.tagTreeApp.GetAccountTags(accountId, &tagentity.TagTreeQuery{ Types: collx.AsArray(tagentity.TagTypeRedis), })) diff --git a/server/internal/redis/api/redis.go b/server/internal/redis/api/redis.go index e9ebaadc..7f7e244a 100644 --- a/server/internal/redis/api/redis.go +++ b/server/internal/redis/api/redis.go @@ -9,6 +9,7 @@ import ( "mayfly-go/internal/redis/application" "mayfly-go/internal/redis/application/dto" "mayfly-go/internal/redis/domain/entity" + "mayfly-go/internal/redis/imsg" "mayfly-go/internal/redis/rdm" tagapp "mayfly-go/internal/tag/application" tagentity "mayfly-go/internal/tag/domain/entity" @@ -24,15 +25,45 @@ import ( ) type Redis struct { - RedisApp application.Redis `inject:""` - TagApp tagapp.TagTree `inject:"TagTreeApp"` + redisApp application.Redis `inject:"T"` + tagApp tagapp.TagTree `inject:"T"` +} + +func (rs *Redis) ReqConfs() *req.Confs { + reqs := [...]*req.Conf{ + // 获取redis list + req.NewGet("", rs.RedisList), + + req.NewPost("/test-conn", rs.TestConn), + + req.NewPost("", rs.Save).Log(req.NewLogSaveI(imsg.LogRedisSave)), + + req.NewDelete(":id", rs.DeleteRedis).Log(req.NewLogSaveI(imsg.LogRedisDelete)), + + req.NewGet("/:id/info", rs.RedisInfo), + + req.NewGet(":id/cluster-info", rs.ClusterInfo), + + req.NewPost(":id/:db/run-cmd", rs.RunCmd).Log(req.NewLogSaveI(imsg.LogRedisRunCmd)), + + // 获取指定redis keys + req.NewPost(":id/:db/scan", rs.ScanKeys), + + req.NewGet(":id/:db/key-info", rs.KeyInfo), + + req.NewGet(":id/:db/key-ttl", rs.TtlKey), + + req.NewGet(":id/:db/key-memuse", rs.MemoryUsage), + } + + return req.NewConfs("/redis", reqs[:]...) } func (r *Redis) RedisList(rc *req.Ctx) { queryCond, page := req.BindQueryAndPage[*entity.RedisQuery](rc, new(entity.RedisQuery)) // 不存在可访问标签id,即没有可操作数据 - tags := r.TagApp.GetAccountTags(rc.GetLoginAccount().Id, &tagentity.TagTreeQuery{ + tags := r.tagApp.GetAccountTags(rc.GetLoginAccount().Id, &tagentity.TagTreeQuery{ TypePaths: collx.AsArray(tagentity.NewTypePaths(tagentity.TagTypeRedis)), CodePathLikes: collx.AsArray(queryCond.TagPath), }) @@ -43,11 +74,11 @@ func (r *Redis) RedisList(rc *req.Ctx) { queryCond.Codes = tags.GetCodes() var redisvos []*vo.Redis - res, err := r.RedisApp.GetPageList(queryCond, page, &redisvos) + res, err := r.redisApp.GetPageList(queryCond, page, &redisvos) biz.ErrIsNil(err) // 填充标签信息 - r.TagApp.FillTagInfo(tagentity.TagType(consts.ResourceTypeRedis), collx.ArrayMap(redisvos, func(rvo *vo.Redis) tagentity.ITagResource { + r.tagApp.FillTagInfo(tagentity.TagType(consts.ResourceTypeRedis), collx.ArrayMap(redisvos, func(rvo *vo.Redis) tagentity.ITagResource { return rvo })...) @@ -71,7 +102,7 @@ func (r *Redis) TestConn(rc *req.Ctx) { authCert.SetExtraValue("redisNodePassword", encPwd) } - biz.ErrIsNil(r.RedisApp.TestConn(&dto.SaveRedis{ + biz.ErrIsNil(r.redisApp.TestConn(&dto.SaveRedis{ Redis: redis, AuthCert: authCert, })) @@ -104,7 +135,7 @@ func (r *Redis) Save(rc *req.Ctx) { form.Password = "****" rc.ReqParam = form - biz.ErrIsNil(r.RedisApp.SaveRedis(rc.MetaCtx, redisParam)) + biz.ErrIsNil(r.redisApp.SaveRedis(rc.MetaCtx, redisParam)) } func (r *Redis) DeleteRedis(rc *req.Ctx) { @@ -113,12 +144,12 @@ func (r *Redis) DeleteRedis(rc *req.Ctx) { ids := strings.Split(idsStr, ",") for _, v := range ids { - r.RedisApp.Delete(rc.MetaCtx, cast.ToUint64(v)) + r.redisApp.Delete(rc.MetaCtx, cast.ToUint64(v)) } } func (r *Redis) RedisInfo(rc *req.Ctx) { - ri, err := r.RedisApp.GetRedisConn(uint64(rc.PathParamInt("id")), 0) + ri, err := r.redisApp.GetRedisConn(uint64(rc.PathParamInt("id")), 0) biz.ErrIsNil(err) section := rc.Query("section") @@ -195,7 +226,7 @@ func (r *Redis) RedisInfo(rc *req.Ctx) { } func (r *Redis) ClusterInfo(rc *req.Ctx) { - ri, err := r.RedisApp.GetRedisConn(uint64(rc.PathParamInt("id")), 0) + ri, err := r.redisApp.GetRedisConn(uint64(rc.PathParamInt("id")), 0) biz.ErrIsNil(err) biz.IsEquals(ri.Info.Mode, rdm.ClusterMode, "non-cluster mode") info, _ := ri.ClusterCli.ClusterInfo(context.Background()).Result() @@ -246,9 +277,9 @@ func (r *Redis) checkKeyAndGetRedisConn(rc *req.Ctx) (*rdm.RedisConn, string) { } func (r *Redis) getRedisConn(rc *req.Ctx) *rdm.RedisConn { - ri, err := r.RedisApp.GetRedisConn(getIdAndDbNum(rc)) + ri, err := r.redisApp.GetRedisConn(getIdAndDbNum(rc)) biz.ErrIsNil(err) - biz.ErrIsNilAppendErr(r.TagApp.CanAccess(rc.GetLoginAccount().Id, ri.Info.CodePath...), "%s") + biz.ErrIsNilAppendErr(r.tagApp.CanAccess(rc.GetLoginAccount().Id, ri.Info.CodePath...), "%s") return ri } diff --git a/server/internal/redis/application/redis.go b/server/internal/redis/application/redis.go index 43e5ea34..8deabdec 100644 --- a/server/internal/redis/application/redis.go +++ b/server/internal/redis/application/redis.go @@ -55,9 +55,9 @@ type Redis interface { type redisAppImpl struct { base.AppImpl[*entity.Redis, repository.Redis] - tagApp tagapp.TagTree `inject:"TagTreeApp"` - procdefApp flowapp.Procdef `inject:"ProcdefApp"` - resourceAuthCertApp tagapp.ResourceAuthCert `inject:"ResourceAuthCertApp"` + tagApp tagapp.TagTree `inject:"T"` + procdefApp flowapp.Procdef `inject:"T"` + resourceAuthCertApp tagapp.ResourceAuthCert `inject:"T"` } // 分页获取redis列表 diff --git a/server/internal/redis/init/init.go b/server/internal/redis/init/init.go index 3f9ef38c..d51c8a15 100644 --- a/server/internal/redis/init/init.go +++ b/server/internal/redis/init/init.go @@ -2,17 +2,17 @@ package init import ( "mayfly-go/initialize" + "mayfly-go/internal/redis/api" "mayfly-go/internal/redis/application" "mayfly-go/internal/redis/infrastructure/persistence" - "mayfly-go/internal/redis/router" ) func init() { initialize.AddInitIocFunc(func() { persistence.InitIoc() application.InitIoc() + api.InitIoc() }) - initialize.AddInitRouterFunc(router.Init) initialize.AddInitFunc(application.Init) } diff --git a/server/internal/redis/router/redis.go b/server/internal/redis/router/redis.go deleted file mode 100644 index ebdd37ed..00000000 --- a/server/internal/redis/router/redis.go +++ /dev/null @@ -1,51 +0,0 @@ -package router - -import ( - "mayfly-go/internal/redis/api" - "mayfly-go/internal/redis/imsg" - "mayfly-go/pkg/biz" - "mayfly-go/pkg/ioc" - "mayfly-go/pkg/req" - - "github.com/gin-gonic/gin" -) - -func InitRedisRouter(router *gin.RouterGroup) { - redis := router.Group("redis") - - rs := new(api.Redis) - biz.ErrIsNil(ioc.Inject(rs)) - - dashbord := new(api.Dashbord) - biz.ErrIsNil(ioc.Inject(dashbord)) - - reqs := [...]*req.Conf{ - req.NewGet("dashbord", dashbord.Dashbord), - - // 获取redis list - req.NewGet("", rs.RedisList), - - req.NewPost("/test-conn", rs.TestConn), - - req.NewPost("", rs.Save).Log(req.NewLogSaveI(imsg.LogRedisSave)), - - req.NewDelete(":id", rs.DeleteRedis).Log(req.NewLogSaveI(imsg.LogRedisDelete)), - - req.NewGet("/:id/info", rs.RedisInfo), - - req.NewGet(":id/cluster-info", rs.ClusterInfo), - - req.NewPost(":id/:db/run-cmd", rs.RunCmd).Log(req.NewLogSaveI(imsg.LogRedisRunCmd)), - - // 获取指定redis keys - req.NewPost(":id/:db/scan", rs.ScanKeys), - - req.NewGet(":id/:db/key-info", rs.KeyInfo), - - req.NewGet(":id/:db/key-ttl", rs.TtlKey), - - req.NewGet(":id/:db/key-memuse", rs.MemoryUsage), - } - - req.BatchSetGroup(redis, reqs[:]) -} diff --git a/server/internal/redis/router/router.go b/server/internal/redis/router/router.go deleted file mode 100644 index ac6df61c..00000000 --- a/server/internal/redis/router/router.go +++ /dev/null @@ -1,7 +0,0 @@ -package router - -import "github.com/gin-gonic/gin" - -func Init(router *gin.RouterGroup) { - InitRedisRouter(router) -} diff --git a/server/internal/sys/api/account.go b/server/internal/sys/api/account.go index 6c5286e7..8bb5dd13 100644 --- a/server/internal/sys/api/account.go +++ b/server/internal/sys/api/account.go @@ -2,7 +2,6 @@ package api import ( "mayfly-go/internal/common/utils" - msgapp "mayfly-go/internal/msg/application" "mayfly-go/internal/sys/api/form" "mayfly-go/internal/sys/api/vo" "mayfly-go/internal/sys/application" @@ -29,11 +28,56 @@ const ( ) type Account struct { - AccountApp application.Account `inject:""` - ResourceApp application.Resource `inject:""` - RoleApp application.Role `inject:""` - MsgApp msgapp.Msg `inject:""` - ConfigApp application.Config `inject:""` + accountApp application.Account `inject:"T"` + resourceApp application.Resource `inject:"T"` + roleApp application.Role `inject:"T"` +} + +func (a *Account) ReqConfs() *req.Confs { + addAccountPermission := req.NewPermission("account:add") + reqs := [...]*req.Conf{ + + // 获取个人账号的权限资源信息 + req.NewGet("/permissions", a.GetPermissions), + + req.NewPost("/change-pwd", a.ChangePassword).DontNeedToken().Log(req.NewLogSaveI(imsg.LogChangePassword)), + + // 获取个人账号信息 + req.NewGet("/self", a.AccountInfo), + + // 更新个人账号信息 + req.NewPut("/self", a.UpdateAccount), + + /** 后台管理接口 **/ + + // 获取所有用户列表 + req.NewGet("", a.Accounts), + + // 获取用户列表信息(只包含最基础信息) + req.NewGet("/simple", a.SimpleAccounts), + + // 根据账号id获取账号基础信息 + req.NewGet("/:id", a.AccountDetail), + + req.NewPost("", a.SaveAccount).Log(req.NewLogSaveI(imsg.LogAccountCreate)).RequiredPermission(addAccountPermission), + + req.NewPut("change-status/:id/:status", a.ChangeStatus).Log(req.NewLogSaveI(imsg.LogAccountChangeStatus)).RequiredPermission(addAccountPermission), + + req.NewPut(":id/reset-otp", a.ResetOtpSecret).Log(req.NewLogSaveI(imsg.LogResetOtpSecret)).RequiredPermission(addAccountPermission), + + req.NewDelete(":id", a.DeleteAccount).Log(req.NewLogSaveI(imsg.LogAccountDelete)).RequiredPermissionCode("account:del"), + + // 关联用户角色 + req.NewPost("/roles", a.RelateRole).Log(req.NewLogSaveI(imsg.LogAssignUserRoles)).RequiredPermissionCode("account:saveRoles"), + + // 获取用户角色 + req.NewGet(":id/roles", a.AccountRoles), + + // 获取用户资源列表 + req.NewGet(":id/resources", a.AccountResources), + } + + return req.NewConfs("sys/accounts", reqs[:]...) } // 获取当前登录用户的菜单与权限码 @@ -42,7 +86,7 @@ func (a *Account) GetPermissions(rc *req.Ctx) { var resources vo.AccountResourceVOList // 获取账号菜单资源 - biz.ErrIsNil(a.ResourceApp.GetAccountResources(account.Id, &resources)) + biz.ErrIsNil(a.resourceApp.GetAccountResources(account.Id, &resources)) // 菜单树与权限code数组 var menus vo.AccountResourceVOList var permissions []string @@ -70,7 +114,7 @@ func (a *Account) ChangePassword(rc *req.Ctx) { biz.ErrIsNilAppendErr(err, "Wrong to decrypt old password: %s") account := &entity.Account{Username: form.Username} - err = a.AccountApp.GetByCond(model.NewModelCond(account).Columns("Id", "Username", "Password", "Status")) + err = a.accountApp.GetByCond(model.NewModelCond(account).Columns("Id", "Username", "Password", "Status")) biz.ErrIsNilI(ctx, err, imsg.ErrOldPasswordWrong) biz.IsTrueI(ctx, cryptox.CheckPwdHash(originOldPwd, account.Password), imsg.ErrOldPasswordWrong) biz.IsTrue(account.IsEnable(), "This account is not available") @@ -82,7 +126,7 @@ func (a *Account) ChangePassword(rc *req.Ctx) { updateAccount := new(entity.Account) updateAccount.Id = account.Id updateAccount.Password = cryptox.PwdHash(originNewPwd) - biz.ErrIsNilAppendErr(a.AccountApp.Update(ctx, updateAccount), "failed to update account password: %s") + biz.ErrIsNilAppendErr(a.accountApp.Update(ctx, updateAccount), "failed to update account password: %s") // 赋值loginAccount 主要用于记录操作日志,因为操作日志保存请求上下文没有该信息不保存日志 contextx.WithLoginAccount(ctx, &model.LoginAccount{ @@ -111,14 +155,14 @@ func (a *Account) UpdateAccount(rc *req.Ctx) { updateAccount.Password = cryptox.PwdHash(updateAccount.Password) } - oldAcc, err := a.AccountApp.GetById(updateAccount.Id) + oldAcc, err := a.accountApp.GetById(updateAccount.Id) biz.ErrIsNilAppendErr(err, "Account does not exist: %s") // 账号创建十分钟内允许修改用户名(兼容oauth2首次登录修改用户名),否则不允许修改 if oldAcc.CreateTime.Add(10 * time.Minute).Before(time.Now()) { // 禁止更新用户名,防止误传被更新 updateAccount.Username = "" } - biz.ErrIsNil(a.AccountApp.Update(ctx, updateAccount)) + biz.ErrIsNil(a.accountApp.Update(ctx, updateAccount)) } /** 后台账号操作 **/ @@ -128,7 +172,7 @@ func (a *Account) Accounts(rc *req.Ctx) { condition := &entity.AccountQuery{} condition.Username = rc.Query("username") condition.Name = rc.Query("name") - res, err := a.AccountApp.GetPageList(condition, rc.GetPageParam(), new([]vo.AccountManageVO)) + res, err := a.accountApp.GetPageList(condition, rc.GetPageParam(), new([]vo.AccountManageVO)) biz.ErrIsNil(err) rc.ResData = res } @@ -143,7 +187,7 @@ func (a *Account) SimpleAccounts(rc *req.Ctx) { return cast.ToUint64(val) }) } - res, err := a.AccountApp.GetPageList(condition, rc.GetPageParam(), new([]vo.SimpleAccountVO)) + res, err := a.accountApp.GetPageList(condition, rc.GetPageParam(), new([]vo.SimpleAccountVO)) biz.ErrIsNil(err) rc.ResData = res } @@ -151,7 +195,7 @@ func (a *Account) SimpleAccounts(rc *req.Ctx) { // 获取账号详情 func (a *Account) AccountDetail(rc *req.Ctx) { accountId := uint64(rc.PathParamInt("id")) - account, err := a.AccountApp.GetById(accountId) + account, err := a.accountApp.GetById(accountId) biz.ErrIsNilAppendErr(err, "Account does not exist: %s") accountvo := new(vo.SimpleAccountVO) structx.Copy(accountvo, account) @@ -173,7 +217,7 @@ func (a *Account) SaveAccount(rc *req.Ctx) { biz.NotEmpty(account.Password, "password is required") biz.IsTrueI(ctx, utils.CheckAccountPasswordLever(account.Password), imsg.ErrAccountPasswordNotFollowRule) account.Password = cryptox.PwdHash(account.Password) - biz.ErrIsNil(a.AccountApp.Create(rc.MetaCtx, account)) + biz.ErrIsNil(a.accountApp.Create(rc.MetaCtx, account)) } else { if account.Password != "" { biz.IsTrueI(ctx, utils.CheckAccountPasswordLever(account.Password), imsg.ErrAccountPasswordNotFollowRule) @@ -181,7 +225,7 @@ func (a *Account) SaveAccount(rc *req.Ctx) { } // 更新操作不允许修改用户名、防止误传更新 account.Username = "" - biz.ErrIsNil(a.AccountApp.Update(ctx, account)) + biz.ErrIsNil(a.accountApp.Update(ctx, account)) } } @@ -194,7 +238,7 @@ func (a *Account) ChangeStatus(rc *req.Ctx) { account.Status = status rc.ReqParam = collx.Kvs("accountId", account.Id, "status", account.Status) - biz.ErrIsNil(a.AccountApp.Update(rc.MetaCtx, account)) + biz.ErrIsNil(a.accountApp.Update(rc.MetaCtx, account)) } func (a *Account) DeleteAccount(rc *req.Ctx) { @@ -203,7 +247,7 @@ func (a *Account) DeleteAccount(rc *req.Ctx) { ids := strings.Split(idsStr, ",") for _, v := range ids { - biz.ErrIsNil(a.AccountApp.Delete(rc.MetaCtx, cast.ToUint64(v))) + biz.ErrIsNil(a.accountApp.Delete(rc.MetaCtx, cast.ToUint64(v))) } } @@ -215,7 +259,7 @@ func (a *Account) AccountRoles(rc *req.Ctx) { func (a *Account) getAccountRoles(accountId uint64) []*vo.AccountRoleVO { vos := make([]*vo.AccountRoleVO, 0) - accountRoles, err := a.RoleApp.GetAccountRoles(accountId) + accountRoles, err := a.roleApp.GetAccountRoles(accountId) biz.ErrIsNil(err) if len(accountRoles) == 0 { @@ -226,7 +270,7 @@ func (a *Account) getAccountRoles(accountId uint64) []*vo.AccountRoleVO { roleIds := collx.ArrayMap[*entity.AccountRole, uint64](accountRoles, func(val *entity.AccountRole) uint64 { return val.RoleId }) - roles, err := a.RoleApp.ListByQuery(&entity.RoleQuery{Ids: roleIds}) + roles, err := a.roleApp.ListByQuery(&entity.RoleQuery{Ids: roleIds}) biz.ErrIsNil(err) roleId2Role := collx.ArrayToMap[*entity.Role, uint64](roles, func(val *entity.Role) uint64 { return val.Id @@ -253,7 +297,7 @@ func (a *Account) getAccountRoles(accountId uint64) []*vo.AccountRoleVO { func (a *Account) AccountResources(rc *req.Ctx) { var resources vo.ResourceManageVOList // 获取账号菜单资源 - biz.ErrIsNil(a.ResourceApp.GetAccountResources(uint64(rc.PathParamInt("id")), &resources)) + biz.ErrIsNil(a.resourceApp.GetAccountResources(uint64(rc.PathParamInt("id")), &resources)) rc.ResData = resources.ToTrees(0) } @@ -261,7 +305,7 @@ func (a *Account) AccountResources(rc *req.Ctx) { func (a *Account) RelateRole(rc *req.Ctx) { form := req.BindJsonAndValid(rc, new(form.AccountRoleForm)) rc.ReqParam = form - biz.ErrIsNil(a.RoleApp.RelateAccountRole(rc.MetaCtx, form.Id, form.RoleId, consts.AccountRoleRelateType(form.RelateType))) + biz.ErrIsNil(a.roleApp.RelateAccountRole(rc.MetaCtx, form.Id, form.RoleId, consts.AccountRoleRelateType(form.RelateType))) } // 重置otp秘钥 @@ -270,5 +314,5 @@ func (a *Account) ResetOtpSecret(rc *req.Ctx) { accountId := uint64(rc.PathParamInt("id")) account.Id = accountId rc.ReqParam = collx.Kvs("accountId", accountId) - biz.ErrIsNil(a.AccountApp.Update(rc.MetaCtx, account)) + biz.ErrIsNil(a.accountApp.Update(rc.MetaCtx, account)) } diff --git a/server/internal/sys/api/api.go b/server/internal/sys/api/api.go new file mode 100644 index 00000000..2ed604a0 --- /dev/null +++ b/server/internal/sys/api/api.go @@ -0,0 +1,12 @@ +package api + +import "mayfly-go/pkg/ioc" + +func InitIoc() { + ioc.Register(new(Account)) + ioc.Register(new(Config)) + ioc.Register(new(Resource)) + ioc.Register(new(Role)) + ioc.Register(new(Syslog)) + ioc.Register(new(System)) +} diff --git a/server/internal/sys/api/config.go b/server/internal/sys/api/config.go index d5f4f6e7..2518bfd9 100644 --- a/server/internal/sys/api/config.go +++ b/server/internal/sys/api/config.go @@ -4,6 +4,7 @@ import ( "mayfly-go/internal/sys/api/form" "mayfly-go/internal/sys/application" "mayfly-go/internal/sys/domain/entity" + "mayfly-go/internal/sys/imsg" "mayfly-go/pkg/biz" "mayfly-go/pkg/config" "mayfly-go/pkg/req" @@ -11,13 +12,30 @@ import ( ) type Config struct { - ConfigApp application.Config `inject:""` + configApp application.Config `inject:"T"` +} + +func (c *Config) ReqConfs() *req.Confs { + baseP := req.NewPermission("config:base") + + reqs := [...]*req.Conf{ + req.NewGet("", c.Configs).RequiredPermission(baseP), + + req.NewGet("/server", c.GetServerConfig).DontNeedToken(), + + // 获取指定配置key对应的值 + req.NewGet("/value", c.GetConfigValueByKey).DontNeedToken(), + + req.NewPost("", c.SaveConfig).Log(req.NewLogSaveI(imsg.LogSaveSysConfig)).RequiredPermissionCode("config:save"), + } + + return req.NewConfs("sys/configs", reqs[:]...) } func (c *Config) Configs(rc *req.Ctx) { condition := &entity.Config{Key: rc.Query("key")} condition.Permission = rc.GetLoginAccount().Username - res, err := c.ConfigApp.GetPageList(condition, rc.GetPageParam(), new([]entity.Config)) + res, err := c.configApp.GetPageList(condition, rc.GetPageParam(), new([]entity.Config)) biz.ErrIsNil(err) rc.ResData = res } @@ -26,7 +44,7 @@ func (c *Config) GetConfigValueByKey(rc *req.Ctx) { key := rc.Query("key") biz.NotEmpty(key, "key cannot be empty") - config := c.ConfigApp.GetConfig(key) + config := c.configApp.GetConfig(key) // 判断是否为公开配置 if config.Permission != "all" { rc.ResData = "" @@ -40,7 +58,7 @@ func (c *Config) SaveConfig(rc *req.Ctx) { form := &form.ConfigForm{} config := req.BindJsonAndCopyTo(rc, form, new(entity.Config)) rc.ReqParam = form - biz.ErrIsNil(c.ConfigApp.Save(rc.MetaCtx, config)) + biz.ErrIsNil(c.configApp.Save(rc.MetaCtx, config)) } // GetServerConfig 获取当前系统启动配置 diff --git a/server/internal/sys/api/resource.go b/server/internal/sys/api/resource.go index abd0f623..01d70a55 100644 --- a/server/internal/sys/api/resource.go +++ b/server/internal/sys/api/resource.go @@ -6,6 +6,7 @@ import ( "mayfly-go/internal/sys/api/vo" "mayfly-go/internal/sys/application" "mayfly-go/internal/sys/domain/entity" + "mayfly-go/internal/sys/imsg" "mayfly-go/pkg/biz" "mayfly-go/pkg/model" "mayfly-go/pkg/req" @@ -13,17 +14,37 @@ import ( ) type Resource struct { - ResourceApp application.Resource `inject:""` + resourceApp application.Resource `inject:"T"` +} + +func (r *Resource) ReqConfs() *req.Confs { + reqs := [...]*req.Conf{ + req.NewGet("", r.GetAllResourceTree), + + req.NewGet(":id", r.GetById), + + req.NewGet(":id/roles", r.GetResourceRoles), + + req.NewPost("", r.SaveResource).Log(req.NewLogSaveI(imsg.LogResourceSave)).RequiredPermissionCode("resource:add"), + + req.NewPut(":id/:status", r.ChangeStatus).Log(req.NewLogSaveI(imsg.LogChangeResourceStatus)).RequiredPermissionCode("resource:changeStatus"), + + req.NewPost("sort", r.Sort).Log(req.NewLogSaveI(imsg.LogSortResource)), + + req.NewDelete(":id", r.DelResource).Log(req.NewLogSaveI(imsg.LogResourceDelete)).RequiredPermissionCode("resource:delete"), + } + + return req.NewConfs("sys/resources", reqs[:]...) } func (r *Resource) GetAllResourceTree(rc *req.Ctx) { var resources vo.ResourceManageVOList - r.ResourceApp.ListByCondToAny(model.NewCond().OrderByAsc("weight"), &resources) + r.resourceApp.ListByCondToAny(model.NewCond().OrderByAsc("weight"), &resources) rc.ResData = resources.ToTrees(0) } func (r *Resource) GetById(rc *req.Ctx) { - res, err := r.ResourceApp.GetById(uint64(rc.PathParamInt("id"))) + res, err := r.resourceApp.GetById(uint64(rc.PathParamInt("id"))) biz.ErrIsNil(err, "The resource does not exist") rc.ResData = res } @@ -38,18 +59,18 @@ func (r *Resource) SaveResource(rc *req.Ctx) { bytes, _ := json.Marshal(form.Meta) entity.Meta = string(bytes) - biz.ErrIsNil(r.ResourceApp.Save(rc.MetaCtx, entity)) + biz.ErrIsNil(r.resourceApp.Save(rc.MetaCtx, entity)) } func (r *Resource) DelResource(rc *req.Ctx) { - biz.ErrIsNil(r.ResourceApp.Delete(rc.MetaCtx, uint64(rc.PathParamInt("id")))) + biz.ErrIsNil(r.resourceApp.Delete(rc.MetaCtx, uint64(rc.PathParamInt("id")))) } func (r *Resource) ChangeStatus(rc *req.Ctx) { rid := uint64(rc.PathParamInt("id")) status := int8(rc.PathParamInt("status")) rc.ReqParam = collx.Kvs("id", rid, "status", status) - biz.ErrIsNil(r.ResourceApp.ChangeStatus(rc.MetaCtx, rid, status)) + biz.ErrIsNil(r.resourceApp.ChangeStatus(rc.MetaCtx, rid, status)) } func (r *Resource) Sort(rc *req.Ctx) { @@ -60,13 +81,13 @@ func (r *Resource) Sort(rc *req.Ctx) { for _, v := range rs { sortE := &entity.Resource{Pid: v.Pid, Weight: v.Weight} sortE.Id = uint64(v.Id) - r.ResourceApp.Sort(rc.MetaCtx, sortE) + r.resourceApp.Sort(rc.MetaCtx, sortE) } } // GetResourceRoles func (r *Resource) GetResourceRoles(rc *req.Ctx) { - rrs, err := r.ResourceApp.GetResourceRoles(uint64(rc.PathParamInt("id"))) + rrs, err := r.resourceApp.GetResourceRoles(uint64(rc.PathParamInt("id"))) biz.ErrIsNil(err) rc.ResData = rrs } diff --git a/server/internal/sys/api/role.go b/server/internal/sys/api/role.go index 7ba2c9bf..2a2cc925 100644 --- a/server/internal/sys/api/role.go +++ b/server/internal/sys/api/role.go @@ -5,6 +5,7 @@ import ( "mayfly-go/internal/sys/api/vo" "mayfly-go/internal/sys/application" "mayfly-go/internal/sys/domain/entity" + "mayfly-go/internal/sys/imsg" "mayfly-go/pkg/biz" "mayfly-go/pkg/req" "mayfly-go/pkg/utils/collx" @@ -14,8 +15,27 @@ import ( ) type Role struct { - RoleApp application.Role `inject:""` - ResourceApp application.Resource `inject:""` + roleApp application.Role `inject:"T"` +} + +func (r *Role) ReqConfs() *req.Confs { + reqs := [...]*req.Conf{ + req.NewGet("", r.Roles), + + req.NewPost("", r.SaveRole).Log(req.NewLogSaveI(imsg.LogRoleSave)).RequiredPermissionCode("role:add"), + + req.NewDelete(":id", r.DelRole).Log(req.NewLogSaveI(imsg.LogRoleDelete)).RequiredPermissionCode("role:del"), + + req.NewGet(":id/resourceIds", r.RoleResourceIds), + + req.NewGet(":id/resources", r.RoleResource), + + req.NewPost(":id/resources", r.SaveResource).Log(req.NewLogSaveI(imsg.LogAssignRoleResource)).RequiredPermissionCode("role:saveResources"), + + req.NewGet(":id/accounts", r.RoleAccount), + } + + return req.NewConfs("sys/roles", reqs[:]...) } func (r *Role) Roles(rc *req.Ctx) { @@ -28,7 +48,7 @@ func (r *Role) Roles(rc *req.Ctx) { }) } - res, err := r.RoleApp.GetPageList(cond, pageParam, new([]entity.Role)) + res, err := r.roleApp.GetPageList(cond, pageParam, new([]entity.Role)) biz.ErrIsNil(err) rc.ResData = res } @@ -39,7 +59,7 @@ func (r *Role) SaveRole(rc *req.Ctx) { role := req.BindJsonAndCopyTo(rc, form, new(entity.Role)) rc.ReqParam = form - r.RoleApp.SaveRole(rc.MetaCtx, role) + r.roleApp.SaveRole(rc.MetaCtx, role) } // 删除角色及其资源关联关系 @@ -49,19 +69,19 @@ func (r *Role) DelRole(rc *req.Ctx) { ids := strings.Split(idsStr, ",") for _, v := range ids { - biz.ErrIsNil(r.RoleApp.DeleteRole(rc.MetaCtx, cast.ToUint64(v))) + biz.ErrIsNil(r.roleApp.DeleteRole(rc.MetaCtx, cast.ToUint64(v))) } } // 获取角色关联的资源id数组,用于分配资源时回显已拥有的资源 func (r *Role) RoleResourceIds(rc *req.Ctx) { - rc.ResData = r.RoleApp.GetRoleResourceIds(uint64(rc.PathParamInt("id"))) + rc.ResData = r.roleApp.GetRoleResourceIds(uint64(rc.PathParamInt("id"))) } // 查看角色关联的资源树信息 func (r *Role) RoleResource(rc *req.Ctx) { var resources vo.ResourceManageVOList - r.RoleApp.GetRoleResources(uint64(rc.PathParamInt("id")), &resources) + r.roleApp.GetRoleResources(uint64(rc.PathParamInt("id")), &resources) rc.ResData = resources.ToTrees(0) } @@ -76,7 +96,7 @@ func (r *Role) SaveResource(rc *req.Ctx) { return cast.ToUint64(val) }) - biz.ErrIsNilAppendErr(r.RoleApp.SaveRoleResource(rc.MetaCtx, form.Id, newIds), "save role resource failed: %s") + biz.ErrIsNilAppendErr(r.roleApp.SaveRoleResource(rc.MetaCtx, form.Id, newIds), "save role resource failed: %s") } // 查看角色关联的用户 @@ -84,7 +104,7 @@ func (r *Role) RoleAccount(rc *req.Ctx) { cond, pageParam := req.BindQueryAndPage[*entity.RoleAccountQuery](rc, new(entity.RoleAccountQuery)) cond.RoleId = uint64(rc.PathParamInt("id")) var accounts []*vo.AccountRoleVO - res, err := r.RoleApp.GetRoleAccountPage(cond, pageParam, &accounts) + res, err := r.roleApp.GetRoleAccountPage(cond, pageParam, &accounts) biz.ErrIsNil(err) rc.ResData = res } diff --git a/server/internal/sys/api/syslog.go b/server/internal/sys/api/syslog.go index 1380794c..d0d8b336 100644 --- a/server/internal/sys/api/syslog.go +++ b/server/internal/sys/api/syslog.go @@ -8,16 +8,25 @@ import ( ) type Syslog struct { - SyslogApp application.Syslog `inject:""` + syslogApp application.Syslog `inject:"T"` +} + +func (s *Syslog) ReqConfs() *req.Confs { + reqs := [...]*req.Conf{ + req.NewGet("", s.Syslogs), + req.NewGet("/:id", s.SyslogDetail), + } + + return req.NewConfs("syslogs", reqs[:]...) } func (r *Syslog) Syslogs(rc *req.Ctx) { queryCond, page := req.BindQueryAndPage[*entity.SysLogQuery](rc, new(entity.SysLogQuery)) - res, err := r.SyslogApp.GetPageList(queryCond, page, new([]entity.SysLog), "create_time DESC") + res, err := r.syslogApp.GetPageList(queryCond, page, new([]entity.SysLog), "create_time DESC") biz.ErrIsNil(err) rc.ResData = res } func (r *Syslog) SyslogDetail(rc *req.Ctx) { - rc.ResData = r.SyslogApp.GetLogDetail(uint64(rc.PathParamInt("id"))) + rc.ResData = r.syslogApp.GetLogDetail(uint64(rc.PathParamInt("id"))) } diff --git a/server/internal/sys/api/system.go b/server/internal/sys/api/system.go index a3c3374f..fd363192 100644 --- a/server/internal/sys/api/system.go +++ b/server/internal/sys/api/system.go @@ -7,16 +7,22 @@ import ( "mayfly-go/pkg/utils/anyx" "mayfly-go/pkg/ws" - "github.com/gin-gonic/gin" "github.com/gorilla/websocket" ) type System struct { } +func (s *System) ReqConfs() *req.Confs { + reqs := [...]*req.Conf{ + req.NewGet("", s.ConnectWs), + } + return req.NewConfs("sysmsg", reqs[:]...) +} + // 连接websocket -func (s *System) ConnectWs(g *gin.Context) { - wsConn, err := ws.Upgrader.Upgrade(g.Writer, g.Request, nil) +func (s *System) ConnectWs(rc *req.Ctx) { + wsConn, err := ws.Upgrader.Upgrade(rc.GetWriter(), rc.GetRequest(), nil) defer func() { if err := recover(); err != nil { errInfo := anyx.ToString(err) @@ -29,11 +35,11 @@ func (s *System) ConnectWs(g *gin.Context) { }() biz.ErrIsNil(err) - clientId := g.Query("clientId") + clientId := rc.Query("clientId") biz.NotEmpty(clientId, "clientId cannot be empty") // 权限校验 - rc := req.NewCtxWithGin(g) + // rc := req.NewCtxWithGin(g) err = req.PermissionHandler(rc) biz.ErrIsNil(err, "sys-websocket connect without permission") diff --git a/server/internal/sys/application/account.go b/server/internal/sys/application/account.go index 68efd495..c271c6cc 100644 --- a/server/internal/sys/application/account.go +++ b/server/internal/sys/application/account.go @@ -25,7 +25,7 @@ type Account interface { type accountAppImpl struct { base.AppImpl[*entity.Account, repository.Account] - accountRoleRepo repository.AccountRole `inject:"AccountRoleRepo"` + accountRoleRepo repository.AccountRole `inject:"T"` } func (a *accountAppImpl) GetPageList(condition *entity.AccountQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) { diff --git a/server/internal/sys/application/resource.go b/server/internal/sys/application/resource.go index 919a8d04..e4da6075 100644 --- a/server/internal/sys/application/resource.go +++ b/server/internal/sys/application/resource.go @@ -35,8 +35,8 @@ type Resource interface { type resourceAppImpl struct { base.AppImpl[*entity.Resource, repository.Resource] - roleResourceRepo repository.RoleResource `inject:"RoleResourceRepo"` - roleApp Role `inject:"RoleApp"` + roleResourceRepo repository.RoleResource `inject:"T"` + roleApp Role `inject:"T"` } var _ (Resource) = (*resourceAppImpl)(nil) diff --git a/server/internal/sys/application/role.go b/server/internal/sys/application/role.go index 448a0edf..cd199763 100644 --- a/server/internal/sys/application/role.go +++ b/server/internal/sys/application/role.go @@ -46,8 +46,8 @@ type Role interface { type roleAppImpl struct { base.AppImpl[*entity.Role, repository.Role] - accountRoleRepo repository.AccountRole `inject:"AccountRoleRepo"` - roleResourceRepo repository.RoleResource `inject:"RoleResourceRepo"` + accountRoleRepo repository.AccountRole `inject:"T"` + roleResourceRepo repository.RoleResource `inject:"T"` } var _ (Role) = (*roleAppImpl)(nil) diff --git a/server/internal/sys/application/syslog.go b/server/internal/sys/application/syslog.go index 6b279fa7..f1bee5ad 100644 --- a/server/internal/sys/application/syslog.go +++ b/server/internal/sys/application/syslog.go @@ -56,11 +56,11 @@ type Syslog interface { } type syslogAppImpl struct { - SyslogRepo repository.Syslog `inject:""` + syslogRepo repository.Syslog `inject:"T"` } func (m *syslogAppImpl) GetPageList(condition *entity.SysLogQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) { - return m.SyslogRepo.GetPageList(condition, pageParam, toEntity, orderBy...) + return m.syslogRepo.GetPageList(condition, pageParam, toEntity, orderBy...) } func (m *syslogAppImpl) SaveFromReq(req *req.Ctx) { @@ -106,7 +106,7 @@ func (m *syslogAppImpl) SaveFromReq(req *req.Ctx) { syslog.Type = entity.SyslogTypeSuccess } - m.SyslogRepo.Insert(req.MetaCtx, syslog) + m.syslogRepo.Insert(req.MetaCtx, syslog) } func (m *syslogAppImpl) GetLogDetail(logId uint64) *entity.SysLog { @@ -114,7 +114,7 @@ func (m *syslogAppImpl) GetLogDetail(logId uint64) *entity.SysLog { if syslog != nil { return syslog } - syslog, err := m.SyslogRepo.GetById(logId) + syslog, err := m.syslogRepo.GetById(logId) if err != nil { return nil } @@ -128,7 +128,7 @@ func (m *syslogAppImpl) CreateLog(ctx context.Context, log *CreateLogReq) (uint6 if len(log.Extra) > 0 { syslog.Extra = jsonx.ToStr(log.Extra) } - if err := m.SyslogRepo.Insert(ctx, syslog); err != nil { + if err := m.syslogRepo.Insert(ctx, syslog); err != nil { return 0, err } return syslog.Id, nil @@ -137,7 +137,7 @@ func (m *syslogAppImpl) CreateLog(ctx context.Context, log *CreateLogReq) (uint6 func (m *syslogAppImpl) AppendLog(logId uint64, appendLog *AppendLogReq) { syslog := m.GetCacheLog(logId) if syslog == nil { - sl, err := m.SyslogRepo.GetById(logId) + sl, err := m.syslogRepo.GetById(logId) if err != nil { logx.Warnf("追加日志不存在: %d", logId) return @@ -159,7 +159,7 @@ func (m *syslogAppImpl) AppendLog(logId uint64, appendLog *AppendLogReq) { func (m *syslogAppImpl) SetExtra(logId uint64, key string, val any) { syslog := m.GetCacheLog(logId) if syslog == nil { - sl, err := m.SyslogRepo.GetById(logId) + sl, err := m.syslogRepo.GetById(logId) if err != nil { logx.Warnf("追加日志不存在: %d", logId) return @@ -195,7 +195,7 @@ func (m *syslogAppImpl) Flush(logId uint64, clearExtra bool) { if clearExtra { syslog.Extra = "" } - m.SyslogRepo.UpdateById(context.Background(), syslog) + m.syslogRepo.UpdateById(context.Background(), syslog) m.DelCacheLog(logId) } diff --git a/server/internal/sys/init/init.go b/server/internal/sys/init/init.go index 49012f67..255e362d 100644 --- a/server/internal/sys/init/init.go +++ b/server/internal/sys/init/init.go @@ -2,15 +2,15 @@ package init import ( "mayfly-go/initialize" + "mayfly-go/internal/sys/api" "mayfly-go/internal/sys/application" "mayfly-go/internal/sys/infrastructure/persistence" - "mayfly-go/internal/sys/router" ) func init() { initialize.AddInitIocFunc(func() { persistence.InitIoc() application.InitIoc() + api.InitIoc() }) - initialize.AddInitRouterFunc(router.Init) } diff --git a/server/internal/sys/router/account.go b/server/internal/sys/router/account.go deleted file mode 100644 index 5a2a5830..00000000 --- a/server/internal/sys/router/account.go +++ /dev/null @@ -1,63 +0,0 @@ -package router - -import ( - "mayfly-go/internal/sys/api" - "mayfly-go/internal/sys/imsg" - "mayfly-go/pkg/biz" - "mayfly-go/pkg/ioc" - "mayfly-go/pkg/req" - - "github.com/gin-gonic/gin" -) - -func InitAccountRouter(router *gin.RouterGroup) { - account := router.Group("sys/accounts") - a := new(api.Account) - biz.ErrIsNil(ioc.Inject(a)) - - addAccountPermission := req.NewPermission("account:add") - - reqs := [...]*req.Conf{ - - // 获取个人账号的权限资源信息 - req.NewGet("/permissions", a.GetPermissions), - - req.NewPost("/change-pwd", a.ChangePassword).DontNeedToken().Log(req.NewLogSaveI(imsg.LogChangePassword)), - - // 获取个人账号信息 - req.NewGet("/self", a.AccountInfo), - - // 更新个人账号信息 - req.NewPut("/self", a.UpdateAccount), - - /** 后台管理接口 **/ - - // 获取所有用户列表 - req.NewGet("", a.Accounts), - - // 获取用户列表信息(只包含最基础信息) - req.NewGet("/simple", a.SimpleAccounts), - - // 根据账号id获取账号基础信息 - req.NewGet("/:id", a.AccountDetail), - - req.NewPost("", a.SaveAccount).Log(req.NewLogSaveI(imsg.LogAccountCreate)).RequiredPermission(addAccountPermission), - - req.NewPut("change-status/:id/:status", a.ChangeStatus).Log(req.NewLogSaveI(imsg.LogAccountChangeStatus)).RequiredPermission(addAccountPermission), - - req.NewPut(":id/reset-otp", a.ResetOtpSecret).Log(req.NewLogSaveI(imsg.LogResetOtpSecret)).RequiredPermission(addAccountPermission), - - req.NewDelete(":id", a.DeleteAccount).Log(req.NewLogSaveI(imsg.LogAccountDelete)).RequiredPermissionCode("account:del"), - - // 关联用户角色 - req.NewPost("/roles", a.RelateRole).Log(req.NewLogSaveI(imsg.LogAssignUserRoles)).RequiredPermissionCode("account:saveRoles"), - - // 获取用户角色 - req.NewGet(":id/roles", a.AccountRoles), - - // 获取用户资源列表 - req.NewGet(":id/resources", a.AccountResources), - } - - req.BatchSetGroup(account, reqs[:]) -} diff --git a/server/internal/sys/router/config.go b/server/internal/sys/router/config.go deleted file mode 100644 index 37bb0095..00000000 --- a/server/internal/sys/router/config.go +++ /dev/null @@ -1,32 +0,0 @@ -package router - -import ( - "mayfly-go/internal/sys/api" - "mayfly-go/internal/sys/imsg" - "mayfly-go/pkg/biz" - "mayfly-go/pkg/ioc" - "mayfly-go/pkg/req" - - "github.com/gin-gonic/gin" -) - -func InitSysConfigRouter(router *gin.RouterGroup) { - configG := router.Group("sys/configs") - r := new(api.Config) - biz.ErrIsNil(ioc.Inject(r)) - - baseP := req.NewPermission("config:base") - - reqs := [...]*req.Conf{ - req.NewGet("", r.Configs).RequiredPermission(baseP), - - req.NewGet("/server", r.GetServerConfig).DontNeedToken(), - - // 获取指定配置key对应的值 - req.NewGet("/value", r.GetConfigValueByKey).DontNeedToken(), - - req.NewPost("", r.SaveConfig).Log(req.NewLogSaveI(imsg.LogSaveSysConfig)).RequiredPermissionCode("config:save"), - } - - req.BatchSetGroup(configG, reqs[:]) -} diff --git a/server/internal/sys/router/resource.go b/server/internal/sys/router/resource.go deleted file mode 100644 index 03d72641..00000000 --- a/server/internal/sys/router/resource.go +++ /dev/null @@ -1,35 +0,0 @@ -package router - -import ( - "mayfly-go/internal/sys/api" - "mayfly-go/internal/sys/imsg" - "mayfly-go/pkg/biz" - "mayfly-go/pkg/ioc" - "mayfly-go/pkg/req" - - "github.com/gin-gonic/gin" -) - -func InitResourceRouter(router *gin.RouterGroup) { - rg := router.Group("sys/resources") - r := new(api.Resource) - biz.ErrIsNil(ioc.Inject(r)) - - reqs := [...]*req.Conf{ - req.NewGet("", r.GetAllResourceTree), - - req.NewGet(":id", r.GetById), - - req.NewGet(":id/roles", r.GetResourceRoles), - - req.NewPost("", r.SaveResource).Log(req.NewLogSaveI(imsg.LogResourceSave)).RequiredPermissionCode("resource:add"), - - req.NewPut(":id/:status", r.ChangeStatus).Log(req.NewLogSaveI(imsg.LogChangeResourceStatus)).RequiredPermissionCode("resource:changeStatus"), - - req.NewPost("sort", r.Sort).Log(req.NewLogSaveI(imsg.LogSortResource)), - - req.NewDelete(":id", r.DelResource).Log(req.NewLogSaveI(imsg.LogResourceDelete)).RequiredPermissionCode("resource:delete"), - } - - req.BatchSetGroup(rg, reqs[:]) -} diff --git a/server/internal/sys/router/role.go b/server/internal/sys/router/role.go deleted file mode 100644 index 7a9ee9dc..00000000 --- a/server/internal/sys/router/role.go +++ /dev/null @@ -1,35 +0,0 @@ -package router - -import ( - "mayfly-go/internal/sys/api" - "mayfly-go/internal/sys/imsg" - "mayfly-go/pkg/biz" - "mayfly-go/pkg/ioc" - "mayfly-go/pkg/req" - - "github.com/gin-gonic/gin" -) - -func InitRoleRouter(router *gin.RouterGroup) { - rg := router.Group("sys/roles") - r := new(api.Role) - biz.ErrIsNil(ioc.Inject(r)) - - reqs := [...]*req.Conf{ - req.NewGet("", r.Roles), - - req.NewPost("", r.SaveRole).Log(req.NewLogSaveI(imsg.LogRoleSave)).RequiredPermissionCode("role:add"), - - req.NewDelete(":id", r.DelRole).Log(req.NewLogSaveI(imsg.LogRoleDelete)).RequiredPermissionCode("role:del"), - - req.NewGet(":id/resourceIds", r.RoleResourceIds), - - req.NewGet(":id/resources", r.RoleResource), - - req.NewPost(":id/resources", r.SaveResource).Log(req.NewLogSaveI(imsg.LogAssignRoleResource)).RequiredPermissionCode("role:saveResources"), - - req.NewGet(":id/accounts", r.RoleAccount), - } - - req.BatchSetGroup(rg, reqs[:]) -} diff --git a/server/internal/sys/router/router.go b/server/internal/sys/router/router.go deleted file mode 100644 index e206169a..00000000 --- a/server/internal/sys/router/router.go +++ /dev/null @@ -1,14 +0,0 @@ -package router - -import ( - "github.com/gin-gonic/gin" -) - -func Init(router *gin.RouterGroup) { - InitAccountRouter(router) // 注册account路由 - InitResourceRouter(router) - InitRoleRouter(router) - InitSystemRouter(router) - InitSyslogRouter(router) - InitSysConfigRouter(router) -} diff --git a/server/internal/sys/router/syslog.go b/server/internal/sys/router/syslog.go deleted file mode 100644 index b8e59dca..00000000 --- a/server/internal/sys/router/syslog.go +++ /dev/null @@ -1,20 +0,0 @@ -package router - -import ( - "mayfly-go/internal/sys/api" - "mayfly-go/pkg/biz" - "mayfly-go/pkg/ioc" - "mayfly-go/pkg/req" - - "github.com/gin-gonic/gin" -) - -func InitSyslogRouter(router *gin.RouterGroup) { - sysG := router.Group("syslogs") - s := new(api.Syslog) - biz.ErrIsNil(ioc.Inject(s)) - - req.NewGet("", s.Syslogs).Group(sysG) - - req.NewGet("/:id", s.SyslogDetail).Group(sysG) -} diff --git a/server/internal/sys/router/system.go b/server/internal/sys/router/system.go deleted file mode 100644 index 4b46d307..00000000 --- a/server/internal/sys/router/system.go +++ /dev/null @@ -1,19 +0,0 @@ -package router - -import ( - "mayfly-go/internal/sys/api" - "mayfly-go/pkg/biz" - "mayfly-go/pkg/ioc" - - "github.com/gin-gonic/gin" -) - -func InitSystemRouter(router *gin.RouterGroup) { - sys := router.Group("sysmsg") - s := new(api.System) - biz.ErrIsNil(ioc.Inject(s)) - - { - sys.GET("", s.ConnectWs) - } -} diff --git a/server/internal/tag/api/api.go b/server/internal/tag/api/api.go new file mode 100644 index 00000000..5bacc20a --- /dev/null +++ b/server/internal/tag/api/api.go @@ -0,0 +1,10 @@ +package api + +import "mayfly-go/pkg/ioc" + +func InitIoc() { + ioc.Register(new(ResourceAuthCert)) + ioc.Register(new(ResourceOpLog)) + ioc.Register(new(TagTree)) + ioc.Register(new(Team)) +} diff --git a/server/internal/tag/api/resource_auth_cert.go b/server/internal/tag/api/resource_auth_cert.go index 6f0b622a..907fb28b 100644 --- a/server/internal/tag/api/resource_auth_cert.go +++ b/server/internal/tag/api/resource_auth_cert.go @@ -5,6 +5,7 @@ import ( "mayfly-go/internal/tag/api/vo" "mayfly-go/internal/tag/application" "mayfly-go/internal/tag/domain/entity" + "mayfly-go/internal/tag/imsg" "mayfly-go/pkg/biz" "mayfly-go/pkg/model" "mayfly-go/pkg/req" @@ -14,7 +15,23 @@ import ( ) type ResourceAuthCert struct { - ResourceAuthCertApp application.ResourceAuthCert `inject:""` + resourceAuthCertApp application.ResourceAuthCert `inject:"T"` +} + +func (r *ResourceAuthCert) ReqConfs() *req.Confs { + reqs := [...]*req.Conf{ + req.NewGet("", r.ListByQuery), + + req.NewGet("/simple", r.SimpleAc), + + req.NewGet("/detail", r.GetCompleteAuthCert).Log(req.NewLogSaveI(imsg.LogAcShowPwd)).RequiredPermissionCode("authcert:showciphertext"), + + req.NewPost("", r.SaveAuthCert).Log(req.NewLogSaveI(imsg.LogAcSave)).RequiredPermissionCode("authcert:save"), + + req.NewDelete(":id", r.Delete).Log(req.NewLogSaveI(imsg.LogAcDelete)).RequiredPermissionCode("authcert:del"), + } + + return req.NewConfs("/auth-certs", reqs[:]...) } func (r *ResourceAuthCert) ListByQuery(rc *req.Ctx) { @@ -25,7 +42,7 @@ func (r *ResourceAuthCert) ListByQuery(rc *req.Ctx) { cond.CiphertextType = entity.AuthCertCiphertextType(rc.QueryInt("ciphertextType")) cond.Name = rc.Query("name") - res, err := r.ResourceAuthCertApp.PageByCond(cond, rc.GetPageParam()) + res, err := r.resourceAuthCertApp.PageByCond(cond, rc.GetPageParam()) biz.ErrIsNil(err) for _, rac := range res.List { rac.CiphertextClear() @@ -38,7 +55,7 @@ func (m *ResourceAuthCert) SimpleAc(rc *req.Ctx) { biz.NotEmpty(acCodesStr, "codes不能为空") var vos []vo.SimpleResourceAuthCert - m.ResourceAuthCertApp.ListByCondToAny(model.NewCond().In("name", strings.Split(acCodesStr, ",")), &vos) + m.resourceAuthCertApp.ListByCondToAny(model.NewCond().In("name", strings.Split(acCodesStr, ",")), &vos) rc.ResData = vos } @@ -48,7 +65,7 @@ func (r *ResourceAuthCert) GetCompleteAuthCert(rc *req.Ctx) { rc.ReqParam = acName res := &entity.ResourceAuthCert{Name: acName} - err := r.ResourceAuthCertApp.GetByCond(res) + err := r.resourceAuthCertApp.GetByCond(res) biz.ErrIsNil(err) res.CiphertextDecrypt() rc.ResData = res @@ -62,11 +79,11 @@ func (c *ResourceAuthCert) SaveAuthCert(rc *req.Ctx) { acForm.Ciphertext = "***" rc.ReqParam = acForm - biz.ErrIsNil(c.ResourceAuthCertApp.SaveAuthCert(rc.MetaCtx, ac)) + biz.ErrIsNil(c.resourceAuthCertApp.SaveAuthCert(rc.MetaCtx, ac)) } func (c *ResourceAuthCert) Delete(rc *req.Ctx) { id := rc.PathParamInt("id") rc.ReqParam = id - biz.ErrIsNil(c.ResourceAuthCertApp.DeleteAuthCert(rc.MetaCtx, cast.ToUint64(id))) + biz.ErrIsNil(c.resourceAuthCertApp.DeleteAuthCert(rc.MetaCtx, cast.ToUint64(id))) } diff --git a/server/internal/tag/api/resource_op_log.go b/server/internal/tag/api/resource_op_log.go index 59976ac4..7f224ef7 100644 --- a/server/internal/tag/api/resource_op_log.go +++ b/server/internal/tag/api/resource_op_log.go @@ -8,7 +8,15 @@ import ( ) type ResourceOpLog struct { - ResourceOpLogApp application.ResourceOpLog `inject:""` + resourceOpLogApp application.ResourceOpLog `inject:"T"` +} + +func (r *ResourceOpLog) ReqConfs() *req.Confs { + reqs := [...]*req.Conf{ + req.NewGet("/account", r.PageAccountOpLog), + } + + return req.NewConfs("/resource-op-logs", reqs[:]...) } func (r *ResourceOpLog) PageAccountOpLog(rc *req.Ctx) { @@ -17,7 +25,7 @@ func (r *ResourceOpLog) PageAccountOpLog(rc *req.Ctx) { cond.ResourceType = int8(rc.QueryInt("resourceType")) cond.CreatorId = rc.GetLoginAccount().Id - rols, err := r.ResourceOpLogApp.PageByCond(cond, rc.GetPageParam()) + rols, err := r.resourceOpLogApp.PageByCond(cond, rc.GetPageParam()) biz.ErrIsNil(err) rc.ResData = rols } diff --git a/server/internal/tag/api/tag_tree.go b/server/internal/tag/api/tag_tree.go index 4cc2a5f7..1a3d2615 100644 --- a/server/internal/tag/api/tag_tree.go +++ b/server/internal/tag/api/tag_tree.go @@ -7,6 +7,7 @@ import ( "mayfly-go/internal/tag/application" "mayfly-go/internal/tag/application/dto" "mayfly-go/internal/tag/domain/entity" + "mayfly-go/internal/tag/imsg" "mayfly-go/pkg/biz" "mayfly-go/pkg/req" "mayfly-go/pkg/utils/collx" @@ -15,8 +16,33 @@ import ( ) type TagTree struct { - TagTreeApp application.TagTree `inject:""` - TagTreeRelateApp application.TagTreeRelate `inject:""` + tagTreeApp application.TagTree `inject:"T"` + tagTreeRelateApp application.TagTreeRelate `inject:"T"` +} + +func (t *TagTree) ReqConfs() *req.Confs { + reqs := [...]*req.Conf{ + // 获取标签树列表 + req.NewGet("", t.GetTagTree), + + // 根据条件获取标签 + req.NewGet("query", t.ListByQuery), + + req.NewPost("", t.SaveTagTree).Log(req.NewLogSaveI(imsg.LogTagSave)).RequiredPermissionCode("tag:save"), + + req.NewDelete(":id", t.DelTagTree).Log(req.NewLogSaveI(imsg.LogTagDelete)).RequiredPermissionCode("tag:del"), + + req.NewPost("/moving", t.MovingTag).Log(req.NewLogSaveI(imsg.LogTagMove)).RequiredPermissionCode("tag:save"), + + req.NewGet("/resources/tag-paths", t.TagResources), + + req.NewGet("/resources/count", t.CountTagResource), + + // 获取关联的标签id列表 + req.NewGet("/relate/:relateType/:relateId", t.GetRelateTagIds), + } + + return req.NewConfs("/tag-trees", reqs[:]...) } func (p *TagTree) GetTagTree(rc *req.Ctx) { @@ -28,7 +54,7 @@ func (p *TagTree) GetTagTree(rc *req.Ctx) { }) } - accountTags := p.TagTreeApp.GetAccountTags(rc.GetLoginAccount().Id, &entity.TagTreeQuery{TypePaths: typePaths}) + accountTags := p.tagTreeApp.GetAccountTags(rc.GetLoginAccount().Id, &entity.TagTreeQuery{TypePaths: typePaths}) if len(accountTags) == 0 { rc.ResData = []any{} return @@ -67,7 +93,7 @@ func (p *TagTree) complteTags(resourceTags []*dto.SimpleTagTree) []*dto.SimpleTa } var tags []*dto.SimpleTagTree - p.TagTreeApp.ListByQuery(&entity.TagTreeQuery{CodePaths: notExistCodePaths}, &tags) + p.tagTreeApp.ListByQuery(&entity.TagTreeQuery{CodePaths: notExistCodePaths}, &tags) // 完善需要补充的标签信息 return append(resourceTags, tags...) } @@ -86,7 +112,7 @@ func (p *TagTree) ListByQuery(rc *req.Ctx) { } var tagTrees []entity.TagTree - p.TagTreeApp.ListByQuery(cond, &tagTrees) + p.tagTreeApp.ListByQuery(cond, &tagTrees) rc.ResData = tagTrees } @@ -96,25 +122,25 @@ func (p *TagTree) SaveTagTree(rc *req.Ctx) { rc.ReqParam = fmt.Sprintf("tagTreeId: %d, tagName: %s, code: %s", tagTree.Id, tagTree.Name, tagTree.Code) - biz.ErrIsNil(p.TagTreeApp.SaveTag(rc.MetaCtx, tagForm.Pid, tagTree)) + biz.ErrIsNil(p.tagTreeApp.SaveTag(rc.MetaCtx, tagForm.Pid, tagTree)) } func (p *TagTree) DelTagTree(rc *req.Ctx) { - biz.ErrIsNil(p.TagTreeApp.Delete(rc.MetaCtx, uint64(rc.PathParamInt("id")))) + biz.ErrIsNil(p.tagTreeApp.Delete(rc.MetaCtx, uint64(rc.PathParamInt("id")))) } func (p *TagTree) MovingTag(rc *req.Ctx) { movingForm := &form.MovingTag{} req.BindJsonAndValid(rc, movingForm) rc.ReqParam = movingForm - biz.ErrIsNil(p.TagTreeApp.MovingTag(rc.MetaCtx, movingForm.FromPath, movingForm.ToPath)) + biz.ErrIsNil(p.tagTreeApp.MovingTag(rc.MetaCtx, movingForm.FromPath, movingForm.ToPath)) } // 获取用户可操作的标签路径 func (p *TagTree) TagResources(rc *req.Ctx) { resourceType := rc.Query("resourceType") biz.NotEmpty(resourceType, "resourceType cannot be empty") - tagResources := p.TagTreeApp.GetAccountTags(rc.GetLoginAccount().Id, &entity.TagTreeQuery{TypePaths: collx.AsArray(entity.TypePath(resourceType))}) + tagResources := p.tagTreeApp.GetAccountTags(rc.GetLoginAccount().Id, &entity.TagTreeQuery{TypePaths: collx.AsArray(entity.TypePath(resourceType))}) tagPath2Resource := collx.ArrayToMap[*dto.SimpleTagTree, string](tagResources, func(tagResource *dto.SimpleTagTree) string { return string(entity.CodePath(tagResource.CodePath).GetTag()) @@ -130,12 +156,12 @@ func (p *TagTree) CountTagResource(rc *req.Ctx) { tagPath := rc.Query("tagPath") accountId := rc.GetLoginAccount().Id - machineCodes := entity.GetCodesByCodePaths(entity.TagTypeMachine, p.TagTreeApp.GetAccountTags(accountId, &entity.TagTreeQuery{ + machineCodes := entity.GetCodesByCodePaths(entity.TagTypeMachine, p.tagTreeApp.GetAccountTags(accountId, &entity.TagTreeQuery{ TypePaths: collx.AsArray(entity.NewTypePaths(entity.TagTypeMachine, entity.TagTypeAuthCert)), CodePathLikes: collx.AsArray(tagPath), }).GetCodePaths()...) - dbCodes := entity.GetCodesByCodePaths(entity.TagTypeDb, p.TagTreeApp.GetAccountTags(accountId, &entity.TagTreeQuery{ + dbCodes := entity.GetCodesByCodePaths(entity.TagTypeDb, p.tagTreeApp.GetAccountTags(accountId, &entity.TagTreeQuery{ Types: collx.AsArray(entity.TagTypeDb), CodePathLikes: collx.AsArray(tagPath), }).GetCodePaths()...) @@ -143,11 +169,11 @@ func (p *TagTree) CountTagResource(rc *req.Ctx) { rc.ResData = collx.M{ "machine": len(machineCodes), "db": len(dbCodes), - "redis": len(p.TagTreeApp.GetAccountTags(accountId, &entity.TagTreeQuery{ + "redis": len(p.tagTreeApp.GetAccountTags(accountId, &entity.TagTreeQuery{ Types: collx.AsArray(entity.TagTypeRedis), CodePathLikes: collx.AsArray(tagPath), }).GetCodes()), - "mongo": len(p.TagTreeApp.GetAccountTags(accountId, &entity.TagTreeQuery{ + "mongo": len(p.tagTreeApp.GetAccountTags(accountId, &entity.TagTreeQuery{ Types: collx.AsArray(entity.TagTypeMongo), CodePathLikes: collx.AsArray(tagPath), }).GetCodes()), @@ -156,5 +182,5 @@ func (p *TagTree) CountTagResource(rc *req.Ctx) { // 获取关联的标签id func (p *TagTree) GetRelateTagIds(rc *req.Ctx) { - rc.ResData = p.TagTreeRelateApp.GetTagPathsByRelate(entity.TagRelateType(rc.PathParamInt("relateType")), uint64(rc.PathParamInt("relateId"))) + rc.ResData = p.tagTreeRelateApp.GetTagPathsByRelate(entity.TagRelateType(rc.PathParamInt("relateType")), uint64(rc.PathParamInt("relateId"))) } diff --git a/server/internal/tag/api/team.go b/server/internal/tag/api/team.go index 1eb5e79d..e8829b56 100644 --- a/server/internal/tag/api/team.go +++ b/server/internal/tag/api/team.go @@ -9,6 +9,7 @@ import ( "mayfly-go/internal/tag/application" "mayfly-go/internal/tag/application/dto" "mayfly-go/internal/tag/domain/entity" + "mayfly-go/internal/tag/imsg" "mayfly-go/pkg/biz" "mayfly-go/pkg/model" "mayfly-go/pkg/req" @@ -19,19 +20,38 @@ import ( ) type Team struct { - TeamApp application.Team `inject:""` - TagTreeApp application.TagTree `inject:""` - TagTreeRelateApp application.TagTreeRelate `inject:""` - AccountApp sys_applicaiton.Account `inject:""` + teamApp application.Team `inject:"T"` + tagTreeRelateApp application.TagTreeRelate `inject:"T"` + accountApp sys_applicaiton.Account `inject:"T"` +} + +func (t *Team) ReqConfs() *req.Confs { + reqs := [...]*req.Conf{ + // 获取团队列表 + req.NewGet("", t.GetTeams), + + req.NewPost("", t.SaveTeam).Log(req.NewLogSaveI(imsg.LogTeamSave)).RequiredPermissionCode("team:save"), + + req.NewDelete(":id", t.DelTeam).Log(req.NewLogSaveI(imsg.LogTeamDelete)).RequiredPermissionCode("team:del"), + + // 获取团队的成员信息列表 + req.NewGet("/:id/members", t.GetTeamMembers), + + req.NewPost("/:id/members", t.SaveTeamMember).Log(req.NewLogSaveI(imsg.LogTeamAddMember)).RequiredPermissionCode("team:member:save"), + + req.NewDelete("/:id/members/:accountId", t.DelTeamMember).Log(req.NewLogSaveI(imsg.LogTeamRemoveMember)).RequiredPermissionCode("team:member:del"), + } + + return req.NewConfs("/teams", reqs[:]...) } func (p *Team) GetTeams(rc *req.Ctx) { queryCond, page := req.BindQueryAndPage(rc, new(entity.TeamQuery)) var teams []*vo.Team - res, err := p.TeamApp.GetPageList(queryCond, page, &teams) + res, err := p.teamApp.GetPageList(queryCond, page, &teams) biz.ErrIsNil(err) - p.TagTreeRelateApp.FillTagInfo(entity.TagRelateTypeTeam, collx.ArrayMap(teams, func(mvo *vo.Team) entity.IRelateTag { + p.tagTreeRelateApp.FillTagInfo(entity.TagRelateTypeTeam, collx.ArrayMap(teams, func(mvo *vo.Team) entity.IRelateTag { return mvo })...) @@ -41,7 +61,7 @@ func (p *Team) GetTeams(rc *req.Ctx) { func (p *Team) SaveTeam(rc *req.Ctx) { team := req.BindJsonAndValid(rc, new(dto.SaveTeam)) rc.ReqParam = team - biz.ErrIsNil(p.TeamApp.SaveTeam(rc.MetaCtx, team)) + biz.ErrIsNil(p.teamApp.SaveTeam(rc.MetaCtx, team)) } func (p *Team) DelTeam(rc *req.Ctx) { @@ -50,7 +70,7 @@ func (p *Team) DelTeam(rc *req.Ctx) { ids := strings.Split(idsStr, ",") for _, v := range ids { - p.TeamApp.Delete(rc.MetaCtx, cast.ToUint64(v)) + p.teamApp.Delete(rc.MetaCtx, cast.ToUint64(v)) } } @@ -59,7 +79,7 @@ func (p *Team) GetTeamMembers(rc *req.Ctx) { condition := &entity.TeamMember{TeamId: uint64(rc.PathParamInt("id"))} condition.Username = rc.Query("username") - res, err := p.TeamApp.GetMemberPage(condition, rc.GetPageParam(), &[]vo.TeamMember{}) + res, err := p.teamApp.GetMemberPage(condition, rc.GetPageParam(), &[]vo.TeamMember{}) biz.ErrIsNil(err) rc.ResData = res } @@ -71,7 +91,7 @@ func (p *Team) SaveTeamMember(rc *req.Ctx) { teamId := teamMems.TeamId for _, accountId := range teamMems.AccountIds { - if p.TeamApp.IsExistMember(teamId, accountId) { + if p.teamApp.IsExistMember(teamId, accountId) { continue } @@ -79,13 +99,13 @@ func (p *Team) SaveTeamMember(rc *req.Ctx) { account := &sys_entity.Account{} account.Id = accountId - biz.ErrIsNil(p.AccountApp.GetByCond(model.NewModelCond(account).Columns("Id", "Username")), "账号不存在") + biz.ErrIsNil(p.accountApp.GetByCond(model.NewModelCond(account).Columns("Id", "Username")), "账号不存在") teamMember := new(entity.TeamMember) teamMember.TeamId = teamId teamMember.AccountId = accountId teamMember.Username = account.Username - p.TeamApp.SaveMember(rc.MetaCtx, teamMember) + p.teamApp.SaveMember(rc.MetaCtx, teamMember) } rc.ReqParam = teamMems @@ -97,5 +117,5 @@ func (p *Team) DelTeamMember(rc *req.Ctx) { aid := rc.PathParamInt("accountId") rc.ReqParam = fmt.Sprintf("teamId: %d, accountId: %d", tid, aid) - p.TeamApp.DeleteMember(rc.MetaCtx, uint64(tid), uint64(aid)) + p.teamApp.DeleteMember(rc.MetaCtx, uint64(tid), uint64(aid)) } diff --git a/server/internal/tag/application/resouce_auth_cert.go b/server/internal/tag/application/resouce_auth_cert.go index 896db7a2..7ac1bfec 100644 --- a/server/internal/tag/application/resouce_auth_cert.go +++ b/server/internal/tag/application/resouce_auth_cert.go @@ -51,7 +51,7 @@ type ResourceAuthCert interface { type resourceAuthCertAppImpl struct { base.AppImpl[*entity.ResourceAuthCert, repository.ResourceAuthCert] - tagTreeApp TagTree `inject:"TagTreeApp"` + tagTreeApp TagTree `inject:"T"` } func (r *resourceAuthCertAppImpl) RelateAuthCert(ctx context.Context, params *dto.RelateAuthCert) error { diff --git a/server/internal/tag/application/resource_op_log.go b/server/internal/tag/application/resource_op_log.go index 8ab4cd3c..c82ab8e0 100644 --- a/server/internal/tag/application/resource_op_log.go +++ b/server/internal/tag/application/resource_op_log.go @@ -21,7 +21,7 @@ type ResourceOpLog interface { type resourceOpLogAppImpl struct { base.AppImpl[*entity.ResourceOpLog, repository.ResourceOpLog] - tagTreeApp TagTree `inject:"TagTreeApp"` + tagTreeApp TagTree `inject:"T"` } var _ (ResourceOpLog) = (*resourceOpLogAppImpl)(nil) diff --git a/server/internal/tag/application/tag_tree.go b/server/internal/tag/application/tag_tree.go index 6386a99a..107a651c 100644 --- a/server/internal/tag/application/tag_tree.go +++ b/server/internal/tag/application/tag_tree.go @@ -69,7 +69,7 @@ type TagTree interface { type tagTreeAppImpl struct { base.AppImpl[*entity.TagTree, repository.TagTree] - tagTreeRelateApp TagTreeRelate `inject:"TagTreeRelateApp"` + tagTreeRelateApp TagTreeRelate `inject:"T"` } var _ (TagTree) = (*tagTreeAppImpl)(nil) diff --git a/server/internal/tag/application/tag_tree_relate.go b/server/internal/tag/application/tag_tree_relate.go index 421f98af..fcc2b402 100644 --- a/server/internal/tag/application/tag_tree_relate.go +++ b/server/internal/tag/application/tag_tree_relate.go @@ -35,9 +35,7 @@ type TagTreeRelate interface { type tagTreeRelateAppImpl struct { base.AppImpl[*entity.TagTreeRelate, repository.TagTreeRelate] - tagTreeRelateRepo repository.TagTreeRelate `inject:"TagTreeRelateRepo"` - - tagTreeApp TagTree `inject:"TagTreeApp"` + tagTreeApp TagTree `inject:"T"` } var _ (TagTreeRelate) = (*tagTreeRelateAppImpl)(nil) @@ -99,15 +97,15 @@ func (tr *tagTreeRelateAppImpl) GetRelateIds(ctx context.Context, relateType ent // 追加可能关联的标签路径,如tagPath = tag1/tag2/1|xxx/,需要获取所有关联的自身及父标签(tag1/ tag1/tag2/ tag1/tag2/1|xxx) poisibleTagPaths = append(poisibleTagPaths, entity.CodePath(tagPath).GetAllPath()...) } - return tr.tagTreeRelateRepo.SelectRelateIdsByTagPaths(relateType, poisibleTagPaths...) + return tr.GetRepo().SelectRelateIdsByTagPaths(relateType, poisibleTagPaths...) } func (tr *tagTreeRelateAppImpl) GetTagPathsByAccountId(accountId uint64) []string { - return tr.tagTreeRelateRepo.SelectTagPathsByAccountId(accountId) + return tr.GetRepo().SelectTagPathsByAccountId(accountId) } func (tr *tagTreeRelateAppImpl) GetTagPathsByRelate(relateType entity.TagRelateType, relateId uint64) []string { - return tr.tagTreeRelateRepo.SelectTagPathsByRelate(relateType, relateId) + return tr.GetRepo().SelectTagPathsByRelate(relateType, relateId) } func (tr *tagTreeRelateAppImpl) FillTagInfo(relateType entity.TagRelateType, relates ...entity.IRelateTag) { diff --git a/server/internal/tag/application/team.go b/server/internal/tag/application/team.go index c220b775..a1b30ec9 100644 --- a/server/internal/tag/application/team.go +++ b/server/internal/tag/application/team.go @@ -47,10 +47,6 @@ type teamAppImpl struct { var _ (Team) = (*teamAppImpl)(nil) -func (p *teamAppImpl) InjectTeamRepo(repo repository.Team) { - p.Repo = repo -} - func (p *teamAppImpl) GetPageList(condition *entity.TeamQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) { return p.GetRepo().GetPageList(condition, pageParam, toEntity, orderBy...) } @@ -64,39 +60,43 @@ func (p *teamAppImpl) SaveTeam(ctx context.Context, saveParam *dto.SaveTeam) err } team.Id = saveParam.Id - if team.Id == 0 { - if p.CountByCond(&entity.Team{Name: saveParam.Name}) > 0 { - return errorx.NewBizI(ctx, imsg.ErrNameExist) + return p.Tx(ctx, func(ctx context.Context) error { + if team.Id == 0 { + if p.CountByCond(&entity.Team{Name: saveParam.Name}) > 0 { + return errorx.NewBizI(ctx, imsg.ErrNameExist) + } + + if err := p.Insert(ctx, team); err != nil { + return err + } + + loginAccount := contextx.GetLoginAccount(ctx) + logx.InfoContext(ctx, "Add [%s] to the [%s] team by default", loginAccount.Username, team.Name) + + teamMem := &entity.TeamMember{} + teamMem.AccountId = loginAccount.Id + teamMem.Username = loginAccount.Username + teamMem.TeamId = team.Id + if err := p.SaveMember(ctx, teamMem); err != nil { + return err + } + } else { + // 置空名称,防止变更 + team.Name = "" + if err := p.UpdateById(ctx, team); err != nil { + return err + } } - if err := p.Insert(ctx, team); err != nil { - return err + // 删除该团队关联账号的标签缓存 + teamMembers, _ := p.teamMemberRepo.SelectByCond(&entity.TeamMember{TeamId: team.Id}) + for _, tm := range teamMembers { + cache.DelAccountTagPaths(tm.AccountId) } - loginAccount := contextx.GetLoginAccount(ctx) - logx.InfoContext(ctx, "Add [%s] to the [%s] team by default", loginAccount.Username, team.Name) - - teamMem := &entity.TeamMember{} - teamMem.AccountId = loginAccount.Id - teamMem.Username = loginAccount.Username - teamMem.TeamId = team.Id - p.SaveMember(ctx, teamMem) - } else { - // 置空名称,防止变更 - team.Name = "" - if err := p.UpdateById(ctx, team); err != nil { - return err - } - } - - // 删除该团队关联账号的标签缓存 - teamMembers, _ := p.teamMemberRepo.SelectByCond(&entity.TeamMember{TeamId: team.Id}) - for _, tm := range teamMembers { - cache.DelAccountTagPaths(tm.AccountId) - } - - // 保存团队关联的标签信息 - return p.tagTreeRelateApp.RelateTag(ctx, entity.TagRelateTypeTeam, team.Id, saveParam.CodePaths...) + // 保存团队关联的标签信息 + return p.tagTreeRelateApp.RelateTag(ctx, entity.TagRelateTypeTeam, team.Id, saveParam.CodePaths...) + }) } func (p *teamAppImpl) Delete(ctx context.Context, id uint64) error { diff --git a/server/internal/tag/init/init.go b/server/internal/tag/init/init.go index 2dd55f5d..0e78f9b3 100644 --- a/server/internal/tag/init/init.go +++ b/server/internal/tag/init/init.go @@ -4,9 +4,9 @@ import ( "context" "mayfly-go/initialize" "mayfly-go/internal/event" + "mayfly-go/internal/tag/api" "mayfly-go/internal/tag/application" "mayfly-go/internal/tag/infrastructure/persistence" - "mayfly-go/internal/tag/router" "mayfly-go/pkg/eventbus" "mayfly-go/pkg/global" ) @@ -15,8 +15,9 @@ func init() { initialize.AddInitIocFunc(func() { persistence.InitIoc() application.InitIoc() + api.InitIoc() }) - initialize.AddInitRouterFunc(router.Init) + initialize.AddInitFunc(Init) } diff --git a/server/internal/tag/router/resource_auth_cert.go b/server/internal/tag/router/resource_auth_cert.go deleted file mode 100644 index 6e064b77..00000000 --- a/server/internal/tag/router/resource_auth_cert.go +++ /dev/null @@ -1,33 +0,0 @@ -package router - -import ( - "mayfly-go/internal/tag/api" - "mayfly-go/internal/tag/imsg" - "mayfly-go/pkg/biz" - "mayfly-go/pkg/ioc" - "mayfly-go/pkg/req" - - "github.com/gin-gonic/gin" -) - -func InitResourceAuthCertRouter(router *gin.RouterGroup) { - m := new(api.ResourceAuthCert) - biz.ErrIsNil(ioc.Inject(m)) - - resourceAuthCert := router.Group("/auth-certs") - { - reqs := [...]*req.Conf{ - req.NewGet("", m.ListByQuery), - - req.NewGet("/simple", m.SimpleAc), - - req.NewGet("/detail", m.GetCompleteAuthCert).Log(req.NewLogSaveI(imsg.LogAcShowPwd)).RequiredPermissionCode("authcert:showciphertext"), - - req.NewPost("", m.SaveAuthCert).Log(req.NewLogSaveI(imsg.LogAcSave)).RequiredPermissionCode("authcert:save"), - - req.NewDelete(":id", m.Delete).Log(req.NewLogSaveI(imsg.LogAcDelete)).RequiredPermissionCode("authcert:del"), - } - - req.BatchSetGroup(resourceAuthCert, reqs[:]) - } -} diff --git a/server/internal/tag/router/resource_op_log.go b/server/internal/tag/router/resource_op_log.go deleted file mode 100644 index 65fe3d4a..00000000 --- a/server/internal/tag/router/resource_op_log.go +++ /dev/null @@ -1,24 +0,0 @@ -package router - -import ( - "mayfly-go/internal/tag/api" - "mayfly-go/pkg/biz" - "mayfly-go/pkg/ioc" - "mayfly-go/pkg/req" - - "github.com/gin-gonic/gin" -) - -func InitResourceOpLogRouter(router *gin.RouterGroup) { - m := new(api.ResourceOpLog) - biz.ErrIsNil(ioc.Inject(m)) - - resourceOpLog := router.Group("/resource-op-logs") - { - reqs := [...]*req.Conf{ - req.NewGet("/account", m.PageAccountOpLog), - } - - req.BatchSetGroup(resourceOpLog, reqs[:]) - } -} diff --git a/server/internal/tag/router/router.go b/server/internal/tag/router/router.go deleted file mode 100644 index 00cad077..00000000 --- a/server/internal/tag/router/router.go +++ /dev/null @@ -1,10 +0,0 @@ -package router - -import "github.com/gin-gonic/gin" - -func Init(router *gin.RouterGroup) { - InitTagTreeRouter(router) - InitTeamRouter(router) - InitResourceAuthCertRouter(router) - InitResourceOpLogRouter(router) -} diff --git a/server/internal/tag/router/tag_tree.go b/server/internal/tag/router/tag_tree.go deleted file mode 100644 index a5f15617..00000000 --- a/server/internal/tag/router/tag_tree.go +++ /dev/null @@ -1,42 +0,0 @@ -package router - -import ( - "mayfly-go/internal/tag/api" - "mayfly-go/internal/tag/imsg" - "mayfly-go/pkg/biz" - "mayfly-go/pkg/ioc" - "mayfly-go/pkg/req" - - "github.com/gin-gonic/gin" -) - -func InitTagTreeRouter(router *gin.RouterGroup) { - m := new(api.TagTree) - biz.ErrIsNil(ioc.Inject(m)) - - tagTree := router.Group("/tag-trees") - { - reqs := [...]*req.Conf{ - // 获取标签树列表 - req.NewGet("", m.GetTagTree), - - // 根据条件获取标签 - req.NewGet("query", m.ListByQuery), - - req.NewPost("", m.SaveTagTree).Log(req.NewLogSaveI(imsg.LogTagSave)).RequiredPermissionCode("tag:save"), - - req.NewDelete(":id", m.DelTagTree).Log(req.NewLogSaveI(imsg.LogTagDelete)).RequiredPermissionCode("tag:del"), - - req.NewPost("/moving", m.MovingTag).Log(req.NewLogSaveI(imsg.LogTagMove)).RequiredPermissionCode("tag:save"), - - req.NewGet("/resources/tag-paths", m.TagResources), - - req.NewGet("/resources/count", m.CountTagResource), - - // 获取关联的标签id列表 - req.NewGet("/relate/:relateType/:relateId", m.GetRelateTagIds), - } - - req.BatchSetGroup(tagTree, reqs[:]) - } -} diff --git a/server/internal/tag/router/team.go b/server/internal/tag/router/team.go deleted file mode 100644 index 94a57d13..00000000 --- a/server/internal/tag/router/team.go +++ /dev/null @@ -1,37 +0,0 @@ -package router - -import ( - "mayfly-go/internal/tag/api" - "mayfly-go/internal/tag/imsg" - "mayfly-go/pkg/biz" - "mayfly-go/pkg/ioc" - "mayfly-go/pkg/req" - - "github.com/gin-gonic/gin" -) - -func InitTeamRouter(router *gin.RouterGroup) { - m := new(api.Team) - biz.ErrIsNil(ioc.Inject(m)) - - team := router.Group("/teams") - { - reqs := [...]*req.Conf{ - // 获取团队列表 - req.NewGet("", m.GetTeams), - - req.NewPost("", m.SaveTeam).Log(req.NewLogSaveI(imsg.LogTeamSave)).RequiredPermissionCode("team:save"), - - req.NewDelete(":id", m.DelTeam).Log(req.NewLogSaveI(imsg.LogTeamDelete)).RequiredPermissionCode("team:del"), - - // 获取团队的成员信息列表 - req.NewGet("/:id/members", m.GetTeamMembers), - - req.NewPost("/:id/members", m.SaveTeamMember).Log(req.NewLogSaveI(imsg.LogTeamAddMember)).RequiredPermissionCode("team:member:save"), - - req.NewDelete("/:id/members/:accountId", m.DelTeamMember).Log(req.NewLogSaveI(imsg.LogTeamRemoveMember)).RequiredPermissionCode("team:member:del"), - } - - req.BatchSetGroup(team, reqs[:]) - } -} diff --git a/server/pkg/ioc/component.go b/server/pkg/ioc/component.go index a1bca302..c6da764b 100644 --- a/server/pkg/ioc/component.go +++ b/server/pkg/ioc/component.go @@ -15,11 +15,14 @@ func WithComponentName(name string) ComponentOption { type Component struct { Name string // 组件名 - Type reflect.Type // 组件类型 - Value any // 组件实例 } +// GetType 获取组件实例类型 +func (c *Component) GetType() reflect.Type { + return reflect.TypeOf(c.Value) +} + func NewComponent(val any, opts ...ComponentOption) *Component { component := &Component{ Value: val, diff --git a/server/pkg/ioc/default.go b/server/pkg/ioc/default.go index 343ba28e..73a4e3db 100644 --- a/server/pkg/ioc/default.go +++ b/server/pkg/ioc/default.go @@ -1,5 +1,10 @@ package ioc +import ( + "mayfly-go/pkg/utils/collx" + "reflect" +) + // 全局默认实例容器 var DefaultContainer = NewContainer() @@ -14,6 +19,13 @@ func Get[T any](name string) T { return c.(T) } +// GetBeansByType 根据组件实例类型从全局默认ioc容器获取实例 +func GetBeansByType[T any](valueType reflect.Type) []T { + return collx.ArrayMap(DefaultContainer.GetBeansByType(valueType), func(val any) T { + return val.(T) + }) +} + // 使用全局默认ioc容器中已注册的组件实例 -> 注入到指定实例所依赖的组件实例 func Inject(component any) error { return DefaultContainer.Inject(component) diff --git a/server/pkg/ioc/ioc.go b/server/pkg/ioc/ioc.go index d455b37f..7e911da5 100644 --- a/server/pkg/ioc/ioc.go +++ b/server/pkg/ioc/ioc.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "mayfly-go/pkg/contextx" "mayfly-go/pkg/logx" "mayfly-go/pkg/utils/collx" "mayfly-go/pkg/utils/structx" @@ -39,16 +40,13 @@ func (c *Container) Register(bean any, opts ...ComponentOption) { component := NewComponent(bean, opts...) componentName := component.Name - cType := reflect.TypeOf(component.Value) - indirectCType := structx.IndirectType(cType) - // 组件名为空,则取组件类型名称作为组件名 + indirectCType := structx.IndirectType(component.GetType()) + // 组件名为空,则取组件类型`包名路径.名称`作为组件名 if componentName == "" { - componentName = indirectCType.Name() + componentName = fmt.Sprintf("%s.%s", indirectCType.PkgPath(), indirectCType.Name()) component.Name = componentName } - component.Type = cType - if _, ok := c.components[componentName]; ok { logx.Warnf("the component name [%s] has been registered to the container. Repeat the registration...", componentName) } @@ -64,10 +62,11 @@ func (c *Container) Inject(obj any) error { return nil } - if err := c.injectWithField(objValue); err != nil { + ctx := contextx.NewTraceId() + if err := c.injectWithField(ctx, objValue); err != nil { return err } - if err := c.injectWithMethod(objValue); err != nil { + if err := c.injectWithMethod(ctx, objValue); err != nil { return err } return nil @@ -101,8 +100,17 @@ func (c *Container) InjectComponents() error { return nil } -// 根据组件实例名,获取对应实例信息 +// Get 根据组件实例名,获取对应实例信息 func (c *Container) Get(name string) (any, error) { + if comp, err := c.GetComponent(name); err == nil { + return comp.Value, nil + } else { + return nil, err + } +} + +// GetComponent 根据组件名,获取对应组件信息 +func (c *Container) GetComponent(name string) (*Component, error) { c.mu.RLock() defer c.mu.RUnlock() @@ -111,29 +119,58 @@ func (c *Container) Get(name string) (any, error) { return nil, errors.New("component not found: " + name) } - return component.Value, nil + return component, nil } // GetByType 根据组件实例类型获取组件实例 func (c *Container) GetByType(fieldType reflect.Type) (any, error) { + if comp, err := c.GetComponentByType(fieldType); err == nil { + return comp.Value, nil + } else { + return nil, err + } +} + +// GetComponentByType 根据组件实例类型获取组件信息 +func (c *Container) GetComponentByType(fieldType reflect.Type) (*Component, error) { c.mu.RLock() defer c.mu.RUnlock() for _, component := range c.components { - if component.Type.AssignableTo(fieldType) { - return component.Value, nil + if component.GetType().AssignableTo(fieldType) { + return component, nil } } return nil, errors.New("component type not found: " + fmt.Sprintf("%s.%s", fieldType.PkgPath(), fieldType.Name())) } +// GetBeansByType 根据组件实例类型获取所有对应类型的组件实例 +func (c *Container) GetBeansByType(fieldType reflect.Type) []any { + return collx.ArrayMap(c.GetComponentsByType(fieldType), func(comp *Component) any { return comp.Value }) +} + +// GetComponentsByType 根据组件实例类型获取指定类型的所有组件信息 +func (c *Container) GetComponentsByType(fieldType reflect.Type) []*Component { + c.mu.RLock() + defer c.mu.RUnlock() + + components := make([]*Component, 0) + for _, component := range c.components { + if component.GetType().AssignableTo(fieldType) { + components = append(components, component) + } + } + + return components +} + // injectWithField 根据实例字段的inject:"xxx"或injectByType:""标签进行依赖注入 -func (c *Container) injectWithField(objValue reflect.Value) error { +func (c *Container) injectWithField(context context.Context, objValue reflect.Value) error { objValue = structx.Indirect(objValue) objType := objValue.Type() - logx.Debugf("start ioc inject with field: %s.%s", objType.PkgPath(), objType.Name()) + logx.DebugfContext(context, "start ioc inject with field: %s.%s", objType.PkgPath(), objType.Name()) for i := 0; i < objType.NumField(); i++ { field := objType.Field(i) @@ -141,7 +178,7 @@ func (c *Container) injectWithField(objValue reflect.Value) error { // 检查字段是否是通过组合包含在当前结构体中的,即嵌套结构体 if field.Anonymous && structx.IndirectType(field.Type).Kind() == reflect.Struct { - c.injectWithField(fieldValue) + c.injectWithField(context, fieldValue) continue } @@ -152,13 +189,13 @@ func (c *Container) injectWithField(objValue reflect.Value) error { // 如果组件名为指定的根据类型注入值,则根据类型注入 if componentName == ByTypeComponentName { - if err := c.injectByType(objType, field, fieldValue); err != nil { + if err := c.injectByType(context, objType, field, fieldValue); err != nil { return err } continue } - if err := c.injectByName(objType, field, fieldValue, componentName); err != nil { + if err := c.injectByName(context, objType, field, fieldValue, componentName); err != nil { return err } } @@ -167,28 +204,29 @@ func (c *Container) injectWithField(objValue reflect.Value) error { } // injectByName 根据实例组件名进行依赖注入 -func (c *Container) injectByName(structType reflect.Type, field reflect.StructField, fieldValue reflect.Value, componentName string) error { +func (c *Container) injectByName(context context.Context, structType reflect.Type, field reflect.StructField, fieldValue reflect.Value, componentName string) error { // inject tag字段名为空则默认为字段名 if componentName == "" { componentName = field.Name } - injectInfo := fmt.Sprintf("ioc field inject [%s -> %s.%s#%s]", componentName, structType.PkgPath(), structType.Name(), field.Name) - logx.Debugf(injectInfo) + injectInfo := fmt.Sprintf("ioc field inject by name => [%s -> %s.%s#%s]", componentName, structType.PkgPath(), structType.Name(), field.Name) - component, err := c.Get(componentName) + component, err := c.GetComponent(componentName) if err != nil { return fmt.Errorf("%s error: %s", injectInfo, err.Error()) } // 判断字段类型与需要注入的组件类型是否为可赋值关系 - componentType := reflect.TypeOf(component) + componentType := component.GetType() if !componentType.AssignableTo(field.Type) { indirectComponentType := structx.IndirectType(componentType) return fmt.Errorf("%s error: injection types are inconsistent(Expected type -> %s.%s, Component type -> %s.%s)", injectInfo, field.Type.PkgPath(), field.Type.Name(), indirectComponentType.PkgPath(), indirectComponentType.Name()) } - if err := setFieldValue(fieldValue, component); err != nil { + logx.DebugfContext(context, fmt.Sprintf("ioc field inject by name => [%s (%s) -> %s.%s#%s]", componentName, getComponentValueDesc(componentType), structType.PkgPath(), structType.Name(), field.Name)) + + if err := setFieldValue(fieldValue, component.Value); err != nil { return fmt.Errorf("%s error: %s", injectInfo, err.Error()) } @@ -196,18 +234,19 @@ func (c *Container) injectByName(structType reflect.Type, field reflect.StructFi } // injectByType 根据实例类型进行依赖注入 -func (c *Container) injectByType(structType reflect.Type, field reflect.StructField, fieldValue reflect.Value) error { +func (c *Container) injectByType(context context.Context, structType reflect.Type, field reflect.StructField, fieldValue reflect.Value) error { fieldType := field.Type - injectInfo := fmt.Sprintf("ioc field inject by type [%s.%s -> %s.%s#%s]", fieldType.PkgPath(), fieldType.Name(), structType.PkgPath(), structType.Name(), field.Name) - logx.Debugf(injectInfo) + injectInfo := fmt.Sprintf("ioc field inject by type => [%s.%s -> %s.%s#%s]", fieldType.PkgPath(), fieldType.Name(), structType.PkgPath(), structType.Name(), field.Name) - component, err := c.GetByType(fieldType) + component, err := c.GetComponentByType(fieldType) if err != nil { return fmt.Errorf("%s error: %s", injectInfo, err.Error()) } - if err := setFieldValue(fieldValue, component); err != nil { + logx.DebugfContext(context, fmt.Sprintf("ioc field inject by type => [%s.%s (%s) -> %s.%s#%s]", fieldType.PkgPath(), fieldType.Name(), getComponentValueDesc(component.GetType()), structType.PkgPath(), structType.Name(), field.Name)) + + if err := setFieldValue(fieldValue, component.Value); err != nil { return fmt.Errorf("%s error: %s", injectInfo, err.Error()) } @@ -215,7 +254,7 @@ func (c *Container) injectByType(structType reflect.Type, field reflect.StructFi } // 根据实例的Inject方法进行依赖注入 -func (c *Container) injectWithMethod(objValue reflect.Value) error { +func (c *Container) injectWithMethod(context context.Context, objValue reflect.Value) error { objType := objValue.Type() for i := 0; i < objType.NumMethod(); i++ { @@ -231,10 +270,10 @@ func (c *Container) injectWithMethod(objValue reflect.Value) error { componentName := methodName[6:] injectInfo := fmt.Sprintf("ioc method inject [%s.%s#%s(%s)]", objType.Elem().PkgPath(), objType.Elem().Name(), methodName, componentName) - logx.Debugf(injectInfo) + logx.DebugfContext(context, injectInfo) if method.Type.NumIn() != 2 { - logx.Warnf("%s error: the method cannot be injected if it does not have one parameter", injectInfo) + logx.WarnfContext(context, "%s error: the method cannot be injected if it does not have one parameter", injectInfo) continue } @@ -270,3 +309,11 @@ func setFieldValue(fieldValue reflect.Value, component any) error { fieldValue.Set(reflect.ValueOf(component)) return nil } + +func getComponentValueDesc(componentValueType reflect.Type) string { + if componentValueType.Kind() == reflect.Ptr { + componentValueType = structx.IndirectType(componentValueType) + return fmt.Sprintf("*%s.%s", componentValueType.PkgPath(), componentValueType.Name()) + } + return fmt.Sprintf("%s.%s", componentValueType.PkgPath(), componentValueType.Name()) +} diff --git a/server/pkg/req/conf.go b/server/pkg/req/conf.go index e9021b1d..2e608748 100644 --- a/server/pkg/req/conf.go +++ b/server/pkg/req/conf.go @@ -15,6 +15,15 @@ type Conf struct { noRes bool // 无需返回结果,即文件下载等 } +type Confs struct { + Group string + Confs []*Conf +} + +func NewConfs(group string, confs ...*Conf) *Confs { + return &Confs{group, confs} +} + func New(method, path string, handler HandlerFunc) *Conf { return &Conf{method: method, path: path, handler: handler, noRes: false} } diff --git a/server/pkg/starter/gorm.go b/server/pkg/starter/gorm.go index 034dc387..8a4a5d55 100644 --- a/server/pkg/starter/gorm.go +++ b/server/pkg/starter/gorm.go @@ -29,7 +29,7 @@ func initGormDb() *gorm.DB { } func initMysql(m config.Mysql) *gorm.DB { - logx.Infof("连接mysql [%s]", m.Host) + logx.Infof("connecting to mysql [%s]", m.Host) mysqlConfig := mysql.Config{ DSN: m.Dsn(), // DSN data source name DefaultStringSize: 191, // string 类型字段的默认长度 @@ -40,7 +40,7 @@ func initMysql(m config.Mysql) *gorm.DB { } if db, err := gorm.Open(mysql.New(mysqlConfig), getGormConfig()); err != nil { - logx.Panicf("连接mysql失败! [%s]", err.Error()) + logx.Panicf("failed to connect to mysql! [%s]", err.Error()) return nil } else { sqlDB, _ := db.DB() @@ -51,9 +51,9 @@ func initMysql(m config.Mysql) *gorm.DB { } func initSqlite(sc config.Sqlite) *gorm.DB { - logx.Infof("连接sqlite [%s]", sc.Path) + logx.Infof("connecting to sqlite [%s]", sc.Path) if db, err := gorm.Open(sqlite.Open(sc.Path), getGormConfig()); err != nil { - logx.Panicf("连接sqlite失败! [%s]", err.Error()) + logx.Panicf("failed to connect to sqlite! [%s]", err.Error()) return nil } else { sqlDB, _ := db.DB()