Exemplo n.º 1
0
    def post(self, match_id):
        """"
        TODO: 如果回调时赛事已满员则自动退款处理

        Parteam Api request example: {
          "message": "成功",
          "code": 200,
          "attribute": {
              "userId": 169,
              "orderNo": "11354642167546",
              "paymentMethod":1, // 支付类型 1微信,2支付宝
              "orderState":2 // // 订单状态 1 待付款 2 已付款 3 超时未付款 4 已发货
          }
        }
        """
        data = self.request.body.decode()
        data = json.loads(data)

        if not data.get("attribute"):
            raise ApiException(400, "未包含 attribute")

        order = data['attribute']
        member = MatchMember.get_or_404(pt_order_no=order['orderNo'])

        if order['orderState'] in (2, 4):

            # 将状态为未支付报名状态修改为正常
            if member.state == MatchMember.MatchMemberState.wait_pay:

                payment_method = (TeamOrder.OrderPaymentMethod.WXPAY,
                                  TeamOrder.OrderPaymentMethod.ALIPAY
                                  )[order['paymentMethod'] - 1]

                with self.db.transaction():
                    MatchMember.update(
                        state=MatchMember.MatchMemberState.normal).where(
                            MatchMember.id == member.id).execute()

                    TeamOrder.update(
                        paid=datetime.now(),
                        state=TeamOrder.OrderState.TRADE_BUYER_PAID,
                        gateway_trade_no=order['orderNo'],
                        payment_method=payment_method).where(
                            TeamOrder.id == member.order_id).execute()

                # 统计赛事人数
                Match.update_members_count(member.match_id)
                if member.group_id > 0:
                    MatchGroup.update_members_count(member.group_id)

            match_notify.join_match_done\
                .apply_async(args=[match_id, member.id], retry=True)

        self.write_success()
Exemplo n.º 2
0
    def _ban(self, member_id):
        """
        ban 成员,并保存原有状态
        """

        member = MatchMember.get_or_404(id=member_id)

        if member.state == MatchMember.MatchMemberState.banned:
            self.write_success()
        else:
            MatchMember.update(state=MatchMember.MatchMemberState.banned,
                               state_before_ban=member.state).where(
                                   MatchMember.id == member_id).execute()

            Match.update_members_count(member.match_id)
            self.write_success()
Exemplo n.º 3
0
    def _unban(self, member_id):
        """
        unban 成员,并恢复到 ban 时原状态
        """

        member = MatchMember.get_or_404(id=member_id)
        match = Match.get_or_404(id=member.match_id)

        if member.state != MatchMember.MatchMemberState.banned:
            self.write_success()
        else:
            # 判断是不是人数已满等 以确定是否可以恢复
            res = match.can_join()
            if res["can"]:
                MatchMember.update(state=member.state_before_ban).where(
                    MatchMember.id == member_id).execute()
                Match.update_members_count(member.match_id)

                self.write_success()
            else:
                self.set_status(403)
                self.write({"reason": res["reason"]})
