From 109b0ce01281a54d056d54b188448ce4f8bf709e Mon Sep 17 00:00:00 2001 From: Rogee Date: Thu, 8 Jan 2026 11:15:42 +0800 Subject: [PATCH] feat: add super order detail snapshot --- backend/app/http/super/v1/dto/super.go | 24 ++++++++++++++++++++---- backend/app/services/super.go | 22 ++++++++++++++++++++++ 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/backend/app/http/super/v1/dto/super.go b/backend/app/http/super/v1/dto/super.go index b6b3e38..0eeb025 100644 --- a/backend/app/http/super/v1/dto/super.go +++ b/backend/app/http/super/v1/dto/super.go @@ -166,10 +166,14 @@ type SuperOrderItem struct { AmountPaid int64 `json:"amount_paid"` Tenant *OrderTenantLite `json:"tenant"` Buyer *OrderBuyerLite `json:"buyer"` - PaidAt string `json:"paid_at"` - RefundedAt string `json:"refunded_at"` - CreatedAt string `json:"created_at"` - UpdatedAt string `json:"updated_at"` + // Snapshot 订单快照,包含下单时的关键参数与定价信息,便于审计回溯。 + Snapshot any `json:"snapshot"` + // Items 订单明细行,用于展示具体内容与金额拆分。 + Items []SuperOrderItemLine `json:"items"` + PaidAt string `json:"paid_at"` + RefundedAt string `json:"refunded_at"` + CreatedAt string `json:"created_at"` + UpdatedAt string `json:"updated_at"` } type OrderTenantLite struct { @@ -183,6 +187,18 @@ type OrderBuyerLite struct { Username string `json:"username"` } +// SuperOrderItemLine 表示订单明细行。 +type SuperOrderItemLine struct { + // ID 订单明细ID。 + ID int64 `json:"id"` + // ContentID 购买的内容ID。 + ContentID int64 `json:"content_id"` + // AmountPaid 该明细实付金额(分)。 + AmountPaid int64 `json:"amount_paid"` + // Snapshot 明细快照,用于展示内容标题等历史信息。 + Snapshot any `json:"snapshot"` +} + type OrderStatisticsResponse struct { TotalCount int64 `json:"total_count"` TotalAmountPaidSum int64 `json:"total_amount_paid_sum"` diff --git a/backend/app/services/super.go b/backend/app/services/super.go index dad4528..99bb2e2 100644 --- a/backend/app/services/super.go +++ b/backend/app/services/super.go @@ -356,7 +356,20 @@ func (s *super) GetOrder(ctx context.Context, id int64) (*super_dto.SuperOrderDe buyer = u } + itemTbl, itemQ := models.OrderItemQuery.QueryContext(ctx) + orderItems, err := itemQ.Where(itemTbl.OrderID.Eq(o.ID)).Find() + if err != nil { + return nil, errorx.ErrDatabaseError.WithCause(err) + } + + items := make([]super_dto.SuperOrderItemLine, 0, len(orderItems)) + for _, it := range orderItems { + items = append(items, s.toSuperOrderItemLine(it)) + } + item := s.toSuperOrderItem(o, tenant, buyer) + item.Snapshot = o.Snapshot.Data() + item.Items = items return &super_dto.SuperOrderDetail{ Order: &item, Tenant: item.Tenant, @@ -590,6 +603,15 @@ func (s *super) toSuperOrderItem(o *models.Order, tenant *models.Tenant, buyer * return item } +func (s *super) toSuperOrderItemLine(item *models.OrderItem) super_dto.SuperOrderItemLine { + return super_dto.SuperOrderItemLine{ + ID: item.ID, + ContentID: item.ContentID, + AmountPaid: item.AmountPaid, + Snapshot: item.Snapshot.Data(), + } +} + func (s *super) contentPriceMap(ctx context.Context, list []*models.Content) (map[int64]*models.ContentPrice, error) { if len(list) == 0 { return map[int64]*models.ContentPrice{}, nil