Beispiel #1
0
 def login(cls, phone: str, password: str) -> dict:
     """
     登录
     :param phone:
     :param password:
     :return:
     """
     mes = {"message": "success"}
     cli = mongo_db.get_client()
     col = mongo_db.get_conn(table_name=cls.get_table_name(), db_client=cli)
     with cli.start_session(causal_consistency=True) as session:
         with session.start_transaction():
             f = {"phone": phone}
             r = col.find_one(filter=f, session=session)
             if r is None:
                 mes['message'] = "手机号码未注册"
             else:
                 pw2 = r['password']
                 if password != pw2:
                     mes['message'] = '密码错误'
                 else:
                     _id = r['_id']
                     mes['_id'] = _id
                     now = datetime.datetime.now()
                     f = dict()
                     f['_id'] = _id
                     u = {"$set": {"last_login": now}}
                     # 更新最后的登录时间
                     col.find_one_and_update(filter=f,
                                             update=u,
                                             session=session)
     return mes
Beispiel #2
0
 def add(cls, **kwargs) -> dict:
     """
     添加角色
     :param kwargs:
     :return:
     """
     mes = {"message": "success"}
     role_name = kwargs.get("role_name", '')
     db = orm_module.get_client()
     conn = orm_module.get_conn(table_name=cls.get_table_name(),
                                db_client=db)
     write_concern = WriteConcern(w=1, j=True)
     with db.start_session(causal_consistency=True) as ses:
         with ses.start_transaction(write_concern=write_concern):
             r = conn.find_one(filter={'role_name': role_name})
             if r is not None:
                 ms = "角色 {} 已存在!".format(role_name)
                 mes['message'] = ms
             else:
                 """添加"""
                 r = conn.insert_one(kwargs)
                 if r is None:
                     ms = "保存用户账户失败"
                     mes['message'] = ms
                 else:
                     pass
     return mes
Beispiel #3
0
 def register(cls, phone: str, password: str) -> dict:
     """
     注册
     :param phone:
     :param password:
     :return:
     """
     mes = {"message": "success"}
     cli = mongo_db.get_client()
     col = mongo_db.get_conn(table_name=cls.get_table_name(), db_client=cli)
     with cli.start_session(causal_consistency=True) as session:
         with session.start_transaction():
             f = {"phone": phone}
             r = col.find_one(filter=f, session=session)
             if isinstance(r, dict):
                 mes['message'] = "手机号码重复"
             else:
                 f['password'] = password
                 nick_name = "用户{}".format(phone[-4:])
                 f['nick_name'] = nick_name
                 now = datetime.datetime.now()
                 f['create_date'] = now
                 r = col.insert_one(document=f, session=session)
                 if r is None:
                     mes['message'] = "插入失败"
                 else:
                     pass
     return mes
Beispiel #4
0
 def add_user(cls, **kwargs) -> dict:
     """
     添加用户
     :param kwargs:
     :return:
     """
     mes = {"message": "success"}
     user_name = kwargs.get("user_name", '')
     pwd = kwargs.get("password", '')
     args = {"user_name": user_name, "password": pwd}
     db = orm_module.get_client()
     conn = orm_module.get_conn(table_name=cls.get_table_name(),
                                db_client=db)
     write_concern = WriteConcern(w=1, j=True)
     with db.start_session(causal_consistency=True) as ses:
         with ses.start_transaction(write_concern=write_concern):
             r = conn.find_one(filter={'user_name': user_name})
             if r is not None:
                 ms = "账户 {} 已存在!".format(user_name)
                 mes['message'] = ms
             else:
                 """提取其他信息"""
                 role_id_str = kwargs.get("role_id", '')
                 if isinstance(role_id_str, str) and len(role_id_str) == 24:
                     role_id = ObjectId(role_id_str)
                 elif isinstance(role_id_str, ObjectId):
                     role_id = role_id_str
                 else:
                     role_id = None
                 args['role_id'] = role_id
                 args['dept_id'] = None
                 now = datetime.datetime.now()  # 创建时间
                 args['time'] = now
                 args['last'] = now
                 args['status'] = 1
                 nick_name = kwargs.get("nick_name", "")
                 if isinstance(nick_name, str) and len(nick_name) > 0:
                     args['nick_name'] = nick_name
                 else:
                     nick_name = "guest_{}".format(
                         str(random.randint(1, 99)).zfill(2))
                     args['nick_name'] = nick_name
                 r = conn.insert_one(args)
                 if r is None:
                     ms = "保存用户账户失败"
                     mes['message'] = ms
                 else:
                     pass
     return mes
