package user import ( "bindbox-game/internal/repository/mysql/dao" "context" "fmt" ) // CancelShipping 取消发货申请 func (s *service) CancelShipping(ctx context.Context, userID int64, inventoryID int64) error { // 1. 开启事务 return s.writeDB.Transaction(func(tx *dao.Query) error { // 2. 查询发货记录(必须是待发货状态 status=1) sr, err := tx.ShippingRecords.WithContext(ctx). Where(tx.ShippingRecords.InventoryID.Eq(inventoryID)). Where(tx.ShippingRecords.UserID.Eq(userID)). Where(tx.ShippingRecords.Status.Eq(1)). First() if err != nil { return fmt.Errorf("shipping record not found or already processed") } // 3. 更新发货记录状态为已取消 (status=5) if _, err := tx.ShippingRecords.WithContext(ctx). Where(tx.ShippingRecords.ID.Eq(sr.ID)). Update(tx.ShippingRecords.Status, 5); err != nil { return err } // 4. 恢复库存状态为可用 (status=1) // 并追加备注 // 使用原生SQL以确保CONCAT行为一致 remark := fmt.Sprintf("|shipping_cancelled_by_user:%d", userID) if err := tx.UserInventory.WithContext(ctx).UnderlyingDB().Exec( "UPDATE user_inventory SET status=1, remark=CONCAT(IFNULL(remark,''), ?) WHERE id=? AND user_id=?", remark, inventoryID, userID, ).Error; err != nil { return err } return nil }) }