增加项目的各个功能

This commit is contained in:
qiaoxinjiu
2026-05-07 19:21:19 +08:00
parent aba1618f89
commit ee6cd4ae66
121 changed files with 9346 additions and 43 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

58
app/api/model/bugModel.py Normal file
View File

@@ -0,0 +1,58 @@
from sqlalchemy import BigInteger, Column, Integer, SmallInteger, String, Text, TIMESTAMP, text
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.ext.declarative import declarative_base
from common.sqlSession import to_dict
Base = declarative_base()
Base.to_dict = to_dict
class Bug(Base):
__tablename__ = 'bug'
id = Column(BigInteger, primary_key=True, autoincrement=True)
bug_key = Column(String(64), nullable=False, unique=True)
title = Column(String(256), nullable=False)
description = Column(Text)
bug_type = Column(SmallInteger, nullable=False, default=1)
severity = Column(SmallInteger, nullable=False, default=2)
priority = Column(SmallInteger, nullable=False, default=2)
status = Column(SmallInteger, nullable=False, default=0)
assignee_id = Column(BigInteger)
reporter_id = Column(BigInteger, nullable=False)
product_id = Column(BigInteger, nullable=False)
project_id = Column(BigInteger, nullable=False)
module_id = Column(BigInteger)
case_id = Column(BigInteger)
plan_id = Column(BigInteger)
environment = Column(String(64))
steps = Column(Text)
solution = Column(Text)
resolve_version = Column(String(64))
resolved_by = Column(BigInteger)
reproduce_rate = Column(SmallInteger)
attachments = Column(JSONB, server_default=text("'[]'::jsonb"))
is_delete = Column(Integer, default=0)
created_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP'), nullable=True)
updated_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP'), server_onupdate=text('CURRENT_TIMESTAMP'), nullable=True)
class BugComment(Base):
__tablename__ = 'bug_comment'
id = Column(BigInteger, primary_key=True, autoincrement=True)
bug_id = Column(BigInteger, nullable=False)
content = Column(Text, nullable=False)
user_id = Column(BigInteger, nullable=False)
is_delete = Column(Integer, default=0)
created_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP'), nullable=True)
class BugHistory(Base):
__tablename__ = 'bug_history'
id = Column(BigInteger, primary_key=True, autoincrement=True)
bug_id = Column(BigInteger, nullable=False)
field_name = Column(String(64), nullable=False)
old_value = Column(String(512))
new_value = Column(String(512))
operator_id = Column(BigInteger, nullable=False)
created_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP'), nullable=True)

View File

@@ -0,0 +1,62 @@
from sqlalchemy import BigInteger, Column, Integer, SmallInteger, String, TIMESTAMP, Text, text
from sqlalchemy.dialects.postgresql import ARRAY, JSONB
from sqlalchemy.ext.declarative import declarative_base
from common.sqlSession import to_dict
Base = declarative_base()
Base.to_dict = to_dict
class Module(Base):
__tablename__ = 'module'
id = Column(BigInteger, primary_key=True, autoincrement=True, comment='id')
project_id = Column(BigInteger, nullable=False, comment='项目id')
parent_id = Column(BigInteger, default=0, comment='父模块id')
name = Column(String(128), nullable=False, comment='模块名称')
sort_order = Column(Integer, default=0, comment='排序')
path = Column(String(512), comment='模块路径')
is_delete = Column(Integer, default=0, comment='0未删除1已删除')
class TestCase(Base):
__tablename__ = 'test_case'
id = Column(BigInteger, primary_key=True, autoincrement=True, comment='id')
project_id = Column(BigInteger, nullable=False, comment='项目id')
module_id = Column(BigInteger, comment='模块id')
case_key = Column(String(64), nullable=False, comment='项目内唯一编号')
title = Column(String(255), nullable=False, comment='标题')
preconditions = Column(Text, comment='前置条件')
steps = Column(Text, comment='步骤')
expected_results = Column(Text, comment='预期结果')
priority = Column(SmallInteger, default=2, comment='0:P0 1:P1 2:P2 3:P3')
case_type = Column(SmallInteger, default=1, comment='1:功能 2:性能 3:安全 4:接口')
tags = Column(ARRAY(String(64)), server_default=text("'{}'::varchar[]"), comment='标签')
status = Column(SmallInteger, default=1, comment='1:正常 2:已废弃 3:评审中 4评审通过')
is_auto = Column(Integer, default=0, comment='0未实现自动化1已实现自动化')
created_by = Column(BigInteger, comment='创建人')
is_delete = Column(Integer, default=0, comment='0未删除1已删除')
created_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP'), nullable=True, comment='创建时间')
updated_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP'), server_onupdate=text('CURRENT_TIMESTAMP'), nullable=True, comment='修改时间')
class CaseSnapshot(Base):
__tablename__ = 'case_snapshot'
id = Column(BigInteger, primary_key=True, autoincrement=True, comment='id')
case_id = Column(BigInteger, nullable=False, comment='用例id')
version = Column(Integer, nullable=False, comment='版本')
snapshot = Column(JSONB, nullable=False, comment='快照')
created_by = Column(BigInteger, comment='创建人')
created_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP'), nullable=True, comment='创建时间')
class CaseReview(Base):
__tablename__ = 'case_review'
id = Column(BigInteger, primary_key=True, autoincrement=True, comment='id')
case_id = Column(BigInteger, nullable=False, comment='用例id')
reviewer_id = Column(BigInteger, nullable=False, comment='评审人')
status = Column(SmallInteger, default=0, comment='0:待评审 1:通过 2:驳回 3:建议修改')
comments = Column(Text, comment='评论')
diff_content = Column(Text, comment='JSON diff')
created_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP'), nullable=True, comment='创建时间')
reviewed_time = Column(TIMESTAMP, nullable=True, comment='评审时间')