Beispiel #5
0
 def un_follow(cls, user_id: (str, ObjectId)) -> dict:
     """
     取消跟踪老师
     :param user_id:
     :return:
     """
     mes = {"message": "取消跟踪失败"}
     user = cls.find_by_id(o_id=user_id, to_dict=True)
     if isinstance(user, dict):
         user_id = user['_id']
         f = {"_id": user_id}
         u = {"$set": {"follow": []}}
         db = mongo_db.get_client()
         con1 = mongo_db.get_conn(table_name=cls.get_table_name(),
                                  db_client=db)
         con2 = mongo_db.get_conn(table_name=FollowRecord.get_table_name(),
                                  db_client=db)
         w = WriteConcern(w=1, j=True)
         with db.start_session(causal_consistency=True) as ses:
             with ses.start_transaction():
                 r = con1.find_one_and_update(
                     filter=f,
                     upsert=False,
                     update=u,
                     return_document=ReturnDocument.AFTER,
                     session=ses)
                 if r is None or len(r['follow']) > 0:
                     mes['message'] = "保存数据失败"
                 else:
                     f2 = {"user_id": user_id, "end": {"$exists": False}}
                     u2 = {"$set": {"end": datetime.datetime.now()}}
                     r2 = con2.find_one_and_update(
                         filter=f2,
                         upsert=True,
                         update=u2,
                         return_document=ReturnDocument.AFTER,
                         session=ses)
                     if r2 is None or not isinstance(
                             r2.get("end"), datetime.datetime):
                         mes['message'] = "保存record失败"
                     else:
                         mes['message'] = "success"
     else:
         ms = "错误的用户id: {}".format(user_id)
         logger.exception(msg=ms)
         print(ms)
         mes['message'] = "用户id错误"
     return mes
Beispiel #6
0
 def change_pw(cls, u_id: ObjectId, pwd_old: str, pw_n1: str,
               pw_n2: str) -> dict:
     """
     修改密码
     :param u_id:
     :param pwd_old:
     :param pw_n1:
     :param pw_n2:
     :return:
     """
     mes = {"message": 'unknow error!'}
     db_client = orm_module.get_client()
     w = orm_module.get_write_concern()
     col = orm_module.get_conn(table_name=cls.get_table_name(),
                               db_client=db_client,
                               write_concern=w)
     with db_client.start_session(causal_consistency=True) as ses:
         with ses.start_transaction(write_concern=w):
             f = {"_id": u_id}
             p = ["_id", "password"]
             r = col.find_one(filter=f, projection=p)
             if r is None:
                 mes['message'] = "错误的用户id:{}".format(u_id)
             else:
                 if r.get("password", "").lower() == pwd_old.lower():
                     if pw_n1 == pw_n2:
                         pw = pw_n1.lower()
                         u = {"$set": {"password": pw}}
                         r = col.find_one_and_update(
                             filter=f,
                             update=u,
                             return_document=orm_module.ReturnDocument.AFTER
                         )
                         if r['password'] == pw:
                             mes['message'] = "success"
                         else:
                             mes['message'] = "保存失败"
                 else:
                     mes['message'] = "原始密码错误"
     return mes
