def get(self, match_id): keyword = self.get_argument("kw", "") match = Match.get_or_404(id=match_id) query = MatchMember.query_all_members(match_id) group_query = MatchGroup.select() \ .where(MatchGroup.match_id == match_id) self.logger.debug(group_query.sql()) groups = [] for group in group_query: groups.append({"name": group.name}) group_name = self.get_argument("group_name", "") if group_name: query = query.where(MatchGroup.name == group_name) if keyword: if is_mobile(keyword): query = query.where(MatchMember.mobile == keyword) else: query = query.where(MatchMember.name.contains(keyword)) members = self.paginate_query(query) sum_fee = MatchMember.select( fn.SUM(MatchMember.total_fee).alias("sum")).where( MatchMember.match_id == match_id).scalar() self.render("match/match_members_list.html", sum_fee=sum_fee, match=match, groups=groups, members=members, pagination=members.pagination)
def post(self): username = self.validated_arguments['username'] verify_code = self.validated_arguments['verify_code'] new_password = self.validated_arguments['new_password'] if is_mobile(username): if not self.verify_mobile(username, verify_code): raise ApiException(400, "验证码错误,请重新输入") user = User.get_or_none(mobile=username) if not user: raise ApiException(400, "手机号还没有注册") User.update(password=User.create_password(new_password)).where( User.id == user.id).execute() elif username.find("@") > 0: user = User.get_or_none(email=username) if not user: raise ApiException(400, "邮箱还没有注册") User.update(password=User.create_password(new_password)).where( User.id == user.id).execute() else: raise ApiException(400, "用户名格式有误,请填写手机号或电子邮箱") self.write_success()
def have_user(cls, name: str) -> User: """ 检查用户是否存在,如果存在返回用户实例,否则返回None Args: name: email or mobile """ if is_mobile(name): data = {"mobile": name} elif is_email(name): data = {"email": name} else: return None return User.get_or_none(**data)
def post(self): username = self.validated_arguments['username'].lower() password = self.validated_arguments['password'] if len(username) == 0 or len(password) == 0: raise ApiException(400, "用户名和密码不能为空") fail_times_key = "yiyun:user:%s:login_fail_times" % username if intval(self.redis.get(fail_times_key)) >= 5: raise ApiException(403, "密码错误次数太多,请休息10分钟再试") if is_mobile(username): user = User.get_or_none(mobile=username) elif username.find('@') > 0: user = User.get_or_none(email=username) else: raise ApiException(400, "用户名格式不正确,请填写手机号或电子邮箱") if not password or not user \ or not User.check_password(user.password, password): fail_times = intval(self.redis.incr(fail_times_key)) if fail_times == 1: self.redis.expire(fail_times_key, 600) raise ApiException(403, "密码有误,如果没有设置密码请使用手机号找回密码") # 重试次数归零 self.redis.delete(fail_times_key) if not user.is_active(): raise ApiException(403, "你的账户不可用,无法登录") update = {"last_login": datetime.now()} if self.device_id > 0: update["last_device_id"] = self.device_id User.update(**update).where(User.id == user.id).execute() if user and self.device_id: Device.update(owner_id=user.id).where( Device.id == self.device_id).execute() self.write(self.create_session(user))
def phone_validator(value): if is_mobile(value): return value raise Invalid("手机号码格式错误")
def validate_username(self, field): username = field.data if not is_mobile(username) and not is_email(username): raise ValidationError("用户名必须是邮箱或手机号")
def validate_mobile(self, field): if not is_mobile(field.data): raise ValidationError('手机号码格式不正确')
def validate_mobile(self, field): if not is_mobile(field.data): raise ValidationError('手机号码格式不正确') if User.select().where(User.mobile == field.data).exists(): raise ValidationError('手机号码已存在')
def post(self): mobile = self.get_argument("mobile") action = self.get_argument("action") if not is_mobile(mobile): raise ArgumentError(400, "手机号码格式不正确") sent_times_key = "yiyun:mobile:%s:code_sent_times" % mobile if intval(self.redis.get(sent_times_key)) >= 5: raise ArgumentError(400, "你已重发5次,请稍后再试") # 有效期内发送相同的验证码 verify_code = random.randint(1000, 9999) is_registered = User.select().where(User.mobile == mobile).exists() self.logger.debug("send: %s to %s" % (verify_code, mobile)) if action == "register" and is_registered: raise ArgumentError(1020, "手机号码已注册", status_code=400) if action in ('register_or_login', 'register', 'login'): # 保存验证码 self.save_verify_code(mobile, verify_code) # 发短信 tasks.message.send_sms_verifycode(mobile, verify_code) self.write_success(is_registered=is_registered) elif action == "forgot": if not is_registered: raise ArgumentError(400, "手机号码没有注册") # 保存验证码 self.save_verify_code(mobile, verify_code) # 发短信 tasks.message.send_sms_verifycode(mobile, verify_code) self.write_success() elif action == "update_mobile": if not self.current_user: raise ArgumentError(403, "登录后才能修改手机号") if is_registered: raise ArgumentError(403, "该号码已经使用,请更换") # 保存验证码 self.save_verify_code(mobile, verify_code) # 发短信 tasks.message.send_sms_verifycode(mobile, verify_code) # 关联验证码与当前用户 self.redis.set( "ihealth:update_mobile:%s:verify_code:%s" % (mobile, verify_code), self.current_user.id) # 30分钟内有效 self.redis.expire( "ihealth:update_mobile:%s:verify_code:%s" % (mobile, verify_code), 1800) self.write_success() # 30分钟内最多发送5次验证码 sent_times = int(self.redis.incr(sent_times_key)) if sent_times == 1: self.redis.expire(sent_times_key, 1800)
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)