支持平台代管客服一键交接
This commit is contained in:
@@ -139,7 +139,7 @@ type PlatformHandoffRequest struct {
|
||||
Reason string `json:"reason" binding:"required"`
|
||||
}
|
||||
|
||||
// ForceHandoffRequest 客服确认普通号主订单已完成线下交接。
|
||||
// ForceHandoffRequest 客服确认订单已完成交接。
|
||||
type ForceHandoffRequest struct {
|
||||
Content string `json:"content"`
|
||||
Reason string `json:"reason" binding:"required"`
|
||||
|
||||
@@ -13,7 +13,13 @@ import (
|
||||
)
|
||||
|
||||
func canAdminForceHandoff(order model.RentalOrder) bool {
|
||||
if isPlatformHandoffOrder(order) || isPlatformSettlementOrder(order) {
|
||||
if isPlatformHandoffOrder(order) {
|
||||
if order.Status == orderStatusPendingHandoff {
|
||||
return order.HandoffStatus == handoffStatusPendingRenterConfirm
|
||||
}
|
||||
return order.Status == orderStatusAbnormal && order.HandoffStatus == handoffStatusRenterConfirmTimeout
|
||||
}
|
||||
if isPlatformSettlementOrder(order) {
|
||||
return false
|
||||
}
|
||||
if order.Status == orderStatusPendingHandoff {
|
||||
@@ -24,11 +30,18 @@ func canAdminForceHandoff(order model.RentalOrder) bool {
|
||||
return order.Status == orderStatusAbnormal && order.HandoffStatus == handoffStatusRenterConfirmTimeout
|
||||
}
|
||||
|
||||
func forceHandoffRecordType(order model.RentalOrder) string {
|
||||
if isPlatformHandoffOrder(order) {
|
||||
return "platform_handoff"
|
||||
}
|
||||
return "owner_handoff"
|
||||
}
|
||||
|
||||
func forceHandoffNeedsContent(order model.RentalOrder) bool {
|
||||
return order.HandoffStatus == handoffStatusPendingOwner || order.HandoffStatus == handoffStatusOwnerTimeout
|
||||
}
|
||||
|
||||
// AdminForceHandoff 由客服确认普通号主订单已完成线下交接,并立即开始租期。
|
||||
// AdminForceHandoff 由客服确认订单已完成交接,并立即开始租期。
|
||||
func (r *Repository) AdminForceHandoff(ctx context.Context, adminID uint64, orderID uint64, req ForceHandoffRequest, meta AuditMeta) error {
|
||||
return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||
var order model.RentalOrder
|
||||
@@ -60,7 +73,7 @@ func (r *Repository) AdminForceHandoff(ctx context.Context, adminID uint64, orde
|
||||
if !needsContent {
|
||||
var handoffCount int64
|
||||
if err := tx.Model(&model.HandoffRecord{}).
|
||||
Where("order_id = ? AND type = ?", order.ID, "owner_handoff").
|
||||
Where("order_id = ? AND type = ?", order.ID, forceHandoffRecordType(order)).
|
||||
Count(&handoffCount).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1079,7 +1079,7 @@ func TestAdminForceHandoffStartsNormalOwnerOrder(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAdminForceHandoffUsesExistingOwnerRecordAndRejectsPlatformOrder(t *testing.T) {
|
||||
func TestAdminForceHandoffUsesExistingOwnerRecordAndRejectsPlatformOrderBeforeHandoff(t *testing.T) {
|
||||
db := setupOrderTestDB(t)
|
||||
if err := db.AutoMigrate(&model.Dispute{}); err != nil {
|
||||
t.Fatalf("migrate disputes failed: %v", err)
|
||||
@@ -1160,6 +1160,72 @@ func TestAdminForceHandoffUsesExistingOwnerRecordAndRejectsPlatformOrder(t *test
|
||||
}
|
||||
}
|
||||
|
||||
func TestAdminForceHandoffStartsPlatformManagedOrderAfterPlatformHandoff(t *testing.T) {
|
||||
db := setupOrderTestDB(t)
|
||||
if err := db.AutoMigrate(&model.Dispute{}); err != nil {
|
||||
t.Fatalf("migrate disputes failed: %v", err)
|
||||
}
|
||||
repo := NewRepository(db)
|
||||
|
||||
owner := model.User{Phone: "admin:force-handoff"}
|
||||
renter := model.User{Phone: "13900003008"}
|
||||
if err := db.Create(&owner).Error; err != nil {
|
||||
t.Fatalf("create owner failed: %v", err)
|
||||
}
|
||||
if err := db.Create(&renter).Error; err != nil {
|
||||
t.Fatalf("create renter failed: %v", err)
|
||||
}
|
||||
|
||||
order := model.RentalOrder{
|
||||
OrderNo: "ORD-FORCE-HANDOFF-PLATFORM-001",
|
||||
ListingID: 4,
|
||||
AccountID: 4,
|
||||
OwnerID: owner.ID,
|
||||
RenterID: renter.ID,
|
||||
Status: orderStatusPendingHandoff,
|
||||
HandoffStatus: handoffStatusPendingRenterConfirm,
|
||||
HandoffMode: handoffModePlatform,
|
||||
SettlementMode: settlementModePlatformManaged,
|
||||
AccountSnapshot: datatypes.JSON([]byte(`{
|
||||
"haf_coin_amount": 100000000,
|
||||
"daily_loss_m": 50
|
||||
}`)),
|
||||
}
|
||||
if err := db.Create(&order).Error; err != nil {
|
||||
t.Fatalf("create order failed: %v", err)
|
||||
}
|
||||
if err := db.Create(&model.HandoffRecord{
|
||||
OrderID: order.ID,
|
||||
FromUserID: 99,
|
||||
ToUserID: renter.ID,
|
||||
Type: "platform_handoff",
|
||||
Content: "客服已提交账号和登录说明",
|
||||
}).Error; err != nil {
|
||||
t.Fatalf("create platform handoff record failed: %v", err)
|
||||
}
|
||||
|
||||
if err := repo.AdminForceHandoff(t.Context(), 99, order.ID, ForceHandoffRequest{
|
||||
Reason: "租客未确认,客服已核实账号可正常使用",
|
||||
}, AuditMeta{}); err != nil {
|
||||
t.Fatalf("AdminForceHandoff() error = %v", err)
|
||||
}
|
||||
|
||||
var saved model.RentalOrder
|
||||
if err := db.First(&saved, order.ID).Error; err != nil {
|
||||
t.Fatalf("load order failed: %v", err)
|
||||
}
|
||||
if saved.Status != orderStatusRenting || saved.HandoffStatus != handoffStatusReceived {
|
||||
t.Fatalf("status = %s/%s, want renting/received", saved.Status, saved.HandoffStatus)
|
||||
}
|
||||
var record model.HandoffRecord
|
||||
if err := db.Where("order_id = ? AND type = ?", order.ID, "admin_force_handoff").First(&record).Error; err != nil {
|
||||
t.Fatalf("find force handoff record failed: %v", err)
|
||||
}
|
||||
if record.Content != "客服已确认双方完成交接,订单已进入使用中。" {
|
||||
t.Fatalf("record content = %q", record.Content)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSubmitCheckoutRefreshesStageTime(t *testing.T) {
|
||||
db := setupOrderTestDB(t)
|
||||
repo := NewRepository(db)
|
||||
|
||||
Reference in New Issue
Block a user