Beispiel #7
0
 def follow(cls, user_id: (str, ObjectId), t_id: (str, ObjectId)) -> dict:
     """
     用户跟单行为。
     1. 如果用户积分不足,那就不能跟单
     2. 如果用户已经跟随了一位老师,那就换人。同时扣分
     :param user_id:
     :param t_id: 老师id
     :return:
     """
     """计算是否需要扣除跟单积分"""
     user = cls.find_by_id(o_id=user_id, to_dict=True)
     if isinstance(user, dict):
         user_id = user['_id']
         score = user.get("score", None)
         if score is None:
             score = Score.re_calculate(u_dict=user)
         f_id = ObjectId(t_id) if isinstance(
             t_id, str) and len(t_id) == 24 else t_id
         now = datetime.datetime.now()
         res = {"message": "关注失败"}
         """
         跟单扣分制度:
         参考上一周的老师胜率排行榜
         第一 -500, 第二 -300, 第三-200, 第四第五-100, >6 -50
         """
         num_dict = {0: -500, 1: -300, 2: -200, 3: -100, 4: -100}
         ses = mongo_db.get_conn(table_name="teacher")
         f = dict()
         s = [("win_ratio", -1)]
         p = ['_id', "win_ratio"]
         rank = ses.find(filter=f, sort=s, projection=p)
         rank = {
             x['_id']: {
                 "index": i + 1,
                 "num": num_dict.get(i, -50)
             }
             for i, x in enumerate(rank)
         }
         x = rank[f_id]
         num = x['num']
         i = x['index']
         if score >= abs(num):
             score += num
             temp = {
                 "type": "follow",
                 "num": num,
                 "user_id": user_id,
                 "desc": "跟随老师 {}, 排名: {}".format(t_id, i),
                 "time": now
             }
             """事务,开始添加扣分记录和更新用户积分"""
             client = mongo_db.get_client()
             t1 = client[mongo_db.db_name][Score.get_table_name()]
             t2 = client[mongo_db.db_name][WXUser.get_table_name()]
             t3 = client[mongo_db.db_name][FollowRecord.get_table_name()]
             with client.start_session(causal_consistency=True) as ses:
                 with ses.start_transaction():
                     t1.insert_one(document=temp, session=ses)
                     f = {"_id": user_id}
                     u = {"$set": {"score": score, "follow": [f_id]}}
                     t2.find_one_and_update(filter=f,
                                            update=u,
                                            upsert=False,
                                            session=ses)
                     """
                     检查用户以前是否有跟踪老师?
                     检查的方式是:检查用户的follow记录。如果有,更新再新建。没有,新建。
                     """
                     follow = user.get("follow", dict())
                     if len(follow) == 0:
                         """没有跟随过老师"""
                         pass
                     else:
                         """有跟随过老师,需要先终结以前的跟随关系。"""
                         f2 = {"user_id": user_id, "t_id": f_id}
                         u2 = {"$set": {"end": now}}
                         t3.find_one_and_update(filter=f2,
                                                update=u2,
                                                upsert=False,
                                                session=ses)
                     """添加一条跟随老师的记录"""
                     temp = {
                         "_id": ObjectId(),
                         "user_id": user_id,
                         "t_id": f_id,
                         "begin": now
                     }
                     t3.insert_one(document=temp, session=ses)
                     res['message'] = "success"
         else:
             res['message'] = "积分不足"
         return res
     else:
         ms = "错误的user_id: {}".format(user_id)
         logger.exception(msg=ms)
         raise ValueError(ms)
