Files
hfb_sys/backend/internal/modules/order/owner_hide.go
T
yml2213andCursor e5cd7b5c34 feat(orders): 号主可从自己的列表隐藏已结束订单
只写入隐藏时间,订单和款项仍保留给租客与后台。详情按钮固定对齐,删除跟在后面。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-01 16:22:55 +08:00

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
})
}