新增:影响域分析web录入
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -396,3 +396,21 @@ class CaseController(ControllerBase):
|
||||
Case.objects.bulk_update(updated_cases, ['exe_time'])
|
||||
return ChenResponse(status=200, code=200, data=len(updated_cases),
|
||||
message=f"成功更新{len(updated_cases)}个用例执行时间")
|
||||
|
||||
# 给级联选择器数据 -> 上一轮次所有用例
|
||||
@route.get("/case/getRelatedCase", url_name='case-related-case')
|
||||
def get_cases_related_case(self, id: int, round_key: str):
|
||||
project_obj = get_object_or_404(Project, id=id)
|
||||
previous_round_obj = project_obj.pField.filter(key=int(round_key) - 1).first()
|
||||
# dut -> design
|
||||
data_list = []
|
||||
for dut in previous_round_obj.rdField.all():
|
||||
dut_dict = {'label': dut.name, 'value': dut.id, 'children': []}
|
||||
for design in dut.rsField.all():
|
||||
design_dict = {'label': design.name, 'value': design.id, 'key': design.key, 'children': []}
|
||||
for case in design.dcField.all():
|
||||
case_dict = {'label': case.name, 'value': case.id, 'key': case.key}
|
||||
design_dict['children'].append(case_dict)
|
||||
dut_dict['children'].append(design_dict)
|
||||
data_list.append(dut_dict)
|
||||
return ChenResponse(message='获取成功', data=data_list)
|
||||
@@ -15,9 +15,9 @@ from ninja import Query
|
||||
from utils.chen_response import ChenResponse
|
||||
from utils.chen_crud import create, multi_delete_project
|
||||
from apps.project.models import Project, Round, ProjectSoftSummary, StuctSortData, StaticSoftItem, StaticSoftHardware, DynamicSoftTable, \
|
||||
DynamicHardwareTable
|
||||
DynamicHardwareTable, ProjectDynamicDescription, EvaluateData, EnvAnalysis
|
||||
from apps.project.schemas.project import ProjectRetrieveSchema, ProjectFilterSchema, ProjectCreateInput, \
|
||||
DeleteSchema, SoftSummarySchema, DataSchema, StaticDynamicData
|
||||
DeleteSchema, SoftSummarySchema, DataSchema, StaticDynamicData, EnvAnalysisSchema
|
||||
from utils.util import get_str_dict
|
||||
# 时间处理模块
|
||||
from apps.project.tool.timeList import time_return_to
|
||||
@@ -99,6 +99,7 @@ class ProjectController(ControllerBase):
|
||||
except FileNotFoundError:
|
||||
return ChenResponse(code=500, status=500, message='文件不存在,请检查')
|
||||
return ChenResponse(code=200, status=200, message="添加项目成功,并添加第一轮测试")
|
||||
return ChenResponse(code=400, status=400, message="未添加任何项目")
|
||||
|
||||
@route.put("/update/{project_id}")
|
||||
@transaction.atomic
|
||||
@@ -139,7 +140,7 @@ class ProjectController(ControllerBase):
|
||||
project_media_path = media_path / ident
|
||||
try:
|
||||
rmtree(project_media_path)
|
||||
except FileNotFoundError as e:
|
||||
except FileNotFoundError:
|
||||
return ChenResponse(status=400, code=400, message='项目模版目录可能不存在,可能之前已删除')
|
||||
return ChenResponse(message="删除成功!")
|
||||
|
||||
@@ -270,48 +271,59 @@ class ProjectController(ControllerBase):
|
||||
time = time_return_to(id)
|
||||
return time
|
||||
|
||||
# 项目级信息前端告警数据获取
|
||||
# [变] 项目级信息前端告警数据获取
|
||||
@route.get("/project_info_status/")
|
||||
@transaction.atomic
|
||||
def project_info_status(self, id: int):
|
||||
# 全部状态
|
||||
all_status = {
|
||||
"soft_summary": False,
|
||||
"interface_image": False,
|
||||
"static_soft_item": False,
|
||||
"static_soft_hardware": False,
|
||||
"dynamic_soft_item": False,
|
||||
"dynamic_soft_hardware": False,
|
||||
}
|
||||
# 1.查看软件概述是否填写
|
||||
project_obj = self.get_project_by_id(id)
|
||||
soft_summary_qs = ProjectSoftSummary.objects.filter(project=project_obj)
|
||||
if soft_summary_qs.exists():
|
||||
# 存在还要判断是否有子项
|
||||
if soft_summary_qs.first().data_schemas.exists():
|
||||
all_status['soft_summary'] = True
|
||||
# 2.查看接口图是否填写
|
||||
image_qs = StuctSortData.objects.filter(project=project_obj)
|
||||
if image_qs.exists():
|
||||
all_status['interface_image'] = True
|
||||
# 3.查看静态软件项是否填写
|
||||
static_item_qs = StaticSoftItem.objects.filter(project=project_obj)
|
||||
if static_item_qs.exists():
|
||||
all_status['static_soft_item'] = True
|
||||
# 4.静态硬件项
|
||||
static_hardware_qs = StaticSoftHardware.objects.filter(project=project_obj)
|
||||
if static_hardware_qs.exists():
|
||||
all_status['static_soft_hardware'] = True
|
||||
# 5.动态软件项
|
||||
dynamic_soft_item_qs = DynamicSoftTable.objects.filter(project=project_obj)
|
||||
if dynamic_soft_item_qs.exists():
|
||||
all_status['dynamic_soft_item'] = True
|
||||
# 5.动态软件项
|
||||
dynamic_hardware_qs = DynamicHardwareTable.objects.filter(project=project_obj)
|
||||
if dynamic_hardware_qs.exists():
|
||||
all_status['dynamic_soft_hardware'] = True
|
||||
|
||||
# 统一配置每个状态的检查逻辑
|
||||
status_configs = {
|
||||
"soft_summary": {
|
||||
"model": ProjectSoftSummary,
|
||||
"check": lambda qs: qs.exists() and qs.first().data_schemas.exists()
|
||||
},
|
||||
"interface_image": {
|
||||
"model": StuctSortData,
|
||||
"check": lambda qs: qs.exists()
|
||||
},
|
||||
"static_soft_item": {
|
||||
"model": StaticSoftItem,
|
||||
"check": lambda qs: qs.exists()
|
||||
},
|
||||
"static_soft_hardware": {
|
||||
"model": StaticSoftHardware,
|
||||
"check": lambda qs: qs.exists()
|
||||
},
|
||||
"dynamic_soft_item": {
|
||||
"model": DynamicSoftTable,
|
||||
"check": lambda qs: qs.exists()
|
||||
},
|
||||
"dynamic_soft_hardware": {
|
||||
"model": DynamicHardwareTable,
|
||||
"check": lambda qs: qs.exists()
|
||||
},
|
||||
"dynamic_des": {
|
||||
"model": ProjectDynamicDescription,
|
||||
"check": lambda qs: qs.exists() and qs.first().data_schemas.exists()
|
||||
},
|
||||
"evaluate_data": {
|
||||
"model": EvaluateData,
|
||||
"check": lambda qs: qs.exists()
|
||||
},
|
||||
"env_analysis": {
|
||||
"model": EnvAnalysis,
|
||||
"check": lambda qs: qs.exists()
|
||||
}
|
||||
}
|
||||
|
||||
all_status = {}
|
||||
for status_key, config in status_configs.items():
|
||||
qs = config["model"].objects.filter(project=project_obj)
|
||||
all_status[status_key] = config["check"](qs)
|
||||
return ChenResponse(status=200, code=20000, data=all_status, message='查询成功')
|
||||
|
||||
# [变] 封装结构化数据新增-修改(针对project - OneToOne - DataSchemas形式)
|
||||
@classmethod
|
||||
def bulk_create_data_schemas(cls, parent_obj, datas: list[DataSchema]):
|
||||
"""
|
||||
@@ -321,11 +333,13 @@ class ProjectController(ControllerBase):
|
||||
datas (list[DataSchema]): 数据模式对象列表
|
||||
"""
|
||||
# 动态确定所属父model
|
||||
field_name = None
|
||||
field_name = None # type:ignore
|
||||
if isinstance(parent_obj, ProjectSoftSummary):
|
||||
field_name = 'soft_summary'
|
||||
elif isinstance(parent_obj, Project):
|
||||
field_name = 'project'
|
||||
elif isinstance(parent_obj, ProjectDynamicDescription):
|
||||
field_name = 'dynamic_description'
|
||||
else:
|
||||
raise HttpError(400, "添加的数据未在系统内,请联系管理员")
|
||||
|
||||
@@ -340,39 +354,66 @@ class ProjectController(ControllerBase):
|
||||
data_list.append(new_data)
|
||||
StuctSortData.objects.bulk_create(data_list)
|
||||
|
||||
# 封装只有model不同 -修改和新增dataSchemas(针对project - OneToOne - DataSchemas形式)
|
||||
@classmethod
|
||||
def create_or_modify_data_schemas(cls, id: int, model, data):
|
||||
project_obj = get_object_or_404(Project, pk=id)
|
||||
qs = model.objects.filter(project=project_obj)
|
||||
if qs.exists():
|
||||
obj = qs.first()
|
||||
# 如果存在则修改:先删除再创建
|
||||
obj.data_schemas.all().delete()
|
||||
cls.bulk_create_data_schemas(obj, data)
|
||||
else:
|
||||
parent_obj = model.objects.create(project=project_obj)
|
||||
cls.bulk_create_data_schemas(parent_obj, data)
|
||||
|
||||
# ~~~软件概述-新增和修改~~~
|
||||
@route.post('/soft_summary/')
|
||||
@transaction.atomic
|
||||
def soft_summary(self, payload: SoftSummarySchema):
|
||||
project_obj = self.get_project_by_id(payload.id)
|
||||
# 安全获取-软件概述
|
||||
soft_summary_qs = ProjectSoftSummary.objects.filter(project=project_obj)
|
||||
if soft_summary_qs.exists():
|
||||
soft_summary = soft_summary_qs.first()
|
||||
# 如果存在则修改:先删除然后创建
|
||||
soft_summary.data_schemas.all().delete()
|
||||
self.bulk_create_data_schemas(soft_summary, payload.data)
|
||||
else:
|
||||
# 不存在软件概述则创建
|
||||
soft_summary_obj = ProjectSoftSummary.objects.create(project=project_obj)
|
||||
self.bulk_create_data_schemas(soft_summary_obj, payload.data)
|
||||
self.create_or_modify_data_schemas(payload.id, ProjectSoftSummary, payload.data)
|
||||
|
||||
# ~~~动态环境描述-新增和修改~~~
|
||||
@route.post('/dynamic_description/')
|
||||
@transaction.atomic
|
||||
def dynamic_description(self, payload: SoftSummarySchema):
|
||||
self.create_or_modify_data_schemas(payload.id, ProjectDynamicDescription, payload.data)
|
||||
|
||||
@classmethod
|
||||
def get_res_from_info(cls, project_obj: Project, model) -> list[dict] | None:
|
||||
"""model: 当前一对一模型,直接获取结构化数据信息数组返回"""
|
||||
qs = model.objects.filter(project=project_obj)
|
||||
if qs.exists():
|
||||
obj = qs.first()
|
||||
ds_qs = obj.data_schemas.all()
|
||||
data_list = [{
|
||||
"type": item.type,
|
||||
"content": item.content,
|
||||
"fontnote": item.fontnote,
|
||||
} for item in ds_qs]
|
||||
return data_list
|
||||
return None
|
||||
|
||||
# ~~~软件概述-获取到前端展示~~~
|
||||
@route.get("/get_soft_summary/", response=list[DataSchema])
|
||||
@transaction.atomic
|
||||
def get_soft_summary(self, id: int):
|
||||
project_obj = self.get_project_by_id(id)
|
||||
soft_summary_qs = ProjectSoftSummary.objects.filter(project=project_obj)
|
||||
if soft_summary_qs.exists():
|
||||
# 如果存在则返回数据
|
||||
soft_summary = soft_summary_qs.first()
|
||||
dataSchem_qs = soft_summary.data_schemas.all()
|
||||
return ChenResponse(status=200, code=25001, data=[{
|
||||
"type": item.type,
|
||||
"content": item.content,
|
||||
"fontnote": item.fontnote,
|
||||
} for item in dataSchem_qs])
|
||||
return ChenResponse(status=200, code=25002, data=[])
|
||||
data_list = self.get_res_from_info(project_obj, ProjectSoftSummary)
|
||||
if data_list:
|
||||
return ChenResponse(status=200, code=20000, data=data_list)
|
||||
return ChenResponse(status=200, code=20000, data=[])
|
||||
|
||||
# ~~~动态环境描述 - 获取展示~~~
|
||||
@route.get("/dynamic_des/", response=list[DataSchema])
|
||||
@transaction.atomic
|
||||
def get_dynamic_des(self, id: int):
|
||||
project_obj = self.get_project_by_id(id)
|
||||
data_list = self.get_res_from_info(project_obj, ProjectDynamicDescription)
|
||||
if data_list:
|
||||
return ChenResponse(status=200, code=20000, data=data_list)
|
||||
return ChenResponse(status=200, code=20000, data=[])
|
||||
|
||||
# ~~~接口图新增或修改~~~
|
||||
@route.post("/interface_image/")
|
||||
@@ -400,13 +441,15 @@ class ProjectController(ControllerBase):
|
||||
})
|
||||
return ChenResponse(status=200, code=25002, data=None)
|
||||
|
||||
# 动态返回是哪个模型
|
||||
@classmethod
|
||||
def get_model_from_category(cls, category: str):
|
||||
mapDict = {
|
||||
'静态软件项': StaticSoftItem,
|
||||
'静态硬件项': StaticSoftHardware,
|
||||
'动态软件项': DynamicSoftTable,
|
||||
'动态硬件项': DynamicHardwareTable
|
||||
'动态硬件项': DynamicHardwareTable,
|
||||
'测评数据': EvaluateData
|
||||
}
|
||||
return mapDict[category]
|
||||
|
||||
@@ -424,7 +467,6 @@ class ProjectController(ControllerBase):
|
||||
@route.post("/post_static_dynamic_item/")
|
||||
@transaction.atomic
|
||||
def post_static_dynamic_item(self, data: StaticDynamicData):
|
||||
print(data)
|
||||
project_obj = self.get_project_by_id(data.id)
|
||||
model = self.get_model_from_category(data.category)
|
||||
item_qs = model.objects.filter(project=project_obj)
|
||||
@@ -432,3 +474,24 @@ class ProjectController(ControllerBase):
|
||||
# 如果存在则修改
|
||||
item_qs.delete()
|
||||
model.objects.create(project=project_obj, table=data.table, fontnote=data.fontnote)
|
||||
|
||||
# ~~~环境差异性分析 - 获取~~~
|
||||
@route.get("/get_env_analysis/")
|
||||
@transaction.atomic
|
||||
def get_env_analysis(self, id: int):
|
||||
project_obj = self.get_project_by_id(id)
|
||||
qs = EnvAnalysis.objects.filter(project=project_obj)
|
||||
if qs.exists():
|
||||
obj = qs.first()
|
||||
return ChenResponse(status=200, code=25001, data={"table": obj.table, "fontnote": obj.fontnote, "description": obj.description})
|
||||
return ChenResponse(status=200, code=25002, data=None)
|
||||
|
||||
# ~~~环境差异性分析 - 新增和修改~~~
|
||||
@route.post("/post_env_analysis/")
|
||||
@transaction.atomic
|
||||
def post_env_analysis(self, data: EnvAnalysisSchema):
|
||||
project_obj = self.get_project_by_id(data.id)
|
||||
qs = EnvAnalysis.objects.filter(project=project_obj)
|
||||
if qs.exists():
|
||||
qs.delete()
|
||||
EnvAnalysis.objects.create(project=project_obj, table=data.table, fontnote=data.fontnote, description=data.description)
|
||||
|
||||
@@ -2,9 +2,9 @@ from ninja_extra import api_controller, ControllerBase, route
|
||||
from ninja_jwt.authentication import JWTAuth
|
||||
from ninja_extra.permissions import IsAuthenticated
|
||||
from django.db import transaction
|
||||
from apps.project.models import Round
|
||||
from apps.project.models import Round, InfluenceArea, InfluenceItem
|
||||
from apps.project.schemas.round import TreeReturnRound, RoundInfoOutSchema, EditSchemaIn, DeleteSchema, \
|
||||
CreateRoundOutSchema, CreateRoundInputSchema
|
||||
CreateRoundOutSchema, CreateRoundInputSchema, InfluenceItemOutSchema, InfluenceInputSchema
|
||||
from typing import List
|
||||
from utils.chen_response import ChenResponse
|
||||
from apps.project.tools.delete_change_key import round_delete_sub_node_key
|
||||
@@ -81,3 +81,63 @@ class RoundController(ControllerBase):
|
||||
return ChenResponse(code=400, status=400, message='标识和其他重复')
|
||||
Round.objects.create(**asert_dict)
|
||||
return ChenResponse(message="新增轮次成功")
|
||||
|
||||
# ~~~影响域分析 - 获取数据和状态~~~
|
||||
@route.get("/round/get_influence", response=List[InfluenceItemOutSchema], url_name="round-get-influence-items")
|
||||
@transaction.atomic
|
||||
def get_influence(self, id: int, round_key: str):
|
||||
round_qs = Round.objects.filter(project__id=id, key=round_key)
|
||||
round_obj = round_qs.first()
|
||||
influence_qs = InfluenceArea.objects.filter(round=round_obj)
|
||||
if influence_qs.exists():
|
||||
influence = influence_qs.first()
|
||||
items_qs = influence.influence_items.all()
|
||||
if items_qs.exists():
|
||||
return items_qs
|
||||
return ChenResponse(status=200, code=25002, data=[])
|
||||
|
||||
# ~~~影响域分析是否有值~~~
|
||||
@route.get("/round/get_status_influence", url_name="round-get-status-influence")
|
||||
@transaction.atomic
|
||||
def get_status_influence(self, id: int, round_key: str):
|
||||
round_qs = Round.objects.filter(project__id=id, key=round_key)
|
||||
round_obj = round_qs.first()
|
||||
influence_qs = InfluenceArea.objects.filter(round=round_obj)
|
||||
if influence_qs.exists():
|
||||
influence = influence_qs.first()
|
||||
items_qs = influence.influence_items.all()
|
||||
if items_qs.exists():
|
||||
return ChenResponse(status=200, code=25005, data=True)
|
||||
return ChenResponse(status=200, code=25006, data=False)
|
||||
|
||||
# ~~~影响域分析 - 修改或新增~~~
|
||||
@route.post("/round/create_influence", url_name="round-influence-create")
|
||||
@transaction.atomic
|
||||
def post_influence(self, data: InfluenceInputSchema):
|
||||
print(data)
|
||||
round_obj = Round.objects.filter(project_id=data.id, key=data.round_key).first()
|
||||
influence_area_qs = InfluenceArea.objects.filter(round=round_obj)
|
||||
if influence_area_qs.exists():
|
||||
influence_area_obj = influence_area_qs.first()
|
||||
influence_area_obj.influence_items.all().delete()
|
||||
# 先删除再创建
|
||||
data_list = []
|
||||
for item in data.item_list:
|
||||
new_item = InfluenceItem(influence=influence_area_obj,
|
||||
change_type=item.change_type,
|
||||
change_influ=item.change_influ,
|
||||
change_des=item.change_des,
|
||||
effect_cases=item.effect_cases)
|
||||
data_list.append(new_item)
|
||||
InfluenceItem.objects.bulk_create(data_list)
|
||||
else:
|
||||
parent_obj = InfluenceArea.objects.create(round=round_obj)
|
||||
data_list = []
|
||||
for item in data.item_list:
|
||||
new_item = InfluenceItem(influence=parent_obj,
|
||||
change_type=item.change_type,
|
||||
change_influ=item.change_influ,
|
||||
change_des=item.change_des,
|
||||
effect_cases=item.effect_cases)
|
||||
data_list.append(new_item)
|
||||
InfluenceItem.objects.bulk_create(data_list)
|
||||
|
||||
28
apps/project/migrations/0025_evaluatedata.py
Normal file
28
apps/project/migrations/0025_evaluatedata.py
Normal file
@@ -0,0 +1,28 @@
|
||||
# Generated by Django 6.0.2 on 2026-02-06 10:56
|
||||
|
||||
import apps.project.models
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('project', '0024_projectdynamicdescription_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='EvaluateData',
|
||||
fields=[
|
||||
('project', models.OneToOneField(db_constraint=False, help_text='关联项目', on_delete=django.db.models.deletion.CASCADE, primary_key=True, related_name='evaluate_data', serialize=False, to='project.project', verbose_name='关联项目')),
|
||||
('table', models.JSONField(default=apps.project.models.default_json_value, help_text='储存表格二维数组', verbose_name='储存表格二维数组')),
|
||||
('fontnote', models.CharField(default='', help_text='数据的题注说明', max_length=256, null=True, verbose_name='题注')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '测评数据',
|
||||
'verbose_name_plural': '测评数据',
|
||||
'db_table': 'project_evaluate_data',
|
||||
},
|
||||
),
|
||||
]
|
||||
29
apps/project/migrations/0026_envanalysis.py
Normal file
29
apps/project/migrations/0026_envanalysis.py
Normal file
@@ -0,0 +1,29 @@
|
||||
# Generated by Django 6.0.2 on 2026-02-06 13:56
|
||||
|
||||
import apps.project.models
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('project', '0025_evaluatedata'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='EnvAnalysis',
|
||||
fields=[
|
||||
('project', models.OneToOneField(db_constraint=False, help_text='关联项目', on_delete=django.db.models.deletion.CASCADE, primary_key=True, related_name='env_analysis', serialize=False, to='project.project', verbose_name='关联项目')),
|
||||
('table', models.JSONField(default=apps.project.models.default_json_value, help_text='储存表格二维数组', verbose_name='储存表格二维数组')),
|
||||
('fontnote', models.CharField(default='', help_text='数据的题注说明', max_length=256, null=True, verbose_name='题注')),
|
||||
('description', models.CharField(default='', max_length=1024, null=True, verbose_name='差异性分析文字')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '环境差异性分析表',
|
||||
'verbose_name_plural': '环境差异性分析表',
|
||||
'db_table': 'project_env_analysis',
|
||||
},
|
||||
),
|
||||
]
|
||||
46
apps/project/migrations/0027_influencearea_influenceitem.py
Normal file
46
apps/project/migrations/0027_influencearea_influenceitem.py
Normal file
@@ -0,0 +1,46 @@
|
||||
# Generated by Django 6.0.2 on 2026-02-06 16:05
|
||||
|
||||
import apps.project.models
|
||||
import django.db.models.deletion
|
||||
import tinymce.models
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('project', '0026_envanalysis'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='InfluenceArea',
|
||||
fields=[
|
||||
('project', models.OneToOneField(db_constraint=False, help_text='关联项目', on_delete=django.db.models.deletion.CASCADE, primary_key=True, related_name='influence', serialize=False, to='project.round', verbose_name='关联项目')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '影响域分析',
|
||||
'verbose_name_plural': '影响域分析',
|
||||
'db_table': 'round_influence_area',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='InfluenceItem',
|
||||
fields=[
|
||||
('id', models.BigAutoField(help_text='Id', primary_key=True, serialize=False, verbose_name='Id')),
|
||||
('remark', models.CharField(blank=True, help_text='描述', max_length=255, null=True, verbose_name='描述')),
|
||||
('update_datetime', models.DateField(auto_now=True, help_text='修改时间', null=True, verbose_name='修改时间')),
|
||||
('create_datetime', models.DateField(auto_now_add=True, help_text='创建时间', null=True, verbose_name='创建时间')),
|
||||
('sort', models.IntegerField(blank=True, default=1, help_text='显示排序', null=True, verbose_name='显示排序')),
|
||||
('change_type', models.CharField(default='', help_text='更改类型', max_length=256, null=True, verbose_name='更改类型')),
|
||||
('change_des', tinymce.models.HTMLField(blank=True, null=True, verbose_name='更改内容描述')),
|
||||
('effect_cases', models.JSONField(default=apps.project.models.create_list, verbose_name='影响的用例key数组')),
|
||||
('influence', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='influence_items', to='project.influencearea', verbose_name='所属影响域分析')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '影响域分析 - 行数据',
|
||||
'verbose_name_plural': '影响域分析 - 行数据',
|
||||
'db_table': 'influence_item',
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 6.0.2 on 2026-02-07 13:45
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('project', '0027_influencearea_influenceitem'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameField(
|
||||
model_name='influencearea',
|
||||
old_name='project',
|
||||
new_name='round',
|
||||
),
|
||||
]
|
||||
18
apps/project/migrations/0029_influenceitem_change_influ.py
Normal file
18
apps/project/migrations/0029_influenceitem_change_influ.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 6.0.2 on 2026-02-07 16:53
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('project', '0028_rename_project_influencearea_round'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='influenceitem',
|
||||
name='change_influ',
|
||||
field=models.TextField(default='', help_text='影响域分析', max_length=2048, null=True, verbose_name='影响域分析'),
|
||||
),
|
||||
]
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -542,7 +542,6 @@ class DynamicSoftTable(models.Model):
|
||||
class DynamicHardwareTable(models.Model):
|
||||
project = models.OneToOneField(to="Project", primary_key=True, db_constraint=False, related_name="dynamic_hardware", on_delete=models.CASCADE,
|
||||
verbose_name="关联项目", help_text="关联项目")
|
||||
|
||||
table = models.JSONField(verbose_name="储存表格二维数组", help_text="储存表格二维数组", default=default_json_value)
|
||||
fontnote = models.CharField(max_length=256, null=True, default="", verbose_name="题注", help_text="数据的题注说明")
|
||||
|
||||
@@ -551,6 +550,32 @@ class DynamicHardwareTable(models.Model):
|
||||
verbose_name = "动态硬件项表"
|
||||
verbose_name_plural = verbose_name
|
||||
|
||||
# 一对一项目model:动态环境 - 测评数据
|
||||
class EvaluateData(models.Model):
|
||||
project = models.OneToOneField(to="Project", primary_key=True, db_constraint=False, related_name="evaluate_data", on_delete=models.CASCADE,
|
||||
verbose_name="关联项目", help_text="关联项目")
|
||||
table = models.JSONField(verbose_name="储存表格二维数组", help_text="储存表格二维数组", default=default_json_value)
|
||||
fontnote = models.CharField(max_length=256, null=True, default="", verbose_name="题注", help_text="数据的题注说明")
|
||||
|
||||
class Meta:
|
||||
db_table = 'project_evaluate_data'
|
||||
verbose_name = "测评数据"
|
||||
verbose_name_plural = verbose_name
|
||||
|
||||
# 一对一项目model:环境差异性分析
|
||||
class EnvAnalysis(models.Model):
|
||||
project = models.OneToOneField(to="Project", primary_key=True, db_constraint=False,
|
||||
related_name="env_analysis", on_delete=models.CASCADE,
|
||||
verbose_name="关联项目", help_text="关联项目")
|
||||
table = models.JSONField(verbose_name="储存表格二维数组", help_text="储存表格二维数组", default=default_json_value)
|
||||
fontnote = models.CharField(max_length=256, null=True, default="", verbose_name="题注", help_text="数据的题注说明")
|
||||
description = models.CharField(max_length=1024, null=True, default="", verbose_name="差异性分析文字")
|
||||
|
||||
class Meta:
|
||||
db_table = 'project_env_analysis'
|
||||
verbose_name = "环境差异性分析表"
|
||||
verbose_name_plural = verbose_name
|
||||
|
||||
# 结构化排序数据
|
||||
class StuctSortData(CoreModel):
|
||||
"""
|
||||
@@ -582,11 +607,7 @@ class StuctSortData(CoreModel):
|
||||
help_text="数据的题注说明"
|
||||
)
|
||||
# 内容字段 - 存储字符串、列表、字典
|
||||
content = models.JSONField(
|
||||
verbose_name="内容",
|
||||
help_text="存储文本内容或二维表格数据或图片数据",
|
||||
default=default_json_value
|
||||
)
|
||||
content = models.JSONField(verbose_name="内容", help_text="存储文本内容或二维表格数据或图片数据", default=default_json_value)
|
||||
|
||||
class Meta:
|
||||
db_table = 'data_schemas'
|
||||
@@ -595,3 +616,28 @@ class StuctSortData(CoreModel):
|
||||
|
||||
def __str__(self):
|
||||
return f"结构排序化数据:({self.pk})"
|
||||
|
||||
# 影响域分析 - 隶属:轮次(不能是第一轮次)
|
||||
class InfluenceArea(models.Model):
|
||||
round = models.OneToOneField(to="Round", primary_key=True, db_constraint=False,
|
||||
related_name="influence", on_delete=models.CASCADE,
|
||||
verbose_name="关联项目", help_text="关联项目")
|
||||
|
||||
class Meta:
|
||||
db_table = 'round_influence_area'
|
||||
verbose_name = "影响域分析"
|
||||
verbose_name_plural = verbose_name
|
||||
|
||||
class InfluenceItem(CoreModel):
|
||||
# 外键:影响域分析
|
||||
influence = models.ForeignKey(InfluenceArea, db_constraint=False, related_name="influence_items", verbose_name="所属影响域分析",
|
||||
on_delete=models.CASCADE, null=True, blank=True)
|
||||
change_type = models.CharField(max_length=256, null=True, default="", verbose_name="更改类型", help_text="更改类型")
|
||||
change_influ = models.TextField(max_length=2048, null=True, default="", verbose_name="影响域分析", help_text="影响域分析")
|
||||
change_des = HTMLField(blank=True, null=True, verbose_name="更改内容描述")
|
||||
effect_cases = models.JSONField(default=create_list, verbose_name="影响的用例key数组")
|
||||
|
||||
class Meta:
|
||||
db_table = 'influence_item'
|
||||
verbose_name = "影响域分析 - 行数据"
|
||||
verbose_name_plural = verbose_name
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -62,3 +62,10 @@ class StaticDynamicData(Schema):
|
||||
category: str
|
||||
table: list[list[str]]
|
||||
fontnote: Optional[str] = ""
|
||||
|
||||
# ~~~环境差异性分析~~~
|
||||
class EnvAnalysisSchema(Schema):
|
||||
id: int
|
||||
table: list[list[str]]
|
||||
fontnote: Optional[str] = ""
|
||||
description: Optional[str] = ""
|
||||
@@ -1,7 +1,7 @@
|
||||
from typing import Optional
|
||||
from ninja import Schema, ModelSchema
|
||||
from pydantic import Field
|
||||
from apps.project.models import Round
|
||||
from apps.project.models import Round, InfluenceItem
|
||||
|
||||
# 输出树状信息的schema
|
||||
class TreeReturnRound(Schema):
|
||||
@@ -55,3 +55,21 @@ class CreateRoundInputSchema(ModelSchema):
|
||||
fields_optional = ['best_condition_tem', 'best_condition_voltage',
|
||||
'low_condition_tem', 'low_condition_voltage', 'typical_condition_tem',
|
||||
'typical_condition_voltage' 'grade']
|
||||
|
||||
# influence_item return
|
||||
class InfluenceItemOutSchema(ModelSchema):
|
||||
class Meta:
|
||||
model = InfluenceItem
|
||||
fields = ['id', 'change_type', 'change_des', 'effect_cases', 'change_influ']
|
||||
|
||||
# influence input
|
||||
class OneItemInputSchema(Schema):
|
||||
change_type: str
|
||||
change_des: Optional[str] = ""
|
||||
effect_cases: Optional[list[str]] = []
|
||||
change_influ: Optional[str] = ""
|
||||
|
||||
class InfluenceInputSchema(Schema):
|
||||
id: int
|
||||
round_key: str
|
||||
item_list: list[OneItemInputSchema]
|
||||
|
||||
Reference in New Issue
Block a user