Beispiel #8
0
 def every_week_mon_check(cls) -> list:
     """
     每个星期一,对本周还在关注老师的用户进行扣分.(先扣分),生产环境下,这是给celery的定时任务使用的
     :return: 操作情况的数组  [{"_id": user_id, "num":-500, "follow": True },...]
     """
     res = list()
     f = {"follow.0": {"$exists": True}}  # 有关注老师的用户
     p = ['_id', "follow", 'score']
     us = WXUser.find(filter_dict=f, projection=p)
     now = datetime.datetime.now()
     rank = TeacherRank.get_rank(cur_time=now)
     """扣分:上周排行第一 -500, 第二 -300, 第三-200, 第四第五-100, >6 -50"""
     num_dict = {0: -500, 1: -300, 2: -200, 3: -100, 4: -100}
     rank_dict = dict()
     for i, x in enumerate(rank):
         rank_dict[x['_id']] = {"index": i, "num": num_dict[i]}
     for x in us:
         u_id = x['_id']
         f_id = x.get("follow", list())
         f_id = None if len(f_id) == 0 else f_id[0]
         score = x.get("score")
         if score is None:
             score = cls.re_calculate(u_dict=x)
         if f_id in rank:
             """关注的老师在上周的排行榜内"""
             s = rank_dict[f_id]
             num = s['num']
             if score >= abs(num):
                 """积分够本周扣分"""
                 score += num
                 temp = {
                     "type": "follow",
                     "num": num,
                     "user_id": u_id,
                     "desc": "跟随老师 {}, 排名: {}".format(f_id, s['index'] + 1),
                     "time": now
                 }
                 """事务,添加一条扣分记录,并修改用户积分"""
                 client = mongo_db.get_client()
                 t1 = client[mongo_db.db_name][cls.get_table_name()]
                 t2 = client[mongo_db.db_name][WXUser.get_table_name()]
                 with client.start_session(causal_consistency=True) as ses:
                     with ses.start_transaction():
                         t1.insert_one(document=temp, session=ses)
                         f = {"_id": u_id}
                         u = {"$set": {"score": score}}
                         r = t2.find_one_and_update(filter=f,
                                                    update=u,
                                                    upsert=False,
                                                    session=ses)
                         if r is None:
                             ms = "用户:{} 关注扣分失败".format(u_id)
                             print(ms)
                             logger.exception(msg=ms)
                             res.append({"_id": u_id, "error": ms})
                         else:
                             res.append({
                                 "_id": u_id,
                                 "num": num,
                                 "follow": True
                             })
             else:
                 """积分不够扣分的,直接解除关注就行了"""
                 f = {"_id": u_id}
                 u = {"$set": {"follow": []}}
                 r = WXUser.find_one_and_update(filter_dict=f,
                                                update_dict=u,
                                                upsert=False)
                 if r is None:
                     ms = "用户:{} 解除关注失败".format(u_id)
                     print(ms)
                     logger.exception(msg=ms)
                     res.append({"_id": u_id, "error": ms})
                 else:
                     res.append({"_id": u_id, "num": 0, "follow": False})
     return res
Beispiel #9
0
 def re_calculate(cls,
                  u_id: (str, ObjectId) = None,
                  u_dict: dict = None) -> int:
     """
     重新计算用户积分并写入记录。会逐一检查用户的积分记录,重新初始化用户积分的时候使用
     1. 补齐缺少的积分增减记录
     2. 计算相关的的记录的积分
     3. 返回最后的分值,
     :param u_id:
     :param u_dict:
     :return:
     """
     user_dict = u_dict if isinstance(u_dict, dict) and "_id" in u_dict else \
         WXUser.find_by_id(o_id=u_id, to_dict=True)
     if isinstance(user_dict, dict) and "_id" in user_dict:
         user_id = user_dict['_id']
         """重新计算历史积分"""
         f = {"user_id": user_id}
         s = {"time": -1}
         rs = cls.find(filter_dict=f, sort_dict=s)
         score = 0
         inserts = list()
         init = False  # 初始化过?
         bind_phone = False  # 绑定手机过?
         for x in rs:
             score += x.get("num", 0)
             if x['type'] == "init":
                 init = True
             elif x['type'] == 'bind_phone':
                 bind_phone = True
             else:
                 score += x['num']
         now = datetime.datetime.now()
         if not init:
             temp = {
                 "type": "init",
                 "num": 50,
                 "user_id": user_id,
                 "desc": "用户初始化",
                 "time": now
             }
             inserts.append(temp)
         if not bind_phone:
             # score += 1000
             temp = {
                 "type": "bind_phone",
                 "num": 100,
                 "user_id": user_id,
                 "desc": "绑定手机",
                 "time": now
             }
             inserts.append(temp)
         else:
             pass
         """事务,开始添加扣分记录和更新用户积分"""
         client = mongo_db.get_client()
         t1 = client[mongo_db.db_name][cls.get_table_name()]
         t2 = client[mongo_db.db_name][WXUser.get_table_name()]
         with client.start_session(causal_consistency=True) as ses:
             with ses.start_transaction():
                 t1.insert_many(documents=inserts, session=ses)
                 f = {"_id": user_id}
                 u = {"$set": {"score": score}}
                 t2.find_one_and_update(filter=f,
                                        update=u,
                                        upsert=False,
                                        session=ses)
         return score
     else:
         ms = "无效的用户! u_id:{}, u_dict: {}".format(u_id, user_dict)
         logger.exception(msg=ms)
         raise ValueError(ms)