class ArticleVote(Model): """ 文章点赞, 只有点赞状态 """ __table_args__ = (PrimaryKeyConstraint('article_id', 'user_id'), ) user_id = db.Column(db.Integer, index=True, comment='点赞此文章的用户id') article_id = db.Column(db.Integer, index=True, comment='文章id')
class CommentVote(Model): """ 评论点赞, 只有点赞状态 """ __table_args__ = (PrimaryKeyConstraint('comment_id', 'user_id'), ) user_id = db.Column(db.Integer, index=True, comment='点赞此文章的用户id') comment_id = db.Column(db.Integer, index=True, comment='评论id')
class AnswerVote(Model): """ 回答投票 包括赞同/反对 """ __table_args__ = (PrimaryKeyConstraint('answer_id', 'user_id'), ) user_id = db.Column(db.Integer, index=True, comment='赞同/反对此回答的用户id') answer_id = db.Column(db.Integer, index=True, comment='回答id') agree = db.Column(db.Boolean, index=True, comment='赞同/反对')
class Follow(Model): """ 关注 """ __table_args__ = (PrimaryKeyConstraint('follower_id', 'followed_id'),) follower_id = db.Column(db.Integer, comment='关注用户id') followed_id = db.Column(db.Integer, comment='被关注用户id') follow_time = db.Column(db.DateTime, default=dt.datetime.now(), comment='关注时间')
class Topic(Model): """ 主题/专题 """ id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, index=True, comment='文章作者id') topic_name = db.Column(db.String(54), comment='专题名') topic_desc = db.Column(db.String(128), comment='专题描述') create_time = db.Column(db.DateTime, default=dt.datetime.now(), comment='创建时间')
class Comment(Model): """ 回答评论 """ id = db.Column(db.BigInteger, primary_key=True) user_id = db.Column(db.Integer, comment='评论用户id') parent_id = db.Column(db.Integer, comment='父评论id') content = db.Column(db.String(1024), nullable=False, comment='评论内容') create_time = db.Column(db.DateTime, default=dt.datetime.now(), comment='评论时间')
class Question(Model): """ 问题 """ id = db.Column(db.BigInteger, primary_key=True) user_id = db.Column(db.Integer, index=True, comment='提问用户id') title = db.Column(db.String(255), unique=True, comment='标题') status = db.Column(Enum(QuestionStatus), default='o', comment='问题状态') content = db.Column(db.String(1024), nullable=True, comment='内容/详细描述') create_time = db.Column(db.DateTime, default=dt.datetime.now(), comment='创建时间') update_time = db.Column(db.DateTime, onupdate=dt.datetime.now(), comment='更新时间')
class Article(Model): """ 文章 """ id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, index=True, comment='文章作者id') title = db.Column(db.String(128), comment='文章标题') content = db.Column(db.String(2048), comment='文章内容') create_time = db.Column(db.DateTime, default=dt.datetime.now(), comment='创建时间') topic_id = db.Column(db.Integer, index=True, comment='主题/专题id')
class Answer(Model): """ 回答 """ id = db.Column(db.BigInteger, primary_key=True) user_id = db.Column(db.Integer, index=True, comment='回答用户id') question_id = db.Column(db.BigInteger, index=True, comment='问题id') content = db.Column(db.String(2048), nullable=False, comment='回答内容') create_time = db.Column(db.DateTime, default=dt.datetime.now(), comment='创建时间/回答时间') update_time = db.Column(db.DateTime, onupdate=dt.datetime.now(), comment='更新回答时间')
class User(Model): """ 用户模块 """ _hide_columns = {'password'} id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(128), unique=True, nullable=False, comment='用户名') email = db.Column(db.String(128), unique=True, nullable=False, comment='邮箱') password = db.Column(db.String(128), nullable=False, comment='是否激活') confirmed = db.Column(db.Boolean, nullable=False, default=False, comment='是否激活') confirm_time = db.Column(db.DateTime, comment='验证/激活时间') create_time = db.Column(db.DateTime, default=dt.datetime.now(), comment='创建时间') update_time = db.Column(db.DateTime, onupdate=dt.datetime.now(), comment='更新时间') def create(self, commit=True): self.set_password(self.password) super(User, self).create() def set_password(self, password): self.password = generate_password_hash(password) def check_password(self, password): """验证密码与保存的hash值是否匹配""" return check_password_hash(self.password, password) def generate_confirm_jwt(self): """生成确认账户的Jwt""" now = dt.datetime.utcnow() payload = dict( user_id=self.id, exp=now + dt.timedelta(seconds=60 * 60), iat=now, aud='quiz', ) token = jwt.encode(payload, current_app.config['SECRET_KEY'], 'HS256').decode( 'utf-8' ) return token def verify_confirm_jwt(self, token): """验证确认账户的JWT""" try: payload = jwt.decode( token, current_app.config['SECRET_KEY'], algorithms=['HS256'], audience='quiz', ) except jwt.PyJWTError: return False if payload.get('user_id') != self.id: return False self.confirmed = True self.confirm_time = dt.datetime.now() self.update() return True def get_jwt(self): """用户登录后, 发放有效的JWT作为JWT过期时间内的登录验证""" now = dt.datetime.utcnow() payload = dict( user_id=self.id, confirmed=self.confirmed, username=self.username, exp=now + dt.timedelta(seconds=3 * 60 * 60), iat=now, aud='quiz', ) token = jwt.encode(payload, current_app.config['SECRET_KEY'], 'HS256').decode( 'utf-8' ) return token @staticmethod def verify_jwt(token): """验证token的有效性""" try: payload = jwt.decode( token, current_app.config['SECRET_KEY'], algorithms=['HS256'], audience='quiz', ) except jwt.PyJWTError: return None return User.query.get(payload.get('user_id'))