feat: 机器列表新增运行状态 & refactor: 登录账号信息存储与context

This commit is contained in:
meilin.huang
2023-11-07 21:05:21 +08:00
parent d9adf0fd25
commit eddda41291
74 changed files with 915 additions and 652 deletions

View File

@@ -1,6 +1,7 @@
package api
import (
"context"
"encoding/json"
"fmt"
"mayfly-go/internal/auth/api/form"
@@ -107,7 +108,7 @@ func (a *AccountLogin) OtpVerify(rc *req.Ctx) {
update := &sysentity.Account{OtpSecret: otpSecret}
update.Id = accountId
update.OtpSecretEncrypt()
biz.ErrIsNil(a.AccountApp.Update(update))
biz.ErrIsNil(a.AccountApp.Update(context.Background(), update))
}
la := &sysentity.Account{Username: otpInfo.Username}
@@ -119,6 +120,7 @@ func (a *AccountLogin) OtpVerify(rc *req.Ctx) {
}
func (a *AccountLogin) Logout(rc *req.Ctx) {
req.GetPermissionCodeRegistery().Remove(rc.LoginAccount.Id)
ws.CloseClient(ws.UserId(rc.LoginAccount.Id))
la := rc.GetLoginAccount()
req.GetPermissionCodeRegistery().Remove(la.Id)
ws.CloseClient(ws.UserId(la.Id))
}

View File

@@ -1,6 +1,7 @@
package api
import (
"context"
"fmt"
"mayfly-go/internal/auth/config"
msgapp "mayfly-go/internal/msg/application"
@@ -108,7 +109,7 @@ func saveLogin(account *sysentity.Account, ip string) {
updateAccount.Id = account.Id
updateAccount.LastLoginIp = ip
// 偷懒为了方便直接获取accountApp
biz.ErrIsNil(sysapp.GetAccountApp().Update(updateAccount))
biz.ErrIsNil(sysapp.GetAccountApp().Update(context.TODO(), updateAccount))
// 创建登录消息
loginMsg := &msgentity.Msg{
@@ -119,5 +120,5 @@ func saveLogin(account *sysentity.Account, ip string) {
loginMsg.CreateTime = &now
loginMsg.Creator = account.Username
loginMsg.CreatorId = account.Id
msgapp.GetMsgApp().Create(loginMsg)
msgapp.GetMsgApp().Create(context.TODO(), loginMsg)
}

View File

@@ -1,6 +1,7 @@
package api
import (
"context"
"crypto/tls"
"fmt"
"mayfly-go/internal/auth/api/form"
@@ -88,10 +89,10 @@ func (a *LdapLogin) createUser(userName, displayName string) {
account := &sysentity.Account{Username: userName}
account.SetBaseInfo(nil)
account.Name = displayName
biz.ErrIsNil(a.AccountApp.Create(account))
biz.ErrIsNil(a.AccountApp.Create(context.TODO(), account))
// 将 LADP 用户本地密码设置为空,不允许本地登录
account.Password = cryptox.PwdHash("")
biz.ErrIsNil(a.AccountApp.Update(account))
biz.ErrIsNil(a.AccountApp.Update(context.TODO(), account))
}
func (a *LdapLogin) getOrCreateUserWithLdap(userName string, password string, cols ...string) (*sysentity.Account, error) {

View File

@@ -1,6 +1,7 @@
package api
import (
"context"
"fmt"
"io"
"mayfly-go/internal/auth/api/vo"
@@ -42,7 +43,7 @@ func (a *Oauth2Login) OAuth2Login(rc *req.Ctx) {
func (a *Oauth2Login) OAuth2Bind(rc *req.Ctx) {
client, _ := a.getOAuthClient()
state := stringx.Rand(32)
cache.SetStr("oauth2:state:"+state, "bind:"+strconv.FormatUint(rc.LoginAccount.Id, 10),
cache.SetStr("oauth2:state:"+state, "bind:"+strconv.FormatUint(rc.GetLoginAccount().Id, 10),
5*time.Minute)
rc.GinCtx.Redirect(http.StatusFound, client.AuthCodeURL(state))
}
@@ -152,7 +153,7 @@ func (a *Oauth2Login) doLoginAction(rc *req.Ctx, userId string, oauth *config.Oa
Name: userId,
Username: userId,
}
biz.ErrIsNil(a.AccountApp.Create(account))
biz.ErrIsNil(a.AccountApp.Create(context.TODO(), account))
// 绑定
err := a.Oauth2App.BindOAuthAccount(&entity.Oauth2Account{
AccountId: account.Id,
@@ -207,7 +208,7 @@ func (a *Oauth2Login) Oauth2Status(ctx *req.Ctx) {
res.Enable = oauth2LoginConfig.Enable
if res.Enable {
err := a.Oauth2App.GetOAuthAccount(&entity.Oauth2Account{
AccountId: ctx.LoginAccount.Id,
AccountId: ctx.GetLoginAccount().Id,
}, "account_id", "identity")
res.Bind = err == nil
}
@@ -216,7 +217,7 @@ func (a *Oauth2Login) Oauth2Status(ctx *req.Ctx) {
}
func (a *Oauth2Login) Oauth2Unbind(rc *req.Ctx) {
a.Oauth2App.Unbind(rc.LoginAccount.Id)
a.Oauth2App.Unbind(rc.GetLoginAccount().Id)
}
// 获取oauth2登录配置信息因为有些字段是敏感字段故单独使用接口获取

View File

@@ -1,6 +1,7 @@
package application
import (
"context"
"mayfly-go/internal/auth/domain/entity"
"mayfly-go/internal/auth/domain/repository"
)
@@ -29,11 +30,11 @@ func (a *oauth2AppImpl) GetOAuthAccount(condition *entity.Oauth2Account, cols ..
func (a *oauth2AppImpl) BindOAuthAccount(e *entity.Oauth2Account) error {
if e.Id == 0 {
return a.oauthAccountRepo.Insert(e)
return a.oauthAccountRepo.Insert(context.Background(), e)
}
return a.oauthAccountRepo.UpdateById(e)
return a.oauthAccountRepo.UpdateById(context.Background(), e)
}
func (a *oauth2AppImpl) Unbind(accountId uint64) {
a.oauthAccountRepo.DeleteByCond(&entity.Oauth2Account{AccountId: accountId})
a.oauthAccountRepo.DeleteByCond(context.Background(), &entity.Oauth2Account{AccountId: accountId})
}

View File

@@ -23,7 +23,7 @@ type Index struct {
}
func (i *Index) Count(rc *req.Ctx) {
accountId := rc.LoginAccount.Id
accountId := rc.GetLoginAccount().Id
tagIds := i.TagApp.ListTagIdByAccountId(accountId)
var mongoNum int64

View File

@@ -13,7 +13,6 @@ import (
tagapp "mayfly-go/internal/tag/application"
"mayfly-go/pkg/biz"
"mayfly-go/pkg/ginx"
"mayfly-go/pkg/gormx"
"mayfly-go/pkg/logx"
"mayfly-go/pkg/model"
"mayfly-go/pkg/req"
@@ -42,7 +41,7 @@ func (d *Db) Dbs(rc *req.Ctx) {
queryCond, page := ginx.BindQueryAndPage[*entity.DbQuery](rc.GinCtx, new(entity.DbQuery))
// 不存在可访问标签id即没有可操作数据
tagIds := d.TagApp.ListTagIdByAccountId(rc.LoginAccount.Id)
tagIds := d.TagApp.ListTagIdByAccountId(rc.GetLoginAccount().Id)
if len(tagIds) == 0 {
rc.ResData = model.EmptyPageResult[any]()
return
@@ -55,7 +54,7 @@ func (d *Db) Dbs(rc *req.Ctx) {
}
func (d *Db) DbTags(rc *req.Ctx) {
rc.ResData = d.TagApp.ListTagByAccountIdAndResource(rc.LoginAccount.Id, new(entity.Db))
rc.ResData = d.TagApp.ListTagByAccountIdAndResource(rc.GetLoginAccount().Id, new(entity.Db))
}
func (d *Db) Save(rc *req.Ctx) {
@@ -64,8 +63,7 @@ func (d *Db) Save(rc *req.Ctx) {
rc.ReqParam = form
db.SetBaseInfo(rc.LoginAccount)
biz.ErrIsNil(d.DbApp.Save(db))
biz.ErrIsNil(d.DbApp.Save(rc.MetaCtx, db))
}
func (d *Db) DeleteDb(rc *req.Ctx) {
@@ -73,13 +71,14 @@ func (d *Db) DeleteDb(rc *req.Ctx) {
rc.ReqParam = idsStr
ids := strings.Split(idsStr, ",")
ctx := rc.MetaCtx
for _, v := range ids {
value, err := strconv.Atoi(v)
biz.ErrIsNilAppendErr(err, "string类型转换为int异常: %s")
dbId := uint64(value)
d.DbApp.Delete(dbId)
d.DbApp.Delete(ctx, dbId)
// 删除该库的sql执行记录
d.DbSqlExecApp.DeleteBy(&entity.DbSqlExec{DbId: dbId})
d.DbSqlExecApp.DeleteBy(ctx, &entity.DbSqlExec{DbId: dbId})
}
}
@@ -91,7 +90,7 @@ func (d *Db) ExecSql(rc *req.Ctx) {
dbId := getDbId(g)
dbConn, err := d.DbApp.GetDbConn(dbId, form.Db)
biz.ErrIsNil(err)
biz.ErrIsNilAppendErr(d.TagApp.CanAccess(rc.LoginAccount.Id, dbConn.Info.TagPath), "%s")
biz.ErrIsNilAppendErr(d.TagApp.CanAccess(rc.GetLoginAccount().Id, dbConn.Info.TagPath), "%s")
rc.ReqParam = fmt.Sprintf("%s\n-> %s", dbConn.Info.GetLogDesc(), form.Sql)
biz.NotEmpty(form.Sql, "sql不能为空")
@@ -104,7 +103,7 @@ func (d *Db) ExecSql(rc *req.Ctx) {
Db: form.Db,
Remark: form.Remark,
DbConn: dbConn,
LoginAccount: rc.LoginAccount,
LoginAccount: rc.GetLoginAccount(),
}
sqls, err := sqlparser.SplitStatementToPieces(sql, sqlparser.WithDialect(dbConn.Info.Type.Dialect()))
@@ -163,7 +162,7 @@ func (d *Db) ExecSqlFile(rc *req.Ctx) {
dbConn, err := d.DbApp.GetDbConn(dbId, dbName)
biz.ErrIsNil(err)
biz.ErrIsNilAppendErr(d.TagApp.CanAccess(rc.LoginAccount.Id, dbConn.Info.TagPath), "%s")
biz.ErrIsNilAppendErr(d.TagApp.CanAccess(rc.GetLoginAccount().Id, dbConn.Info.TagPath), "%s")
rc.ReqParam = fmt.Sprintf("filename: %s -> %s", filename, dbConn.Info.GetLogDesc())
defer func() {
@@ -172,7 +171,7 @@ func (d *Db) ExecSqlFile(rc *req.Ctx) {
if len(errInfo) > 300 {
errInfo = errInfo[:300] + "..."
}
d.MsgApp.CreateAndSend(rc.LoginAccount, msgdto.ErrSysMsg("sql脚本执行失败", fmt.Sprintf("[%s][%s]执行失败: [%s]", filename, dbConn.Info.GetLogDesc(), errInfo)).WithClientId(clientId))
d.MsgApp.CreateAndSend(rc.GetLoginAccount(), msgdto.ErrSysMsg("sql脚本执行失败", fmt.Sprintf("[%s][%s]执行失败: [%s]", filename, dbConn.Info.GetLogDesc(), errInfo)).WithClientId(clientId))
}
}()
@@ -181,7 +180,7 @@ func (d *Db) ExecSqlFile(rc *req.Ctx) {
Db: dbName,
Remark: filename,
DbConn: dbConn,
LoginAccount: rc.LoginAccount,
LoginAccount: rc.GetLoginAccount(),
}
var sql string
@@ -191,7 +190,8 @@ func (d *Db) ExecSqlFile(rc *req.Ctx) {
executedStatements := 0
progressId := stringx.Rand(32)
defer ws.SendJsonMsg(ws.UserId(rc.LoginAccount.Id), clientId, msgdto.InfoSysMsg("sql脚本执行进度", &progressMsg{
laId := rc.GetLoginAccount().Id
defer ws.SendJsonMsg(ws.UserId(laId), clientId, msgdto.InfoSysMsg("sql脚本执行进度", &progressMsg{
Id: progressId,
Title: filename,
ExecutedStatements: executedStatements,
@@ -202,7 +202,7 @@ func (d *Db) ExecSqlFile(rc *req.Ctx) {
for {
select {
case <-ticker.C:
ws.SendJsonMsg(ws.UserId(rc.LoginAccount.Id), clientId, msgdto.InfoSysMsg("sql脚本执行进度", &progressMsg{
ws.SendJsonMsg(ws.UserId(laId), clientId, msgdto.InfoSysMsg("sql脚本执行进度", &progressMsg{
Id: progressId,
Title: filename,
ExecutedStatements: executedStatements,
@@ -231,7 +231,7 @@ func (d *Db) ExecSqlFile(rc *req.Ctx) {
}
dbConn, err = d.DbApp.GetDbConn(dbId, stmtUse.DBName.String())
biz.ErrIsNil(err)
biz.ErrIsNilAppendErr(d.TagApp.CanAccess(rc.LoginAccount.Id, dbConn.Info.TagPath), "%s")
biz.ErrIsNilAppendErr(d.TagApp.CanAccess(laId, dbConn.Info.TagPath), "%s")
execReq.DbConn = dbConn
}
// 需要记录执行记录
@@ -245,7 +245,7 @@ func (d *Db) ExecSqlFile(rc *req.Ctx) {
biz.ErrIsNilAppendErr(err, "%s")
}
d.MsgApp.CreateAndSend(rc.LoginAccount, msgdto.SuccessSysMsg("sql脚本执行成功", fmt.Sprintf("sql脚本执行完成%s", rc.ReqParam)).WithClientId(clientId))
d.MsgApp.CreateAndSend(rc.GetLoginAccount(), msgdto.SuccessSysMsg("sql脚本执行成功", fmt.Sprintf("sql脚本执行完成%s", rc.ReqParam)).WithClientId(clientId))
}
// 数据库dump
@@ -268,9 +268,10 @@ func (d *Db) DumpSql(rc *req.Ctx) {
// 是否需要导出数据
needData := dumpType == "2" || dumpType == "3"
la := rc.GetLoginAccount()
db, err := d.DbApp.GetById(new(entity.Db), dbId)
biz.ErrIsNil(err, "该数据库不存在")
biz.ErrIsNilAppendErr(d.TagApp.CanAccess(rc.LoginAccount.Id, db.TagPath), "%s")
biz.ErrIsNilAppendErr(d.TagApp.CanAccess(la.Id, db.TagPath), "%s")
now := time.Now()
filename := fmt.Sprintf("%s.%s.sql%s", db.Name, now.Format("20060102150405"), extName)
@@ -294,7 +295,7 @@ func (d *Db) DumpSql(rc *req.Ctx) {
if len(msg) > 0 {
msg = "数据库导出失败: " + msg
writer.WriteString(msg)
d.MsgApp.CreateAndSend(rc.LoginAccount, msgdto.ErrSysMsg("数据库导出失败", msg))
d.MsgApp.CreateAndSend(la, msgdto.ErrSysMsg("数据库导出失败", msg))
}
writer.Close()
}()
@@ -444,73 +445,6 @@ func (d *Db) GetCreateTableDdl(rc *req.Ctx) {
rc.ResData = res
}
// @router /api/db/:dbId/sql [post]
func (d *Db) SaveSql(rc *req.Ctx) {
g := rc.GinCtx
account := rc.LoginAccount
dbSqlForm := &form.DbSqlSaveForm{}
ginx.BindJsonAndValid(g, dbSqlForm)
rc.ReqParam = dbSqlForm
dbId := getDbId(g)
// 判断dbId是否存在
err := gormx.GetById(new(entity.Db), dbId)
biz.ErrIsNil(err, "该数据库信息不存在")
// 获取用于是否有该dbsql的保存记录有则更改否则新增
dbSql := &entity.DbSql{Type: dbSqlForm.Type, DbId: dbId, Name: dbSqlForm.Name, Db: dbSqlForm.Db}
dbSql.CreatorId = account.Id
e := gormx.GetBy(dbSql)
dbSql.SetBaseInfo(account)
// 更新sql信息
dbSql.Sql = dbSqlForm.Sql
if e == nil {
gormx.UpdateById(dbSql)
} else {
gormx.Insert(dbSql)
}
}
// 获取所有保存的sql names
func (d *Db) GetSqlNames(rc *req.Ctx) {
dbId := getDbId(rc.GinCtx)
dbName := getDbName(rc.GinCtx)
// 获取用于是否有该dbsql的保存记录有则更改否则新增
dbSql := &entity.DbSql{Type: 1, DbId: dbId, Db: dbName}
dbSql.CreatorId = rc.LoginAccount.Id
var sqls []entity.DbSql
gormx.ListBy(dbSql, &sqls, "id", "name")
rc.ResData = sqls
}
// 删除保存的sql
func (d *Db) DeleteSql(rc *req.Ctx) {
dbSql := &entity.DbSql{Type: 1, DbId: getDbId(rc.GinCtx)}
dbSql.CreatorId = rc.LoginAccount.Id
dbSql.Name = rc.GinCtx.Query("name")
dbSql.Db = rc.GinCtx.Query("db")
biz.ErrIsNil(gormx.DeleteBy(dbSql))
}
// @router /api/db/:dbId/sql [get]
func (d *Db) GetSql(rc *req.Ctx) {
dbId := getDbId(rc.GinCtx)
dbName := getDbName(rc.GinCtx)
// 根据创建者id 数据库id以及sql模板名称查询保存的sql信息
dbSql := &entity.DbSql{Type: 1, DbId: dbId, Db: dbName}
dbSql.CreatorId = rc.LoginAccount.Id
dbSql.Name = rc.GinCtx.Query("name")
e := gormx.GetBy(dbSql)
if e != nil {
return
}
rc.ResData = dbSql
}
func getDbId(g *gin.Context) uint64 {
dbId, _ := strconv.Atoi(g.Param("dbId"))
biz.IsTrue(dbId > 0, "dbId错误")

View File

@@ -0,0 +1,77 @@
package api
import (
"mayfly-go/internal/db/api/form"
"mayfly-go/internal/db/application"
"mayfly-go/internal/db/domain/entity"
"mayfly-go/pkg/biz"
"mayfly-go/pkg/ginx"
"mayfly-go/pkg/req"
)
type DbSql struct {
DbSqlApp application.DbSql
}
// @router /api/db/:dbId/sql [post]
func (d *DbSql) SaveSql(rc *req.Ctx) {
g := rc.GinCtx
dbSqlForm := &form.DbSqlSaveForm{}
ginx.BindJsonAndValid(g, dbSqlForm)
rc.ReqParam = dbSqlForm
dbId := getDbId(g)
account := rc.GetLoginAccount()
// 获取用于是否有该dbsql的保存记录有则更改否则新增
dbSql := &entity.DbSql{Type: dbSqlForm.Type, DbId: dbId, Name: dbSqlForm.Name, Db: dbSqlForm.Db}
dbSql.CreatorId = account.Id
e := d.DbSqlApp.GetBy(dbSql)
// 更新sql信息
dbSql.Sql = dbSqlForm.Sql
if e == nil {
d.DbSqlApp.UpdateById(rc.MetaCtx, dbSql)
} else {
d.DbSqlApp.Insert(rc.MetaCtx, dbSql)
}
}
// 获取所有保存的sql names
func (d *DbSql) GetSqlNames(rc *req.Ctx) {
dbId := getDbId(rc.GinCtx)
dbName := getDbName(rc.GinCtx)
// 获取用于是否有该dbsql的保存记录有则更改否则新增
dbSql := &entity.DbSql{Type: 1, DbId: dbId, Db: dbName}
dbSql.CreatorId = rc.GetLoginAccount().Id
var sqls []entity.DbSql
d.DbSqlApp.ListByCond(dbSql, &sqls, "id", "name")
rc.ResData = sqls
}
// 删除保存的sql
func (d *DbSql) DeleteSql(rc *req.Ctx) {
dbSql := &entity.DbSql{Type: 1, DbId: getDbId(rc.GinCtx)}
dbSql.CreatorId = rc.GetLoginAccount().Id
dbSql.Name = rc.GinCtx.Query("name")
dbSql.Db = rc.GinCtx.Query("db")
biz.ErrIsNil(d.DbSqlApp.DeleteByCond(rc.MetaCtx, dbSql))
}
// @router /api/db/:dbId/sql [get]
func (d *DbSql) GetSql(rc *req.Ctx) {
dbId := getDbId(rc.GinCtx)
dbName := getDbName(rc.GinCtx)
// 根据创建者id 数据库id以及sql模板名称查询保存的sql信息
dbSql := &entity.DbSql{Type: 1, DbId: dbId, Db: dbName}
dbSql.CreatorId = rc.GetLoginAccount().Id
dbSql.Name = rc.GinCtx.Query("name")
e := d.DbSqlApp.GetBy(dbSql)
if e != nil {
return
}
rc.ResData = dbSql
}

View File

@@ -14,7 +14,7 @@ type DbSqlExec struct {
func (d *DbSqlExec) DbSqlExecs(rc *req.Ctx) {
queryCond, page := ginx.BindQueryAndPage(rc.GinCtx, new(entity.DbSqlExecQuery))
queryCond.CreatorId = rc.LoginAccount.Id
queryCond.CreatorId = rc.GetLoginAccount().Id
res, err := d.DbSqlExecApp.GetPageList(queryCond, page, new([]entity.DbSqlExec))
biz.ErrIsNil(err)
rc.ResData = res

View File

@@ -43,9 +43,7 @@ func (d *Instance) SaveInstance(rc *req.Ctx) {
// 密码脱敏记录日志
form.Password = "****"
rc.ReqParam = form
instance.SetBaseInfo(rc.LoginAccount)
biz.ErrIsNil(d.InstanceApp.Save(instance))
biz.ErrIsNil(d.InstanceApp.Save(rc.MetaCtx, instance))
}
// GetInstance 获取数据库实例密码,由于数据库是加密存储,故提供该接口展示原文密码
@@ -84,7 +82,7 @@ func (d *Instance) DeleteInstance(rc *req.Ctx) {
biz.ErrIsNil(err, "获取数据库实例错误数据库实例ID为: %d", instance.Id)
biz.IsTrue(false, "不能删除数据库实例【%s】请先删除其关联的数据库资源。", instance.Name)
}
d.InstanceApp.Delete(instanceId)
d.InstanceApp.Delete(rc.MetaCtx, instanceId)
}
}

View File

@@ -8,6 +8,7 @@ var (
instanceApp Instance = newInstanceApp(persistence.GetInstanceRepo())
dbApp Db = newDbApp(persistence.GetDbRepo(), persistence.GetDbSqlRepo(), instanceApp)
dbSqlExecApp DbSqlExec = newDbSqlExecApp(persistence.GetDbSqlExecRepo())
dbSqlApp DbSql = newDbSqlApp(persistence.GetDbSqlRepo())
)
func GetInstanceApp() Instance {
@@ -18,6 +19,10 @@ func GetDbApp() Db {
return dbApp
}
func GetDbSqlApp() DbSql {
return dbSqlApp
}
func GetDbSqlExecApp() DbSqlExec {
return dbSqlExecApp
}

View File

@@ -1,6 +1,7 @@
package application
import (
"context"
"mayfly-go/internal/db/dbm"
"mayfly-go/internal/db/domain/entity"
"mayfly-go/internal/db/domain/repository"
@@ -20,10 +21,10 @@ type Db interface {
Count(condition *entity.DbQuery) int64
Save(entity *entity.Db) error
Save(ctx context.Context, entity *entity.Db) error
// 删除数据库信息
Delete(id uint64) error
Delete(ctx context.Context, id uint64) error
// 获取数据库连接实例
// @param id 数据库id
@@ -56,7 +57,7 @@ func (d *dbAppImpl) Count(condition *entity.DbQuery) int64 {
return d.GetRepo().Count(condition)
}
func (d *dbAppImpl) Save(dbEntity *entity.Db) error {
func (d *dbAppImpl) Save(ctx context.Context, dbEntity *entity.Db) error {
// 查找是否存在
oldDb := &entity.Db{Name: dbEntity.Name, InstanceId: dbEntity.InstanceId}
err := d.GetBy(oldDb)
@@ -65,7 +66,7 @@ func (d *dbAppImpl) Save(dbEntity *entity.Db) error {
if err == nil {
return errorx.NewBiz("该实例下数据库名已存在")
}
return d.Insert(dbEntity)
return d.Insert(ctx, dbEntity)
}
// 如果存在该库,则校验修改的库是否为该库
@@ -90,13 +91,13 @@ func (d *dbAppImpl) Save(dbEntity *entity.Db) error {
// 关闭数据库连接
dbm.CloseDb(dbEntity.Id, v)
// 删除该库关联的所有sql记录
d.dbSqlRepo.DeleteByCond(&entity.DbSql{DbId: dbId, Db: v})
d.dbSqlRepo.DeleteByCond(ctx, &entity.DbSql{DbId: dbId, Db: v})
}
return d.UpdateById(dbEntity)
return d.UpdateById(ctx, dbEntity)
}
func (d *dbAppImpl) Delete(id uint64) error {
func (d *dbAppImpl) Delete(ctx context.Context, id uint64) error {
db, err := d.GetById(new(entity.Db), id)
if err != nil {
return errorx.NewBiz("该数据库不存在")
@@ -107,8 +108,8 @@ func (d *dbAppImpl) Delete(id uint64) error {
dbm.CloseDb(id, v)
}
// 删除该库下用户保存的所有sql信息
d.dbSqlRepo.DeleteByCond(&entity.DbSql{DbId: id})
return d.DeleteById(id)
d.dbSqlRepo.DeleteByCond(ctx, &entity.DbSql{DbId: id})
return d.DeleteById(ctx, id)
}
func (d *dbAppImpl) GetDbConn(dbId uint64, dbName string) (*dbm.DbConn, error) {

View File

@@ -0,0 +1,21 @@
package application
import (
"mayfly-go/internal/db/domain/entity"
"mayfly-go/internal/db/domain/repository"
"mayfly-go/pkg/base"
)
type DbSql interface {
base.App[*entity.DbSql]
}
type dbSqlAppImpl struct {
base.AppImpl[*entity.DbSql, repository.DbSql]
}
func newDbSqlApp(dbSqlRepo repository.DbSql) DbSql {
app := new(dbSqlAppImpl)
app.Repo = dbSqlRepo
return app
}

View File

@@ -1,6 +1,7 @@
package application
import (
"context"
"encoding/json"
"fmt"
"mayfly-go/internal/db/config"
@@ -49,7 +50,7 @@ type DbSqlExec interface {
Exec(execSqlReq *DbSqlExecReq) (*DbSqlExecRes, error)
// 根据条件删除sql执行记录
DeleteBy(condition *entity.DbSqlExec)
DeleteBy(ctx context.Context, condition *entity.DbSqlExec)
// 分页获取
GetPageList(condition *entity.DbSqlExecQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error)
@@ -139,19 +140,19 @@ func (d *dbSqlExecAppImpl) Exec(execSqlReq *DbSqlExecReq) (*DbSqlExecRes, error)
// 保存sql执行记录如果是查询类则根据系统配置判断是否保存
func (d *dbSqlExecAppImpl) saveSqlExecLog(isQuery bool, dbSqlExecRecord *entity.DbSqlExec) {
if !isQuery {
d.dbSqlExecRepo.Insert(dbSqlExecRecord)
d.dbSqlExecRepo.Insert(context.TODO(), dbSqlExecRecord)
return
}
if config.GetDbSaveQuerySql() {
dbSqlExecRecord.Table = "-"
dbSqlExecRecord.OldValue = "-"
dbSqlExecRecord.Type = entity.DbSqlExecTypeQuery
d.dbSqlExecRepo.Insert(dbSqlExecRecord)
d.dbSqlExecRepo.Insert(context.TODO(), dbSqlExecRecord)
}
}
func (d *dbSqlExecAppImpl) DeleteBy(condition *entity.DbSqlExec) {
d.dbSqlExecRepo.DeleteByCond(condition)
func (d *dbSqlExecAppImpl) DeleteBy(ctx context.Context, condition *entity.DbSqlExec) {
d.dbSqlExecRepo.DeleteByCond(ctx, condition)
}
func (d *dbSqlExecAppImpl) GetPageList(condition *entity.DbSqlExecQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {

View File

@@ -1,6 +1,7 @@
package application
import (
"context"
"mayfly-go/internal/db/domain/entity"
"mayfly-go/internal/db/domain/repository"
"mayfly-go/pkg/base"
@@ -16,10 +17,10 @@ type Instance interface {
Count(condition *entity.InstanceQuery) int64
Save(instanceEntity *entity.DbInstance) error
Save(ctx context.Context, instanceEntity *entity.DbInstance) error
// Delete 删除数据库信息
Delete(id uint64) error
Delete(ctx context.Context, id uint64) error
// GetDatabases 获取数据库实例的所有数据库列表
GetDatabases(entity *entity.DbInstance) ([]string, error)
@@ -44,7 +45,7 @@ func (app *instanceAppImpl) Count(condition *entity.InstanceQuery) int64 {
return app.CountByCond(condition)
}
func (app *instanceAppImpl) Save(instanceEntity *entity.DbInstance) error {
func (app *instanceAppImpl) Save(ctx context.Context, instanceEntity *entity.DbInstance) error {
// 默认tcp连接
instanceEntity.Network = instanceEntity.GetNetwork()
@@ -72,7 +73,7 @@ func (app *instanceAppImpl) Save(instanceEntity *entity.DbInstance) error {
return errorx.NewBiz("该数据库实例已存在")
}
instanceEntity.PwdEncrypt()
return app.Insert(instanceEntity)
return app.Insert(ctx, instanceEntity)
}
// 如果存在该库,则校验修改的库是否为该库
@@ -80,11 +81,11 @@ func (app *instanceAppImpl) Save(instanceEntity *entity.DbInstance) error {
return errorx.NewBiz("该数据库实例已存在")
}
instanceEntity.PwdEncrypt()
return app.UpdateById(instanceEntity)
return app.UpdateById(ctx, instanceEntity)
}
func (app *instanceAppImpl) Delete(id uint64) error {
return app.DeleteById(id)
func (app *instanceAppImpl) Delete(ctx context.Context, id uint64) error {
return app.DeleteById(ctx, id)
}
func (app *instanceAppImpl) GetDatabases(ed *entity.DbInstance) ([]string, error) {

View File

@@ -46,15 +46,6 @@ func InitDbRouter(router *gin.RouterGroup) {
req.NewGet(":dbId/c-metadata", d.ColumnMA),
req.NewGet(":dbId/hint-tables", d.HintTables),
// 用户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),
}
req.BatchSetGroup(db, reqs[:])

View File

@@ -0,0 +1,32 @@
package router
import (
"mayfly-go/internal/db/api"
"mayfly-go/internal/db/application"
"mayfly-go/pkg/req"
"github.com/gin-gonic/gin"
)
func InitDbSqlRouter(router *gin.RouterGroup) {
db := router.Group("dbs")
dbSql := &api.DbSql{
DbSqlApp: application.GetDbSqlApp(),
}
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

@@ -5,5 +5,6 @@ import "github.com/gin-gonic/gin"
func Init(router *gin.RouterGroup) {
InitInstanceRouter(router)
InitDbRouter(router)
InitDbSqlRouter(router)
InitDbSqlExecRouter(router)
}

View File

@@ -44,8 +44,7 @@ func (c *AuthCert) SaveAuthCert(rc *req.Ctx) {
acForm.Password = "***"
rc.ReqParam = acForm
ac.SetBaseInfo(rc.LoginAccount)
biz.ErrIsNil(c.AuthCertApp.Save(ac))
biz.ErrIsNil(c.AuthCertApp.Save(rc.MetaCtx, ac))
}
func (c *AuthCert) Delete(rc *req.Ctx) {
@@ -56,6 +55,6 @@ func (c *AuthCert) Delete(rc *req.Ctx) {
for _, v := range ids {
value, err := strconv.Atoi(v)
biz.ErrIsNilAppendErr(err, "string类型转换为int异常: %s")
c.AuthCertApp.DeleteById(uint64(value))
c.AuthCertApp.DeleteById(rc.MetaCtx, uint64(value))
}
}

View File

@@ -39,7 +39,7 @@ func (m *Machine) Machines(rc *req.Ctx) {
condition, pageParam := ginx.BindQueryAndPage(rc.GinCtx, new(entity.MachineQuery))
// 不存在可访问标签id即没有可操作数据
tagIds := m.TagApp.ListTagIdByAccountId(rc.LoginAccount.Id)
tagIds := m.TagApp.ListTagIdByAccountId(rc.GetLoginAccount().Id)
if len(tagIds) == 0 {
rc.ResData = model.EmptyPageResult[any]()
return
@@ -55,12 +55,20 @@ func (m *Machine) Machines(rc *req.Ctx) {
for _, mv := range *res.List {
mv.HasCli = mcm.HasCli(mv.Id)
if machineStats, err := m.MachineApp.GetMachineStats(mv.Id); err == nil {
mv.Stat = collx.M{
"cpuIdle": machineStats.CPU.Idle,
"memAvailable": machineStats.MemInfo.Available,
"memTotal": machineStats.MemInfo.Total,
"fsInfos": machineStats.FSInfos,
}
}
}
rc.ResData = res
}
func (m *Machine) MachineTags(rc *req.Ctx) {
rc.ResData = m.TagApp.ListTagByAccountIdAndResource(rc.LoginAccount.Id, new(entity.Machine))
rc.ResData = m.TagApp.ListTagByAccountIdAndResource(rc.GetLoginAccount().Id, new(entity.Machine))
}
func (m *Machine) MachineStats(rc *req.Ctx) {
@@ -77,8 +85,7 @@ func (m *Machine) SaveMachine(rc *req.Ctx) {
machineForm.Password = "******"
rc.ReqParam = machineForm
me.SetBaseInfo(rc.LoginAccount)
biz.ErrIsNil(m.MachineApp.Save(me))
biz.ErrIsNil(m.MachineApp.Save(rc.MetaCtx, me))
}
func (m *Machine) TestConn(rc *req.Ctx) {
@@ -92,7 +99,7 @@ func (m *Machine) ChangeStatus(rc *req.Ctx) {
id := uint64(ginx.PathParamInt(g, "machineId"))
status := int8(ginx.PathParamInt(g, "status"))
rc.ReqParam = collx.Kvs("id", id, "status", status)
biz.ErrIsNil(m.MachineApp.ChangeStatus(id, status))
biz.ErrIsNil(m.MachineApp.ChangeStatus(rc.MetaCtx, id, status))
}
func (m *Machine) DeleteMachine(rc *req.Ctx) {
@@ -103,7 +110,7 @@ func (m *Machine) DeleteMachine(rc *req.Ctx) {
for _, v := range ids {
value, err := strconv.Atoi(v)
biz.ErrIsNilAppendErr(err, "string类型转换为int异常: %s")
m.MachineApp.Delete(uint64(value))
m.MachineApp.Delete(rc.MetaCtx, uint64(value))
}
}
@@ -133,7 +140,7 @@ func (m *Machine) GetProcess(rc *req.Ctx) {
cli, err := m.MachineApp.GetCli(GetMachineId(rc.GinCtx))
biz.ErrIsNilAppendErr(err, "获取客户端连接失败: %s")
biz.ErrIsNilAppendErr(m.TagApp.CanAccess(rc.LoginAccount.Id, cli.Info.TagPath), "%s")
biz.ErrIsNilAppendErr(m.TagApp.CanAccess(rc.GetLoginAccount().Id, cli.Info.TagPath), "%s")
res, err := cli.Run(cmd)
biz.ErrIsNilAppendErr(err, "获取进程信息失败: %s")
@@ -147,7 +154,7 @@ func (m *Machine) KillProcess(rc *req.Ctx) {
cli, err := m.MachineApp.GetCli(GetMachineId(rc.GinCtx))
biz.ErrIsNilAppendErr(err, "获取客户端连接失败: %s")
biz.ErrIsNilAppendErr(m.TagApp.CanAccess(rc.LoginAccount.Id, cli.Info.TagPath), "%s")
biz.ErrIsNilAppendErr(m.TagApp.CanAccess(rc.GetLoginAccount().Id, cli.Info.TagPath), "%s")
res, err := cli.Run("sudo kill -9 " + pid)
biz.ErrIsNil(err, "终止进程失败: %s", res)
@@ -173,7 +180,7 @@ func (m *Machine) WsSSH(g *gin.Context) {
cli, err := m.MachineApp.GetCli(GetMachineId(g))
biz.ErrIsNilAppendErr(err, "获取客户端连接失败: %s")
biz.ErrIsNilAppendErr(m.TagApp.CanAccess(rc.LoginAccount.Id, cli.Info.TagPath), "%s")
biz.ErrIsNilAppendErr(m.TagApp.CanAccess(rc.GetLoginAccount().Id, cli.Info.TagPath), "%s")
cols := ginx.QueryInt(g, "cols", 80)
rows := ginx.QueryInt(g, "rows", 40)
@@ -182,7 +189,7 @@ func (m *Machine) WsSSH(g *gin.Context) {
if cli.Info.EnableRecorder == 1 {
now := time.Now()
// 回放文件路径为: 基础配置路径/机器id/操作日期/操作者账号/操作时间.cast
recPath := fmt.Sprintf("%s/%d/%s/%s", config.Conf.Server.GetMachineRecPath(), cli.Info.Id, now.Format("20060102"), rc.LoginAccount.Username)
recPath := fmt.Sprintf("%s/%d/%s/%s", config.Conf.Server.GetMachineRecPath(), cli.Info.Id, now.Format("20060102"), rc.GetLoginAccount().Username)
os.MkdirAll(recPath, 0766)
fileName := path.Join(recPath, fmt.Sprintf("%s.cast", now.Format("20060102_150405")))
f, err := os.OpenFile(fileName, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0766)

View File

@@ -35,12 +35,12 @@ func (m *MachineCronJob) Save(rc *req.Ctx) {
jobForm := new(form.MachineCronJobForm)
mcj := ginx.BindJsonAndCopyTo[*entity.MachineCronJob](rc.GinCtx, jobForm, new(entity.MachineCronJob))
rc.ReqParam = jobForm
mcj.SetBaseInfo(rc.LoginAccount)
cronJobId, err := m.MachineCronJobApp.Save(mcj)
cronJobId, err := m.MachineCronJobApp.Save(rc.MetaCtx, mcj)
biz.ErrIsNil(err)
// 关联机器
m.MachineCronJobApp.CronJobRelateMachines(cronJobId, jobForm.MachineIds, rc.LoginAccount)
m.MachineCronJobApp.CronJobRelateMachines(rc.MetaCtx, cronJobId, jobForm.MachineIds)
}
func (m *MachineCronJob) Delete(rc *req.Ctx) {
@@ -51,7 +51,7 @@ func (m *MachineCronJob) Delete(rc *req.Ctx) {
for _, v := range ids {
value, err := strconv.Atoi(v)
biz.ErrIsNilAppendErr(err, "string类型转换为int异常: %s")
m.MachineCronJobApp.Delete(uint64(value))
m.MachineCronJobApp.Delete(rc.MetaCtx, uint64(value))
}
}

View File

@@ -52,14 +52,13 @@ func (m *MachineFile) MachineFiles(rc *req.Ctx) {
func (m *MachineFile) SaveMachineFiles(rc *req.Ctx) {
fileForm := new(form.MachineFileForm)
entity := ginx.BindJsonAndCopyTo[*entity.MachineFile](rc.GinCtx, fileForm, new(entity.MachineFile))
entity.SetBaseInfo(rc.LoginAccount)
rc.ReqParam = fileForm
biz.ErrIsNil(m.MachineFileApp.Save(entity))
biz.ErrIsNil(m.MachineFileApp.Save(rc.MetaCtx, entity))
}
func (m *MachineFile) DeleteFile(rc *req.Ctx) {
biz.ErrIsNil(m.MachineFileApp.Delete(GetMachineFileId(rc.GinCtx)))
biz.ErrIsNil(m.MachineFileApp.Delete(rc.MetaCtx, GetMachineFileId(rc.GinCtx)))
}
/*** sftp相关操作 */
@@ -190,7 +189,7 @@ func (m *MachineFile) UploadFile(rc *req.Ctx) {
file, _ := fileheader.Open()
defer file.Close()
la := rc.LoginAccount
la := rc.GetLoginAccount()
defer func() {
if anyx.ToString(recover()) != "" {
logx.Errorf("文件上传失败: %s", err)
@@ -262,7 +261,7 @@ func (m *MachineFile) UploadFolder(rc *req.Ctx) {
wg.Add(len(chunks))
isSuccess := true
la := rc.LoginAccount
la := rc.GetLoginAccount()
for _, chunk := range chunks {
go func(files []FolderFile, wg *sync.WaitGroup) {
defer func() {
@@ -298,7 +297,7 @@ func (m *MachineFile) UploadFolder(rc *req.Ctx) {
wg.Wait()
if isSuccess {
// 保存消息并发送文件上传成功通知
m.MsgApp.CreateAndSend(rc.LoginAccount, msgdto.SuccessSysMsg("文件上传成功", fmt.Sprintf("[%s]文件夹已成功上传至 %s[%s:%s]", folderName, mi.Name, mi.Ip, basePath)))
m.MsgApp.CreateAndSend(la, msgdto.SuccessSysMsg("文件上传成功", fmt.Sprintf("[%s]文件夹已成功上传至 %s[%s:%s]", folderName, mi.Name, mi.Ip, basePath)))
}
}

View File

@@ -37,9 +37,7 @@ func (m *MachineScript) SaveMachineScript(rc *req.Ctx) {
machineScript := ginx.BindJsonAndCopyTo(rc.GinCtx, form, new(entity.MachineScript))
rc.ReqParam = form
machineScript.SetBaseInfo(rc.LoginAccount)
biz.ErrIsNil(m.MachineScriptApp.Save(machineScript))
biz.ErrIsNil(m.MachineScriptApp.Save(rc.MetaCtx, machineScript))
}
func (m *MachineScript) DeleteMachineScript(rc *req.Ctx) {
@@ -50,7 +48,7 @@ func (m *MachineScript) DeleteMachineScript(rc *req.Ctx) {
for _, v := range ids {
value, err := strconv.Atoi(v)
biz.ErrIsNilAppendErr(err, "string类型转换为int异常: %s")
m.MachineScriptApp.Delete(uint64(value))
m.MachineScriptApp.Delete(rc.MetaCtx, uint64(value))
}
}
@@ -71,7 +69,7 @@ func (m *MachineScript) RunMachineScript(rc *req.Ctx) {
}
cli, err := m.MachineApp.GetCli(machineId)
biz.ErrIsNilAppendErr(err, "获取客户端连接失败: %s")
biz.ErrIsNilAppendErr(m.TagApp.CanAccess(rc.LoginAccount.Id, cli.Info.TagPath), "%s")
biz.ErrIsNilAppendErr(m.TagApp.CanAccess(rc.GetLoginAccount().Id, cli.Info.TagPath), "%s")
res, err := cli.Run(script)
// 记录请求参数

View File

@@ -26,11 +26,13 @@ type MachineVO struct {
UpdateTime *time.Time `json:"updateTime"`
Modifier *string `json:"modifier"`
ModifierId *int64 `json:"modifierId"`
HasCli bool `json:"hasCli" gorm:"-"`
Remark *string `json:"remark"`
EnableRecorder int8 `json:"enableRecorder"`
TagId uint64 `json:"tagId"`
TagPath string `json:"tagPath"`
HasCli bool `json:"hasCli" gorm:"-"`
Stat map[string]any `json:"stat" gorm:"-"`
}
type MachineScriptVO struct {

View File

@@ -1,6 +1,7 @@
package application
import (
"context"
"mayfly-go/internal/machine/domain/entity"
"mayfly-go/internal/machine/domain/repository"
"mayfly-go/pkg/base"
@@ -13,7 +14,7 @@ type AuthCert interface {
GetPageList(condition *entity.AuthCertQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error)
Save(ac *entity.AuthCert) error
Save(ctx context.Context, ac *entity.AuthCert) error
GetByIds(ids ...uint64) []*entity.AuthCert
}
@@ -32,7 +33,7 @@ func (a *authCertAppImpl) GetPageList(condition *entity.AuthCertQuery, pageParam
return a.GetRepo().GetPageList(condition, pageParam, toEntity)
}
func (a *authCertAppImpl) Save(ac *entity.AuthCert) error {
func (a *authCertAppImpl) Save(ctx context.Context, ac *entity.AuthCert) error {
oldAc := &entity.AuthCert{Name: ac.Name}
err := a.GetBy(oldAc, "Id", "Name")
@@ -41,14 +42,14 @@ func (a *authCertAppImpl) Save(ac *entity.AuthCert) error {
if err == nil {
return errorx.NewBiz("该凭证名已存在")
}
return a.Insert(ac)
return a.Insert(ctx, ac)
}
// 如果存在该库,则校验修改的库是否为该库
if err == nil && oldAc.Id != ac.Id {
return errorx.NewBiz("该凭证名已存在")
}
return a.UpdateById(ac)
return a.UpdateById(ctx, ac)
}
func (a *authCertAppImpl) GetByIds(ids ...uint64) []*entity.AuthCert {

View File

@@ -1,14 +1,20 @@
package application
import (
"context"
"fmt"
"mayfly-go/internal/machine/api/vo"
"mayfly-go/internal/machine/domain/entity"
"mayfly-go/internal/machine/domain/repository"
"mayfly-go/internal/machine/infrastructure/cache"
"mayfly-go/internal/machine/mcm"
"mayfly-go/pkg/base"
"mayfly-go/pkg/errorx"
"mayfly-go/pkg/gormx"
"mayfly-go/pkg/logx"
"mayfly-go/pkg/model"
"mayfly-go/pkg/scheduler"
"time"
"gorm.io/gorm"
)
@@ -16,17 +22,17 @@ import (
type Machine interface {
base.App[*entity.Machine]
Save(*entity.Machine) error
Save(ctx context.Context, m *entity.Machine) error
// 测试机器连接
TestConn(me *entity.Machine) error
// 调整机器状态
ChangeStatus(id uint64, status int8) error
ChangeStatus(ctx context.Context, id uint64, status int8) error
Count(condition *entity.MachineQuery) int64
Delete(id uint64) error
Delete(ctx context.Context, id uint64) error
// 分页获取机器信息列表
GetMachineList(condition *entity.MachineQuery, pageParam *model.PageParam, toEntity *[]*vo.MachineVO, orderBy ...string) (*model.PageResult[*[]*vo.MachineVO], error)
@@ -36,6 +42,12 @@ type Machine interface {
// 获取ssh隧道机器连接
GetSshTunnelMachine(id int) (*mcm.SshTunnelMachine, error)
// 定时更新机器状态信息
TimerUpdateStats()
// 获取机器运行时状态信息
GetMachineStats(machineId uint64) (*mcm.Stats, error)
}
func newMachineApp(machineRepo repository.Machine, authCertApp AuthCert) Machine {
@@ -61,7 +73,7 @@ func (m *machineAppImpl) Count(condition *entity.MachineQuery) int64 {
return m.GetRepo().Count(condition)
}
func (m *machineAppImpl) Save(me *entity.Machine) error {
func (m *machineAppImpl) Save(ctx context.Context, me *entity.Machine) error {
oldMachine := &entity.Machine{Ip: me.Ip, Port: me.Port, Username: me.Username}
if me.SshTunnelMachineId > 0 {
oldMachine.SshTunnelMachineId = me.SshTunnelMachineId
@@ -75,7 +87,7 @@ func (m *machineAppImpl) Save(me *entity.Machine) error {
}
// 新增机器,默认启用状态
me.Status = entity.MachineStatusEnable
return m.Insert(me)
return m.Insert(ctx, me)
}
// 如果存在该库,则校验修改的库是否为该库
@@ -85,7 +97,7 @@ func (m *machineAppImpl) Save(me *entity.Machine) error {
// 关闭连接
mcm.DeleteCli(me.Id)
return m.UpdateById(me)
return m.UpdateById(ctx, me)
}
func (m *machineAppImpl) TestConn(me *entity.Machine) error {
@@ -102,7 +114,7 @@ func (m *machineAppImpl) TestConn(me *entity.Machine) error {
return nil
}
func (m *machineAppImpl) ChangeStatus(id uint64, status int8) error {
func (m *machineAppImpl) ChangeStatus(ctx context.Context, id uint64, status int8) error {
if status == entity.MachineStatusDisable {
// 关闭连接
mcm.DeleteCli(id)
@@ -110,11 +122,11 @@ func (m *machineAppImpl) ChangeStatus(id uint64, status int8) error {
machine := new(entity.Machine)
machine.Id = id
machine.Status = status
return m.UpdateById(machine)
return m.UpdateById(ctx, machine)
}
// 根据条件获取机器信息
func (m *machineAppImpl) Delete(id uint64) error {
func (m *machineAppImpl) Delete(ctx context.Context, id uint64) error {
// 关闭连接
mcm.DeleteCli(id)
return gormx.Tx(
@@ -145,6 +157,39 @@ func (m *machineAppImpl) GetSshTunnelMachine(machineId int) (*mcm.SshTunnelMachi
})
}
func (m *machineAppImpl) TimerUpdateStats() {
logx.Debug("开始定时收集并缓存服务器状态信息...")
scheduler.AddFun("@every 2m", func() {
machineIds := new([]entity.Machine)
m.GetRepo().ListByCond(&entity.Machine{Status: entity.MachineStatusEnable}, machineIds, "id")
for _, ma := range *machineIds {
go func(mid uint64) {
defer func() {
if err := recover(); err != nil {
logx.ErrorTrace(fmt.Sprintf("定时获取机器[id=%d]状态信息失败", mid), err.(error))
}
}()
logx.Debugf("定时获取机器[id=%d]状态信息开始", mid)
cli, err := m.GetCli(mid)
// ssh获取客户端失败则更新机器状态为禁用
if err != nil {
updateMachine := &entity.Machine{Status: entity.MachineStatusDisable}
updateMachine.Id = mid
now := time.Now()
updateMachine.UpdateTime = &now
m.UpdateById(context.TODO(), updateMachine)
}
cache.SaveMachineStats(mid, cli.GetAllStats())
logx.Debugf("定时获取机器[id=%d]状态信息结束", mid)
}(ma.Id)
}
})
}
func (m *machineAppImpl) GetMachineStats(machineId uint64) (*mcm.Stats, error) {
return cache.GetMachineStats(machineId)
}
// 生成机器信息根据授权凭证id填充用户密码等
func (m *machineAppImpl) toMachineInfoById(machineId uint64) (*mcm.MachineInfo, error) {
me, err := m.GetById(new(entity.Machine), machineId)

View File

@@ -1,6 +1,7 @@
package application
import (
"context"
"mayfly-go/internal/machine/domain/entity"
"mayfly-go/internal/machine/domain/repository"
"mayfly-go/pkg/base"
@@ -25,9 +26,9 @@ type MachineCronJob interface {
// 获取分页执行结果列表
GetExecPageList(condition *entity.MachineCronJobExec, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error)
Save(entity *entity.MachineCronJob) (uint64, error)
Save(ctx context.Context, entity *entity.MachineCronJob) (uint64, error)
Delete(id uint64)
Delete(ctx context.Context, id uint64)
// 获取计划任务关联的机器列表id
GetRelateMachineIds(cronJobId uint64) []uint64
@@ -36,10 +37,10 @@ type MachineCronJob interface {
GetRelateCronJobIds(machineId uint64) []uint64
// 计划任务关联机器
CronJobRelateMachines(cronJobId uint64, machineIds []uint64, la *model.LoginAccount)
CronJobRelateMachines(ctx context.Context, cronJobId uint64, machineIds []uint64)
// 机器关联计划任务
MachineRelateCronJobs(machineId uint64, cronJobs []uint64, la *model.LoginAccount)
MachineRelateCronJobs(ctx context.Context, machineId uint64, cronJobs []uint64)
// 初始化计划任务
InitCronJob()
@@ -79,10 +80,10 @@ func (m *machineCropJobAppImpl) GetExecPageList(condition *entity.MachineCronJob
}
// 保存机器任务信息
func (m *machineCropJobAppImpl) Save(mcj *entity.MachineCronJob) (uint64, error) {
func (m *machineCropJobAppImpl) Save(ctx context.Context, mcj *entity.MachineCronJob) (uint64, error) {
// 更新操作
if mcj.Id != 0 {
m.UpdateById(mcj)
m.UpdateById(ctx, mcj)
cj, err := m.GetById(new(entity.MachineCronJob), mcj.Id)
if err != nil {
return 0, errorx.NewBiz("该任务不存在")
@@ -93,16 +94,16 @@ func (m *machineCropJobAppImpl) Save(mcj *entity.MachineCronJob) (uint64, error)
}
m.addCronJob(mcj)
if err := m.Insert(mcj); err != nil {
if err := m.Insert(ctx, mcj); err != nil {
return 0, err
}
return mcj.Id, nil
}
func (m *machineCropJobAppImpl) Delete(id uint64) {
m.DeleteById(id)
m.machineCropJobExecRepo.DeleteByCond(&entity.MachineCronJobExec{CronJobId: id})
m.machineCropJobRelateRepo.DeleteByCond(&entity.MachineCronJobRelate{CronJobId: id})
func (m *machineCropJobAppImpl) Delete(ctx context.Context, id uint64) {
m.DeleteById(ctx, id)
m.machineCropJobExecRepo.DeleteByCond(ctx, &entity.MachineCronJobExec{CronJobId: id})
m.machineCropJobRelateRepo.DeleteByCond(ctx, &entity.MachineCronJobRelate{CronJobId: id})
}
func (m *machineCropJobAppImpl) GetRelateMachineIds(cronJobId uint64) []uint64 {
@@ -113,47 +114,39 @@ func (m *machineCropJobAppImpl) GetRelateCronJobIds(machineId uint64) []uint64 {
return m.machineCropJobRelateRepo.GetCronJobIds(machineId)
}
func (m *machineCropJobAppImpl) CronJobRelateMachines(cronJobId uint64, machineIds []uint64, la *model.LoginAccount) {
func (m *machineCropJobAppImpl) CronJobRelateMachines(ctx context.Context, cronJobId uint64, machineIds []uint64) {
oldMachineIds := m.machineCropJobRelateRepo.GetMachineIds(cronJobId)
addIds, delIds, _ := collx.ArrayCompare[uint64](machineIds, oldMachineIds, func(u1, u2 uint64) bool { return u1 == u2 })
addVals := make([]*entity.MachineCronJobRelate, 0)
now := time.Now()
for _, addId := range addIds {
addVals = append(addVals, &entity.MachineCronJobRelate{
MachineId: addId,
CronJobId: cronJobId,
Creator: la.Username,
CreatorId: la.Id,
CreateTime: &now,
MachineId: addId,
CronJobId: cronJobId,
})
}
m.machineCropJobRelateRepo.BatchInsert(addVals)
m.machineCropJobRelateRepo.BatchInsert(ctx, addVals)
for _, delId := range delIds {
m.machineCropJobRelateRepo.DeleteByCond(&entity.MachineCronJobRelate{CronJobId: cronJobId, MachineId: delId})
m.machineCropJobRelateRepo.DeleteByCond(ctx, &entity.MachineCronJobRelate{CronJobId: cronJobId, MachineId: delId})
}
}
func (m *machineCropJobAppImpl) MachineRelateCronJobs(machineId uint64, cronJobs []uint64, la *model.LoginAccount) {
func (m *machineCropJobAppImpl) MachineRelateCronJobs(ctx context.Context, machineId uint64, cronJobs []uint64) {
oldCronIds := m.machineCropJobRelateRepo.GetCronJobIds(machineId)
addIds, delIds, _ := collx.ArrayCompare[uint64](cronJobs, oldCronIds, func(u1, u2 uint64) bool { return u1 == u2 })
addVals := make([]*entity.MachineCronJobRelate, 0)
now := time.Now()
for _, addId := range addIds {
addVals = append(addVals, &entity.MachineCronJobRelate{
MachineId: machineId,
CronJobId: addId,
Creator: la.Username,
CreatorId: la.Id,
CreateTime: &now,
MachineId: machineId,
CronJobId: addId,
})
}
m.machineCropJobRelateRepo.BatchInsert(addVals)
m.machineCropJobRelateRepo.BatchInsert(ctx, addVals)
for _, delId := range delIds {
m.machineCropJobRelateRepo.DeleteByCond(&entity.MachineCronJobRelate{CronJobId: delId, MachineId: machineId})
m.machineCropJobRelateRepo.DeleteByCond(ctx, &entity.MachineCronJobRelate{CronJobId: delId, MachineId: machineId})
}
}
@@ -240,7 +233,7 @@ func (m *machineCropJobAppImpl) runCronJob0(mid uint64, cronJob *entity.MachineC
defer func() {
if err := recover(); err != nil {
res := anyx.ToString(err)
m.machineCropJobExecRepo.Insert(&entity.MachineCronJobExec{
m.machineCropJobExecRepo.Insert(context.TODO(), &entity.MachineCronJobExec{
MachineId: mid,
CronJobId: cronJob.Id,
ExecTime: time.Now(),
@@ -280,5 +273,5 @@ func (m *machineCropJobAppImpl) runCronJob0(mid uint64, cronJob *entity.MachineC
execRes.Status = entity.MachineCronJobExecStatusError
}
// 保存执行记录
m.machineCropJobExecRepo.Insert(execRes)
m.machineCropJobExecRepo.Insert(context.TODO(), execRes)
}

View File

@@ -1,6 +1,7 @@
package application
import (
"context"
"errors"
"fmt"
"io"
@@ -27,9 +28,9 @@ type MachineFile interface {
// 根据id获取
GetById(id uint64, cols ...string) *entity.MachineFile
Save(entity *entity.MachineFile) error
Save(ctx context.Context, entity *entity.MachineFile) error
Delete(id uint64) error
Delete(ctx context.Context, id uint64) error
// 获取文件关联的机器信息,主要用于记录日志使用
// GetMachine(fileId uint64) *mcm.Info
@@ -91,31 +92,34 @@ func (m *machineFileAppImpl) GetPageList(condition *entity.MachineFile, pagePara
// 根据条件获取
func (m *machineFileAppImpl) GetMachineFile(condition *entity.MachineFile, cols ...string) error {
return m.machineFileRepo.GetMachineFile(condition, cols...)
return m.machineFileRepo.GetBy(condition, cols...)
}
// 根据id获取
func (m *machineFileAppImpl) GetById(id uint64, cols ...string) *entity.MachineFile {
return m.machineFileRepo.GetById(id, cols...)
mf := new(entity.MachineFile)
if err := m.machineFileRepo.GetById(mf, id, cols...); err == nil {
return mf
}
return nil
}
// 保存机器文件配置
func (m *machineFileAppImpl) Save(mf *entity.MachineFile) error {
func (m *machineFileAppImpl) Save(ctx context.Context, mf *entity.MachineFile) error {
_, err := m.machineApp.GetById(new(entity.Machine), mf.MachineId, "Name")
if err != nil {
return errorx.NewBiz("该机器不存在")
}
if mf.Id != 0 {
return m.machineFileRepo.UpdateById(mf)
return m.machineFileRepo.UpdateById(ctx, mf)
}
return m.machineFileRepo.Create(mf)
return m.machineFileRepo.Insert(ctx, mf)
}
// 根据id删除
func (m *machineFileAppImpl) Delete(id uint64) error {
return m.machineFileRepo.Delete(id)
func (m *machineFileAppImpl) Delete(ctx context.Context, id uint64) error {
return m.machineFileRepo.DeleteById(ctx, id)
}
func (m *machineFileAppImpl) ReadDir(fid uint64, path string) ([]fs.FileInfo, error) {

View File

@@ -1,6 +1,7 @@
package application
import (
"context"
"mayfly-go/internal/machine/domain/entity"
"mayfly-go/internal/machine/domain/repository"
"mayfly-go/pkg/base"
@@ -14,9 +15,9 @@ type MachineScript interface {
// 分页获取机器脚本信息列表
GetPageList(condition *entity.MachineScript, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error)
Save(entity *entity.MachineScript) error
Save(ctx context.Context, entity *entity.MachineScript) error
Delete(id uint64)
Delete(ctx context.Context, id uint64)
}
func newMachineScriptApp(machineScriptRepo repository.MachineScript, machineApp Machine) MachineScript {
@@ -39,7 +40,7 @@ func (m *machineScriptAppImpl) GetPageList(condition *entity.MachineScript, page
}
// 保存机器脚本
func (m *machineScriptAppImpl) Save(ms *entity.MachineScript) error {
func (m *machineScriptAppImpl) Save(ctx context.Context, ms *entity.MachineScript) error {
// 如果机器id不为公共脚本id则校验机器是否存在
if machineId := ms.MachineId; machineId != Common_Script_Machine_Id {
_, err := m.machineApp.GetById(new(entity.Machine), machineId, "Name")
@@ -49,12 +50,12 @@ func (m *machineScriptAppImpl) Save(ms *entity.MachineScript) error {
}
if ms.Id != 0 {
return m.UpdateById(ms)
return m.UpdateById(ctx, ms)
}
return m.Insert(ms)
return m.Insert(ctx, ms)
}
// 根据id删除
func (m *machineScriptAppImpl) Delete(id uint64) {
m.DeleteById(id)
func (m *machineScriptAppImpl) Delete(ctx context.Context, id uint64) {
m.DeleteById(ctx, id)
}

View File

@@ -30,6 +30,13 @@ type MachineCronJobRelate struct {
CreateTime *time.Time
}
func (m *MachineCronJobRelate) SetBaseInfo(la *model.LoginAccount) {
now := time.Now()
m.CreateTime = &now
m.Creator = la.Username
m.CreatorId = la.Id
}
// 机器任务执行记录
type MachineCronJobExec struct {
model.DeletedModel

View File

@@ -3,6 +3,7 @@ package entity
type MachineQuery struct {
Ids string `json:"ids" form:"ids"`
Name string `json:"name" form:"name"`
Status int8 `json:"status" form:"status"`
Ip string `json:"ip" form:"ip"` // IP地址
TagPath string `json:"tagPath" form:"tagPath"`
TagIds []uint64

View File

@@ -2,22 +2,13 @@ package repository
import (
"mayfly-go/internal/machine/domain/entity"
"mayfly-go/pkg/base"
"mayfly-go/pkg/model"
)
type MachineFile interface {
base.Repo[*entity.MachineFile]
// 分页获取机器脚本信息列表
GetPageList(condition *entity.MachineFile, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error)
// 根据条件获取
GetMachineFile(condition *entity.MachineFile, cols ...string) error
// 根据id获取
GetById(id uint64, cols ...string) *entity.MachineFile
Delete(id uint64) error
Create(entity *entity.MachineFile) error
UpdateById(entity *entity.MachineFile) error
}

View File

@@ -0,0 +1,24 @@
package cache
import (
"errors"
"fmt"
"mayfly-go/internal/machine/mcm"
global_cache "mayfly-go/pkg/cache"
"mayfly-go/pkg/utils/jsonx"
"time"
)
const MachineStatCackeKey = "mayfly:machine:%d:stat"
func SaveMachineStats(machineId uint64, stat *mcm.Stats) error {
return global_cache.SetStr(fmt.Sprintf(MachineStatCackeKey, machineId), jsonx.ToStr(stat), 10*time.Minute)
}
func GetMachineStats(machineId uint64) (*mcm.Stats, error) {
cacheStr := global_cache.GetStr(fmt.Sprintf(MachineStatCackeKey, machineId))
if cacheStr == "" {
return nil, errors.New("不存在该值")
}
return jsonx.To(cacheStr, new(mcm.Stats))
}

View File

@@ -23,6 +23,7 @@ func newMachineRepo() repository.Machine {
// 分页获取机器信息列表
func (m *machineRepoImpl) GetMachineList(condition *entity.MachineQuery, pageParam *model.PageParam, toEntity *[]*vo.MachineVO, orderBy ...string) (*model.PageResult[*[]*vo.MachineVO], error) {
qd := gormx.NewQuery(new(entity.Machine)).
Eq("status", condition.Status).
Like("ip", condition.Ip).
Like("name", condition.Name).
In("tag_id", condition.TagIds).

View File

@@ -3,14 +3,17 @@ package persistence
import (
"mayfly-go/internal/machine/domain/entity"
"mayfly-go/internal/machine/domain/repository"
"mayfly-go/pkg/base"
"mayfly-go/pkg/gormx"
"mayfly-go/pkg/model"
)
type machineFileRepoImpl struct{}
type machineFileRepoImpl struct {
base.RepoImpl[*entity.MachineFile]
}
func newMachineFileRepo() repository.MachineFile {
return new(machineFileRepoImpl)
return &machineFileRepoImpl{base.RepoImpl[*entity.MachineFile]{M: new(entity.MachineFile)}}
}
// 分页获取机器文件信息列表
@@ -18,30 +21,3 @@ func (m *machineFileRepoImpl) GetPageList(condition *entity.MachineFile, pagePar
qd := gormx.NewQuery(condition).WithCondModel(condition).WithOrderBy(orderBy...)
return gormx.PageQuery(qd, pageParam, toEntity)
}
// 根据条件获取账号信息
func (m *machineFileRepoImpl) GetMachineFile(condition *entity.MachineFile, cols ...string) error {
return gormx.GetBy(condition, cols...)
}
// 根据id获取
func (m *machineFileRepoImpl) GetById(id uint64, cols ...string) *entity.MachineFile {
ms := new(entity.MachineFile)
if err := gormx.GetById(ms, id, cols...); err != nil {
return nil
}
return ms
}
// 根据id获取
func (m *machineFileRepoImpl) Delete(id uint64) error {
return gormx.DeleteById(new(entity.MachineFile), id)
}
func (m *machineFileRepoImpl) Create(entity *entity.MachineFile) error {
return gormx.Insert(entity)
}
func (m *machineFileRepoImpl) UpdateById(entity *entity.MachineFile) error {
return gormx.UpdateById(entity)
}

View File

@@ -4,4 +4,5 @@ import "mayfly-go/internal/machine/application"
func Init() {
application.GetMachineCronJobApp().InitCronJob()
application.GetMachineApp().TimerUpdateStats()
}

View File

@@ -42,7 +42,13 @@ func (c *Cli) GetSession() (*ssh.Session, error) {
if c.sshClient == nil {
return nil, errorx.NewBiz("请先进行机器客户端连接")
}
return c.sshClient.NewSession()
session, err := c.sshClient.NewSession()
if err != nil {
// 获取session失败则关闭cli重试
DeleteCli(c.Info.Id)
return nil, errorx.NewBiz("请重试...")
}
return session, nil
}
// 执行shell
@@ -51,7 +57,6 @@ func (c *Cli) GetSession() (*ssh.Session, error) {
func (c *Cli) Run(shell string) (string, error) {
session, err := c.GetSession()
if err != nil {
c.Close()
return "", err
}
defer session.Close()
@@ -67,6 +72,10 @@ func (c *Cli) GetAllStats() *Stats {
res, _ := c.Run(StatsShell)
infos := strings.Split(res, "-----")
stats := new(Stats)
if len(infos) < 8 {
logx.Warnf("获取机器[id=%d, name=%s]的状态信息失败", c.Info.Id, c.Info.Name)
return stats
}
getUptime(infos[0], stats)
getHostname(infos[1], stats)
getLoad(infos[2], stats)

View File

@@ -9,48 +9,52 @@ import (
)
type FSInfo struct {
MountPoint string
Used uint64
Free uint64
MountPoint string `json:"mountPoint"`
Used uint64 `json:"used"`
Free uint64 `json:"free"`
}
type NetIntfInfo struct {
IPv4 string
IPv6 string
Rx uint64
Tx uint64
IPv4 string `json:"ipv4"`
IPv6 string `json:"ipv6"`
Rx uint64 `json:"rx"`
Tx uint64 `json:"tx"`
}
type MemInfo struct {
Total uint64 `json:"total"`
Free uint64 `json:"free"`
Buffers uint64 `json:"buffers"`
Available uint64 `json:"available"`
Cached uint64 `json:"cached"`
SwapTotal uint64 `json:"swapTotal"`
SwapFree uint64 `json:"swapFree"`
}
type CPUInfo struct {
User float32
Nice float32
System float32
Idle float32
Iowait float32
Irq float32
SoftIrq float32
Steal float32
Guest float32
User float32 `json:"user"`
Nice float32 `json:"nice"`
System float32 `json:"system"`
Idle float32 `json:"idle"`
Iowait float32 `json:"iowait"`
Irq float32 `json:"irq"`
SoftIrq float32 `json:"softIrq"`
Steal float32 `json:"steal"`
Guest float32 `json:"guest"`
}
type Stats struct {
Uptime string
Hostname string
Load1 string
Load5 string
Load10 string
RunningProcs string
TotalProcs string
MemTotal uint64
MemFree uint64
MemBuffers uint64
MemAvailable uint64
MemCached uint64
SwapTotal uint64
SwapFree uint64
FSInfos []FSInfo
NetIntf map[string]NetIntfInfo
CPU CPUInfo // or []CPUInfo to get all the cpu-core's stats?
Uptime string `json:"uptime"`
Hostname string `json:"hostname"`
Load1 string `json:"load1"`
Load5 string `json:"load5"`
Load10 string `json:"load10"`
RunningProcs string `json:"runningProcs"`
TotalProcs string `json:"totalProcs"`
MemInfo MemInfo `json:"memInfo"`
FSInfos []FSInfo `json:"fSInfos"`
NetIntf map[string]NetIntfInfo `json:"netIntf"`
CPU CPUInfo `json:"cpu"` // or []CPUInfo to get all the cpu-core's stats?
}
const StatsShell = `
@@ -141,19 +145,19 @@ func getMemInfo(memInfo string, stats *Stats) (err error) {
val *= 1024
switch parts[0] {
case "MemTotal:":
stats.MemTotal = val
stats.MemInfo.Total = val
case "MemFree:":
stats.MemFree = val
stats.MemInfo.Free = val
case "Buffers:":
stats.MemBuffers = val
stats.MemInfo.Buffers = val
case "Cached:":
stats.MemCached = val
stats.MemInfo.Cached = val
case "SwapTotal:":
stats.SwapTotal = val
stats.MemInfo.SwapTotal = val
case "SwapFree:":
stats.SwapFree = val
stats.MemInfo.SwapFree = val
case "MemAvailable:":
stats.MemAvailable = val
stats.MemInfo.Available = val
}
}
}

View File

@@ -30,7 +30,7 @@ func (m *Mongo) Mongos(rc *req.Ctx) {
queryCond, page := ginx.BindQueryAndPage[*entity.MongoQuery](rc.GinCtx, new(entity.MongoQuery))
// 不存在可访问标签id即没有可操作数据
tagIds := m.TagApp.ListTagIdByAccountId(rc.LoginAccount.Id)
tagIds := m.TagApp.ListTagIdByAccountId(rc.GetLoginAccount().Id)
if len(tagIds) == 0 {
rc.ResData = model.EmptyPageResult[any]()
return
@@ -43,7 +43,7 @@ func (m *Mongo) Mongos(rc *req.Ctx) {
}
func (m *Mongo) MongoTags(rc *req.Ctx) {
rc.ResData = m.TagApp.ListTagByAccountIdAndResource(rc.LoginAccount.Id, new(entity.Mongo))
rc.ResData = m.TagApp.ListTagByAccountIdAndResource(rc.GetLoginAccount().Id, new(entity.Mongo))
}
func (m *Mongo) Save(rc *req.Ctx) {
@@ -57,8 +57,7 @@ func (m *Mongo) Save(rc *req.Ctx) {
}(form.Uri)
rc.ReqParam = form
mongo.SetBaseInfo(rc.LoginAccount)
biz.ErrIsNil(m.MongoApp.Save(mongo))
biz.ErrIsNil(m.MongoApp.Save(rc.MetaCtx, mongo))
}
func (m *Mongo) DeleteMongo(rc *req.Ctx) {
@@ -69,7 +68,7 @@ func (m *Mongo) DeleteMongo(rc *req.Ctx) {
for _, v := range ids {
value, err := strconv.Atoi(v)
biz.ErrIsNilAppendErr(err, "string类型转换为int异常: %s")
m.MongoApp.Delete(uint64(value))
m.MongoApp.Delete(rc.MetaCtx, uint64(value))
}
}

View File

@@ -1,6 +1,7 @@
package application
import (
"context"
"mayfly-go/internal/mongo/domain/entity"
"mayfly-go/internal/mongo/domain/repository"
"mayfly-go/internal/mongo/mgm"
@@ -17,10 +18,10 @@ type Mongo interface {
Count(condition *entity.MongoQuery) int64
Save(entity *entity.Mongo) error
Save(ctx context.Context, entity *entity.Mongo) error
// 删除数据库信息
Delete(id uint64) error
Delete(ctx context.Context, id uint64) error
// 获取mongo连接实例
// @param id mongo id
@@ -46,19 +47,19 @@ func (d *mongoAppImpl) Count(condition *entity.MongoQuery) int64 {
return d.GetRepo().Count(condition)
}
func (d *mongoAppImpl) Delete(id uint64) error {
func (d *mongoAppImpl) Delete(ctx context.Context, id uint64) error {
mgm.CloseConn(id)
return d.GetRepo().DeleteById(id)
return d.GetRepo().DeleteById(ctx, id)
}
func (d *mongoAppImpl) Save(m *entity.Mongo) error {
func (d *mongoAppImpl) Save(ctx context.Context, m *entity.Mongo) error {
if m.Id == 0 {
return d.GetRepo().Insert(m)
return d.GetRepo().Insert(ctx, m)
}
// 先关闭连接
mgm.CloseConn(m.Id)
return d.GetRepo().UpdateById(m)
return d.GetRepo().UpdateById(ctx, m)
}
func (d *mongoAppImpl) GetMongoConn(id uint64) (*mgm.MongoConn, error) {

View File

@@ -15,7 +15,7 @@ type Msg struct {
// 获取账号接收的消息列表
func (m *Msg) GetMsgs(rc *req.Ctx) {
condition := &entity.Msg{
RecipientId: int64(rc.LoginAccount.Id),
RecipientId: int64(rc.GetLoginAccount().Id),
}
res, err := m.MsgApp.GetPageList(condition, ginx.GetPageParam(rc.GinCtx), new([]entity.Msg))
biz.ErrIsNil(err)

View File

@@ -1,6 +1,7 @@
package application
import (
"context"
"mayfly-go/internal/msg/application/dto"
"mayfly-go/internal/msg/domain/entity"
"mayfly-go/internal/msg/domain/repository"
@@ -12,7 +13,7 @@ import (
type Msg interface {
GetPageList(condition *entity.Msg, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error)
Create(msg *entity.Msg)
Create(ctx context.Context, msg *entity.Msg)
// 创建消息并通过ws发送
CreateAndSend(la *model.LoginAccount, msg *dto.SysMsg)
@@ -32,13 +33,13 @@ func (a *msgAppImpl) GetPageList(condition *entity.Msg, pageParam *model.PagePar
return a.msgRepo.GetPageList(condition, pageParam, toEntity)
}
func (a *msgAppImpl) Create(msg *entity.Msg) {
a.msgRepo.Insert(msg)
func (a *msgAppImpl) Create(ctx context.Context, msg *entity.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(msg)
a.msgRepo.Insert(context.TODO(), msg)
ws.SendJsonMsg(ws.UserId(la.Id), wmsg.ClientId, wmsg)
}

View File

@@ -31,7 +31,7 @@ func (r *Redis) RedisList(rc *req.Ctx) {
queryCond, page := ginx.BindQueryAndPage[*entity.RedisQuery](rc.GinCtx, new(entity.RedisQuery))
// 不存在可访问标签id即没有可操作数据
tagIds := r.TagApp.ListTagIdByAccountId(rc.LoginAccount.Id)
tagIds := r.TagApp.ListTagIdByAccountId(rc.GetLoginAccount().Id)
if len(tagIds) == 0 {
rc.ResData = model.EmptyPageResult[any]()
return
@@ -44,7 +44,7 @@ func (r *Redis) RedisList(rc *req.Ctx) {
}
func (r *Redis) RedisTags(rc *req.Ctx) {
rc.ResData = r.TagApp.ListTagByAccountIdAndResource(rc.LoginAccount.Id, new(entity.Redis))
rc.ResData = r.TagApp.ListTagByAccountIdAndResource(rc.GetLoginAccount().Id, new(entity.Redis))
}
func (r *Redis) Save(rc *req.Ctx) {
@@ -60,8 +60,7 @@ func (r *Redis) Save(rc *req.Ctx) {
form.Password = "****"
rc.ReqParam = form
redis.SetBaseInfo(rc.LoginAccount)
biz.ErrIsNil(r.RedisApp.Save(redis))
biz.ErrIsNil(r.RedisApp.Save(rc.MetaCtx, redis))
}
// 获取redis实例密码由于数据库是加密存储故提供该接口展示原文密码
@@ -81,7 +80,7 @@ func (r *Redis) DeleteRedis(rc *req.Ctx) {
for _, v := range ids {
value, err := strconv.Atoi(v)
biz.ErrIsNilAppendErr(err, "string类型转换为int异常: %s")
r.RedisApp.Delete(uint64(value))
r.RedisApp.Delete(rc.MetaCtx, uint64(value))
}
}
@@ -218,7 +217,7 @@ 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.GinCtx))
biz.ErrIsNil(err)
biz.ErrIsNilAppendErr(r.TagApp.CanAccess(rc.LoginAccount.Id, ri.Info.TagPath), "%s")
biz.ErrIsNilAppendErr(r.TagApp.CanAccess(rc.GetLoginAccount().Id, ri.Info.TagPath), "%s")
return ri
}

View File

@@ -1,6 +1,7 @@
package application
import (
"context"
"mayfly-go/internal/redis/domain/entity"
"mayfly-go/internal/redis/domain/repository"
"mayfly-go/internal/redis/rdm"
@@ -19,10 +20,10 @@ type Redis interface {
Count(condition *entity.RedisQuery) int64
Save(re *entity.Redis) error
Save(ctx context.Context, re *entity.Redis) error
// 删除数据库信息
Delete(id uint64) error
Delete(ctx context.Context, id uint64) error
// 获取数据库连接实例
// id: 数据库实例id
@@ -52,7 +53,7 @@ func (r *redisAppImpl) Count(condition *entity.RedisQuery) int64 {
return r.GetRepo().Count(condition)
}
func (r *redisAppImpl) Save(re *entity.Redis) error {
func (r *redisAppImpl) Save(ctx context.Context, re *entity.Redis) error {
// ’修改信息且密码不为空‘ or ‘新增’需要测试是否可连接
if (re.Id != 0 && re.Password != "") || re.Id == 0 {
if err := r.TestConn(re); err != nil {
@@ -72,7 +73,7 @@ func (r *redisAppImpl) Save(re *entity.Redis) error {
return errorx.NewBiz("该实例已存在")
}
re.PwdEncrypt()
return r.Insert(re)
return r.Insert(ctx, re)
}
// 如果存在该库,则校验修改的库是否为该库
@@ -87,11 +88,11 @@ func (r *redisAppImpl) Save(re *entity.Redis) error {
}
}
re.PwdEncrypt()
return r.UpdateById(re)
return r.UpdateById(ctx, re)
}
// 删除Redis信息
func (r *redisAppImpl) Delete(id uint64) error {
func (r *redisAppImpl) Delete(ctx context.Context, id uint64) error {
re, err := r.GetById(new(entity.Redis), id)
if err != nil {
return errorx.NewBiz("该redis信息不存在")
@@ -101,7 +102,7 @@ func (r *redisAppImpl) Delete(id uint64) error {
db, _ := strconv.Atoi(dbStr)
rdm.CloseConn(re.Id, db)
}
return r.DeleteById(id)
return r.DeleteById(ctx, id)
}
// 获取数据库连接实例

View File

@@ -35,7 +35,7 @@ type Account struct {
// 获取当前登录用户的菜单与权限码
func (a *Account) GetPermissions(rc *req.Ctx) {
account := rc.LoginAccount
account := rc.GetLoginAccount()
var resources vo.AccountResourceVOList
// 获取账号菜单资源
@@ -78,15 +78,13 @@ func (a *Account) ChangePassword(rc *req.Ctx) {
updateAccount := new(entity.Account)
updateAccount.Id = account.Id
updateAccount.Password = cryptox.PwdHash(originNewPwd)
biz.ErrIsNil(a.AccountApp.Update(updateAccount), "更新账号密码失败")
biz.ErrIsNil(a.AccountApp.Update(rc.MetaCtx, updateAccount), "更新账号密码失败")
// 赋值loginAccount 主要用于记录操作日志,因为操作日志保存请求上下文没有该信息不保存日志
if rc.LoginAccount == nil {
rc.LoginAccount = &model.LoginAccount{
Id: account.Id,
Username: account.Username,
}
}
contextx.WithLoginAccount(rc.MetaCtx, &model.LoginAccount{
Id: account.Id,
Username: account.Username,
})
}
// 获取个人账号信息
@@ -94,7 +92,7 @@ func (a *Account) AccountInfo(rc *req.Ctx) {
ap := new(vo.AccountPersonVO)
// 角色信息
roles := new([]vo.AccountRoleVO)
a.RoleApp.GetAccountRoles(rc.LoginAccount.Id, roles)
a.RoleApp.GetAccountRoles(rc.GetLoginAccount().Id, roles)
ap.Roles = *roles
rc.ResData = ap
@@ -104,7 +102,7 @@ func (a *Account) AccountInfo(rc *req.Ctx) {
func (a *Account) UpdateAccount(rc *req.Ctx) {
updateAccount := ginx.BindJsonAndCopyTo[*entity.Account](rc.GinCtx, new(form.AccountUpdateForm), new(entity.Account))
// 账号id为登录者账号
updateAccount.Id = rc.LoginAccount.Id
updateAccount.Id = rc.GetLoginAccount().Id
if updateAccount.Password != "" {
biz.IsTrue(utils.CheckAccountPasswordLever(updateAccount.Password), "密码强度必须8位以上且包含字⺟⼤⼩写+数字+特殊符号")
@@ -118,7 +116,7 @@ func (a *Account) UpdateAccount(rc *req.Ctx) {
// 禁止更新用户名,防止误传被更新
updateAccount.Username = ""
}
biz.ErrIsNil(a.AccountApp.Update(updateAccount))
biz.ErrIsNil(a.AccountApp.Update(rc.MetaCtx, updateAccount))
}
/** 后台账号操作 **/
@@ -139,10 +137,9 @@ func (a *Account) SaveAccount(rc *req.Ctx) {
form.Password = "*****"
rc.ReqParam = form
account.SetBaseInfo(rc.LoginAccount)
if account.Id == 0 {
biz.ErrIsNil(a.AccountApp.Create(account))
biz.ErrIsNil(a.AccountApp.Create(rc.MetaCtx, account))
} else {
if account.Password != "" {
biz.IsTrue(utils.CheckAccountPasswordLever(account.Password), "密码强度必须8位以上且包含字⺟⼤⼩写+数字+特殊符号")
@@ -150,7 +147,7 @@ func (a *Account) SaveAccount(rc *req.Ctx) {
}
// 更新操作不允许修改用户名、防止误传更新
account.Username = ""
biz.ErrIsNil(a.AccountApp.Update(account))
biz.ErrIsNil(a.AccountApp.Update(rc.MetaCtx, account))
}
}
@@ -161,7 +158,7 @@ func (a *Account) ChangeStatus(rc *req.Ctx) {
account.Id = uint64(ginx.PathParamInt(g, "id"))
account.Status = int8(ginx.PathParamInt(g, "status"))
rc.ReqParam = collx.Kvs("accountId", account.Id, "status", account.Status)
biz.ErrIsNil(a.AccountApp.Update(account))
biz.ErrIsNil(a.AccountApp.Update(rc.MetaCtx, account))
}
func (a *Account) DeleteAccount(rc *req.Ctx) {
@@ -172,7 +169,7 @@ func (a *Account) DeleteAccount(rc *req.Ctx) {
for _, v := range ids {
value, err := strconv.Atoi(v)
biz.ErrIsNilAppendErr(err, "string类型转换为int异常: %s")
biz.ErrIsNilAppendErr(a.AccountApp.Delete(uint64(value)), "删除失败:%s")
biz.ErrIsNilAppendErr(a.AccountApp.Delete(rc.MetaCtx, uint64(value)), "删除失败:%s")
}
}
@@ -207,7 +204,7 @@ func (a *Account) SaveRoles(rc *req.Ctx) {
return uint64(id)
})
a.RoleApp.SaveAccountRole(contextx.NewLoginAccount(rc.LoginAccount), form.Id, newIds)
a.RoleApp.SaveAccountRole(rc.MetaCtx, form.Id, newIds)
}
// 重置otp秘钥
@@ -216,5 +213,5 @@ func (a *Account) ResetOtpSecret(rc *req.Ctx) {
accountId := uint64(ginx.PathParamInt(rc.GinCtx, "id"))
account.Id = accountId
rc.ReqParam = collx.Kvs("accountId", accountId)
biz.ErrIsNil(a.AccountApp.Update(account))
biz.ErrIsNil(a.AccountApp.Update(rc.MetaCtx, account))
}

View File

@@ -16,7 +16,7 @@ type Config struct {
func (c *Config) Configs(rc *req.Ctx) {
g := rc.GinCtx
condition := &entity.Config{Key: g.Query("key")}
condition.Permission = rc.LoginAccount.Username
condition.Permission = rc.GetLoginAccount().Username
res, err := c.ConfigApp.GetPageList(condition, ginx.GetPageParam(g), new([]entity.Config))
biz.ErrIsNil(err)
rc.ResData = res
@@ -40,6 +40,5 @@ func (c *Config) SaveConfig(rc *req.Ctx) {
form := &form.ConfigForm{}
config := ginx.BindJsonAndCopyTo(rc.GinCtx, form, new(entity.Config))
rc.ReqParam = form
config.SetBaseInfo(rc.LoginAccount)
biz.ErrIsNil(c.ConfigApp.Save(config))
biz.ErrIsNil(c.ConfigApp.Save(rc.MetaCtx, config))
}

View File

@@ -39,19 +39,18 @@ func (r *Resource) SaveResource(rc *req.Ctx) {
bytes, _ := json.Marshal(form.Meta)
entity.Meta = string(bytes)
entity.SetBaseInfo(rc.LoginAccount)
biz.ErrIsNil(r.ResourceApp.Save(entity))
biz.ErrIsNil(r.ResourceApp.Save(rc.MetaCtx, entity))
}
func (r *Resource) DelResource(rc *req.Ctx) {
biz.ErrIsNil(r.ResourceApp.Delete(uint64(ginx.PathParamInt(rc.GinCtx, "id"))))
biz.ErrIsNil(r.ResourceApp.Delete(rc.MetaCtx, uint64(ginx.PathParamInt(rc.GinCtx, "id"))))
}
func (r *Resource) ChangeStatus(rc *req.Ctx) {
rid := uint64(ginx.PathParamInt(rc.GinCtx, "id"))
status := int8(ginx.PathParamInt(rc.GinCtx, "status"))
rc.ReqParam = collx.Kvs("id", rid, "status", status)
biz.ErrIsNil(r.ResourceApp.ChangeStatus(rid, status))
biz.ErrIsNil(r.ResourceApp.ChangeStatus(rc.MetaCtx, rid, status))
}
func (r *Resource) Sort(rc *req.Ctx) {
@@ -62,6 +61,6 @@ func (r *Resource) Sort(rc *req.Ctx) {
for _, v := range rs {
sortE := &entity.Resource{Pid: v.Pid, Weight: v.Weight}
sortE.Id = uint64(v.Id)
r.ResourceApp.Sort(sortE)
r.ResourceApp.Sort(rc.MetaCtx, sortE)
}
}

View File

@@ -6,7 +6,6 @@ import (
"mayfly-go/internal/sys/application"
"mayfly-go/internal/sys/domain/entity"
"mayfly-go/pkg/biz"
"mayfly-go/pkg/contextx"
"mayfly-go/pkg/ginx"
"mayfly-go/pkg/req"
"mayfly-go/pkg/utils/collx"
@@ -32,9 +31,8 @@ func (r *Role) SaveRole(rc *req.Ctx) {
form := &form.RoleForm{}
role := ginx.BindJsonAndCopyTo(rc.GinCtx, form, new(entity.Role))
rc.ReqParam = form
role.SetBaseInfo(rc.LoginAccount)
r.RoleApp.SaveRole(role)
r.RoleApp.SaveRole(rc.MetaCtx, role)
}
// 删除角色及其资源关联关系
@@ -46,7 +44,7 @@ func (r *Role) DelRole(rc *req.Ctx) {
for _, v := range ids {
value, err := strconv.Atoi(v)
biz.ErrIsNilAppendErr(err, "string类型转换为int异常: %s")
r.RoleApp.DeleteRole(uint64(value))
r.RoleApp.DeleteRole(rc.MetaCtx, uint64(value))
}
}
@@ -77,5 +75,5 @@ func (r *Role) SaveResource(rc *req.Ctx) {
return uint64(id)
})
r.RoleApp.SaveRoleResource(contextx.NewLoginAccount(rc.LoginAccount), form.Id, newIds)
r.RoleApp.SaveRoleResource(rc.MetaCtx, form.Id, newIds)
}

View File

@@ -38,8 +38,6 @@ func (s *System) ConnectWs(g *gin.Context) {
biz.ErrIsNil(err, "sys websocket没有权限连接")
// 登录账号信息
la := rc.LoginAccount
if la != nil {
ws.AddClient(ws.UserId(la.Id), clientId, wsConn)
}
la := rc.GetLoginAccount()
ws.AddClient(ws.UserId(la.Id), clientId, wsConn)
}

View File

@@ -1,6 +1,7 @@
package application
import (
"context"
"mayfly-go/internal/sys/domain/entity"
"mayfly-go/internal/sys/domain/repository"
"mayfly-go/pkg/base"
@@ -17,11 +18,11 @@ type Account interface {
GetPageList(condition *entity.Account, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error)
Create(account *entity.Account) error
Create(ctx context.Context, account *entity.Account) error
Update(account *entity.Account) error
Update(ctx context.Context, account *entity.Account) error
Delete(id uint64) error
Delete(ctx context.Context, id uint64) error
}
func newAccountApp(accountRepo repository.Account) Account {
@@ -36,17 +37,17 @@ func (a *accountAppImpl) GetPageList(condition *entity.Account, pageParam *model
return a.GetRepo().GetPageList(condition, pageParam, toEntity)
}
func (a *accountAppImpl) Create(account *entity.Account) error {
func (a *accountAppImpl) Create(ctx context.Context, account *entity.Account) error {
if a.GetBy(&entity.Account{Username: account.Username}) == nil {
return errorx.NewBiz("该账号用户名已存在")
}
// 默认密码为账号用户名
account.Password = cryptox.PwdHash(account.Username)
account.Status = entity.AccountEnableStatus
return a.Insert(account)
return a.Insert(ctx, account)
}
func (a *accountAppImpl) Update(account *entity.Account) error {
func (a *accountAppImpl) Update(ctx context.Context, account *entity.Account) error {
if account.Username != "" {
unAcc := &entity.Account{Username: account.Username}
err := a.GetBy(unAcc)
@@ -55,14 +56,14 @@ func (a *accountAppImpl) Update(account *entity.Account) error {
}
}
return a.UpdateById(account)
return a.UpdateById(ctx, account)
}
func (a *accountAppImpl) Delete(id uint64) error {
func (a *accountAppImpl) Delete(ctx context.Context, id uint64) error {
return gormx.Tx(
func(db *gorm.DB) error {
// 删除account信息
return a.DeleteByIdWithDb(db, id)
return a.DeleteByIdWithDb(ctx, db, id)
},
func(db *gorm.DB) error {
// 删除账号关联的角色信息

View File

@@ -1,6 +1,7 @@
package application
import (
"context"
"encoding/json"
"mayfly-go/internal/sys/domain/entity"
"mayfly-go/internal/sys/domain/repository"
@@ -20,7 +21,7 @@ type Config interface {
GetPageList(condition *entity.Config, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error)
Save(config *entity.Config) error
Save(ctx context.Context, config *entity.Config) error
// GetConfig 获取指定key的配置信息, 不会返回nil, 若不存在则值都默认值即空字符串
GetConfig(key string) *entity.Config
@@ -41,9 +42,9 @@ func (a *configAppImpl) GetPageList(condition *entity.Config, pageParam *model.P
return a.GetRepo().GetPageList(condition, pageParam, toEntity)
}
func (a *configAppImpl) Save(config *entity.Config) error {
func (a *configAppImpl) Save(ctx context.Context, config *entity.Config) error {
if config.Id == 0 {
if err := a.Insert(config); err != nil {
if err := a.Insert(ctx, config); err != nil {
return err
}
} else {
@@ -52,7 +53,7 @@ func (a *configAppImpl) Save(config *entity.Config) error {
return errorx.NewBiz("您无权修改该配置")
}
if err := a.UpdateById(config); err != nil {
if err := a.UpdateById(ctx, config); err != nil {
return err
}
}

View File

@@ -1,6 +1,7 @@
package application
import (
"context"
"mayfly-go/internal/common/consts"
"mayfly-go/internal/sys/domain/entity"
"mayfly-go/internal/sys/domain/repository"
@@ -15,13 +16,13 @@ import (
type Resource interface {
base.App[*entity.Resource]
Save(entity *entity.Resource) error
Save(ctx context.Context, entity *entity.Resource) error
Delete(id uint64) error
Delete(ctx context.Context, id uint64) error
ChangeStatus(resourceId uint64, status int8) error
ChangeStatus(ctx context.Context, resourceId uint64, status int8) error
Sort(re *entity.Resource) error
Sort(ctx context.Context, re *entity.Resource) error
GetAccountResources(accountId uint64, toEntity any) error
}
@@ -36,7 +37,7 @@ type resourceAppImpl struct {
base.AppImpl[*entity.Resource, repository.Resource]
}
func (r *resourceAppImpl) Save(resource *entity.Resource) error {
func (r *resourceAppImpl) Save(ctx context.Context, resource *entity.Resource) error {
// 更新操作
if resource.Id != 0 {
if resource.Code != "" {
@@ -51,7 +52,7 @@ func (r *resourceAppImpl) Save(resource *entity.Resource) error {
}
}
}
return gormx.UpdateById(resource)
return r.UpdateById(ctx, resource)
}
// 生成随机八位唯一标识符
@@ -73,10 +74,10 @@ func (r *resourceAppImpl) Save(resource *entity.Resource) error {
return err
}
resource.Weight = int(time.Now().Unix())
return gormx.Insert(resource)
return r.Insert(ctx, resource)
}
func (r *resourceAppImpl) ChangeStatus(resourceId uint64, status int8) error {
func (r *resourceAppImpl) ChangeStatus(ctx context.Context, resourceId uint64, status int8) error {
resource, err := r.GetById(new(entity.Resource), resourceId)
if err != nil {
return errorx.NewBiz("资源不存在")
@@ -85,7 +86,7 @@ func (r *resourceAppImpl) ChangeStatus(resourceId uint64, status int8) error {
return r.GetRepo().UpdateByUiPathLike(resource)
}
func (r *resourceAppImpl) Sort(sortResource *entity.Resource) error {
func (r *resourceAppImpl) Sort(ctx context.Context, sortResource *entity.Resource) error {
resource, err := r.GetById(new(entity.Resource), sortResource.Id)
if err != nil {
return errorx.NewBiz("资源不存在")
@@ -95,7 +96,7 @@ func (r *resourceAppImpl) Sort(sortResource *entity.Resource) error {
if sortResource.Pid == resource.Pid {
saveE := &entity.Resource{Weight: sortResource.Weight}
saveE.Id = sortResource.Id
return r.Save(saveE)
return r.Save(ctx, saveE)
}
// 若资源原本唯一标识路径为xxxx/yyyy/zzzz/,则获取其父节点路径标识 xxxx/yyyy/ 与自身节点标识 zzzz/
@@ -131,7 +132,7 @@ func (r *resourceAppImpl) Sort(sortResource *entity.Resource) error {
} else {
updateUiPath.UiPath = strings.ReplaceAll(v.UiPath, parentResourceUiPath, newParentResourceUiPath)
}
r.Save(updateUiPath)
r.Save(ctx, updateUiPath)
}
// 更新零值使用map因为pid=0表示根节点
@@ -155,7 +156,7 @@ func (r *resourceAppImpl) checkCode(code string) error {
return nil
}
func (r *resourceAppImpl) Delete(id uint64) error {
func (r *resourceAppImpl) Delete(ctx context.Context, id uint64) error {
resource, err := r.GetById(new(entity.Resource), id)
if err != nil {
return errorx.NewBiz("资源不存在")
@@ -164,7 +165,7 @@ func (r *resourceAppImpl) Delete(id uint64) error {
// 删除当前节点及其所有子节点
children := r.GetRepo().GetChildren(resource.UiPath)
for _, v := range children {
r.GetRepo().DeleteById(v.Id)
r.GetRepo().DeleteById(ctx, v.Id)
// 删除角色关联的资源信息
gormx.DeleteBy(&entity.RoleResource{ResourceId: v.Id})
}

View File

@@ -17,9 +17,9 @@ import (
type Role interface {
GetPageList(condition *entity.Role, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error)
SaveRole(role *entity.Role) error
SaveRole(ctx context.Context, role *entity.Role) error
DeleteRole(id uint64) error
DeleteRole(ctx context.Context, id uint64) error
GetRoleResourceIds(roleId uint64) []uint64
@@ -29,7 +29,7 @@ type Role interface {
SaveRoleResource(ctx context.Context, roleId uint64, resourceIds []uint64)
// 删除角色资源关联记录
DeleteRoleResource(roleId uint64, resourceId uint64)
DeleteRoleResource(ctx context.Context, roleId uint64, resourceId uint64)
// 获取账号角色id列表
GetAccountRoleIds(accountId uint64) []uint64
@@ -37,7 +37,7 @@ type Role interface {
// 保存账号角色关联信息
SaveAccountRole(ctx context.Context, accountId uint64, roleIds []uint64)
DeleteAccountRole(accountId, roleId uint64)
DeleteAccountRole(ctx context.Context, accountId, roleId uint64)
GetAccountRoles(accountId uint64, toEntity any)
}
@@ -56,7 +56,7 @@ func (m *roleAppImpl) GetPageList(condition *entity.Role, pageParam *model.PageP
return m.roleRepo.GetPageList(condition, pageParam, toEntity, orderBy...)
}
func (m *roleAppImpl) SaveRole(role *entity.Role) error {
func (m *roleAppImpl) SaveRole(ctx context.Context, role *entity.Role) error {
role.Code = strings.ToUpper(role.Code)
if role.Id != 0 {
// code不可更改防止误传
@@ -68,11 +68,11 @@ func (m *roleAppImpl) SaveRole(role *entity.Role) error {
return gormx.Insert(role)
}
func (m *roleAppImpl) DeleteRole(id uint64) error {
func (m *roleAppImpl) DeleteRole(ctx context.Context, id uint64) error {
// 删除角色与资源的关联关系
return gormx.Tx(
func(db *gorm.DB) error {
return m.roleRepo.DeleteByIdWithDb(db, id)
return m.roleRepo.DeleteByIdWithDb(ctx, db, id)
},
func(db *gorm.DB) error {
return gormx.DeleteByWithDb(db, &entity.RoleResource{RoleId: id})
@@ -110,11 +110,11 @@ func (m *roleAppImpl) SaveRoleResource(ctx context.Context, roleId uint64, resou
m.roleRepo.SaveRoleResource(addVals)
for _, v := range delIds {
m.DeleteRoleResource(roleId, v)
m.DeleteRoleResource(ctx, roleId, v)
}
}
func (m *roleAppImpl) DeleteRoleResource(roleId uint64, resourceId uint64) {
func (m *roleAppImpl) DeleteRoleResource(ctx context.Context, roleId uint64, resourceId uint64) {
m.roleRepo.DeleteRoleResource(roleId, resourceId)
}
@@ -140,11 +140,11 @@ func (m *roleAppImpl) SaveAccountRole(ctx context.Context, accountId uint64, rol
m.roleRepo.SaveAccountRole(rr)
}
for _, v := range delIds {
m.DeleteAccountRole(accountId, v)
m.DeleteAccountRole(ctx, accountId, v)
}
}
func (m *roleAppImpl) DeleteAccountRole(accountId, roleId uint64) {
func (m *roleAppImpl) DeleteAccountRole(ctx context.Context, accountId, roleId uint64) {
m.roleRepo.DeleteAccountRole(accountId, roleId)
}

View File

@@ -5,6 +5,7 @@ import (
"fmt"
"mayfly-go/internal/sys/domain/entity"
"mayfly-go/internal/sys/domain/repository"
"mayfly-go/pkg/contextx"
"mayfly-go/pkg/errorx"
"mayfly-go/pkg/model"
"mayfly-go/pkg/req"
@@ -34,7 +35,7 @@ func (m *syslogAppImpl) GetPageList(condition *entity.SysLogQuery, pageParam *mo
}
func (m *syslogAppImpl) SaveFromReq(req *req.Ctx) {
lg := req.LoginAccount
lg := contextx.GetLoginAccount(req.MetaCtx)
if lg == nil {
lg = &model.LoginAccount{Id: 0, Username: "-"}
}
@@ -74,5 +75,5 @@ func (m *syslogAppImpl) SaveFromReq(req *req.Ctx) {
syslog.Type = entity.SyslogTypeNorman
}
m.syslogRepo.Insert(syslog)
m.syslogRepo.Insert(req.MetaCtx, syslog)
}

View File

@@ -16,7 +16,7 @@ type TagTree struct {
}
func (p *TagTree) GetAccountTags(rc *req.Ctx) {
tagPaths := p.TagTreeApp.ListTagByAccountId(rc.LoginAccount.Id)
tagPaths := p.TagTreeApp.ListTagByAccountId(rc.GetLoginAccount().Id)
allTagPath := make([]string, 0)
if len(tagPaths) > 0 {
tags := p.TagTreeApp.ListTagByPath(tagPaths...)
@@ -46,13 +46,11 @@ func (p *TagTree) SaveTagTree(rc *req.Ctx) {
tagTree := &entity.TagTree{}
ginx.BindJsonAndValid(rc.GinCtx, tagTree)
loginAccount := rc.LoginAccount
tagTree.SetBaseInfo(loginAccount)
rc.ReqParam = fmt.Sprintf("tagTreeId: %d, tagName: %s, codePath: %s", tagTree.Id, tagTree.Name, tagTree.CodePath)
biz.ErrIsNil(p.TagTreeApp.Save(tagTree))
biz.ErrIsNil(p.TagTreeApp.Save(rc.MetaCtx, tagTree))
}
func (p *TagTree) DelTagTree(rc *req.Ctx) {
biz.ErrIsNil(p.TagTreeApp.Delete(uint64(ginx.PathParamInt(rc.GinCtx, "id"))))
biz.ErrIsNil(p.TagTreeApp.Delete(rc.MetaCtx, uint64(ginx.PathParamInt(rc.GinCtx, "id"))))
}

View File

@@ -35,9 +35,8 @@ func (p *Team) SaveTeam(rc *req.Ctx) {
rc.ReqParam = team
isAdd := team.Id == 0
loginAccount := rc.LoginAccount
team.SetBaseInfo(loginAccount)
p.TeamApp.Save(team)
loginAccount := rc.GetLoginAccount()
p.TeamApp.Save(rc.MetaCtx, team)
// 如果是新增团队则默认将自己加入该团队
if isAdd {
@@ -46,8 +45,7 @@ func (p *Team) SaveTeam(rc *req.Ctx) {
teamMem.Username = loginAccount.Username
teamMem.TeamId = team.Id
teamMem.SetBaseInfo(rc.LoginAccount)
p.TeamApp.SaveMember(teamMem)
p.TeamApp.SaveMember(rc.MetaCtx, teamMem)
}
}
@@ -59,7 +57,7 @@ func (p *Team) DelTeam(rc *req.Ctx) {
for _, v := range ids {
value, err := strconv.Atoi(v)
biz.ErrIsNilAppendErr(err, "string类型转换为int异常: %s")
p.TeamApp.Delete(uint64(value))
p.TeamApp.Delete(rc.MetaCtx, uint64(value))
}
}
@@ -94,8 +92,7 @@ func (p *Team) SaveTeamMember(rc *req.Ctx) {
teamMember.TeamId = teamId
teamMember.AccountId = accountId
teamMember.Username = account.Username
teamMember.SetBaseInfo(rc.LoginAccount)
p.TeamApp.SaveMember(teamMember)
p.TeamApp.SaveMember(rc.MetaCtx, teamMember)
}
rc.ReqParam = teamMems
@@ -108,7 +105,7 @@ func (p *Team) DelTeamMember(rc *req.Ctx) {
aid := ginx.PathParamInt(g, "accountId")
rc.ReqParam = fmt.Sprintf("teamId: %d, accountId: %d", tid, aid)
p.TeamApp.DeleteMember(uint64(tid), uint64(aid))
p.TeamApp.DeleteMember(rc.MetaCtx, uint64(tid), uint64(aid))
}
// 获取团队关联的标签id
@@ -133,18 +130,16 @@ func (p *Team) SaveTags(rc *req.Ctx) {
return i1 == i2
})
loginAccount := rc.LoginAccount
for _, v := range addIds {
tagId := v
tag, err := p.TagApp.GetById(new(entity.TagTree), tagId)
biz.ErrIsNil(err, "存在非法标签id")
ptt := &entity.TagTreeTeam{TeamId: teamId, TagId: tagId, TagPath: tag.CodePath}
ptt.SetBaseInfo(loginAccount)
p.TeamApp.SaveTag(ptt)
p.TeamApp.SaveTag(rc.MetaCtx, ptt)
}
for _, v := range delIds {
p.TeamApp.DeleteTag(teamId, v)
p.TeamApp.DeleteTag(rc.MetaCtx, teamId, v)
}
rc.ReqParam = form

View File

@@ -1,6 +1,7 @@
package application
import (
"context"
dbapp "mayfly-go/internal/db/application"
dbentity "mayfly-go/internal/db/domain/entity"
machineapp "mayfly-go/internal/machine/application"
@@ -23,9 +24,9 @@ type TagTree interface {
ListByQuery(condition *entity.TagTreeQuery, toEntity any)
Save(tt *entity.TagTree) error
Save(ctx context.Context, tt *entity.TagTree) error
Delete(id uint64) error
Delete(ctx context.Context, id uint64) error
// 获取账号id拥有的可访问的标签id
ListTagIdByAccountId(accountId uint64) []uint64
@@ -74,7 +75,7 @@ type tagTreeAppImpl struct {
dbApp dbapp.Db
}
func (p *tagTreeAppImpl) Save(tag *entity.TagTree) error {
func (p *tagTreeAppImpl) Save(ctx context.Context, tag *entity.TagTree) error {
// 新建项目树节点信息
if tag.Id == 0 {
if strings.Contains(tag.Code, entity.CodePathSeparator) {
@@ -96,13 +97,13 @@ func (p *tagTreeAppImpl) Save(tag *entity.TagTree) error {
return errorx.NewBiz("已存在该标签路径开头的标签, 请修改该标识code")
}
return p.GetRepo().Insert(tag)
return p.Insert(ctx, tag)
}
// 防止误传导致被更新
tag.Code = ""
tag.CodePath = ""
return p.GetRepo().UpdateById(tag)
return p.UpdateById(ctx, tag)
}
func (p *tagTreeAppImpl) ListByQuery(condition *entity.TagTreeQuery, toEntity any) {
@@ -161,7 +162,7 @@ func (p *tagTreeAppImpl) CanAccess(accountId uint64, tagPath string) error {
return errorx.NewBiz("您无权操作该资源")
}
func (p *tagTreeAppImpl) Delete(id uint64) error {
func (p *tagTreeAppImpl) Delete(ctx context.Context, id uint64) error {
tagIds := [1]uint64{id}
if p.machineApp.Count(&machineentity.MachineQuery{TagIds: tagIds[:]}) > 0 {
return errorx.NewBiz("请先删除该标签关联的机器信息")
@@ -176,7 +177,7 @@ func (p *tagTreeAppImpl) Delete(id uint64) error {
return errorx.NewBiz("请先删除该标签关联的Mongo信息")
}
p.DeleteById(id)
p.DeleteById(ctx, id)
// 删除该标签关联的团队信息
return p.tagTreeTeamRepo.DeleteByCond(&entity.TagTreeTeam{TagId: id})
return p.tagTreeTeamRepo.DeleteByCond(ctx, &entity.TagTreeTeam{TagId: id})
}

View File

@@ -1,6 +1,7 @@
package application
import (
"context"
"mayfly-go/internal/tag/domain/entity"
"mayfly-go/internal/tag/domain/repository"
"mayfly-go/pkg/biz"
@@ -14,17 +15,17 @@ type Team interface {
// 分页获取项目团队信息列表
GetPageList(condition *entity.Team, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error)
Save(team *entity.Team) error
Save(ctx context.Context, team *entity.Team) error
Delete(id uint64) error
Delete(ctx context.Context, id uint64) error
//--------------- 团队成员相关接口 ---------------
GetMemberPage(condition *entity.TeamMember, pageParam *model.PageParam, toEntity any) (*model.PageResult[any], error)
SaveMember(tagTeamMember *entity.TeamMember)
SaveMember(ctx context.Context, tagTeamMember *entity.TeamMember)
DeleteMember(teamId, accountId uint64)
DeleteMember(tx context.Context, teamId, accountId uint64)
IsExistMember(teamId, accounId uint64) bool
@@ -32,9 +33,9 @@ type Team interface {
ListTagIds(teamId uint64) []uint64
SaveTag(tagTeam *entity.TagTreeTeam) error
SaveTag(ctx context.Context, tagTeam *entity.TagTreeTeam) error
DeleteTag(teamId, tagId uint64) error
DeleteTag(tx context.Context, teamId, tagId uint64) error
}
func newTeamApp(teamRepo repository.Team,
@@ -58,23 +59,23 @@ func (p *teamAppImpl) GetPageList(condition *entity.Team, pageParam *model.PageP
return p.teamRepo.GetPageList(condition, pageParam, toEntity, orderBy...)
}
func (p *teamAppImpl) Save(team *entity.Team) error {
func (p *teamAppImpl) Save(ctx context.Context, team *entity.Team) error {
if team.Id == 0 {
return p.teamRepo.Insert(team)
return p.teamRepo.Insert(ctx, team)
}
return p.teamRepo.UpdateById(team)
return p.teamRepo.UpdateById(ctx, team)
}
func (p *teamAppImpl) Delete(id uint64) error {
func (p *teamAppImpl) Delete(ctx context.Context, id uint64) error {
return gormx.Tx(
func(db *gorm.DB) error {
return p.teamRepo.DeleteByIdWithDb(db, id)
return p.teamRepo.DeleteByIdWithDb(ctx, db, id)
},
func(db *gorm.DB) error {
return p.teamMemberRepo.DeleteByCondWithDb(db, &entity.TeamMember{TeamId: id})
return p.teamMemberRepo.DeleteByCondWithDb(ctx, db, &entity.TeamMember{TeamId: id})
},
func(db *gorm.DB) error {
return p.tagTreeTeamRepo.DeleteByCondWithDb(db, &entity.TagTreeTeam{TeamId: id})
return p.tagTreeTeamRepo.DeleteByCondWithDb(ctx, db, &entity.TagTreeTeam{TeamId: id})
},
)
}
@@ -86,15 +87,15 @@ func (p *teamAppImpl) GetMemberPage(condition *entity.TeamMember, pageParam *mod
}
// 保存团队成员信息
func (p *teamAppImpl) SaveMember(teamMember *entity.TeamMember) {
func (p *teamAppImpl) SaveMember(ctx context.Context, teamMember *entity.TeamMember) {
teamMember.Id = 0
biz.IsTrue(!p.teamMemberRepo.IsExist(teamMember.TeamId, teamMember.AccountId), "该成员已存在")
p.teamMemberRepo.Insert(teamMember)
p.teamMemberRepo.Insert(ctx, teamMember)
}
// 删除团队成员信息
func (p *teamAppImpl) DeleteMember(teamId, accountId uint64) {
p.teamMemberRepo.DeleteByCond(&entity.TeamMember{TeamId: teamId, AccountId: accountId})
func (p *teamAppImpl) DeleteMember(ctx context.Context, teamId, accountId uint64) {
p.teamMemberRepo.DeleteByCond(ctx, &entity.TeamMember{TeamId: teamId, AccountId: accountId})
}
func (p *teamAppImpl) IsExistMember(teamId, accounId uint64) bool {
@@ -114,12 +115,12 @@ func (p *teamAppImpl) ListTagIds(teamId uint64) []uint64 {
}
// 保存关联项目信息
func (p *teamAppImpl) SaveTag(tagTreeTeam *entity.TagTreeTeam) error {
func (p *teamAppImpl) SaveTag(ctx context.Context, tagTreeTeam *entity.TagTreeTeam) error {
tagTreeTeam.Id = 0
return p.tagTreeTeamRepo.Insert(tagTreeTeam)
return p.tagTreeTeamRepo.Insert(ctx, tagTreeTeam)
}
// 删除关联项目信息
func (p *teamAppImpl) DeleteTag(teamId, tagId uint64) error {
return p.tagTreeTeamRepo.DeleteByCond(&entity.TagTreeTeam{TeamId: teamId, TagId: tagId})
func (p *teamAppImpl) DeleteTag(ctx context.Context, teamId, tagId uint64) error {
return p.tagTreeTeamRepo.DeleteByCond(ctx, &entity.TagTreeTeam{TeamId: teamId, TagId: tagId})
}