View File

@@ -0,0 +1,38 @@
from sqlalchemy import BigInteger, Column, Integer, SmallInteger, String, TIMESTAMP, Text, text
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.ext.declarative import declarative_base
from common.sqlSession import to_dict
Base = declarative_base()
Base.to_dict = to_dict
class DataBuilder(Base):
__tablename__ = 'data_builder'
id = Column(BigInteger, primary_key=True, autoincrement=True, comment='id')
project_id = Column(BigInteger, nullable=False, comment='项目id')
name = Column(String(128), nullable=False, comment='造数器名称')
description = Column(Text, comment='描述')
builder_type = Column(SmallInteger, default=1, comment='1:流程编排 2:SQL 3:脚本')
definition = Column(JSONB, nullable=False, comment='构造定义')
input_schema = Column(JSONB, comment='输入定义')
output_example = Column(JSONB, comment='输出示例')
created_by = Column(BigInteger, comment='创建人')
is_delete = Column(Integer, default=0, comment='0未删除1已删除')
created_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP'), nullable=True, comment='创建时间')
updated_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP'), server_onupdate=text('CURRENT_TIMESTAMP'), nullable=True, comment='修改时间')
class DataTask(Base):
__tablename__ = 'data_task'
id = Column(BigInteger, primary_key=True, autoincrement=True, comment='id')
builder_id = Column(BigInteger, nullable=False, comment='造数器id')
project_id = Column(BigInteger, nullable=False, comment='项目id')
params = Column(JSONB, comment='任务参数')
status = Column(SmallInteger, default=0, comment='0:等待 1:执行中 2:成功 3:失败')
result_data = Column(JSONB, comment='生成数据')
error_message = Column(Text, comment='错误信息')
created_by = Column(BigInteger, comment='创建人')
created_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP'), nullable=True, comment='创建时间')
completed_time = Column(TIMESTAMP, nullable=True, comment='完成时间')

View File

