refactor: remove router、ioc is adjusted to inject by type

This commit is contained in:
meilin.huang
2024-12-16 23:29:18 +08:00
parent 7f2a49ba3c
commit 68f553f4b0
142 changed files with 1403 additions and 1905 deletions

View File

@@ -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",

View File

@@ -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
}

View File

@@ -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}

View File

@@ -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))
}

View File

@@ -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}

View File

@@ -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) {

View File

@@ -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登录配置信息因为有些字段是敏感字段故单独使用接口获取

View File

@@ -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})
}

View File

@@ -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)
}

View File

@@ -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[:])
}

View File

@@ -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)
}
}

View File

@@ -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[:])
}

View File

@@ -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[:])
}

View File

@@ -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)
}

View File

@@ -0,0 +1,7 @@
package api
import "mayfly-go/pkg/ioc"
func InitIoc() {
ioc.Register(new(Common))
}

View File

@@ -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
}

View File

@@ -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()
})
}

View File

@@ -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)
}
}

View File

@@ -1,7 +0,0 @@
package router
import "github.com/gin-gonic/gin"
func Init(router *gin.RouterGroup) {
InitCommonRouter(router)
}

View File

@@ -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))
}

View File

@@ -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),

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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)

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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,
}))
}()
}

View File

@@ -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...)

View File

@@ -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) {

View File

@@ -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...)

View File

@@ -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
}

View File

@@ -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 {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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)
}

View File

@@ -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[:])
}

View File

@@ -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)
}

View File

@@ -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[:])
}

View File

@@ -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)
}

View File

@@ -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[:])
}

View File

@@ -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)
}

View File

@@ -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[:])
}

View File

@@ -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[:])
}

View File

@@ -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)
}

View File

@@ -0,0 +1,7 @@
package api
import "mayfly-go/pkg/ioc"
func InitIoc() {
ioc.Register(new(File))
}

View File

@@ -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")))
}

View File

@@ -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)
}

View File

@@ -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[:])
}

View File

@@ -1,9 +0,0 @@
package router
import (
"github.com/gin-gonic/gin"
)
func Init(router *gin.RouterGroup) {
InitFileRouter(router)
}

View File

@@ -0,0 +1,8 @@
package api
import "mayfly-go/pkg/ioc"
func InitIoc() {
ioc.Register(new(Procdef))
ioc.Register(new(Procinst))
}

View File

@@ -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")
}
}

View File

@@ -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))
}

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)
}

View File

@@ -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[:])
}
}

View File

@@ -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[:])
}
}

View File

@@ -1,8 +0,0 @@
package router
import "github.com/gin-gonic/gin"
func Init(router *gin.RouterGroup) {
InitProcdefouter(router)
InitProcinstRouter(router)
}

View File

@@ -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))
}

View File

@@ -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{

View File

@@ -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()

View File

@@ -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")))
}

View File

@@ -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
}

View File

@@ -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")
}

View File

@@ -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)
// 记录请求参数

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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 {

View File

@@ -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...",

View File

@@ -39,6 +39,10 @@ const (
ErrFileUploadFail
MsgUploadFileSuccess
LogMachineCronJobSave
LogMachineCronJobDelete
LogMachineCronJobRun
// security
LogMachineSecurityCmdSave
LogMachineSecurityCmdDelete

View File

@@ -31,6 +31,10 @@ var Zh_CN = map[i18n.MsgId]string{
ErrFileUploadFail: "文件上传失败",
MsgUploadFileSuccess: "文件上传成功",
LogMachineCronJobSave: "机器-保存计划任务",
LogMachineCronJobDelete: "机器-删除计划任务",
LogMachineCronJobRun: "机器-执行计划任务",
LogMachineSecurityCmdSave: "机器-安全-保存命令配置",
LogMachineSecurityCmdDelete: "机器-安全-删除命令配置",
TerminalCmdDisable: "该命令已被禁用...",

View File

@@ -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)
}

View File

@@ -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)
}
}

View File

@@ -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[:])
}

View File

@@ -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[:])
}

View File

@@ -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[:])
}

View File

@@ -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[:])
}

View File

@@ -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)
}

View File

@@ -0,0 +1,8 @@
package api
import "mayfly-go/pkg/ioc"
func InitIoc() {
ioc.Register(new(Mongo))
ioc.Register(new(Dashbord))
}

View File

@@ -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,
}}))

View File

@@ -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)

View File

@@ -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
})
}

View File

@@ -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)
}

View File

@@ -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[:])
}

View File

@@ -1,7 +0,0 @@
package router
import "github.com/gin-gonic/gin"
func Init(router *gin.RouterGroup) {
InitMongoRouter(router)
}

View File

@@ -0,0 +1,7 @@
package api
import "mayfly-go/pkg/ioc"
func InitIoc() {
ioc.Register(new(Msg))
}

View File

@@ -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
}

View File

@@ -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)
}

View File

@@ -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)
}

View File

@@ -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)
}

View File

@@ -1,9 +0,0 @@
package router
import (
"github.com/gin-gonic/gin"
)
func Init(router *gin.RouterGroup) {
InitMsgRouter(router)
}

View File

@@ -0,0 +1,8 @@
package api
import "mayfly-go/pkg/ioc"
func InitIoc() {
ioc.Register(new(Redis))
ioc.Register(new(Dashbord))
}

View File

@@ -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
}

View File

@@ -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),
}))

View File

@@ -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
}

View File

@@ -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列表

View File

@@ -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)
}

Some files were not shown because too many files have changed in this diff Show More