log_service.go 7.9 KB
package domainService

import (
	"fmt"
	pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
	"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
	"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/repository"
	"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/starrocks"
	"strings"
	"time"
)

type PGLogService struct {
	transactionContext *pgTransaction.TransactionContext
}

func NewPGLogService(transactionContext *pgTransaction.TransactionContext) (*PGLogService, error) {
	if transactionContext == nil {
		return nil, fmt.Errorf("transactionContext参数不能为nil")
	} else {
		return &PGLogService{
			transactionContext: transactionContext,
		}, nil
	}
}

func FastLog(transactionContext *pgTransaction.TransactionContext, logType domain.LogType, sourceId int, logEntry Log) error {
	logService, _ := NewPGLogService(transactionContext)
	return logService.Log(logType, sourceId, logEntry)
}

func (ptr *PGLogService) Log(logType domain.LogType, sourceId int, logEntry Log) error {
	logRepository, _ := repository.NewLogRepository(ptr.transactionContext)
	entry := logEntry.Entry()
	log := &domain.Log{
		LogType:       logType.ToString(),
		SourceId:      sourceId,
		Entry:         &entry,
		ObjectName:    entry.ObjectName,
		ObjectType:    domain.EnumsDescription(domain.ObjectTypeMap, entry.ObjectType),
		OperationType: domain.EnumsDescription(domain.OperationTypeMap, entry.OperationType),
		Content:       logEntry.Content(),
		OperatorName:  entry.OperatorName,
		CreatedAt:     time.Now(),
		Context:       logEntry.Context(),
		LogTime:       entry.LogTime,
	}

	if v, ok := logEntry.Context().GetValue(domain.ContextWithLogLevel); ok {
		log.Entry.Level = string(v.(domain.LogLevel))
	}
	if v, ok := logEntry.Context().GetValue(domain.ContextWithLogMsg); ok {
		log.Entry.Error = v.(string)
	}
	_, err := logRepository.Save(log)
	return err
}

func (ptr *PGLogService) NewLogEntry() domain.LogEntry {
	return domain.LogEntry{}
}

type Log interface {
	Content() string
	Entry() domain.LogEntry
	Context() *domain.Context
}

var _ Log = (*FileUploadSuccessLog)(nil)

// 1.1文件上传成功
type FileUploadSuccessLog struct {
	domain.LogEntry
}

func (l *FileUploadSuccessLog) Content() string {
	return fmt.Sprintf("上传成功")
}

// 1.2文件上传失败
type FileUploadFailLog struct {
	domain.LogEntry
	Reason string
}

func (l *FileUploadFailLog) Content() string {
	return fmt.Sprintf("上传失败,失败原因:%s", l.Reason)
}

// 2.文件校验
type FileVerifyLog struct {
	domain.LogEntry
	// 错误信息
	Errors []string
	// 记录数
	Total int
}

func (l *FileVerifyLog) Content() string {
	msg := fmt.Sprintf("校验完成,共计%d条记录 ", l.Total)
	if len(l.Errors) > 0 {
		msg += fmt.Sprintf("存在%v条报错", len(l.Errors))
	}
	return msg
}

// 3.主表生成日志
type GenerateMainTableLog struct {
	domain.LogEntry
	// 表名
	TableName string
	// 文件名
	FileName string
}

func (l *GenerateMainTableLog) Content() string {
	msg := fmt.Sprintf("来源校验文件:%v", l.FileName)
	return msg
}

// 4.主表拆分
type SpiltMainTableLog struct {
	domain.LogEntry
	Reserve []*domain.Field
	Delete  []*domain.Field
	Add     []*domain.Field
	// 表名
	SourceTableName string
}

func (l *SpiltMainTableLog) Content() string {
	var msg string
	msg += fmt.Sprintf("来源表:%v", l.SourceTableName)
	msg += l.makeMsg(" 删除字段", l.Delete)
	msg += l.makeMsg(" 保留字段", l.Reserve)
	msg += l.makeMsg(" 添加字段", l.Add)
	return msg
}

func (l *SpiltMainTableLog) makeMsg(title string, fields []*domain.Field) string {
	if len(l.fieldNames(fields)) > 0 {
		return fmt.Sprintf("%s: %s ", title, strings.Join(l.fieldNames(fields), "、"))
	}
	return ""
}

func (l *SpiltMainTableLog) fieldNames(fields []*domain.Field) []string {
	names := make([]string, 0)
	for _, f := range fields {
		names = append(names, f.Name)
	}
	return names
}

// 5.分表编辑
type SubTableEditLog struct {
	domain.LogEntry

	Reserve []*domain.Field
	Delete  []*domain.Field
	Add     []*domain.Field
}