Exemplo n.º 4
0
    def post(self, match_id):
        """ 报名赛事

        :match_id: 赛事ID
        :returns:

        """

        match = Match.get_or_404(id=match_id)

        # 检查赛事是否可以报名
        result = match.can_join()
        self.has_joined(match, user_id=self.current_user.id)

        if not result['can']:
            raise ApiException(403,
                               result['reason'],
                               log_message="报名失败:{0}, {1}".format(
                                   match_id, result['reason']))

        team = Team.get_or_404(id=match.team_id)

        # 分组比赛模式
        group = None
        if match.group_type == 1:
            group_id = self.get_argument("group_id")
            group = MatchGroup.get_or_none(id=group_id, match_id=match_id)
            if group is None:
                raise ApiException(404, "赛事分组不存在")

            # 分组是否已报满
            if group.max_members <= group.members_count:
                raise ApiException(403, "赛事分组已报满")

            total_fee = group.price

        else:
            total_fee = match.price

        name = self.get_argument("name")
        mobile = self.get_argument("mobile")

        if not name:
            raise ApiException(400, "请填写名称")

        if not mobile:
            raise ApiException(400, "请填写手机号码")

        elif not is_mobile(mobile):
            raise ApiException(400, "手机号码格式有误")

        # TODO: 上线前移除
        # member = MatchMember.get_or_none(match_id=match.id,
        #                                  user_id=self.current_user.id)
        # if member is not None:
        #     raise ApiException(403, "你已报名此赛事,无需重复报名")

        extra_attrs = self.parse_options(match_id)

        with self.db.transaction() as txn:

            # 零元赛事无需支付不生成订单
            order = None
            if total_fee > 0:
                order = TeamOrder.create(
                    order_no=TeamOrder.get_new_order_no(),
                    team=team,
                    user=team.owner_id,
                    title=match.title,
                    order_type=TeamOrder.OrderType.MATCH,
                    payment_fee=total_fee,
                    total_fee=total_fee,
                    activity_id=match.id,
                    state=TeamOrder.OrderState.WAIT_BUYER_PAY)

            other_attrs = {}
            if "avatar" in match.fields:
                other_attrs['avatar_key'] = self.upload_photo("avatar", "头像")

            if "idcard_photo" in match.fields:
                other_attrs['idcard_front'] = self.upload_photo(
                    "idcard_front", "证件照片正面")
                other_attrs['idcard_back'] = self.upload_photo(
                    "idcard_back", "证件照片背面")

            gender = self.get_argument("gender", "")
            if gender in ("0", "1"):
                gender = ("f", "m")[int(gender)]
            else:
                gender = "n"

            if order and order.state == TeamOrder.OrderState.WAIT_BUYER_PAY:
                member_state = MatchMember.MatchMemberState.wait_pay
            else:
                member_state = MatchMember.MatchMemberState.normal

            team.add_member(self.current_user.id,
                            nick=name,
                            state=TeamMember.TeamMemberState.normal)
            member = MatchMember.create(
                match_id=match.id,
                group_id=group.id if group else 0,
                member_type=match.join_type,
                user_id=self.current_user.id,
                name=name,
                mobile=mobile,
                gender=gender,
                age=self.get_argument("age", "0"),
                is_leader=self.get_argument("is_leader", False),
                realname=self.get_argument("realname", ""),
                idcard_number=self.get_argument("idcard_number", ""),
                extra_attrs=extra_attrs,
                order_id=order.id if order else 0,
                total_fee=total_fee,
                state=member_state,
                **other_attrs)

            # 如果需要付费则生成支付订单
            if total_fee > 0:

                if match.refund_expire:
                    refund_expire = match.refund_expire.strftime(
                        "%Y%m%d%H%M%S")
                else:
                    refund_expire = datetime.now().strftime("%Y%m%d%H%M%S")

                resp = self.parteam_request(
                    "/match/openapi/createOrderInfo.do",
                    post_args={
                        "orderValue":
                        match.id,
                        "eachFee":
                        int(total_fee * 100),
                        "num":
                        1,
                        "totalFee":
                        int(total_fee * 100),
                        "subject":
                        match.title,
                        "userId":
                        self.current_user.id,
                        "notifyUrl":
                        urljoin(
                            self.request.full_url(),
                            self.reverse_url('rest_match_join_notify',
                                             match.id)),
                        "version":
                        1,
                        "expDatetime":
                        refund_expire,
                        "tradeType":
                        "APP" if self.device_type.lower() in ("ios", "android")
                        else "WEB",
                    })

                if "orderNo" not in resp:
                    txn.rollback()
                    raise ApiException(
                        400,
                        "创建订单失败",
                        log_message="match order fail:{0}".format(resp))

                MatchMember.update(pt_order_no=resp['orderNo']).where(
                    MatchMember.id == member.id).execute()

            # 统计赛事人数
            Match.update_members_count(match.id)
            if group:
                MatchGroup.update_members_count(group.id)

            member = MatchMember.get_or_404(id=member.id)

        member_info = member.info
        member_info['order'] = {
            "orderNo": member.pt_order_no,
            "orderValue": match.id,
            "eachFee": int(total_fee * 100),
            "num": 1,
            "totalFee": int(total_fee * 100),
            "subject": match.title,
            "userId": self.current_user.id,
        }

        self.write(member_info)