class Project(Base): """项目类""" __tablename__ = "project" name = db.Column(db.String(30), unique=True, comment="项目名") product = db.relationship("Product", backref="project", lazy="dynamic", cascade="save-update,delete") def __init__(self, name): self.name = name @classmethod def get(cls, id, parseName, obj=True): pro = super(Project, cls).get(id, parseName) if obj: return pro else: info = {"name": pro.name, "product": cls.product_records} return info @property def product_records(self): return self.product.filter_by().all() def __repr__(self): return f"project: {self.name}"
class User(db.Model, UserMixin): __tablename__ = 'user' id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(20), unique=True, nullable=False) email = db.Column(db.String(120), unique=True, nullable=False) image_file = db.Column(db.String(20), nullable=False, default='default.jpg') password = db.Column(db.String(60), nullable=False) logs = db.relationship('Log', backref='author', lazy=True) def get_reset_token(self, expires_sec=1800): s = Serializer(current_app.config['SECRET_KEY'], expires_sec) return s.dumps({'user_id': self.id}).decode('utf-8') @staticmethod def verify_reset_token(token): s = Serializer(current_app.config["SECRET_KEY"]) try: user_id = s.loads(token)['user_id'] except: return None return User.query.get(user_id) def __repr__(self): return f"User('{self.username}','{self.email}', '{self.image_file}')"
class Build(Base): """所用版本类""" __tablename__ = "build" name = db.Column(db.String(30), unique=False, comment="版本编号") product = db.Column(db.Integer, db.ForeignKey("product.id"), nullable=False, comment='所属产品') bugs = db.relationship("Bugs", backref="build_bugs", lazy='dynamic') builder = db.Column(db.String(20), comment="构建者") desc = db.Column(db.String(50), comment="描述") def __init__(self, name, productId, builder, desc=None): self.name = name self.product = productId self.builder = builder self.desc = desc @classmethod def get(cls, id, name, obj=True): build = super(Build, cls).get(id, name) if obj: return build else: info = { "name": build.name, "builder": build.builder, "desc": build.desc, "ctime": build.create_time } return info def __repr__(self): return f"build: {self.name}"
class Admin(db.Model): __tablename__ = "admin" id = db.Column(db.Integer, primary_key=True) # 编号 name = db.Column(db.String(100), unique=True) password = db.Column(db.String(100)) is_super = db.Column(db.SmallInteger) role_id = db.Column(db.Integer, db.ForeignKey('role.id')) addTime = db.Column(db.DateTime, index=True, default=datetime.now) adminlogs = db.relationship("Adminlog", backref='admin') adminsoplog = db.relationship("Oplog", backref='admin') def __repr__(self): return "<Admin %r>" % self.name def check_pwd(self, pwd): from werkzeug.security import check_password_hash return check_password_hash(self.password, pwd)
class User(db.Model): __tablename__ = "user" id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(100), unique=True) password = db.Column(db.String(100)) phone = db.Column(db.String(11), unique=True) addTime = db.Column(db.DateTime, index=True, default=datetime.now()) userlogs = db.relationship('Userlog', backref='user') # 关联 外键关系关联 def __repr__(self): return "<user %r>" % self.name
class Post(db.Model): id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String(80), nullable=False) body = db.Column(db.Text, nullable=False) pub_date = db.Column(db.DateTime, nullable=False, default=datetime.utcnow) category_id = db.Column(db.Integer, db.ForeignKey('category.id'), nullable=False) category = db.relationship('Category', backref=db.backref('posts', lazy=True)) def __repr__(self): return '<Post %r>' % self.title
class Module(Base): """bug模块类""" __tablename__ = "module" name = db.Column(db.String(30), unique=False, comment="模块名") product = db.Column(db.Integer, db.ForeignKey("product.id"), nullable=True, comment='所属产品') bugs = db.relationship("Bugs", backref="model_bugs", lazy='dynamic') def __init__(self, name, productId): self.name = name self.product = productId def __repr__(self): return f"module: {self.name}"
class ErrorType(Base): """错误类型类""" __tablename__ = "error_type" name = db.Column(db.String(30), unique=False, comment="错误类型") product = db.Column(db.Integer, db.ForeignKey("product.id"), nullable=False, comment='所属产品') bugs = db.relationship("Bugs", backref="error_type_bugs", lazy='dynamic') def __init__(self, name, productId): self.name = name self.product = productId def __repr__(self): return f"error_type: {self.name}"
class Platform(Base): """所用平台类""" __tablename__ = "platform" name = db.Column(db.String(30), unique=False, comment="平台名称") product = db.Column(db.Integer, db.ForeignKey("product.id"), nullable=False, comment='所属产品') bugs = db.relationship("Bugs", backref="platform_bugs", lazy='dynamic') def __init__(self, name, productId): self.name = name self.product = productId def __repr__(self): return f"platform: {self.name}"
class Solution(Base): """解决方案类""" __tablename__ = "solution" name = db.Column(db.String(30), unique=False, comment="解决方案名") product = db.Column(db.Integer, db.ForeignKey("product.id"), nullable=False, comment='所属产品') bugs = db.relationship("Bugs", backref="solution_bugs", lazy='dynamic') def __init__(self, name, productId): self.name = name self.product = productId def __repr__(self): return f"resolved: {self.name}"
class Department(Base): """部门类""" __tablename__ = "department" name = db.Column(db.String(20), unique=True, comment="部门名") users = db.relationship("User", backref="user_part", lazy="dynamic") def __init__(self, name): self.name = name def __repr__(self): return f"departmentName: {self.name}" @classmethod def get(cls, id, parseName, obj=True): depart = super(Department, cls).get(id, parseName) if obj: return depart else: info = { "name": depart.name, } return info
class User(Base): """ 用户类 """ __tablename__ = "user" account = db.Column(db.String(20), comment="用户名") name = db.Column(db.String(20), unique=True, comment="真实姓名") password = db.Column(db.String(50), comment="密码") gender = db.Column(db.Boolean, default=True, comment="性别") admin = db.Column(db.Boolean, default=False, comment="管理员") department = db.Column(db.Integer, db.ForeignKey("department.id"), nullable=True) avatar = db.Column(db.String(100), nullable=True, comment="头像") email = db.Column(db.String(50), nullable=True, comment="邮箱") phone = db.Column(db.String(12), nullable=True, comment="手机") myNote = db.relationship("Note", backref="userNote", lazy='dynamic') # 我的备注 def __init__(self, account, name, password, gender, department, admin=None, email=None, avatar=None, phone=None): self.account = account self.name = name self.gender = gender self.admin = admin self.department = department self.email = email self.avatar = avatar self.phone = phone self.hash_password(password) def get_uid(self): """get id""" return self.id @classmethod def getUsers(cls) -> list: """返回所有用户""" return [{ "uid": info.id, "account": info.account, "name": info.name, "department": info.department, "ctime": info.create_time, "role": "admin " if info.admin else "editor" } for info in cls.all()] @classmethod def get(cls, id, parseName=None, obj=True): user = super(User, cls).get(id, parseName) if obj: return user else: info = { "uid": user.id, "account": user.account, "name": user.name, "department": user.department, "ctime": user.create_time, "role": 1 if user.admin else 0 } return info @property def getName(self): return self.name def getInfo(self): departInfo = Department.get(self.department, "department") return { "userId": self.id, "name": self.name, "department": departInfo.name, "account": self.account, "avatar": self.avatar, "email": self.email, "phone": self.phone, "ctime": self.create_time, "access": "admin" if self.admin else "" } def is_superuser(self) -> bool: """是否是管理员""" return self.admin def hash_password(self, password): """密码哈希""" self.password = generate_password_hash(password) @classmethod def verify_account(cls, account): res = cls.query.filter_by(account=account).first() if res: abort( myResponse(ResponseCode.ERROR, None, f"{account} already exists")) def verify_password(self, password): """验证密码""" return check_password_hash(self.password, password) def generate_auth_token(self, expires_time=100 * 1000): """ 生产token :param expires_time: 过期时间 :return: token """ return jwt.encode({ 'id': self.id, 'exp': time.time() + expires_time }, current_app.config['SECRET_KEY'], algorithm='HS256') @staticmethod def verify_token(token): """ token 验证 :param token: token :return: user """ try: data = jwt.decode(token, current_app.config['SECRET_KEY'], algorithm=["HS256"]) except: return None return User.query.get(data['id']) def __repr__(self): return f"User: {self.id}"
class Bugs(Base): """bug类""" __tablename__ = "bugs" title = db.Column(db.String(100), index=True, comment="BUG标题") level = db.Column(db.Enum("p1", "p2", "p3", "p4"), server_default="p3", comment='BUG严重等级') priority = db.Column(db.Enum("p1", "p2", "p3", "p4"), server_default="p3", comment="BUG优先级") status = db.Column(db.Enum("ACTIVE", "RESOLVED", "CLOSED"), server_default="ACTIVE", comment="BUG状态") confirmed = db.Column(db.Boolean, default=False, comment="是否确认") creater = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=False, comment="创建者ID") createrName = db.Column(db.String(32), comment="创建者姓名") updater = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=True, comment="修改者") updaterName = db.Column(db.String(32), nullable=True, comment="修改者姓名") assignedTo = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=True, comment="指派给") resolvedBy = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=True, comment="解决者") mailTo = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=True, comment="抄送给") stepsBody = db.Column(db.TEXT, comment="步骤") solution = db.Column(db.Integer, db.ForeignKey("solution.id"), nullable=True, comment="解决方案") platform = db.Column(db.Integer, db.ForeignKey("platform.id"), nullable=True, comment="测试平台") module = db.Column(db.Integer, db.ForeignKey("module.id"), nullable=True, comment="所属模块") product = db.Column(db.Integer, db.ForeignKey("product.id"), nullable=True, comment="所属项目") build = db.Column(db.Integer, db.ForeignKey("build.id"), nullable=False, comment="版本") errorType = db.Column(db.Integer, db.ForeignKey("error_type.id"), nullable=True, comment="错误类型") bugFile = db.relationship('BugFile', backref="bug_file", lazy='dynamic') def __init__(self, title, creater, stepsBody, product, build): self.title = title self.creater = creater self.stepsBody = stepsBody self.build = build self.product = product def __repr__(self): return f"bug: {self.title}" @classmethod def get(cls, id, parse, obj=True): bug = super(Bugs, cls).get(id, parse) if obj: return bug else: bugInfo = { "bugID": bug.id, "createTime": bug.create_time, "title": bug.title, "level": bug.level, "priority": bug.priority, "status": bug.status, "confirmed": bug.confirmed, "creater": bug.creater, "updater": bug.updater, "creatername": bug.createrName, "updaterName": bug.updaterName, "assignedTo": bug.assignedTo, "resolvedBy": bug.resolvedBy, "mailTo": bug.mailTo, "stepsBody": bug.stepsBody, "solutionID": bug.solution, "platformID": bug.platform, "productID": bug.product, "buildID": bug.build, "errorTypeID": bug.errorType, "module": bug.module, "bugFiles": bug.myFiles() } return bugInfo def myFiles(self): """ [{fileName:xxx,filePath:xxx}] """ return [{ "id": f.id, "fileName": f.fileName, "filePath": f.filePath } for f in self.bugFile.filter_by().all()] def updateBug(self, updateBody: dict): """数据更新""" try: if updateBody.get("module"): self.module = updateBody.get("module") if updateBody.get("title"): self.title = updateBody.get("title") if updateBody.get("level"): self.level = updateBody.get("level") if updateBody.get("priority"): self.priority = updateBody.get("priority") if updateBody.get("status"): self.status = updateBody.get("status") if updateBody.get("confirmed"): self.confirmed = updateBody.get("confirmed") if updateBody.get("platformId"): self.platform = updateBody.get("platformId") if updateBody.get("buildId"): self.build = updateBody.get("buildId") if updateBody.get("errorTypeId"): self.errorType = updateBody.get("errorTypeId") if updateBody.get("assignedTo"): self.assignedTo = updateBody.get("assignedTo") if updateBody.get("mailTo"): self.mailTo = updateBody.get("mailTo") if updateBody.get("stepsBody"): self.stepsBody = updateBody.get("stepsBody") db.session.add(self) db.session.commit() except Exception as e: log.error(e) abort(myResponse(1, None, e)) @classmethod def optGetBugInfos(cls, opt) -> list: from flask import g if opt == "all": return Bugs.all() elif opt == "unClose": return Bugs.query.filter(Bugs.status == "CLOSED").order_by( desc(Bugs.id)).all() elif opt == "createByMe": return Bugs.query.filter(Bugs.creater == g.user.id).order_by( desc(Bugs.id)).all() elif opt == "assignedToMe": return Bugs.query.filter(Bugs.assignedTo == g.user.id).order_by( desc(Bugs.id)).all() elif opt == "resolvedByMe": return Bugs.query.filter(Bugs.resolvedBy == g.user.id).order_by( desc(Bugs.id)).all()
class Product(Base): """产品类""" __tabelname__ = "product" name = db.Column(db.String(50), unique=True, comment="产品名") # 所有解决方案 solutions = db.relationship("Solution", backref="product_solutions", lazy="dynamic", cascade="save-update,delete") # 所有测试平台 platforms = db.relationship("Platform", backref="product_platforms", lazy="dynamic", cascade="save-update,delete") # 所有版本 builds = db.relationship("Build", backref="product_builds", lazy="dynamic", cascade="save-update,delete") # 所有错误类型 errorTypes = db.relationship("ErrorType", backref="product_error_types", lazy="dynamic", cascade="save-update,delete") # 所有bug bugs = db.relationship("Bugs", backref="product_bugs", lazy="dynamic") # 所属项目 projectId = db.Column(db.Integer, db.ForeignKey("project.id"), nullable=False, comment='所属项目') # 所有模块 modules = db.relationship("Module", backref="product_modules", lazy="dynamic", cascade="save-update,delete") def __init__(self, name, projectId): self.projectId = projectId self.name = name @classmethod def get(cls, id, parseName, obj=True): pro = super(Product, cls).get(id, parseName) if obj: return pro else: info = {"name": pro.name, "ctime": pro.create_time} return info @classmethod def getBugs(cls, id, name): pro = super(Product, cls).get(id, name) info = { "name": pro.name, "ctime": pro.create_time, "bugs": pro.bugs_records } return info @property def modules_records(self) -> list: return self.modules.filter_by().all() @property def bugs_records(self): bugInfo = [{ "bugID": bug.id, "createTime": bug.create_time, "title": bug.title, "level": bug.level, "priority": bug.priority, "status": bug.status, "confirmed": bug.confirmed, "creater": bug.creater, "updater": bug.updater, "assignedTo": bug.assignedTo, "resolvedBy": bug.resolvedBy, } for bug in self.bugs.all()] return bugInfo @property def solutions_records(self): return self.solutions.filter_by().all() @property def platforms_records(self): return self.platforms.filter_by().all() @property def builds_records(self): return self.builds.filter_by().all() @property def projects_records(self): return self.projects.filter_by().all() @property def errorTypes_records(self): return self.errorTypes.filter_by().all() def __repr__(self): return f"product {self.name}"
class User(UserMixin, db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(64), index=True, unique=True) email = db.Column(db.String(120), index=True, unique=True) password_hash = db.Column(db.String(128)) posts = db.relationship('Post', backref='author', lazy='dynamic') tasks = db.relationship('Task', backref='user', lazy='dynamic') notifications = db.relationship('Notification', backref='user', lazy='dynamic') about_me = db.Column(db.String(140)) messages_sent = db.relationship('Message', foreign_keys='Message.sender_id', backref='author', lazy='dynamic') messages_received = db.relationship('Message', foreign_keys='Message.recipient_id', backref='recipient', lazy='dynamic') last_message_read_time = db.Column(db.DateTime) last_seen = db.Column(db.DateTime) followed = db.relationship( 'User', secondary=followers, primaryjoin=(followers.c.follower_id == id), secondaryjoin=(followers.c.followed_id == id), backref=db.backref('followers', lazy='dynamic'), lazy='dynamic') def __repr__(self): return '<User {}>'.format(self.username) def set_password(self, password): self.password_hash = generate_password_hash(password) def check_password(self, password): return check_password_hash(self.password_hash, password) def avatar(self, size): digest = md5(self.email.lower().encode('utf-8')).hexdigest() return 'https://www.gravatar.com/avatar/{}?d=identicon&s={}'.format( digest, size) def follow(self, user): if not self.is_following(user): self.followed.append(user) def unfollow(self, user): if self.is_following(user): self.followed.remove(user) def is_following(self, user): return self.followed.filter( followers.c.followed_id == user.id).count() > 0 def followed_posts(self): followed = Post.query.join( followers, (followers.c.followed_id == Post.user_id)).filter( followers.c.follower_id == self.id) own = Post.query.filter_by(user_id=self.id) return followed.union(own).order_by(Post.timestamp.desc()) def get_reset_password_token(self, expires_in=600): return jwt.encode( {'reset_password': self.id, 'exp': time() + expires_in}, current_app.config['SECRET_KEY'], algorithm='HS256').decode('utf-8') def new_messages(self): last_read_time = self.last_message_read_time or datetime(1900, 1, 1) return Message.query.filter_by(recipient=self).filter( Message.timestamp > last_read_time).count() def add_notification(self, name, data): self.notifications.filter_by(name=name).delete() n = Notification(name=name, payload_json=json.dumps(data), user=self) db.session.add(n) return n def launch_task(self, name, description, *args, **kwargs): rq_job = current_app.task_queue.enqueue('APP.tasks.' + name, self.id, *args, **kwargs) task = Task(id=rq_job.get_id(), name=name, description=description, user=self) db.session.add(task) return task def get_tasks_in_progress(self): return Task.query.filter_by(user=self, complete=False).all() def get_task_in_progress(self, name): return Task.query.filter_by(name=name, user=self, complete=False).first() @staticmethod def verify_reset_password_token(token): try: id = jwt.decode(token, current_app.config['SECRET_KEY'], algorithms=['HS256'])['reset_password'] except: return return User.query.get(id)