mirror of
				https://gitee.com/dromara/mayfly-go
				synced 2025-11-04 08:20:25 +08:00 
			
		
		
		
	feat: 数据迁移新增实时日志&数据库游标遍历查询问题修复
This commit is contained in:
		@@ -17,3 +17,7 @@ func (r *Syslog) Syslogs(rc *req.Ctx) {
 | 
			
		||||
	biz.ErrIsNil(err)
 | 
			
		||||
	rc.ResData = res
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (r *Syslog) SyslogDetail(rc *req.Ctx) {
 | 
			
		||||
	rc.ResData = r.SyslogApp.GetLogDetail(uint64(rc.PathParamInt("id")))
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,27 +1,62 @@
 | 
			
		||||
package application
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"mayfly-go/internal/sys/domain/entity"
 | 
			
		||||
	"mayfly-go/internal/sys/domain/repository"
 | 
			
		||||
	"mayfly-go/pkg/contextx"
 | 
			
		||||
	"mayfly-go/pkg/errorx"
 | 
			
		||||
	"mayfly-go/pkg/logx"
 | 
			
		||||
	"mayfly-go/pkg/model"
 | 
			
		||||
	"mayfly-go/pkg/req"
 | 
			
		||||
	"mayfly-go/pkg/utils/anyx"
 | 
			
		||||
	"mayfly-go/pkg/utils/collx"
 | 
			
		||||
	"mayfly-go/pkg/utils/jsonx"
 | 
			
		||||
	"mayfly-go/pkg/utils/structx"
 | 
			
		||||
	"mayfly-go/pkg/utils/timex"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type CreateLogReq struct {
 | 
			
		||||
	Type        int8           `json:"type"`
 | 
			
		||||
	Description string         `json:"description"`
 | 
			
		||||
	ReqParam    any            `json:"reqParam" ` // 请求参数
 | 
			
		||||
	Resp        string         `json:"resp" `     // 响应结构
 | 
			
		||||
	Extra       map[string]any // 额外日志信息
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type AppendLogReq struct {
 | 
			
		||||
	Type       int8           `json:"type"`
 | 
			
		||||
	AppendResp string         `json:"appendResp" ` // 追加日志信息
 | 
			
		||||
	Extra      map[string]any // 额外日志信息
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Syslog interface {
 | 
			
		||||
	GetPageList(condition *entity.SysLogQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error)
 | 
			
		||||
 | 
			
		||||
	// 从请求上下文的参数保存系统日志
 | 
			
		||||
	SaveFromReq(req *req.Ctx)
 | 
			
		||||
 | 
			
		||||
	GetLogDetail(logId uint64) *entity.SysLog
 | 
			
		||||
 | 
			
		||||
	// CreateLog 创建日志信息
 | 
			
		||||
	CreateLog(ctx context.Context, log *CreateLogReq) (uint64, error)
 | 
			
		||||
 | 
			
		||||
	// AppendLog 追加日志信息
 | 
			
		||||
	AppendLog(logId uint64, appendLog *AppendLogReq)
 | 
			
		||||
 | 
			
		||||
	// Flush 实时追加的日志到库里
 | 
			
		||||
	Flush(logId uint64)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type syslogAppImpl struct {
 | 
			
		||||
	SyslogRepo repository.Syslog `inject:""`
 | 
			
		||||
 | 
			
		||||
	appendLogs map[uint64]*entity.SysLog
 | 
			
		||||
	rwLock     sync.RWMutex
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *syslogAppImpl) GetPageList(condition *entity.SysLogQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
 | 
			
		||||
@@ -34,7 +69,8 @@ func (m *syslogAppImpl) SaveFromReq(req *req.Ctx) {
 | 
			
		||||
		lg = &model.LoginAccount{Id: 0, Username: "-"}
 | 
			
		||||
	}
 | 
			
		||||
	syslog := new(entity.SysLog)
 | 
			
		||||
	syslog.CreateTime = time.Now()
 | 
			
		||||
	now := time.Now()
 | 
			
		||||
	syslog.CreateTime = &now
 | 
			
		||||
	syslog.Creator = lg.Username
 | 
			
		||||
	syslog.CreatorId = lg.Id
 | 
			
		||||
 | 
			
		||||
@@ -67,8 +103,78 @@ func (m *syslogAppImpl) SaveFromReq(req *req.Ctx) {
 | 
			
		||||
		}
 | 
			
		||||
		syslog.Resp = errMsg
 | 
			
		||||
	} else {
 | 
			
		||||
		syslog.Type = entity.SyslogTypeNorman
 | 
			
		||||
		syslog.Type = entity.SyslogTypeSuccess
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m.SyslogRepo.Insert(req.MetaCtx, syslog)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *syslogAppImpl) GetLogDetail(logId uint64) *entity.SysLog {
 | 
			
		||||
	syslog := new(entity.SysLog)
 | 
			
		||||
	if err := m.SyslogRepo.GetById(syslog, logId); err != nil {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if syslog.Type == entity.SyslogTypeRunning {
 | 
			
		||||
		m.rwLock.RLock()
 | 
			
		||||
		defer m.rwLock.RUnlock()
 | 
			
		||||
		return m.appendLogs[logId]
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return syslog
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *syslogAppImpl) CreateLog(ctx context.Context, log *CreateLogReq) (uint64, error) {
 | 
			
		||||
	syslog := new(entity.SysLog)
 | 
			
		||||
	structx.Copy(syslog, log)
 | 
			
		||||
	syslog.ReqParam = anyx.ToString(log.ReqParam)
 | 
			
		||||
	if log.Extra != nil {
 | 
			
		||||
		syslog.Extra = jsonx.ToStr(log.Extra)
 | 
			
		||||
	}
 | 
			
		||||
	if err := m.SyslogRepo.Insert(ctx, syslog); err != nil {
 | 
			
		||||
		return 0, err
 | 
			
		||||
	}
 | 
			
		||||
	return syslog.Id, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *syslogAppImpl) AppendLog(logId uint64, appendLog *AppendLogReq) {
 | 
			
		||||
	m.rwLock.Lock()
 | 
			
		||||
	defer m.rwLock.Unlock()
 | 
			
		||||
 | 
			
		||||
	if m.appendLogs == nil {
 | 
			
		||||
		m.appendLogs = make(map[uint64]*entity.SysLog)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	syslog := m.appendLogs[logId]
 | 
			
		||||
	if syslog == nil {
 | 
			
		||||
		syslog = new(entity.SysLog)
 | 
			
		||||
		if err := m.SyslogRepo.GetById(syslog, logId); err != nil {
 | 
			
		||||
			logx.Warnf("追加日志不存在: %d", logId)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		m.appendLogs[logId] = syslog
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	appendLogMsg := fmt.Sprintf("%s %s", timex.DefaultFormat(time.Now()), appendLog.AppendResp)
 | 
			
		||||
	syslog.Resp = fmt.Sprintf("%s\n%s", syslog.Resp, appendLogMsg)
 | 
			
		||||
	syslog.Type = appendLog.Type
 | 
			
		||||
	if appendLog.Extra != nil {
 | 
			
		||||
		existExtra := jsonx.ToMap(syslog.Extra)
 | 
			
		||||
		syslog.Extra = jsonx.ToStr(collx.MapMerge(existExtra, appendLog.Extra))
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *syslogAppImpl) Flush(logId uint64) {
 | 
			
		||||
	syslog := m.appendLogs[logId]
 | 
			
		||||
	if syslog == nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 如果刷入库的的时候还是执行中状态,则默认改为成功状态
 | 
			
		||||
	if syslog.Type == entity.SyslogTypeRunning {
 | 
			
		||||
		syslog.Type = entity.SyslogTypeSuccess
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m.SyslogRepo.UpdateById(context.Background(), syslog)
 | 
			
		||||
	delete(m.appendLogs, logId)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,21 +2,17 @@ package entity
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"mayfly-go/pkg/model"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// 系统操作日志
 | 
			
		||||
type SysLog struct {
 | 
			
		||||
	model.DeletedModel
 | 
			
		||||
 | 
			
		||||
	CreateTime time.Time `json:"createTime"`
 | 
			
		||||
	CreatorId  uint64    `json:"creatorId"`
 | 
			
		||||
	Creator    string    `json:"creator"`
 | 
			
		||||
	model.CreateModel
 | 
			
		||||
 | 
			
		||||
	Type        int8   `json:"type"`
 | 
			
		||||
	Description string `json:"description"`
 | 
			
		||||
	ReqParam    string `json:"reqParam" gorm:"column:req_param;type:varchar(1000)"` // 请求参数
 | 
			
		||||
	Resp        string `json:"resp" gorm:"column:resp;type:varchar(1000)"`          // 响应结构
 | 
			
		||||
	Resp        string `json:"resp" gorm:"column:resp;type:varchar(10000)"`         // 响应结构
 | 
			
		||||
	Extra       string `json:"extra"`                                               // 日志额外信息
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (a *SysLog) TableName() string {
 | 
			
		||||
@@ -24,6 +20,7 @@ func (a *SysLog) TableName() string {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	SyslogTypeNorman int8 = 1 // 正常状态
 | 
			
		||||
	SyslogTypeError  int8 = 2 // 错误状态
 | 
			
		||||
	SyslogTypeRunning int8 = -1 // 执行中
 | 
			
		||||
	SyslogTypeSuccess int8 = 1  // 正常状态
 | 
			
		||||
	SyslogTypeError   int8 = 2  // 错误状态
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
@@ -15,4 +15,6 @@ func InitSyslogRouter(router *gin.RouterGroup) {
 | 
			
		||||
	biz.ErrIsNil(ioc.Inject(s))
 | 
			
		||||
 | 
			
		||||
	req.NewGet("", s.Syslogs).Group(sysG)
 | 
			
		||||
 | 
			
		||||
	req.NewGet("/:id", s.SyslogDetail).Group(sysG)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user