@@ -0,0 +1,50 @@
from sqlalchemy import BigInteger, Column, Date, Integer, SmallInteger, String, TIMESTAMP, Text, text
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.ext.declarative import declarative_base
from common.sqlSession import to_dict
Base = declarative_base()
Base.to_dict = to_dict
class TestPlan(Base):
__tablename__ = 'test_plan'
id = Column(BigInteger, primary_key=True, autoincrement=True, comment='id')
project_id = Column(BigInteger, nullable=False, comment='项目id')
name = Column(String(128), nullable=False, comment='计划名称')
version = Column(String(32), comment='测试版本')
description = Column(Text, comment='描述')
start_date = Column(Date, comment='开始日期')
end_date = Column(Date, comment='结束日期')
owner_id = Column(BigInteger, comment='负责人')
status = Column(SmallInteger, default=0, comment='0:草稿 1:进行中 2:已完成 3:已归档 4已通过')
environment_id = Column(BigInteger, comment='环境id')
is_delete = Column(Integer, default=0, comment='0未删除1已删除')
created_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP'), nullable=True, comment='创建时间')
updated_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP'), server_onupdate=text('CURRENT_TIMESTAMP'), nullable=True, comment='修改时间')
class PlanCase(Base):
__tablename__ = 'plan_case'
id = Column(BigInteger, primary_key=True, autoincrement=True, comment='id')
plan_id = Column(BigInteger, nullable=False, comment='计划id')
case_id = Column(BigInteger, nullable=False, comment='用例id')
assignee_id = Column(BigInteger, comment='执行人')
round_no = Column(Integer, default=1, comment='执行轮次')
status = Column(SmallInteger, default=0, comment='0:未开始 1:通过 2:失败 3:阻塞')
actual_result = Column(Text, comment='实际结果')
defect_links = Column(JSONB, server_default=text("'[]'::jsonb"), comment='缺陷链接')
attachments = Column(JSONB, server_default=text("'[]'::jsonb"), comment='附件')
executed_time = Column(TIMESTAMP, comment='执行时间')
execution_duration = Column(Integer, comment='执行耗时')
role_name_map = {1: '测试经理', 2: '测试工程师', 3: '开发工程师', 4: '访客'}
class TestRound(Base):
__tablename__ = 'test_round'
id = Column(BigInteger, primary_key=True, autoincrement=True, comment='id')
plan_id = Column(BigInteger, nullable=False, comment='计划id')
round_no = Column(Integer, nullable=False, comment='轮次')
name = Column(String(64), comment='轮次名称')
start_date = Column(Date, comment='开始日期')
end_date = Column(Date, comment='结束日期')

View File

@@ -0,0 +1,19 @@
from sqlalchemy import BigInteger, Column, Integer, SmallInteger, String, TIMESTAMP, Text, text
from sqlalchemy.ext.declarative import declarative_base
from common.sqlSession import to_dict
Base = declarative_base()
Base.to_dict = to_dict
class Product(Base):
__tablename__ = 'product'
id = Column(BigInteger, primary_key=True, autoincrement=True, comment='id')
name = Column(String(128), nullable=False, comment='产品名称')
code = Column(String(64), unique=True, nullable=False, comment='产品编码')
description = Column(Text, comment='产品描述')
status = Column(SmallInteger, default=1, comment='1:启用 0:禁用')
is_delete = Column(Integer, default=0, comment='0未删除1已删除')
created_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP'), nullable=True, comment='创建时间')
updated_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP'), server_onupdate=text('CURRENT_TIMESTAMP'), nullable=True, comment='修改时间')

View File

@@ -0,0 +1,23 @@
from sqlalchemy import BigInteger, Column, Integer, SmallInteger, String, Text, TIMESTAMP, text
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.ext.declarative import declarative_base
from common.sqlSession import to_dict
Base = declarative_base()
Base.to_dict = to_dict
class ProjectHook(Base):
__tablename__ = 'project_hook'
id = Column(BigInteger, primary_key=True, autoincrement=True, comment='id')
project_id = Column(BigInteger, nullable=False, comment='项目id')
hook_type = Column(SmallInteger, nullable=False, comment='1:飞书 2:钉钉 3:企微')
webhook_url = Column(String(512), nullable=False, comment='webhook地址')
secret = Column(String(256), comment='签名密钥')
enabled = Column(SmallInteger, default=1, comment='1:启用 0:禁用')
description = Column(String(256), comment='描述')
config = Column(JSONB, server_default=text("'{}'::jsonb"), comment='扩展配置')
is_delete = Column(Integer, default=0, comment='0未删除1已删除')
created_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP'), nullable=True, comment='创建时间')
updated_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP'), server_onupdate=text('CURRENT_TIMESTAMP'), nullable=True, comment='修改时间')

View File

