只写入隐藏时间,订单和款项仍保留给租客与后台。详情按钮固定对齐,删除跟在后面。 Co-authored-by: Cursor <cursoragent@cursor.com>
113 lines
3.0 KiB
Go
113 lines
3.0 KiB
Go
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
|
|
})
|
|
}
|