mobile . themes
This commit is contained in:
67
models.py
67
models.py
@@ -1,6 +1,11 @@
|
||||
# models.py
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timezone, timedelta
|
||||
|
||||
_beijing_tz = timezone(timedelta(hours=8))
|
||||
|
||||
def beijing_now():
|
||||
return datetime.now(_beijing_tz).replace(tzinfo=None)
|
||||
import json
|
||||
|
||||
db = SQLAlchemy()
|
||||
@@ -17,7 +22,7 @@ class User(db.Model):
|
||||
is_banned = db.Column(db.Boolean, default=False)
|
||||
completed_exams = db.Column(db.Integer, default=0) # 已完成并批改的考试次数
|
||||
name_changed_at = db.Column(db.DateTime, nullable=True) # 上次修改用户名时间
|
||||
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
created_at = db.Column(db.DateTime, default=beijing_now)
|
||||
|
||||
# 关系
|
||||
exams_created = db.relationship('Exam', back_populates='creator', lazy=True)
|
||||
@@ -39,7 +44,7 @@ class ContestMembership(db.Model):
|
||||
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
|
||||
contest_id = db.Column(db.Integer, db.ForeignKey('contest.id'), nullable=False)
|
||||
role = db.Column(db.String(20), nullable=False) # 'owner' 或 'teacher'
|
||||
joined_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
joined_at = db.Column(db.DateTime, default=beijing_now)
|
||||
|
||||
user = db.relationship('User', back_populates='contest_memberships')
|
||||
contest = db.relationship('Contest', back_populates='members')
|
||||
@@ -55,7 +60,7 @@ class ContestApplication(db.Model):
|
||||
description = db.Column(db.Text)
|
||||
contact = db.Column(db.String(100))
|
||||
status = db.Column(db.String(20), default='pending') # pending, approved, rejected
|
||||
applied_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
applied_at = db.Column(db.DateTime, default=beijing_now)
|
||||
reviewed_at = db.Column(db.DateTime)
|
||||
total_score = db.Column(db.Integer, default=150) # 杯赛默认满分
|
||||
start_date = db.Column(db.String(20)) # 申请时填写的开始日期
|
||||
@@ -78,7 +83,7 @@ class ContestRegistration(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
|
||||
contest_id = db.Column(db.Integer, db.ForeignKey('contest.id'), nullable=False)
|
||||
registered_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
registered_at = db.Column(db.DateTime, default=beijing_now)
|
||||
|
||||
__table_args__ = (db.UniqueConstraint('user_id', 'contest_id', name='uq_user_contest_reg'),)
|
||||
|
||||
@@ -93,7 +98,7 @@ class Contest(db.Model):
|
||||
status = db.Column(db.String(20), default='upcoming')
|
||||
participants = db.Column(db.Integer, default=0)
|
||||
created_by = db.Column(db.Integer, db.ForeignKey('user.id'))
|
||||
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
created_at = db.Column(db.DateTime, default=beijing_now)
|
||||
past_papers = db.Column(db.Text) # JSON 存储历年真题 [{year, title, file}]
|
||||
total_score = db.Column(db.Integer, default=150) # 杯赛默认考试满分
|
||||
visible = db.Column(db.Boolean, default=True) # 是否对普通用户可见
|
||||
@@ -125,7 +130,7 @@ class QuestionBankItem(db.Model):
|
||||
options = db.Column(db.Text) # JSON,选择题选项
|
||||
answer = db.Column(db.Text) # 答案
|
||||
score = db.Column(db.Integer, default=10) # 建议分值
|
||||
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
created_at = db.Column(db.DateTime, default=beijing_now)
|
||||
|
||||
contest = db.relationship('Contest', backref='question_bank_items')
|
||||
contributor = db.relationship('User', backref='contributed_questions')
|
||||
@@ -146,7 +151,7 @@ class Exam(db.Model):
|
||||
scheduled_start = db.Column(db.DateTime, nullable=True) # 预定开始时间
|
||||
scheduled_end = db.Column(db.DateTime, nullable=True) # 预定结束时间
|
||||
score_release_time = db.Column(db.DateTime, nullable=True) # 成绩公布时间
|
||||
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
created_at = db.Column(db.DateTime, default=beijing_now)
|
||||
status = db.Column(db.String(20), default='available')
|
||||
visibility = db.Column(db.String(20), default='private') # 'private' 或 'public'
|
||||
|
||||
@@ -170,7 +175,7 @@ class Submission(db.Model):
|
||||
question_scores = db.Column(db.Text) # JSON
|
||||
graded = db.Column(db.Boolean, default=False)
|
||||
graded_by = db.Column(db.String(80))
|
||||
submitted_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
submitted_at = db.Column(db.DateTime, default=beijing_now)
|
||||
|
||||
exam = db.relationship('Exam', back_populates='submissions')
|
||||
user = db.relationship('User', back_populates='submissions')
|
||||
@@ -193,7 +198,7 @@ class Draft(db.Model):
|
||||
exam_id = db.Column(db.Integer, db.ForeignKey('exam.id'))
|
||||
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
|
||||
answers = db.Column(db.Text) # JSON
|
||||
saved_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||
saved_at = db.Column(db.DateTime, default=beijing_now, onupdate=beijing_now)
|
||||
|
||||
exam = db.relationship('Exam', back_populates='drafts')
|
||||
user = db.relationship('User', back_populates='drafts')
|
||||
@@ -219,8 +224,8 @@ class Post(db.Model):
|
||||
has_poll = db.Column(db.Boolean, default=False)
|
||||
images = db.Column(db.Text) # JSON
|
||||
contest_id = db.Column(db.Integer, db.ForeignKey('contest.id'), nullable=True)
|
||||
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||
created_at = db.Column(db.DateTime, default=beijing_now)
|
||||
updated_at = db.Column(db.DateTime, default=beijing_now, onupdate=beijing_now)
|
||||
|
||||
author = db.relationship('User', back_populates='posts')
|
||||
replies = db.relationship('Reply', back_populates='post', lazy=True, cascade='all, delete-orphan')
|
||||
@@ -243,8 +248,8 @@ class Reply(db.Model):
|
||||
content = db.Column(db.Text, nullable=False)
|
||||
likes = db.Column(db.Integer, default=0)
|
||||
reply_to = db.Column(db.String(80))
|
||||
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||
created_at = db.Column(db.DateTime, default=beijing_now)
|
||||
updated_at = db.Column(db.DateTime, default=beijing_now, onupdate=beijing_now)
|
||||
|
||||
post = db.relationship('Post', back_populates='replies')
|
||||
author = db.relationship('User', back_populates='replies')
|
||||
@@ -259,7 +264,7 @@ class Poll(db.Model):
|
||||
voters = db.Column(db.Text) # JSON
|
||||
multi = db.Column(db.Boolean, default=False)
|
||||
total_votes = db.Column(db.Integer, default=0)
|
||||
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
created_at = db.Column(db.DateTime, default=beijing_now)
|
||||
|
||||
post = db.relationship('Post', back_populates='poll')
|
||||
|
||||
@@ -282,7 +287,7 @@ class Reaction(db.Model):
|
||||
post_id = db.Column(db.Integer, db.ForeignKey('post.id'), nullable=True)
|
||||
reply_id = db.Column(db.Integer, db.ForeignKey('reply.id'), nullable=True)
|
||||
reaction = db.Column(db.String(20))
|
||||
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
created_at = db.Column(db.DateTime, default=beijing_now)
|
||||
|
||||
user = db.relationship('User', back_populates='reactions')
|
||||
post = db.relationship('Post', back_populates='reactions')
|
||||
@@ -298,7 +303,7 @@ class Bookmark(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
|
||||
post_id = db.Column(db.Integer, db.ForeignKey('post.id'))
|
||||
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
created_at = db.Column(db.DateTime, default=beijing_now)
|
||||
|
||||
user = db.relationship('User', back_populates='bookmarks')
|
||||
post = db.relationship('Post', back_populates='bookmarks')
|
||||
@@ -314,7 +319,7 @@ class Report(db.Model):
|
||||
reason = db.Column(db.String(100))
|
||||
detail = db.Column(db.Text)
|
||||
status = db.Column(db.String(20), default='pending')
|
||||
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
created_at = db.Column(db.DateTime, default=beijing_now)
|
||||
|
||||
# reporter 已在 User 中通过 backref 定义
|
||||
|
||||
@@ -327,7 +332,7 @@ class Notification(db.Model):
|
||||
from_user = db.Column(db.String(80))
|
||||
post_id = db.Column(db.Integer, nullable=True)
|
||||
read = db.Column(db.Boolean, default=False)
|
||||
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
created_at = db.Column(db.DateTime, default=beijing_now)
|
||||
|
||||
# user 已在 User 中通过 backref 定义
|
||||
|
||||
@@ -338,8 +343,8 @@ class SystemNotification(db.Model):
|
||||
content = db.Column(db.Text, nullable=False)
|
||||
author_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
|
||||
pinned = db.Column(db.Boolean, default=False)
|
||||
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||
created_at = db.Column(db.DateTime, default=beijing_now)
|
||||
updated_at = db.Column(db.DateTime, default=beijing_now, onupdate=beijing_now)
|
||||
|
||||
author = db.relationship('User', backref='system_notifications')
|
||||
|
||||
@@ -350,7 +355,7 @@ class EditHistory(db.Model):
|
||||
title = db.Column(db.String(200))
|
||||
content = db.Column(db.Text)
|
||||
edited_by = db.Column(db.String(80))
|
||||
edited_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
edited_at = db.Column(db.DateTime, default=beijing_now)
|
||||
|
||||
post = db.relationship('Post')
|
||||
|
||||
@@ -364,7 +369,7 @@ class TeacherApplication(db.Model):
|
||||
email = db.Column(db.String(120), nullable=False) # 申请人邮箱
|
||||
reason = db.Column(db.Text, nullable=False) # 申请理由
|
||||
status = db.Column(db.String(20), default='pending') # pending, approved, rejected
|
||||
applied_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
applied_at = db.Column(db.DateTime, default=beijing_now)
|
||||
reviewed_at = db.Column(db.DateTime)
|
||||
reviewed_by = db.Column(db.Integer, db.ForeignKey('user.id'))
|
||||
# 拒绝次数控制
|
||||
@@ -384,7 +389,7 @@ class Friend(db.Model):
|
||||
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
|
||||
friend_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
|
||||
status = db.Column(db.String(20), default='pending') # pending, accepted
|
||||
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
created_at = db.Column(db.DateTime, default=beijing_now)
|
||||
|
||||
user = db.relationship('User', foreign_keys=[user_id], backref=db.backref('friends_initiated', lazy='dynamic'))
|
||||
friend = db.relationship('User', foreign_keys=[friend_id], backref=db.backref('friends_received', lazy='dynamic'))
|
||||
@@ -394,7 +399,7 @@ class ExamBookmark(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
|
||||
exam_id = db.Column(db.Integer, db.ForeignKey('exam.id'), nullable=False)
|
||||
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
created_at = db.Column(db.DateTime, default=beijing_now)
|
||||
|
||||
user = db.relationship('User', backref=db.backref('exam_bookmarks', lazy='dynamic', cascade='all, delete-orphan'))
|
||||
exam = db.relationship('Exam', backref=db.backref('bookmarked_by', lazy='dynamic', cascade='all, delete-orphan'))
|
||||
@@ -412,7 +417,7 @@ class ChatRoom(db.Model):
|
||||
announcement = db.Column(db.Text, default='')
|
||||
announcement_by = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=True)
|
||||
announcement_at = db.Column(db.DateTime, nullable=True)
|
||||
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
created_at = db.Column(db.DateTime, default=beijing_now)
|
||||
|
||||
creator = db.relationship('User', foreign_keys=[creator_id], backref='chatrooms_created')
|
||||
announcement_user = db.relationship('User', foreign_keys=[announcement_by])
|
||||
@@ -428,8 +433,8 @@ class ChatRoomMember(db.Model):
|
||||
role = db.Column(db.String(20), default='member') # 'admin' | 'member'
|
||||
nickname = db.Column(db.String(50), default='')
|
||||
muted = db.Column(db.Boolean, default=False)
|
||||
last_read_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
joined_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
last_read_at = db.Column(db.DateTime, default=beijing_now)
|
||||
joined_at = db.Column(db.DateTime, default=beijing_now)
|
||||
|
||||
user = db.relationship('User', backref='chat_memberships')
|
||||
|
||||
@@ -447,7 +452,7 @@ class Message(db.Model):
|
||||
recalled = db.Column(db.Boolean, default=False)
|
||||
reply_to_id = db.Column(db.Integer, db.ForeignKey('message.id'), nullable=True)
|
||||
mentions = db.Column(db.Text, default='') # JSON array of user IDs, e.g. "[1,2,3]" or "all"
|
||||
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
created_at = db.Column(db.DateTime, default=beijing_now)
|
||||
|
||||
sender = db.relationship('User', backref='messages_sent')
|
||||
reply_to = db.relationship('Message', remote_side='Message.id', backref='replies')
|
||||
@@ -459,7 +464,7 @@ class MessageReaction(db.Model):
|
||||
message_id = db.Column(db.Integer, db.ForeignKey('message.id'), nullable=False)
|
||||
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
|
||||
emoji = db.Column(db.String(10), nullable=False)
|
||||
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
created_at = db.Column(db.DateTime, default=beijing_now)
|
||||
|
||||
user = db.relationship('User', backref='message_reactions')
|
||||
|
||||
@@ -472,7 +477,7 @@ class InviteCode(db.Model):
|
||||
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
|
||||
application_id = db.Column(db.Integer, db.ForeignKey('teacher_application.id'), nullable=False)
|
||||
used = db.Column(db.Boolean, default=False)
|
||||
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
created_at = db.Column(db.DateTime, default=beijing_now)
|
||||
used_at = db.Column(db.DateTime, nullable=True)
|
||||
|
||||
user = db.relationship('User', backref='invite_codes')
|
||||
|
||||
Reference in New Issue
Block a user