Files
junhong_cmp_fiber/internal/service/asset_audit/service.go
huang cb75b5668b
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m10s
操作日志
2026-04-27 12:16:38 +08:00

150 lines
3.9 KiB
Go

// Package asset_audit 提供资产操作审计日志服务。
package asset_audit
import (
"context"
"github.com/break/junhong_cmp_fiber/internal/model"
"github.com/break/junhong_cmp_fiber/internal/model/dto"
"github.com/break/junhong_cmp_fiber/pkg/constants"
"github.com/break/junhong_cmp_fiber/pkg/logger"
"go.uber.org/zap"
)
// AssetOperationLogStore 资产操作日志存储接口。
type AssetOperationLogStore interface {
Create(ctx context.Context, log *model.AssetOperationLog) error
ListByAssetPaged(
ctx context.Context,
assetType string,
assetID uint,
page int,
pageSize int,
operationType string,
resultStatus string,
) ([]*model.AssetOperationLog, int64, error)
}
// OperationLogger 资产审计记录接口。
type OperationLogger interface {
LogOperation(ctx context.Context, log *model.AssetOperationLog)
}
// Service 资产审计服务。
type Service struct {
store AssetOperationLogStore
}
// ListByAssetParams 按资产查询日志参数。
type ListByAssetParams struct {
AssetType string
AssetID uint
Page int
PageSize int
OperationType string
ResultStatus string
}
// NewService 创建资产审计服务实例。
func NewService(store AssetOperationLogStore) *Service {
return &Service{store: store}
}
// LogOperation 记录资产操作日志(异步写入,不阻塞主流程)。
func (s *Service) LogOperation(ctx context.Context, log *model.AssetOperationLog) {
if s == nil || s.store == nil || log == nil {
return
}
go func() {
if err := s.store.Create(context.Background(), log); err != nil {
logger.GetAppLogger().Error("写入资产操作日志失败",
zap.String("asset_type", log.AssetType),
zap.Uint("asset_id", log.AssetID),
zap.String("operation_type", log.OperationType),
zap.String("result_status", log.ResultStatus),
zap.Error(err))
}
}()
}
// ListByAsset 按资产分页查询操作日志。
func (s *Service) ListByAsset(ctx context.Context, params ListByAssetParams) (*dto.AssetOperationLogListResponse, error) {
if s == nil || s.store == nil {
return &dto.AssetOperationLogListResponse{
Total: 0,
Page: 1,
PageSize: constants.DefaultPageSize,
Items: []*dto.AssetOperationLogItem{},
}, nil
}
page := params.Page
pageSize := params.PageSize
if page <= 0 {
page = 1
}
if pageSize <= 0 {
pageSize = constants.DefaultPageSize
}
if pageSize > 100 {
pageSize = 100
}
logs, total, err := s.store.ListByAssetPaged(
ctx,
NormalizeAssetType(params.AssetType),
params.AssetID,
page,
pageSize,
params.OperationType,
params.ResultStatus,
)
if err != nil {
return nil, err
}
items := make([]*dto.AssetOperationLogItem, 0, len(logs))
for _, item := range logs {
items = append(items, toAssetOperationLogItem(item))
}
return &dto.AssetOperationLogListResponse{
Total: total,
Page: page,
PageSize: pageSize,
Items: items,
}, nil
}
func toAssetOperationLogItem(log *model.AssetOperationLog) *dto.AssetOperationLogItem {
if log == nil {
return nil
}
return &dto.AssetOperationLogItem{
ID: log.ID,
CreatedAt: log.CreatedAt,
OperatorID: log.OperatorID,
OperatorType: log.OperatorType,
OperatorName: log.OperatorName,
AssetType: log.AssetType,
AssetID: log.AssetID,
AssetIdentifier: log.AssetIdentifier,
OperationType: log.OperationType,
OperationDesc: log.OperationDesc,
BeforeData: map[string]any(log.BeforeData),
AfterData: map[string]any(log.AfterData),
RequestID: log.RequestID,
IPAddress: log.IPAddress,
UserAgent: log.UserAgent,
RequestPath: log.RequestPath,
RequestMethod: log.RequestMethod,
ResultStatus: log.ResultStatus,
ErrorCode: log.ErrorCode,
ErrorMsg: log.ErrorMsg,
BatchTotal: log.BatchTotal,
SuccessCount: log.SuccessCount,
FailCount: log.FailCount,
}
}