package order import ( "context" "time" "hfb_sys/backend/internal/model" "gorm.io/gorm" "gorm.io/gorm/clause" ) // ownerMayHideOrder 判断号主能否把订单从自己的列表里隐藏。 // 进行中的订单、未结清的款项、暂扣押金、处理中争议和未释放的分销结算都不能藏。 func ownerMayHideOrder(order model.RentalOrder, hasOpenDispute bool, distributionSettlement string) bool { if order.OwnerHiddenAt != nil { return false } switch order.Status { case orderStatusCompleted, orderStatusClosed: if order.SettlementStatus != settlementStatusSettled && order.SettlementStatus != settlementStatusClosed && order.SettlementStatus != settlementStatusArbitrated { return false } if order.OfflineSettlementStatus == offlineSettlementStatusPending { return false } case orderStatusCancelled: default: return false } switch order.RefundStatus { case "", "none", refundStatusRefunded: default: return false } if order.DepositHoldStatus == model.DepositHoldStatusHeld { return false } if hasOpenDispute { return false } if distributionSettlement != "" && distributionSettlement != "settled" { return false } return true } type ownerHideSignal struct { disputed map[uint64]struct{} dist map[uint64]string } func loadOwnerHideSignals(db *gorm.DB, orderIDs []uint64) (ownerHideSignal, error) { signal := ownerHideSignal{ disputed: map[uint64]struct{}{}, dist: map[uint64]string{}, } if len(orderIDs) == 0 { return signal, nil } var disputeIDs []uint64 if err := db.Model(&model.Dispute{}). Where("order_id IN ? AND status IN ?", orderIDs, []string{"open", "processing"}). Distinct(). Pluck("order_id", &disputeIDs).Error; err != nil { return signal, err } for _, id := range disputeIDs { signal.disputed[id] = struct{}{} } var rows []struct { OrderID uint64 `gorm:"column:order_id"` SettlementStatus string `gorm:"column:settlement_status"` } if err := db.Model(&model.DistributionOrderFinancial{}). Select("order_id, settlement_status"). Where("order_id IN ?", orderIDs). Scan(&rows).Error; err != nil { return signal, err } for _, row := range rows { signal.dist[row.OrderID] = row.SettlementStatus } return signal, nil } func (r *Repository) HideForOwner(ctx context.Context, userID uint64, orderID uint64) error { return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error { var order model.RentalOrder if err := tx.Clauses(clause.Locking{Strength: "UPDATE"}).First(&order, orderID).Error; err != nil { return err } if order.OwnerID != userID { return ErrPermissionDenied } if order.OwnerHiddenAt != nil { return nil } signals, err := loadOwnerHideSignals(tx, []uint64{order.ID}) if err != nil { return err } _, disputed := signals.disputed[order.ID] if !ownerMayHideOrder(order, disputed, signals.dist[order.ID]) { return ErrOrderCannotHide } now := time.Now() return tx.Model(&model.RentalOrder{}).Where("id = ?", order.ID).Update("owner_hidden_at", now).Error }) }