def can_leave(self, match: Match, user_id: int) -> bool: """ 赛事是否可以退出 :param match: :param user_id: :return: """ # 先判断是否加入过赛事 self.has_joined_match(match, user_id) # 当前赛事状态是不是允许退出 if match.can_leave(): return True raise ApiException(422, "不满足赛事退塞条件, 无法退出")
def leave(cls, user_id, match: Match, notify_url: str = None, insists=False, role: int = 1): """ 退出赛事 :param user_id: :param match: :param notify_url: 派队回调地址 :param insists: 强制退出 :param role: 退赛发起人, 1 用户, 2 赛事方 :return: """ logging.debug("notify_url: {0}, insists: {1}".format( notify_url, insists)) if not insists and notify_url is None: raise AssertionError("非强制退出 `insists=False` 操作需要提供退款回调" "地址 `notify_url`") if insists is False and not match.can_leave(): raise MatchException("赛事无法退出") # 退出赛事 member = MatchMember.get(user_id=user_id, match_id=match.id) # type: MatchMember with Match._meta.database.transaction(): if insists: match.leave(member) # Warning: 数据库事物中尝试远程 HTTP 调用, 需要修复 else: # match.leave_request(member) # 调用退款接口 pt = Parteam(app.settings["parteam_api_url"]) if member.order_id: # 有支付信息, 调用退款接口 order = TeamOrder.get( id=member.order_id) # type: TeamOrder refund_fee = int(order.payment_fee * 100) try: pt.order_refund(user_id=user_id, order_no=member.pt_order_no, refund_fee=refund_fee, notify_url=notify_url, role=role) except NotPaidError as e: logging.warning("调用派队退款接口发现订单未支付: {0}".format(str(e))) TeamOrder.update(state=TeamOrder.OrderState .TRADE_CLOSED_BY_USER.value) \ .where(TeamOrder.id == member.order_id) \ .execute() match.leave(member) except RefundError as e: raise MatchException(e) else: # 更新订单状态为 `退款`, 订单退款状态为 `全部退款` TeamOrder.update( state=TeamOrder.OrderState.TRADE_CLOSED.value, refund_state=TeamOrder.OrderRefundState.FULL_REFUNDED.value, refunded_time=datetime.now())\ .where(TeamOrder.id == member.order_id)\ .execute() match.leave(member) else: # 无支付信息直接退赛 match.leave(member)