完善订单交接结账流程留痕

This commit is contained in:
yml2213
2026-08-28 23:48:32 +08:00
parent a9a9127076
commit c87883cc65
27 changed files with 915 additions and 5 deletions
@@ -105,6 +105,13 @@ func (r *Repository) Create(ctx context.Context, req CreateRequest, adminID uint
if err := tx.Create(&pickup).Error; err != nil {
return err
}
if err := appendPickupEvent(tx, pickup, "pickup_created", adminID, "管理员创建线下提号。", pickup.Remark, map[string]any{
"listing_price_cent": pickup.ListingPriceCent, "profit_amount_cent": pickup.ProfitAmountCent,
"account_source": pickup.AccountSource, "source_channel": pickup.SourceChannel,
"settlement_mode": pickup.SettlementMode,
}, map[string]any{}); err != nil {
return err
}
createdID = pickup.ID
// 锁定商品:status=rented,从「已上架」列表移除,进入「已锁定」
@@ -188,6 +195,7 @@ func (r *Repository) Complete(ctx context.Context, pickupID uint64, req Complete
if pickup.Status != StatusPickingUp {
return ErrPickupNotPickingUp
}
before := pickupState(pickup)
var listing model.RentalListing
if err := tx.Clauses(clause.Locking{Strength: "UPDATE"}).First(&listing, pickup.ListingID).Error; err != nil {
@@ -273,6 +281,12 @@ func (r *Repository) Complete(ctx context.Context, pickupID uint64, req Complete
return err
}
}
if err := appendPickupEvent(tx, pickup, "pickup_completed", adminID, "管理员完成提号。", pickup.CompleteRemark, map[string]any{
"settle_amount_cent": pickup.SettleAmountCent, "profit_amount_cent": pickup.ProfitAmountCent,
"settlement_mode": pickup.SettlementMode, "offline_settlement_status": pickup.OfflineSettlementStatus,
}, before); err != nil {
return err
}
if err := auditlog.Append(tx, auditlog.Entry{
ActorType: "admin",
@@ -316,6 +330,7 @@ func (r *Repository) MarkOfflineSettlement(ctx context.Context, pickupID uint64,
pickup.OfflineSettlementStatus != OfflineSettlementStatusPending || pickup.SettleAmountCent <= 0 {
return ErrOfflineSettlementCannotMark
}
before := pickupState(pickup)
pendingTotals, err := pendingPickupFinancialAdjustmentTotals(tx, pickup.ID)
if err != nil {
return err
@@ -345,6 +360,11 @@ func (r *Repository) MarkOfflineSettlement(ctx context.Context, pickupID uint64,
return err
}
}
if err := appendPickupEvent(tx, pickup, "pickup_offline_settlement_confirmed", adminID, "确认已完成提号线下结算。", pickup.OfflineSettlementRemark, map[string]any{
"settle_amount_cent": effectiveSettleAmountCent, "settled_adjustment_count": pendingTotals.Count,
}, before); err != nil {
return err
}
bid := pickup.ID
return auditlog.Append(tx, auditlog.Entry{
@@ -386,12 +406,18 @@ func (r *Repository) UpdateProfit(ctx context.Context, pickupID uint64, req Upda
if pickup.Status != StatusPickingUp {
return ErrPickupNotPickingUp
}
before := pickupState(pickup)
oldProfitAmountCent := pickup.ProfitAmountCent
pickup.ProfitAmountCent = req.ProfitAmountCent
if err := tx.Model(&pickup).Update("profit_amount_cent", pickup.ProfitAmountCent).Error; err != nil {
return err
}
if err := appendPickupEvent(tx, pickup, "pickup_profit_updated", adminID, "修改提号利润。", strings.TrimSpace(req.Reason), map[string]any{
"old_profit_amount_cent": oldProfitAmountCent, "profit_amount_cent": pickup.ProfitAmountCent,
}, before); err != nil {
return err
}
bid := pickup.ID
return auditlog.Append(tx, auditlog.Entry{
@@ -431,6 +457,7 @@ func (r *Repository) CreateFinancialAdjustment(ctx context.Context, pickupID uin
if pickup.Status != StatusCompleted {
return ErrFinancialAdjustmentInvalid
}
before := pickupState(pickup)
totals, err := pickupFinancialAdjustmentTotals(tx, pickup.ID)
if err != nil {
@@ -471,6 +498,13 @@ func (r *Repository) CreateFinancialAdjustment(ctx context.Context, pickupID uin
if err := tx.Create(&adjustment).Error; err != nil {
return err
}
if err := appendPickupEvent(tx, pickup, "pickup_financial_adjusted", adminID, "创建提号财务调整。", adjustment.Reason, map[string]any{
"adjustment_id": adjustment.ID, "profit_delta_cent": adjustment.ProfitDeltaCent,
"settle_delta_cent": adjustment.SettleDeltaCent, "settlement_mode": adjustment.SettlementMode,
"adjustment_status": adjustment.Status,
}, before); err != nil {
return err
}
// 站内钱包的补款在创建调整时立即到账;扣款统一转待追回,避免余额被扣成负数。
if pickup.SettlementMode == SettlementModeOwnerWallet && settleDeltaCent > 0 {
@@ -559,6 +593,17 @@ func (r *Repository) SettleFinancialAdjustment(ctx context.Context, adjustmentID
if err := tx.Save(&adjustment).Error; err != nil {
return err
}
var pickup model.AdminPickup
if err := tx.First(&pickup, adjustment.PickupID).Error; err != nil {
return err
}
if err := appendPickupEvent(tx, pickup, "pickup_adjustment_settled", adminID, "确认提号财务调整已处理。", adjustment.SettlementRemark, map[string]any{
"adjustment_id": adjustment.ID, "profit_delta_cent": adjustment.ProfitDeltaCent,
"settle_delta_cent": adjustment.SettleDeltaCent, "before_status": beforeStatus,
"adjustment_status": adjustment.Status,
}, pickupState(pickup)); err != nil {
return err
}
bid := adjustment.ID
return auditlog.Append(tx, auditlog.Entry{
ActorType: "admin",
@@ -595,6 +640,7 @@ func (r *Repository) Cancel(ctx context.Context, pickupID uint64, reason string,
if pickup.Status != StatusPickingUp {
return ErrPickupNotPickingUp
}
before := pickupState(pickup)
var listing model.RentalListing
if err := tx.Clauses(clause.Locking{Strength: "UPDATE"}).First(&listing, pickup.ListingID).Error; err != nil {
return err
@@ -609,6 +655,9 @@ func (r *Repository) Cancel(ctx context.Context, pickupID uint64, reason string,
if err := tx.Save(&pickup).Error; err != nil {
return err
}
if err := appendPickupEvent(tx, pickup, "pickup_cancelled", adminID, "管理员取消提号。", reason, nil, before); err != nil {
return err
}
// 取消提号:恢复上架,重新出现在商品管理「已上架」
fromStatus := listing.Status
listing.InTransaction = false