@@ -0,0 +1,44 @@
from sqlalchemy import BigInteger, Boolean, Column, Integer, SmallInteger, String, TIMESTAMP, Text, text
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.ext.declarative import declarative_base
from common.sqlSession import to_dict
Base = declarative_base()
Base.to_dict = to_dict
class Project(Base):
__tablename__ = 'project'
id = Column(BigInteger, primary_key=True, autoincrement=True, comment='id')
key = Column(String(32), unique=True, nullable=False, comment='项目唯一标识')
name = Column(String(128), nullable=False, comment='项目名称')
product_id = Column(Integer, comment='产品id')
description = Column(Text, comment='项目描述')
department = Column(String(64), comment='部门')
status = Column(SmallInteger, default=1, comment='1:启用 0:禁用')
config = Column(JSONB, server_default=text("'{}'::jsonb"), comment='扩展配置')
created_by = Column(BigInteger, comment='创建人')
is_delete = Column(Integer, default=0, comment='0未删除1已删除')
created_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP'), nullable=True, comment='创建时间')
updated_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP'), server_onupdate=text('CURRENT_TIMESTAMP'), nullable=True, comment='修改时间')
class ProjectMember(Base):
__tablename__ = 'project_member'
id = Column(BigInteger, primary_key=True, autoincrement=True, comment='id')
project_id = Column(BigInteger, nullable=False, comment='项目id')
user_id = Column(BigInteger, nullable=False, comment='用户id')
role = Column(SmallInteger, nullable=False, comment='1:测试经理 2:测试工程师 3:开发工程师 4:访客')
joined_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP'), nullable=True, comment='加入时间')
class Environment(Base):
__tablename__ = 'environment'
id = Column(BigInteger, primary_key=True, autoincrement=True, comment='id')
project_id = Column(BigInteger, nullable=False, comment='项目id')
name = Column(String(64), nullable=False, comment='环境名称,如 dev/st/pre/prod')
variables = Column(JSONB, nullable=False, comment='环境变量')
is_encrypted = Column(Boolean, default=False, comment='是否加密')
is_delete = Column(Integer, default=0, comment='0未删除1已删除')
created_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP'), nullable=True, comment='创建时间')

View File

@@ -0,0 +1,72 @@
from sqlalchemy import BigInteger, Column, Integer, SmallInteger, String, TIMESTAMP, Text, text
from sqlalchemy.ext.declarative import declarative_base
from common.sqlSession import to_dict
Base = declarative_base()
Base.to_dict = to_dict
class Role(Base):
__tablename__ = 'role'
id = Column(BigInteger, primary_key=True, autoincrement=True, comment='id')
code = Column(String(64), unique=True, nullable=False, comment='角色编码')
name = Column(String(64), nullable=False, comment='角色名称')
description = Column(Text, comment='角色描述')
status = Column(SmallInteger, default=1, comment='1:启用 0:禁用')
is_system = Column(SmallInteger, default=0, comment='是否系统内置角色')
created_by = Column(BigInteger, comment='创建人')
is_delete = Column(Integer, default=0, comment='0未删除1已删除')
created_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP'), nullable=True, comment='创建时间')
updated_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP'), server_onupdate=text('CURRENT_TIMESTAMP'), nullable=True, comment='修改时间')
class Permission(Base):
__tablename__ = 'permission'
id = Column(BigInteger, primary_key=True, autoincrement=True, comment='id')
code = Column(String(128), unique=True, nullable=False, comment='权限编码')
name = Column(String(128), nullable=False, comment='权限名称')
module = Column(String(64), comment='所属模块')
action = Column(String(64), comment='动作')
description = Column(Text, comment='描述')
status = Column(SmallInteger, default=1, comment='1:启用 0:禁用')
is_delete = Column(Integer, default=0, comment='0未删除1已删除')
created_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP'), nullable=True, comment='创建时间')
updated_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP'), server_onupdate=text('CURRENT_TIMESTAMP'), nullable=True, comment='修改时间')
class RolePermission(Base):
__tablename__ = 'role_permission'
id = Column(BigInteger, primary_key=True, autoincrement=True, comment='id')
role_id = Column(BigInteger, nullable=False, comment='角色id')
permission_id = Column(BigInteger, nullable=False, comment='权限id')
is_delete = Column(Integer, default=0, comment='0未删除1已删除')
created_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP'), nullable=True, comment='创建时间')
class Menu(Base):
__tablename__ = 'menu'
id = Column(BigInteger, primary_key=True, autoincrement=True, comment='id')
parent_id = Column(BigInteger, default=0, comment='父菜单id')
name = Column(String(64), nullable=False, comment='菜单名称')
code = Column(String(64), unique=True, comment='菜单编码')
type = Column(SmallInteger, default=1, comment='1:目录 2:菜单 3:按钮')
path = Column(String(255), comment='路由路径')
component = Column(String(255), comment='前端组件路径')
icon = Column(String(64), comment='图标')
permission_code = Column(String(128), comment='对应权限编码')
sort = Column(Integer, default=0, comment='排序')
visible = Column(SmallInteger, default=1, comment='1:显示 0:隐藏')
status = Column(SmallInteger, default=1, comment='1:启用 0:禁用')
is_delete = Column(Integer, default=0, comment='0未删除1已删除')
created_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP'), nullable=True, comment='创建时间')
updated_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP'), server_onupdate=text('CURRENT_TIMESTAMP'), nullable=True, comment='修改时间')
class RoleMenu(Base):
__tablename__ = 'role_menu'
id = Column(BigInteger, primary_key=True, autoincrement=True, comment='id')
role_id = Column(BigInteger, nullable=False, comment='角色id')
menu_id = Column(BigInteger, nullable=False, comment='菜单id')
is_delete = Column(Integer, default=0, comment='0未删除1已删除')
created_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP'), nullable=True, comment='创建时间')

