完善订单交接结账流程留痕
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
// Package processlog 提供交易过程的追加式留痕能力。
|
||||
package processlog
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"hfb_sys/backend/internal/model"
|
||||
|
||||
"gorm.io/datatypes"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
const (
|
||||
ActorUser = "user"
|
||||
ActorAdmin = "admin"
|
||||
ActorSystem = "system"
|
||||
)
|
||||
|
||||
type Entry struct {
|
||||
BusinessType string
|
||||
BusinessID uint64
|
||||
Stage string
|
||||
Action string
|
||||
ActorType string
|
||||
ActorID uint64
|
||||
TargetType string
|
||||
TargetID *uint64
|
||||
Content string
|
||||
Reason string
|
||||
Payload map[string]any
|
||||
Attachments []string
|
||||
StateBefore map[string]any
|
||||
StateAfter map[string]any
|
||||
}
|
||||
|
||||
func Append(tx *gorm.DB, entry Entry) error {
|
||||
actorName, err := displayName(tx, entry.ActorType, entry.ActorID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
targetName := ""
|
||||
if entry.TargetID != nil && *entry.TargetID > 0 {
|
||||
targetName, err = displayName(tx, entry.TargetType, *entry.TargetID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return tx.Create(&model.ProcessEvent{
|
||||
BusinessType: entry.BusinessType,
|
||||
BusinessID: entry.BusinessID,
|
||||
Stage: entry.Stage,
|
||||
Action: entry.Action,
|
||||
ActorType: entry.ActorType,
|
||||
ActorID: entry.ActorID,
|
||||
ActorName: actorName,
|
||||
TargetType: entry.TargetType,
|
||||
TargetID: entry.TargetID,
|
||||
TargetName: targetName,
|
||||
Content: strings.TrimSpace(entry.Content),
|
||||
Reason: strings.TrimSpace(entry.Reason),
|
||||
Payload: jsonValue(entry.Payload),
|
||||
AttachmentURLs: jsonValue(entry.Attachments),
|
||||
StateBefore: jsonValue(entry.StateBefore),
|
||||
StateAfter: jsonValue(entry.StateAfter),
|
||||
}).Error
|
||||
}
|
||||
|
||||
func List(tx *gorm.DB, businessType string, businessID uint64) ([]model.ProcessEvent, error) {
|
||||
var rows []model.ProcessEvent
|
||||
err := tx.Where("business_type = ? AND business_id = ?", businessType, businessID).
|
||||
Order("id ASC").Find(&rows).Error
|
||||
return rows, err
|
||||
}
|
||||
|
||||
func displayName(tx *gorm.DB, actorType string, id uint64) (string, error) {
|
||||
if id == 0 || actorType == ActorSystem {
|
||||
return "系统", nil
|
||||
}
|
||||
switch actorType {
|
||||
case ActorAdmin:
|
||||
var row model.AdminUser
|
||||
if err := tx.Select("id", "username", "nickname").First(&row, id).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return "客服 ID " + formatID(id), nil
|
||||
}
|
||||
return "", err
|
||||
}
|
||||
if strings.TrimSpace(row.Nickname) != "" {
|
||||
return row.Nickname + "(客服)", nil
|
||||
}
|
||||
if strings.TrimSpace(row.Username) != "" {
|
||||
return row.Username + "(客服)", nil
|
||||
}
|
||||
return "客服 ID " + formatID(id), nil
|
||||
default:
|
||||
var row model.User
|
||||
if err := tx.Select("id", "nickname", "phone").First(&row, id).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return "用户 ID " + formatID(id), nil
|
||||
}
|
||||
return "", err
|
||||
}
|
||||
if strings.TrimSpace(row.Nickname) != "" {
|
||||
return row.Nickname + "(用户)", nil
|
||||
}
|
||||
if strings.TrimSpace(row.Phone) != "" {
|
||||
return row.Phone + "(用户)", nil
|
||||
}
|
||||
return "用户 ID " + formatID(id), nil
|
||||
}
|
||||
}
|
||||
|
||||
func jsonValue(value any) datatypes.JSON {
|
||||
if value == nil {
|
||||
return datatypes.JSON([]byte("{}"))
|
||||
}
|
||||
raw, err := json.Marshal(value)
|
||||
if err != nil || len(raw) == 0 {
|
||||
return datatypes.JSON([]byte("{}"))
|
||||
}
|
||||
return datatypes.JSON(raw)
|
||||
}
|
||||
|
||||
func formatID(id uint64) string {
|
||||
return strconv.FormatUint(id, 10)
|
||||
}
|
||||
Reference in New Issue
Block a user