func (l *SubTableEditLog) Content() string {
	var msg string
	msg = "分表编辑 "
	msg += l.makeMsg("删除字段", l.Delete)
	msg += l.makeMsg("保留字段", l.Reserve)
	msg += l.makeMsg("添加字段", l.Add)
	return msg
}

func (l *SubTableEditLog) makeMsg(title string, fields []*domain.Field) string {
	if len(l.fieldNames(fields)) > 0 {
		return fmt.Sprintf("%s: %s ", title, strings.Join(l.fieldNames(fields), "、"))
	}
	return ""
}

func (l *SubTableEditLog) fieldNames(fields []*domain.Field) []string {
	names := make([]string, 0)
	for _, f := range fields {
		names = append(names, f.Name)
	}
	return names
}

// 6.表复制日志
type CopyTableLog struct {
	domain.LogEntry
	// 表名
	SourceTableName string
}

func (l *CopyTableLog) Content() string {
	msg := fmt.Sprintf("来源表:%v", l.SourceTableName)
	return msg
}

// 7.编辑记录
type RowAddLog struct {
	domain.LogEntry
}

func (l *RowAddLog) Content() string {
	msg := fmt.Sprintf("新增行数据")
	return msg
}

type RowUpdateLog struct {
	domain.LogEntry
	FieldValue []*domain.FieldValue
	Where      domain.Where
	Number     int
}

func (l *RowUpdateLog) Content() string {
	change := ""
	//index := l.Number + l.Where.Offset()
	for _, f := range l.FieldValue {
		if f.OldValue != f.Value {
			//change += fmt.Sprintf("%v字段%v行的值从%v更改为%v;", f.Field.Name, index, f.OldValue, f.Value)
			change += fmt.Sprintf("【%v】字段的值从“%v”更改为“%v”;", f.Field.Name, f.OldValue, f.Value)
		}
	}
	if len(change) == 0 {
		return "更新数据内容"
	}
	msg := fmt.Sprintf("更改数据内容:%v", change)
	return msg
}

type RowRemoveLog struct {
	domain.LogEntry
	DeleteRowCount int
	Where          domain.Where
}

func (l *RowRemoveLog) Content() string {
	index := l.DeleteRowCount
	//msg := fmt.Sprintf("删除%v行数据;筛选件:%v",index,"")
	msg := fmt.Sprintf("删除%v行数据;", index)
	filters := make([]string, 0)
	inArgs := func(args []string) string {
		return strings.Join(args, "、")
	}
	for _, c := range l.Where.Conditions {
		if len(c.In) > 0 {
			filters = append(filters, fmt.Sprintf("【%v】 包含 %v", c.Field.Name, inArgs(starrocks.ArrayInterfaceToString(c.In))))
		}
		if len(c.Ex) > 0 {
			filters = append(filters, fmt.Sprintf("【%v】 不包含 %v", c.Field.Name, inArgs(starrocks.ArrayInterfaceToString(c.Ex))))
		}
	}
	if len(filters) > 0 {
		msg += "筛选件:" + strings.Join(filters, "|")
	}
	return msg
}

// 8.表删除日志
type DeleteTableLog struct {
	domain.LogEntry
	// 表名
	SourceTableName string
	RowCount        int
	SubTables       []*domain.Table
}

func (l *DeleteTableLog) Content() string {
	msg := fmt.Sprintf("共计%v条数据", l.RowCount)
	var tables []string
	for _, t := range l.SubTables {
		tables = append(tables, t.Name+"分表")
	}
	if len(tables) > 0 {
		msg += fmt.Sprintf(",(存在分表)同步删除%s", strings.Join(tables, "/"))
	}
	return msg
}

// 9.数据追加日志
type AppendDataToTableLog struct {
	domain.LogEntry
	Table     *domain.Table
	File      *domain.File
	RowCount  int
	SubTables []*domain.Table
}

func (l *AppendDataToTableLog) Content() string {
	msg := fmt.Sprintf("来源文件:%v校验文件,导入成功%v条,目标表单:%v", l.File.FileInfo.Name, l.RowCount, l.Table.Name)
	var tables []string
	for _, t := range l.SubTables {
		tables = append(tables, t.Name+"分表")
	}
	if len(tables) > 0 {
		msg += fmt.Sprintf(",关联更新%s", strings.Join(tables, "/"))
	}
	return msg
}

/*步骤日志*/
type ExcelTableEditLog struct {
	domain.LogEntry
	// 操作名称
	OperateName string
	// 操作列
	ProcessFields []*domain.Field
}

func (l *ExcelTableEditLog) Content() string {
	fieldsName := make([]string, 0)
	for _, f := range l.ProcessFields {
		fieldsName = append(fieldsName, fmt.Sprintf("【%v】", f.Name))
	}
	msg := fmt.Sprintf("%v:%v", l.OperateName, strings.Join(fieldsName, "、"))
	return msg
}