129 lines
2.7 KiB
Go
129 lines
2.7 KiB
Go
package listingstatus
|
|
|
|
import (
|
|
"strings"
|
|
"time"
|
|
|
|
"hfb_sys/backend/internal/model"
|
|
"hfb_sys/backend/internal/timeutil"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// 统计用的事件类型(与 to_status 对齐时优先用这些标准值)。
|
|
const (
|
|
EventPublished = "published"
|
|
EventOffline = "offline"
|
|
EventRented = "rented"
|
|
EventCompleted = "completed"
|
|
EventSealed = "sealed"
|
|
EventAbnormal = "abnormal"
|
|
)
|
|
|
|
// 来源
|
|
const (
|
|
SourceSeller = "seller"
|
|
SourceAdmin = "admin"
|
|
SourceReview = "review"
|
|
SourceOrder = "order"
|
|
SourcePickup = "pickup"
|
|
SourceDispute = "dispute"
|
|
SourceSystem = "system"
|
|
)
|
|
|
|
// 操作者类型
|
|
const (
|
|
ActorUser = "user"
|
|
ActorAdmin = "admin"
|
|
ActorSystem = "system"
|
|
)
|
|
|
|
// Entry 单次状态变更事件。
|
|
type Entry struct {
|
|
ListingID uint64
|
|
OwnerID uint64
|
|
EventType string
|
|
FromStatus string
|
|
ToStatus string
|
|
Source string
|
|
ActorType string
|
|
ActorID uint64
|
|
Remark string
|
|
// CreatedAt 为空时使用上海时间当前时刻。
|
|
CreatedAt time.Time
|
|
}
|
|
|
|
// Append 写入一条状态事件。from==to 或 event 无法识别时跳过。
|
|
func Append(tx *gorm.DB, entry Entry) error {
|
|
if tx == nil {
|
|
return nil
|
|
}
|
|
from := strings.TrimSpace(entry.FromStatus)
|
|
to := strings.TrimSpace(entry.ToStatus)
|
|
if to == "" {
|
|
to = strings.TrimSpace(entry.EventType)
|
|
}
|
|
if to == "" || from == to {
|
|
return nil
|
|
}
|
|
eventType := strings.TrimSpace(entry.EventType)
|
|
if eventType == "" {
|
|
eventType = normalizeEventType(to)
|
|
}
|
|
if eventType == "" {
|
|
return nil
|
|
}
|
|
createdAt := entry.CreatedAt
|
|
if createdAt.IsZero() {
|
|
createdAt = timeutil.ShanghaiNow()
|
|
}
|
|
row := model.ListingStatusEvent{
|
|
ListingID: entry.ListingID,
|
|
OwnerID: entry.OwnerID,
|
|
EventType: eventType,
|
|
FromStatus: from,
|
|
ToStatus: to,
|
|
Source: strings.TrimSpace(entry.Source),
|
|
ActorType: strings.TrimSpace(entry.ActorType),
|
|
ActorID: entry.ActorID,
|
|
Remark: strings.TrimSpace(entry.Remark),
|
|
CreatedAt: createdAt,
|
|
}
|
|
return tx.Create(&row).Error
|
|
}
|
|
|
|
// AppendTransition 根据 listing 变更前后状态写事件。
|
|
func AppendTransition(
|
|
tx *gorm.DB,
|
|
listing *model.RentalListing,
|
|
fromStatus string,
|
|
source string,
|
|
actorType string,
|
|
actorID uint64,
|
|
remark string,
|
|
) error {
|
|
if listing == nil {
|
|
return nil
|
|
}
|
|
return Append(tx, Entry{
|
|
ListingID: listing.ID,
|
|
OwnerID: listing.OwnerID,
|
|
EventType: normalizeEventType(listing.Status),
|
|
FromStatus: fromStatus,
|
|
ToStatus: listing.Status,
|
|
Source: source,
|
|
ActorType: actorType,
|
|
ActorID: actorID,
|
|
Remark: remark,
|
|
})
|
|
}
|
|
|
|
func normalizeEventType(status string) string {
|
|
switch strings.TrimSpace(status) {
|
|
case EventPublished, EventOffline, EventRented, EventCompleted, EventSealed, EventAbnormal:
|
|
return status
|
|
default:
|
|
return ""
|
|
}
|
|
}
|