Files
affiliate_dash/backend/internal/service/rock_token_status_log.go
T

94 lines
2.9 KiB
Go

package service
import (
"context"
"log"
"strings"
"affiliate_dash/internal/model"
"gorm.io/gorm"
)
// Token 生命周期事件类型。
const (
rockTokenEventCreated = "created"
rockTokenEventStatusChanged = "status_changed"
rockTokenEventDeleted = "deleted"
rockTokenEventRestored = "restored"
)
// Token 状态来源,用于前端展示流转原因。
const (
rockTokenSourceAssign = "assign"
rockTokenSourceBindCheck = "bindcheck"
rockTokenSourceRedeem = "redeem"
rockTokenSourceRefresh = "refresh"
rockTokenSourceRelease = "release"
rockTokenSourceReset = "reset"
rockTokenSourceManual = "manual"
rockTokenSourceOrderCancel = "order_cancel"
rockTokenSourcePurchase = "purchase"
rockTokenSourcePackageSync = "package_sync"
rockTokenSourceDelete = "delete"
rockTokenSourceRestore = "restore"
)
// writeRockTokenStatusLog 记录 Token 生命周期/状态变化。
//
// 采用 best-effort:日志写入失败只打印错误,不影响主流程(避免因为审计表异常阻断发货)。
func writeRockTokenStatusLog(tx *gorm.DB, token *model.RockToken, eventType, from, to, source, reason string, forced bool, actorUserID *uint) {
if tx == nil || token == nil || token.ID == 0 {
return
}
entry := &model.RockTokenStatusLog{
TokenID: token.ID,
UpstreamTokenID: strings.TrimSpace(token.UpstreamTokenID),
EventType: eventType,
FromStatus: from,
ToStatus: to,
Source: source,
Reason: truncateRunes(strings.TrimSpace(reason), 240),
Forced: forced,
ActorUserID: actorUserID,
}
if err := tx.Create(entry).Error; err != nil {
log.Printf("[Rock] 写入 Token 状态日志失败 token=%d %s->%s: %v", token.ID, from, to, err)
}
}
// writeRockTokenStatusChange 仅在状态确实发生变化时写日志。
func writeRockTokenStatusChange(tx *gorm.DB, token *model.RockToken, from, to, source, reason string, forced bool, actorUserID *uint) {
if strings.TrimSpace(from) == strings.TrimSpace(to) {
return
}
writeRockTokenStatusLog(tx, token, rockTokenEventStatusChanged, from, to, source, reason, forced, actorUserID)
}
func truncateRunes(value string, limit int) string {
if limit <= 0 {
return ""
}
runes := []rune(value)
if len(runes) <= limit {
return value
}
return string(runes[:limit])
}
// ListTokenStatusLogs 返回指定 Token 的状态历史(最新在前)。
func (s *RockService) ListTokenStatusLogs(ctx context.Context, tokenID uint) ([]model.RockTokenStatusLog, error) {
var token model.RockToken
if err := s.db.WithContext(ctx).Unscoped().First(&token, tokenID).Error; err != nil {
return nil, err
}
var logs []model.RockTokenStatusLog
if err := s.db.WithContext(ctx).
Where("token_id = ?", tokenID).
Order("id DESC").
Limit(200).
Find(&logs).Error; err != nil {
return nil, err
}
return logs, nil
}