View File

@@ -0,0 +1,34 @@
from sqlalchemy import BigInteger, Column, SmallInteger, String, TIMESTAMP, Text, text
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.ext.declarative import declarative_base
from common.sqlSession import to_dict
Base = declarative_base()
Base.to_dict = to_dict
class Report(Base):
__tablename__ = 'report'
id = Column(BigInteger, primary_key=True, autoincrement=True, comment='id')
plan_id = Column(BigInteger, nullable=False, comment='计划id')
project_id = Column(BigInteger, nullable=False, comment='项目id')
product_id = Column(BigInteger, nullable=False, comment='产品id')
name = Column(String(128), nullable=False, comment='报告名称')
report_type = Column(SmallInteger, default=1, comment='1:实时报告 2:归档报告')
summary = Column(JSONB, comment='统计数据')
content = Column(Text, comment='HTML内容')
file_url = Column(String(512), comment='文件地址')
generated_by = Column(BigInteger, comment='生成人')
generated_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP'), nullable=True, comment='生成时间')
class DefectSync(Base):
__tablename__ = 'defect_sync'
id = Column(BigInteger, primary_key=True, autoincrement=True, comment='id')
project_id = Column(BigInteger, nullable=False, comment='项目id')
external_id = Column(String(64), nullable=False, comment='外部缺陷id')
external_system = Column(String(32), comment='外部系统')
plan_case_id = Column(BigInteger, comment='计划用例id')
status = Column(String(32), comment='外部状态')
last_sync_time = Column(TIMESTAMP, comment='最后同步时间')

View File

@@ -25,6 +25,3 @@ class UpdateSqlProject(Base):
nullable=True,
comment='修改时间'
)
def __repr__(self):
return '<update_sql_project %r>' % self.id

View File

@@ -0,0 +1,33 @@
from sqlalchemy import BigInteger, Column, Integer, SmallInteger, String, TIMESTAMP, text
from sqlalchemy.ext.declarative import declarative_base
from common.sqlSession import to_dict
Base = declarative_base()
Base.to_dict = to_dict
class User(Base):
__tablename__ = 'user'
id = Column(BigInteger, primary_key=True, autoincrement=True, comment='id')
username = Column(String(64), unique=True, nullable=False, comment='登录用户名')
real_name = Column(String(64), comment='真实姓名')
password_hash = Column(String(255), nullable=False, comment='密码哈希')
mobile = Column(String(32), comment='手机号')
email = Column(String(128), comment='邮箱')
avatar = Column(String(255), comment='头像地址')
status = Column(SmallInteger, default=1, comment='1:启用 0:禁用')
last_login_time = Column(TIMESTAMP, nullable=True, comment='最后登录时间')
created_by = Column(BigInteger, comment='创建人')
is_delete = Column(Integer, default=0, comment='0未删除1已删除')
created_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP'), nullable=True, comment='创建时间')
updated_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP'), server_onupdate=text('CURRENT_TIMESTAMP'), nullable=True, comment='修改时间')
class UserRole(Base):
__tablename__ = 'user_role'
id = Column(BigInteger, primary_key=True, autoincrement=True, comment='id')
user_id = Column(BigInteger, nullable=False, comment='用户id')
role_id = Column(BigInteger, nullable=False, comment='角色id')
is_delete = Column(Integer, default=0, comment='0未删除1已删除')
created_time = Column(TIMESTAMP, server_default=text('CURRENT_TIMESTAMP'), nullable=True, comment='创建时间')