diff --git a/apps/createDocument/controllers/__pycache__/bg.cpython-313.pyc b/apps/createDocument/controllers/__pycache__/bg.cpython-313.pyc index d846df0..1568b2d 100644 Binary files a/apps/createDocument/controllers/__pycache__/bg.cpython-313.pyc and b/apps/createDocument/controllers/__pycache__/bg.cpython-313.pyc differ diff --git a/apps/createDocument/controllers/__pycache__/dg.cpython-313.pyc b/apps/createDocument/controllers/__pycache__/dg.cpython-313.pyc index cb7c1d1..37ecbd9 100644 Binary files a/apps/createDocument/controllers/__pycache__/dg.cpython-313.pyc and b/apps/createDocument/controllers/__pycache__/dg.cpython-313.pyc differ diff --git a/apps/createDocument/controllers/__pycache__/hjl.cpython-313.pyc b/apps/createDocument/controllers/__pycache__/hjl.cpython-313.pyc index 5c8b2b7..eedbf18 100644 Binary files a/apps/createDocument/controllers/__pycache__/hjl.cpython-313.pyc and b/apps/createDocument/controllers/__pycache__/hjl.cpython-313.pyc differ diff --git a/apps/createDocument/controllers/__pycache__/hsm.cpython-313.pyc b/apps/createDocument/controllers/__pycache__/hsm.cpython-313.pyc index 83fb0b0..b671034 100644 Binary files a/apps/createDocument/controllers/__pycache__/hsm.cpython-313.pyc and b/apps/createDocument/controllers/__pycache__/hsm.cpython-313.pyc differ diff --git a/apps/createDocument/controllers/__pycache__/jl.cpython-313.pyc b/apps/createDocument/controllers/__pycache__/jl.cpython-313.pyc index 8b7e906..7befcc7 100644 Binary files a/apps/createDocument/controllers/__pycache__/jl.cpython-313.pyc and b/apps/createDocument/controllers/__pycache__/jl.cpython-313.pyc differ diff --git a/apps/createDocument/controllers/__pycache__/sm.cpython-313.pyc b/apps/createDocument/controllers/__pycache__/sm.cpython-313.pyc index 3f6987f..e308959 100644 Binary files a/apps/createDocument/controllers/__pycache__/sm.cpython-313.pyc and b/apps/createDocument/controllers/__pycache__/sm.cpython-313.pyc differ diff --git a/apps/createDocument/controllers/__pycache__/wtd.cpython-313.pyc b/apps/createDocument/controllers/__pycache__/wtd.cpython-313.pyc index bb6436a..96b6c84 100644 Binary files a/apps/createDocument/controllers/__pycache__/wtd.cpython-313.pyc and b/apps/createDocument/controllers/__pycache__/wtd.cpython-313.pyc differ diff --git a/apps/createDocument/controllers/bg.py b/apps/createDocument/controllers/bg.py index 00972b0..f5cc1bc 100644 --- a/apps/createDocument/controllers/bg.py +++ b/apps/createDocument/controllers/bg.py @@ -357,7 +357,7 @@ class GenerateControllerBG(ControllerBase): context = create_round_context(project_obj, round_str) template_path = Path.cwd() / 'media' / project_path_str / 'form_template' / 'bg' / '测试内容和结果_第二轮次.docx' doc = DocxTemplate(template_path) - doc.render(context) + doc.render(context, autoescape=True) try: doc.save( Path.cwd() / "media" / project_path_str / "output_dir/bg" / f"测试内容和结果_第{context['round_id']}轮次.docx") @@ -629,7 +629,7 @@ class GenerateControllerBG(ControllerBase): temporary_file = Path.cwd() / 'media' / project_path_str / 'form_template' / 'bg' / 'temporary' / '研总需归追踪_temp.docx' out_put_file = Path.cwd() / 'media' / project_path_str / 'output_dir' / 'bg' / '研总需归追踪.docx' doc = DocxTemplate(input_file) - doc.render(context) + doc.render(context, autoescape=True) doc.save(temporary_file) # 通过docx合并单元格 if temporary_file.is_file(): @@ -686,7 +686,7 @@ class GenerateControllerBG(ControllerBase): 'data_list': data_list } - doc.render(context) + doc.render(context, autoescape=True) try: doc.save(Path.cwd() / "media" / project_path(id) / "output_dir/bg" / "问题汇总表.docx") return ChenResponse(status=200, code=200, message="文档生成成功!") @@ -724,7 +724,7 @@ class GenerateControllerBG(ControllerBase): context = { 'modi_list': modi_list, } - doc.render(context) + doc.render(context, autoescape=True) try: doc.save(Path.cwd() / "media" / project_path(id) / "output_dir/bg" / "摸底清单.docx") return ChenResponse(status=200, code=200, message="文档生成成功!") diff --git a/apps/createDocument/controllers/dg.py b/apps/createDocument/controllers/dg.py index 895e040..ec10cd5 100644 --- a/apps/createDocument/controllers/dg.py +++ b/apps/createDocument/controllers/dg.py @@ -1,3 +1,4 @@ +from datetime import datetime from ninja.errors import HttpError from ninja_extra import ControllerBase, api_controller, route from ninja_extra.permissions import IsAuthenticated @@ -34,7 +35,8 @@ class GenerateControllerDG(ControllerBase, FragementToolsMixin): @transaction.atomic def create_testdemand(self, id: int): # type:ignore """目前生成第一轮测试项""" - tplTestDemandGenerate_path = Path.cwd() / "media" / project_path(id) / "form_template" / "dg" / "测试项及方法.docx" + tplTestDemandGenerate_path = Path.cwd() / "media" / project_path( + id) / "form_template" / "dg" / "测试项及方法.docx" doc = DocxTemplate(tplTestDemandGenerate_path) # 获取指定的项目对象 project_qs = get_object_or_404(Project, id=id) @@ -57,6 +59,7 @@ class GenerateControllerDG(ControllerBase, FragementToolsMixin): "index": index + 1, "rindex": str(index + 1).rjust(2, '0'), "subName": content.subName, + "subDescription": content.subDescription, # 修改遍历content下面的step,content变量是TestDemandContent表 "subStep": [ {'index': index + 1, 'operation': step_obj.operation, 'expect': step_obj.expect} @@ -78,7 +81,6 @@ class GenerateControllerDG(ControllerBase, FragementToolsMixin): # ***Inspect-end*** html_parser = RichParser(single_qs.design.description) desc_list = html_parser.get_final_list(doc) - # 查询关联design以及普通design doc_list = [{'dut_name': single_qs.dut.name, 'design_chapter': single_qs.design.chapter, 'design_name': single_qs.design.name}] @@ -88,6 +90,7 @@ class GenerateControllerDG(ControllerBase, FragementToolsMixin): doc_list.append(ddict) # 组装单个测试项 + ## 打印本项目是FPGA还是CPU testdemand_dict = { "name": single_qs.name, "key": single_qs.key, @@ -96,16 +99,13 @@ class GenerateControllerDG(ControllerBase, FragementToolsMixin): "doc_list": doc_list, "design_description": desc_list, "test_demand_content": content_list, - "testMethod": testmethod_str, + "testMethod": testmethod_str.strip(), "adequacy": single_qs.adequacy.replace("\n", "\a"), - "testDesciption": single_qs.testDesciption.replace("\n", "\a") # 测试项描述 + "testDesciption": single_qs.testDesciption.replace("\n", "\a"), # 测试项描述 + "testType": get_testType(single_qs.testType, 'testType'), } list_list[type_index].append(testdemand_dict) - # 定义渲染context字典 - context = { - "project_name": project_qs.name - } output_list = [] for (index, li) in enumerate(list_list): @@ -122,8 +122,15 @@ class GenerateControllerDG(ControllerBase, FragementToolsMixin): # 排序1:测试类型排序 output_list = sorted(output_list, key=(lambda x: x["sort"])) - context["data"] = output_list - doc.render(context) + # 定义渲染context字典 + context = { + "project_name": project_qs.name, + "is_JD": True if project_qs.report_type == '9' else False, + "data": output_list, + "isFPGA": '1' in project_qs.plant_type + } + + doc.render(context, autoescape=True) try: doc.save(Path.cwd() / "media" / project_path(id) / "output_dir" / "测试项及方法.docx") return ChenResponse(status=200, code=200, message="文档生成成功!") @@ -148,7 +155,8 @@ class GenerateControllerDG(ControllerBase, FragementToolsMixin): # 找出所属项目 project_qs = get_object_or_404(Project, id=id) # 根据项目找出被测件-只找第一轮次 - duties_qs = project_qs.pdField.filter(Q(type='XQ') | Q(type='SJ') | Q(type='XY') | Q(type='YZ')).filter( + duties_qs = project_qs.pdField.filter( + Q(type='XQ') | Q(type='SJ') | Q(type='XY') | Q(type='YZ')).filter( round__key='0') # 先定义个字典 std_documents = [] @@ -169,7 +177,8 @@ class GenerateControllerDG(ControllerBase, FragementToolsMixin): # 先找出所属项目 project_qs = get_object_or_404(Project, id=id) contact_dict = model_to_dict(project_qs, - fields=['entrust_unit', 'entrust_contact', 'entrust_contact_phone', 'dev_unit', + fields=['entrust_unit', 'entrust_contact', 'entrust_contact_phone', + 'dev_unit', 'dev_contact', 'dev_contact_phone', 'test_unit', 'test_contact', 'test_contact_phone']) # 根据entrust_unit、dev_unit、test_unit查找Contact中地址信息 @@ -190,8 +199,18 @@ class GenerateControllerDG(ControllerBase, FragementToolsMixin): def create_timeaddress(self, id: int): doc_timer = DocTime(id) context = doc_timer.dg_address_time() + context = self.change_time_to_another(context, ['beginTime_strf', 'dgCompileStart', 'dgCompileEnd', + 'designStart', 'designEnd']) return create_dg_docx('测评时间和地点.docx', context, id) + # 2025/12/11:将20250417格式改为2025年04月17日 - 封装函数,传入字典和键值,修改对应键值信息 + def change_time_to_another(self, context: dict, key_list: list[str]): + for key in key_list: + time_val = context.get(key, None) + if time_val: + context[key] = datetime.strptime(time_val, "%Y%m%d").strftime("%Y年%m月%d日") + return context + # 生成【主要功能和性能指标】文档片段 @route.get('/create/indicators', url_name='create-indicators') @transaction.atomic @@ -255,7 +274,7 @@ class GenerateControllerDG(ControllerBase, FragementToolsMixin): 'md_demand_list': md_demand_list, 'is_has_modi': is_has_modi } - doc.render(context) + doc.render(context, autoescape=True) try: doc.save(Path.cwd() / "media" / project_path(id) / "output_dir" / '主要功能和性能指标.docx') return ChenResponse(status=200, code=200, message="文档生成成功!") @@ -273,7 +292,7 @@ class GenerateControllerDG(ControllerBase, FragementToolsMixin): "replace": replace, # 指定是否由数据库文档片段进行生成 "user_content": frag and rich_text_list } - doc.render(context) + doc.render(context, autoescape=True) try: doc.save(Path.cwd() / "media" / project_path(id) / "output_dir" / '测评对象.docx') return ChenResponse(status=200, code=200, message="文档生成成功!") @@ -344,7 +363,7 @@ class GenerateControllerDG(ControllerBase, FragementToolsMixin): "replace": replace, # 指定是否由数据库文档片段进行生成 "user_content": frag and rich_text_list } - doc.render(context) + doc.render(context, autoescape=True) try: doc.save(Path.cwd() / "media" / project_path(id) / "output_dir" / '静态测试环境说明.docx') return ChenResponse(status=200, code=200, message="文档生成成功!") @@ -378,14 +397,16 @@ class GenerateControllerDG(ControllerBase, FragementToolsMixin): # 动态测评环境说明 @route.get('/create/dynamic_env', url_name='create-dynamic_env') def create_dynamic_env(self, id: int): + project_obj: Project = get_object_or_404(Project, id=id) input_path = Path.cwd() / 'media' / project_path(id) / 'form_template' / 'dg' / '动态测试环境说明.docx' doc = DocxTemplate(input_path) replace, frag, rich_text_list = self._generate_frag(id, doc, '动态测试环境说明') context = { + 'project_name': project_obj.name, "replace": replace, "user_content": frag and rich_text_list } - doc.render(context) + doc.render(context, autoescape=True) try: doc.save(Path.cwd() / "media" / project_path(id) / "output_dir" / '动态测试环境说明.docx') return ChenResponse(status=200, code=200, message="文档生成成功!") @@ -395,10 +416,12 @@ class GenerateControllerDG(ControllerBase, FragementToolsMixin): # 动态软件项 @route.get('/create/dynamic_soft', url_name='create-dynamic_soft') def create_dynamic_soft(self, id: int): + project_obj: Project = get_object_or_404(Project, id=id) input_path = Path.cwd() / 'media' / project_path(id) / 'form_template' / 'dg' / '动态软件项.docx' doc = DocxTemplate(input_path) replace, frag, rich_text_list = self._generate_frag(id, doc, '动态软件项') context = { + 'project_name': project_obj.name, "replace": replace, "user_content": frag and rich_text_list } @@ -462,6 +485,7 @@ class GenerateControllerDG(ControllerBase, FragementToolsMixin): # 渲染上下文 context = { 'project_name': project_qs.name, + 'is_JD': True if project_qs.report_type == '9' else False, 'security_level': security, 'language': "\a".join(language_list), 'version': version, @@ -492,7 +516,8 @@ class GenerateControllerDG(ControllerBase, FragementToolsMixin): # 获取所有已录入测试类型 test_types = project_qs.ptField.values("testType").distinct() # 通过测试类型查询字典中的中文 - type_name_list = list(map(lambda qs_item: get_str_dict(qs_item['testType'], 'testType'), test_types)) + type_name_list = list( + map(lambda qs_item: get_str_dict(qs_item['testType'], 'testType'), test_types)) # 定义测试类型一览的顺序,注意word里面也要一样 word_types = ['文档审查', '静态分析', '代码审查', '逻辑测试', '功能测试', '性能测试', '边界测试', '恢复性测试', '安装性测试', '数据处理测试', '余量测试', '强度测试', '接口测试', @@ -503,6 +528,7 @@ class GenerateControllerDG(ControllerBase, FragementToolsMixin): if exist_type == test_type: type_index.append(str(index)) context = { + "security_level": get_str_dict(project_qs.security_level, 'security_level'), "testTypes": "、".join(type_name_list), "project_name": project_qs.name, "type_index": type_index @@ -526,15 +552,24 @@ class GenerateControllerDG(ControllerBase, FragementToolsMixin): # 根据关键等级检查是否有代码审查 security = project_qs.security_level isDmsc = True if int(security) <= 2 else False + # 获取第一轮所有测试项QuerySet + project_round_one = project_qs.pField.filter(key=0).first() + testDemand_qs = project_round_one.rtField.all() + # grouped_data的键是测试类型名称,值为测试项名称数组 + grouped_data = {} + for item in testDemand_qs: + grouped_data.setdefault(get_str_dict(item.testType, 'testType'), []).append(item.name) # 获取当前测试项的测试类型 - test_types = project_qs.ptField.values("testType").distinct() - type_name_list = list(map(lambda qs_item: get_str_dict(qs_item['testType'], 'testType'), test_types)) + test_types = testDemand_qs.values("testType").distinct() + type_name_list = list( + map(lambda qs_item: get_str_dict(qs_item['testType'], 'testType'), test_types)) context = { "project_name": project_qs.name, # 查询关键等级-类似“关键”输出 "security_level_str": get_str_abbr(security, 'security_level'), "isDmsc": isDmsc, - "test_types": type_name_list + "test_types": type_name_list, + "grouped_data": grouped_data, } return create_dg_docx("测试策略.docx", context, id) @@ -563,6 +598,7 @@ class GenerateControllerDG(ControllerBase, FragementToolsMixin): type_str_list.append(f"{key}{value}项") context = { 'project_name': project_qs.name, + 'test_item_count': testDemands.count(), 'length': length, 'type_str': "、".join(type_str_list), } @@ -614,30 +650,39 @@ class GenerateControllerDG(ControllerBase, FragementToolsMixin): # 形成一个数组['1','2','3','4','9']后面用来判断测试项的章节号 project_qs = get_object_or_404(Project, id=id) design_list = [] # 先按照design的思路进行追踪 - # 判断是否为鉴定测评,有则生成该表 - if project_qs.report_type == '9': - project_round_one = project_qs.pField.filter(key=0).first() - testType_list, last_chapter_items = create_csx_chapter_dict(project_round_one) - # 找出第一轮的研总 - yz_dut = project_round_one.rdField.filter(type='YZ').first() - if yz_dut: - # 查询出验证所有design - yz_designs = yz_dut.rsField.all() - # 遍历所有研总的design - for design in yz_designs: - design_dict = {'name': design.name, 'chapter': design.chapter, 'test_demand': []} - # 获取一个design的所有测试项 - test_items = design.dtField.all() - for test_item in test_items: - reveal_ident = "_".join( - ["XQ", get_testType(test_item.testType, "testType"), test_item.ident]) - # 查字典方式确认章节号最后一位 - test_item_last_chapter = last_chapter_items[test_item.testType].index(test_item.key) + 1 - test_chapter = ".".join([test_item_prefix, str(testType_list.index(test_item.testType) + 1), - str(test_item_last_chapter)]) - test_item_dict = {'name': test_item.name, 'chapter': test_chapter, 'ident': reveal_ident} - design_dict['test_demand'].append(test_item_dict) - design_list.append(design_dict) + # 查询第一轮次 + project_round_one = project_qs.pField.filter(key=0).first() + testType_list, last_chapter_items = create_csx_chapter_dict(project_round_one) + # 找出第一轮的研总 + yz_dut = project_round_one.rdField.filter(type='YZ').first() + if yz_dut: + # 查询出验证所有design + yz_designs = yz_dut.rsField.all() + # 遍历所有研总的design + for design in yz_designs: + design_dict = {'name': design.name, 'chapter': design.chapter, 'test_demand': []} + # 获取一个design的所有测试项 + test_items = design.dtField.all() + # 连接两个QuerySet,默认去重 + test_items = test_items.union(design.odField.all()) + print('ok:', test_items) + for test_item in test_items: + reveal_ident = "_".join( + ["XQ", get_testType(test_item.testType, "testType"), test_item.ident]) + # 查字典方式确认章节号最后一位 + test_item_last_chapter = last_chapter_items[test_item.testType].index( + test_item.key) + 1 + test_chapter = ".".join( + [test_item_prefix, str(testType_list.index(test_item.testType) + 1), + str(test_item_last_chapter)]) + test_item_dict = {'name': test_item.name, 'chapter': test_chapter, + 'ident': reveal_ident} + design_dict['test_demand'].append(test_item_dict) + design_list.append(design_dict) + try: + design_list = sorted(design_list, key=chapter_key) + except Exception as e: + print("研总的追踪排序报错,错误原因:", e) context = { 'design_list': design_list } @@ -671,10 +716,13 @@ class GenerateControllerDG(ControllerBase, FragementToolsMixin): reveal_ident = "_".join( ["XQ", get_testType(test_item.testType, "testType"), test_item.ident]) # 查字典方式确认章节号最后一位 - test_item_last_chapter = last_chapter_items[test_item.testType].index(test_item.key) + 1 - test_chapter = ".".join([test_item_prefix, str(testType_list.index(test_item.testType) + 1), - str(test_item_last_chapter)]) - test_item_dict = {'name': test_item.name, 'chapter': test_chapter, 'ident': reveal_ident} + test_item_last_chapter = last_chapter_items[test_item.testType].index( + test_item.key) + 1 + test_chapter = ".".join( + [test_item_prefix, str(testType_list.index(test_item.testType) + 1), + str(test_item_last_chapter)]) + test_item_dict = {'name': test_item.name, 'chapter': test_chapter, + 'ident': reveal_ident} design_dict['test_demand'].append(test_item_dict) design_list.append(design_dict) @@ -691,13 +739,21 @@ class GenerateControllerDG(ControllerBase, FragementToolsMixin): reveal_ident = "_".join( ["XQ", get_testType(test_item.testType, "testType"), test_item.ident]) # 查字典方式确认章节号最后一位 - test_item_last_chapter = last_chapter_items[test_item.testType].index(test_item.key) + 1 - test_chapter = ".".join([test_item_prefix, str(testType_list.index(test_item.testType) + 1), - str(test_item_last_chapter)]) - test_item_dict = {'name': test_item.name, 'chapter': test_chapter, 'ident': reveal_ident} + test_item_last_chapter = last_chapter_items[test_item.testType].index( + test_item.key) + 1 + test_chapter = ".".join( + [test_item_prefix, str(testType_list.index(test_item.testType) + 1), + str(test_item_last_chapter)]) + test_item_dict = {'name': test_item.name, 'chapter': test_chapter, + 'ident': reveal_ident} design_dict['test_demand'].append(test_item_dict) design_list.append(design_dict) + # 根据design的chapter排序-为防止报错崩溃使用try-但难排查 + try: + design_list = sorted(design_list, key=chapter_key) + except Exception as e: + print("追踪排序报错,错误原因:", e) context = { 'design_list': design_list } @@ -719,8 +775,9 @@ class GenerateControllerDG(ControllerBase, FragementToolsMixin): items_list = [] for test_item in test_items: # 第二个处理被测件为"XQ",第二个处理被测件为'SO',并且为测试项testType为['8', '15', '3', '2']的 - if test_item.dut.type == 'XQ' or (test_item.dut.type == 'SO' and test_item.testType in ['8', '15', '3', - '2']): + if test_item.dut.type == 'XQ' or ( + test_item.dut.type == 'SO' and test_item.testType in ['8', '15', '3', + '2']): reveal_ident = "_".join( ["XQ", get_testType(test_item.testType, "testType"), test_item.ident]) # 查字典方式确认章节号最后一位 @@ -782,3 +839,13 @@ class GenerateControllerDG(ControllerBase, FragementToolsMixin): else: return ChenResponse(message='未找到源代码被测件', code=400) return create_dg_docx('代码质量度量分析表.docx', context, id) + +# 工具方法-给sorted排序使用-知识点:python里面可以元组排序 +def chapter_key(item): + big_num = [5000, 5000, 5000, 5000] + if "." in item['chapter']: + # 如果是有章节号的则排序 + return [int(part) for part in item['chapter'].split(".")] + if item['test_demand'][0]['name'] in ['文档审查', '静态分析', '代码审查', '代码走查']: + return [0, 0, 0, 0] + return big_num diff --git a/apps/createDocument/controllers/hjl.py b/apps/createDocument/controllers/hjl.py index 5b12821..bc13be6 100644 --- a/apps/createDocument/controllers/hjl.py +++ b/apps/createDocument/controllers/hjl.py @@ -87,7 +87,7 @@ class GenerateControllerHJL(ControllerBase): context_round['version_info'] = version_info # 开始渲染每个轮次的二级文档 save_path = Path.cwd() / 'media' / project_path_str / 'output_dir/hjl' / f"第{cname}轮被测软件基本信息.docx" - doc.render(context=context_round) + doc.render(context=context_round, autoescape=True) try: doc.save(save_path) except PermissionError: @@ -204,7 +204,7 @@ class GenerateControllerHJL(ControllerBase): context["data"] = output_list # 最后渲染 save_path = Path.cwd() / 'media' / project_path_str / 'output_dir/hjl' / f"第{cname}轮测试用例记录.docx" - doc.render(context) + doc.render(context, autoescape=True) try: doc.save(save_path) except PermissionError: diff --git a/apps/createDocument/controllers/hsm.py b/apps/createDocument/controllers/hsm.py index 9592163..23f56b7 100644 --- a/apps/createDocument/controllers/hsm.py +++ b/apps/createDocument/controllers/hsm.py @@ -103,7 +103,7 @@ class GenerateControllerHSM(ControllerBase): context_round['version_info'] = version_info # 开始渲染每个轮次的二级文档 save_path = Path.cwd() / 'media' / project_path_str / 'output_dir/hsm' / f"第{cname}轮被测软件基本信息.docx" - doc.render(context=context_round) + doc.render(context=context_round, autoescape=True) try: doc.save(save_path) except PermissionError: @@ -141,7 +141,7 @@ class GenerateControllerHSM(ControllerBase): round_context['last_version'] = so_dut_last.version round_context['round_chinese'] = cname save_path = Path.cwd() / 'media' / project_path_str / 'output_dir/hsm' / f"第{cname}轮文档概述.docx" - doc.render(context=round_context) + doc.render(context=round_context, autoescape=True) try: doc.save(save_path) except PermissionError: @@ -171,9 +171,11 @@ class GenerateControllerHSM(ControllerBase): 'publish_date': timer.dg_cover_time, 'source': project_obj.test_unit} std_documents.append(dg_duty) # 需要添加说明、记录 - sm_duty = {'doc_name': f'{project_obj.name}软件测试说明', 'ident_version': f'PT-{project_obj.ident}-TD-1.00', + sm_duty = {'doc_name': f'{project_obj.name}软件测试说明', + 'ident_version': f'PT-{project_obj.ident}-TD-1.00', 'publish_date': timer.sm_cover_time, 'source': project_obj.test_unit} - jl_duty = {'doc_name': f'{project_obj.name}软件测试记录', 'ident_version': f'PT-{project_obj.ident}-TN', + jl_duty = {'doc_name': f'{project_obj.name}软件测试记录', + 'ident_version': f'PT-{project_obj.ident}-TN', 'publish_date': timer.jl_cover_time, 'source': project_obj.test_unit} std_documents.extend([sm_duty, jl_duty]) @@ -196,7 +198,7 @@ class GenerateControllerHSM(ControllerBase): 'std_documents': std_documents_round } save_path = Path.cwd() / 'media' / project_path_str / 'output_dir/hsm' / f"第{cname}轮技术依据文件.docx" - doc.render(context=context) + doc.render(context=context, autoescape=True) try: doc.save(save_path) except PermissionError: @@ -254,7 +256,7 @@ class GenerateControllerHSM(ControllerBase): context_round['so_str'] = f"被测软件代码{now_dm_version}版本和{last_dm_version}版本" save_path = Path.cwd() / 'media' / project_path_str / 'output_dir/hsm' / f"第{cname}轮软件更改部分.docx" - doc.render(context_round) + doc.render(context_round, autoescape=True) try: doc.save(save_path) except PermissionError: @@ -346,7 +348,7 @@ class GenerateControllerHSM(ControllerBase): output_list = sorted(output_list, key=(lambda x: x["sort"])) context["data"] = output_list save_path = Path.cwd() / 'media' / project_path_str / 'output_dir/hsm' / f"第{cname}轮回归测试需求.docx" - doc.render(context) + doc.render(context, autoescape=True) try: doc.save(save_path) except PermissionError: @@ -403,7 +405,7 @@ class GenerateControllerHSM(ControllerBase): output_list = sorted(output_list, key=(lambda x: x["sort"])) context["data"] = output_list save_path = Path.cwd() / 'media' / project_path_str / 'output_dir/hsm' / f"第{cname}轮回归测试用例概述.docx" - doc.render(context=context) + doc.render(context=context, autoescape=True) try: doc.save(save_path) except PermissionError: @@ -494,7 +496,7 @@ class GenerateControllerHSM(ControllerBase): context["data"] = output_list context["round_han"] = cname save_path = Path.cwd() / 'media' / project_path_str / 'output_dir/hsm' / f"第{cname}轮测试用例.docx" - doc.render(context=context) + doc.render(context=context, autoescape=True) try: doc.save(save_path) except PermissionError: @@ -585,7 +587,7 @@ class GenerateControllerHSM(ControllerBase): temporary_file = Path.cwd() / 'media' / project_path_str / 'form_template' / 'hsm' / 'temporary' / f'第{cname}轮用例追踪_temp.docx' out_put_file = Path.cwd() / 'media' / project_path_str / 'output_dir' / 'hsm' / f'第{cname}轮用例追踪.docx' doc = DocxTemplate(input_file) - doc.render(context) + doc.render(context, autoescape=True) doc.save(temporary_file) # 通过docx合并单元格 if temporary_file.is_file(): diff --git a/apps/createDocument/controllers/jl.py b/apps/createDocument/controllers/jl.py index c1c1da0..69d2c00 100644 --- a/apps/createDocument/controllers/jl.py +++ b/apps/createDocument/controllers/jl.py @@ -146,7 +146,7 @@ class GenerateControllerJL(ControllerBase): output_list = sorted(output_list, key=(lambda x: x["sort"])) context["data"] = output_list - doc.render(context) + doc.render(context, autoescape=True) try: doc.save(Path.cwd() / "media" / project_path_str / "output_dir/jl" / "测试用例记录.docx") return ChenResponse(status=200, code=200, message="文档生成成功!") diff --git a/apps/createDocument/controllers/sm.py b/apps/createDocument/controllers/sm.py index 7d92336..72e4b7c 100644 --- a/apps/createDocument/controllers/sm.py +++ b/apps/createDocument/controllers/sm.py @@ -135,7 +135,7 @@ class GenerateControllerSM(ControllerBase): # 排序 output_list = sorted(output_list, key=(lambda x: x["sort"])) context["data"] = output_list - doc.render(context) + doc.render(context, autoescape=True) try: doc.save(Path.cwd() / "media" / project_path_str / "output_dir/sm" / "测试用例.docx") return ChenResponse(status=200, code=200, message="文档生成成功!") @@ -265,7 +265,7 @@ class GenerateControllerSM(ControllerBase): temporary_file = Path.cwd() / 'media' / project_path_str / 'form_template' / 'sm' / 'temporary' / '说明追踪_temp.docx' out_put_file = Path.cwd() / 'media' / project_path_str / 'output_dir' / 'sm' / '说明追踪.docx' doc = DocxTemplate(input_file) - doc.render(context) + doc.render(context, autoescape=True) doc.save(temporary_file) # 通过docx合并单元格 if temporary_file.is_file(): diff --git a/apps/createDocument/controllers/wtd.py b/apps/createDocument/controllers/wtd.py index 3fa9ee7..4958fe1 100644 --- a/apps/createDocument/controllers/wtd.py +++ b/apps/createDocument/controllers/wtd.py @@ -147,7 +147,7 @@ class GenerateControllerWtd(ControllerBase): 'project_ident': project_obj.ident, 'problem_list': data_list, } - doc.render(context) + doc.render(context, autoescape=True) try: doc.save(Path.cwd() / "media" / project_path_str / "output_dir/wtd" / '问题详情表.docx') return ChenResponse(status=200, code=200, message="文档生成成功!") diff --git a/apps/createDocument/extensions/__pycache__/parse_rich_text.cpython-313.pyc b/apps/createDocument/extensions/__pycache__/parse_rich_text.cpython-313.pyc index b0bedd2..3deaf57 100644 Binary files a/apps/createDocument/extensions/__pycache__/parse_rich_text.cpython-313.pyc and b/apps/createDocument/extensions/__pycache__/parse_rich_text.cpython-313.pyc differ diff --git a/apps/createDocument/extensions/__pycache__/util.cpython-313.pyc b/apps/createDocument/extensions/__pycache__/util.cpython-313.pyc index 1c65620..36da3a5 100644 Binary files a/apps/createDocument/extensions/__pycache__/util.cpython-313.pyc and b/apps/createDocument/extensions/__pycache__/util.cpython-313.pyc differ diff --git a/apps/createDocument/extensions/parse_rich_text.py b/apps/createDocument/extensions/parse_rich_text.py index 674b1ae..a97bc1d 100644 --- a/apps/createDocument/extensions/parse_rich_text.py +++ b/apps/createDocument/extensions/parse_rich_text.py @@ -85,11 +85,15 @@ class RichParser: if oneline.startswith("data:image/png;base64"): base64_bytes = base64.b64decode(oneline.replace("data:image/png;base64,", "")) # ~~~设置了固定宽度、高度~~~ - final_list.append(InlineImage(doc, io.BytesIO(base64_bytes), width=Mm(img_size), height=Mm(height))) + final_list.append( + InlineImage(doc, io.BytesIO(base64_bytes), width=Mm(img_size), height=Mm(height))) else: final_list.append(oneline) if len(final_list) <= 0: final_list.append("") + # 针对tinymce中,粘贴表格最后一行显示句号问题,这里统一删除 + if final_list[-1] == '\xa0': + final_list.pop() return final_list # 4.2.最终方法,在上面方法基础上,增加格式,例如
增加缩进,图片居中,
包含“图x”则居中 diff --git a/apps/createDocument/extensions/util.py b/apps/createDocument/extensions/util.py index 1eb06f8..b11590a 100644 --- a/apps/createDocument/extensions/util.py +++ b/apps/createDocument/extensions/util.py @@ -18,7 +18,7 @@ def merge_all_cell(table: Table) -> None: temp_text = cell.text else: if cell.text == temp_text: - if cell.text == '': # 不知道什么原因必须这样判断下 + if cell.text == '': # 不知道什么原因必须这样判断下 cell.text = '/' text_temp = cell.text ce = cell.merge(col_right.cells[index - 1]) @@ -31,7 +31,7 @@ def create_sm_docx(template_name: str, context: dict, id: int) -> ChenResponse: """生成最终说明文档工具函数""" input_path = Path.cwd() / 'media' / project_path(id) / 'form_template' / 'sm' / template_name doc = DocxTemplate(input_path) - doc.render(context) + doc.render(context, autoescape=True) try: doc.save(Path.cwd() / "media" / project_path(id) / "output_dir/sm" / template_name) return ChenResponse(status=200, code=200, message="文档生成成功!") @@ -42,7 +42,7 @@ def create_dg_docx(template_name: str, context: dict, id: int) -> ChenResponse: """生成最终大纲文档工具函数""" input_path = Path.cwd() / 'media' / project_path(id) / 'form_template' / 'dg' / template_name doc = DocxTemplate(input_path) - doc.render(context) + doc.render(context, autoescape=True) try: doc.save(Path.cwd() / "media" / project_path(id) / "output_dir" / template_name) return ChenResponse(status=200, code=200, message="文档生成成功!") @@ -53,7 +53,7 @@ def create_bg_docx(template_name: str, context: dict, id: int) -> ChenResponse: """生成最终报告文档工具函数""" input_path = Path.cwd() / 'media' / project_path(id) / 'form_template' / 'bg' / template_name doc = DocxTemplate(input_path) - doc.render(context) + doc.render(context, autoescape=True) try: doc.save(Path.cwd() / "media" / project_path(id) / "output_dir/bg" / template_name) return ChenResponse(status=200, code=200, message="文档生成成功!") @@ -64,7 +64,7 @@ def create_wtd_docx(template_name: str, context: dict, id: int) -> ChenResponse: """生成最终问题单文档工具函数""" input_path = Path.cwd() / 'media' / project_path(id) / 'form_template' / 'wtd' / template_name doc = DocxTemplate(input_path) - doc.render(context) + doc.render(context, autoescape=True) try: doc.save(Path.cwd() / "media" / project_path(id) / "output_dir/wtd" / template_name) return ChenResponse(status=200, code=200, message="文档生成成功!") diff --git a/apps/createSeiTaiDocument/__pycache__/controllers.cpython-313.pyc b/apps/createSeiTaiDocument/__pycache__/controllers.cpython-313.pyc index b4fcda4..2bec58b 100644 Binary files a/apps/createSeiTaiDocument/__pycache__/controllers.cpython-313.pyc and b/apps/createSeiTaiDocument/__pycache__/controllers.cpython-313.pyc differ diff --git a/apps/createSeiTaiDocument/controllers.py b/apps/createSeiTaiDocument/controllers.py index 5ca4492..a6a7034 100644 --- a/apps/createSeiTaiDocument/controllers.py +++ b/apps/createSeiTaiDocument/controllers.py @@ -52,7 +52,7 @@ class GenerateSeitaiController(ControllerBase): 'project_ident': self.project_obj.ident, 'project_name': self.project_obj.name, 'test_purpose': "装备鉴定和列装定型" if is_jd else "软件交付和使用", - 'sec_title': sec_title, + 'sec_title': '密级:' + sec_title, 'sec': sec_title, 'duty_person': duty_person, 'member': self.project_obj.member[0] if len( @@ -64,7 +64,8 @@ class GenerateSeitaiController(ControllerBase): self.get_xq_doc_informations() result = generate_temp_doc('dg', payload.id, frag_list=payload.frag) if isinstance(result, dict): - return ChenResponse(status=400, code=400, message=result.get('msg', 'dg未报出错误原因,反正在生成文档出错')) + return ChenResponse(status=400, code=400, + message=result.get('msg', 'dg未报出错误原因,反正在生成文档出错')) dg_replace_path, dg_seitai_final_path = result # ~~~~start:2025/04/19-新增渲染单个字段(可能封装为函数-对temp文件下的jinja字段处理)~~~~ # 现在已经把alias和stdContent对应起来了 @@ -122,7 +123,8 @@ class GenerateSeitaiController(ControllerBase): self.project_obj = get_object_or_404(Project, id=payload.id) # seitai文档所需变量 is_jd = True if self.project_obj.report_type == '9' else False - member = self.project_obj.member[0] if len(self.project_obj.member) > 0 else self.project_obj.duty_person + member = self.project_obj.member[0] if len( + self.project_obj.member) > 0 else self.project_obj.duty_person self.temp_context = { 'project_name': self.project_obj.name, 'project_ident': self.project_obj.ident, @@ -164,7 +166,8 @@ class GenerateSeitaiController(ControllerBase): # 将cname存入一个list,以便后续拼接给下载函数 cname_list.append(cname) is_jd = True if self.project_obj.report_type == '9' else False - member = self.project_obj.member[0] if len(self.project_obj.member) > 0 else self.project_obj.duty_person + member = self.project_obj.member[0] if len( + self.project_obj.member) > 0 else self.project_obj.duty_person # 回归轮次的标识和版本 so_dut: Dut = hround.rdField.filter(type='SO').first() if not so_dut: @@ -216,7 +219,8 @@ class GenerateSeitaiController(ControllerBase): # 取出当前轮次key减1就是上一轮次 cname = self.chinese_round_name[int(hround.key)] # 输出二、三... cname_list.append(cname) - member = self.project_obj.member[0] if len(self.project_obj.member) > 0 else self.project_obj.duty_person + member = self.project_obj.member[0] if len( + self.project_obj.member) > 0 else self.project_obj.duty_person is_jd = True if self.project_obj.report_type == '9' else False so_dut: Dut = hround.rdField.filter(type='SO').first() if not so_dut: @@ -260,7 +264,8 @@ class GenerateSeitaiController(ControllerBase): """生成最后的问题单""" self.project_obj = get_object_or_404(Project, id=payload.id) # seitai文档所需变量 - member = self.project_obj.member[0] if len(self.project_obj.member) > 0 else self.project_obj.duty_person + member = self.project_obj.member[0] if len( + self.project_obj.member) > 0 else self.project_obj.duty_person is_jd = True if self.project_obj.report_type == '9' else False self.temp_context = { "project_name": self.project_obj.name, @@ -272,7 +277,8 @@ class GenerateSeitaiController(ControllerBase): } | DocTime(payload.id).wtd_final_time() result = generate_temp_doc('wtd', payload.id, frag_list=payload.frag) if isinstance(result, dict): - return ChenResponse(status=400, code=400, message=result.get('msg', 'wtd未报出错误原因,反正在生成文档出错')) + return ChenResponse(status=400, code=400, + message=result.get('msg', 'wtd未报出错误原因,反正在生成文档出错')) wtd_replace_path, wtd_seitai_final_path = result text_frag_name_list, doc_docx = get_jinja_stdContent_element(wtd_replace_path) # 文本片段操作 @@ -290,7 +296,8 @@ class GenerateSeitaiController(ControllerBase): self.project_obj = get_object_or_404(Project, id=payload.id) # seitai文档所需变量 ## 1.判断是否为JD - member = self.project_obj.member[0] if len(self.project_obj.member) > 0 else self.project_obj.duty_person + member = self.project_obj.member[0] if len( + self.project_obj.member) > 0 else self.project_obj.duty_person is_jd = True if self.project_obj.report_type == '9' else False self.temp_context = { 'project_name': self.project_obj.name, @@ -306,7 +313,8 @@ class GenerateSeitaiController(ControllerBase): } | DocTime(payload.id).bg_final_time() result = generate_temp_doc('bg', payload.id, frag_list=payload.frag) if isinstance(result, dict): - return ChenResponse(status=400, code=400, message=result.get('msg', 'bg未报出错误原因,反正在生成文档出错')) + return ChenResponse(status=400, code=400, + message=result.get('msg', 'bg未报出错误原因,反正在生成文档出错')) bg_replace_path, bg_seitai_final_path = result text_frag_name_list, doc_docx = get_jinja_stdContent_element(bg_replace_path) # 文本片段操作 @@ -375,14 +383,16 @@ class CreateFragmentController(ControllerBase): frags = self.get_fragment_name_by_document_name(id, documentType) # 如果没有文档片段-说明没有生成二段文档 if not frags: - return ChenResponse(status=500, code=500, message='文档片段还未生成,请关闭后再打开/或者先下载基础文档') + return ChenResponse(status=500, code=500, + message='文档片段还未生成,请关闭后再打开/或者先下载基础文档') # 到这里说fragments_files数组有值,返回文件名数组 return ChenResponse(data=[fragment for fragment in frags], message='返回文档片段成功') @staticmethod def get_fragment_name_by_document_name(id: int, document_name: str): # 1.找到模版的路径 - 不用异常肯定存在 - document_path = main_download_path / project_path(id) / 'form_template' / 'products' / f"{document_name}.docx" + document_path = main_download_path / project_path( + id) / 'form_template' / 'products' / f"{document_name}.docx" # 2.识别其中的文档片段 frag_list = get_frag_from_document(document_path) # 3.这里处理报告里第十轮次前端展示问题 @@ -402,7 +412,8 @@ class CreateFragmentController(ControllerBase): filter_frags = list(filter(lambda x: '测试内容和结果' not in x['frag_name'], frag_list)) # 再找到白名单的“测试内容和结果_”的片段 content_and_result_frags = list( - filter(lambda x: '测试内容和结果' in x['frag_name'] and x['frag_name'] in white_list_frag, frag_list)) + filter(lambda x: '测试内容和结果' in x['frag_name'] and x['frag_name'] in white_list_frag, + frag_list)) # 再组合起来返回 filter_frags.extend(content_and_result_frags) return filter_frags diff --git a/apps/dict/controllers/__pycache__/common.cpython-313.pyc b/apps/dict/controllers/__pycache__/common.cpython-313.pyc index 0082306..851e577 100644 Binary files a/apps/dict/controllers/__pycache__/common.cpython-313.pyc and b/apps/dict/controllers/__pycache__/common.cpython-313.pyc differ diff --git a/apps/dict/controllers/common.py b/apps/dict/controllers/common.py index 0375972..0a79779 100644 --- a/apps/dict/controllers/common.py +++ b/apps/dict/controllers/common.py @@ -31,6 +31,7 @@ class AITestController(ControllerBase): "children": [ { "name": "外部32MHz时钟布线到HCLKBUF级冲测试", + "subDescription": "验证外部32MH布线的测试子项描述", "subStep": [ { "operation": "配置FPGA逻辑,将外部32MHz晶振输入连接到HCLKBUF缓冲器。", @@ -45,6 +46,7 @@ class AITestController(ControllerBase): ] }, { "name": "内部10KHz时钟布线到CLKINT缓冲测试", + "subDescription": "验证内部10KHz时钟布线到CLKINT缓冲的测试子项描述", "subStep": [ { "operation": "在FPGA中启用内部10KHz时钟源并将其连接至CLKINT缓冲器。", @@ -59,6 +61,7 @@ class AITestController(ControllerBase): ] }, { "name": "异常情况下的时钟处理测试", + "subDescription": "验证异常情况下的时钟处理测试的测试子项描述", "subStep": [ { "operation": "断开外部32MHz晶振输入后尝试进行HCLKBUF配置。", @@ -76,7 +79,7 @@ class AITestController(ControllerBase): } ] return { - "history":[["我是没有用的",json.dumps(res)]] + "history": [["我是没有用的", json.dumps(res)]] } # 这是其他common内容接口 diff --git a/apps/project/__pycache__/models.cpython-313.pyc b/apps/project/__pycache__/models.cpython-313.pyc index 9d53f82..7389745 100644 Binary files a/apps/project/__pycache__/models.cpython-313.pyc and b/apps/project/__pycache__/models.cpython-313.pyc differ diff --git a/apps/project/controllers/__pycache__/case.cpython-313.pyc b/apps/project/controllers/__pycache__/case.cpython-313.pyc index 072474e..d582b52 100644 Binary files a/apps/project/controllers/__pycache__/case.cpython-313.pyc and b/apps/project/controllers/__pycache__/case.cpython-313.pyc differ diff --git a/apps/project/controllers/__pycache__/design.cpython-313.pyc b/apps/project/controllers/__pycache__/design.cpython-313.pyc index 116cdab..5ebe11c 100644 Binary files a/apps/project/controllers/__pycache__/design.cpython-313.pyc and b/apps/project/controllers/__pycache__/design.cpython-313.pyc differ diff --git a/apps/project/controllers/__pycache__/testDemand.cpython-313.pyc b/apps/project/controllers/__pycache__/testDemand.cpython-313.pyc index afe7185..9d66517 100644 Binary files a/apps/project/controllers/__pycache__/testDemand.cpython-313.pyc and b/apps/project/controllers/__pycache__/testDemand.cpython-313.pyc differ diff --git a/apps/project/controllers/case.py b/apps/project/controllers/case.py index c3f56c5..b1dcaa3 100644 --- a/apps/project/controllers/case.py +++ b/apps/project/controllers/case.py @@ -8,8 +8,9 @@ from utils.chen_pagination import MyPagination from django.db import transaction from django.shortcuts import get_object_or_404 from django.db.models.functions import Replace -from django.db.models import Q, F, Value +from django.db.models import F, Value from typing import List +from django.utils import timezone from utils.chen_response import ChenResponse from utils.chen_crud import multi_delete_case from apps.project.models import Design, Dut, Round, TestDemand, Case, CaseStep, Project, Problem @@ -20,8 +21,9 @@ from utils.util import get_testType from utils.codes import HTTP_INDEX_ERROR, HTTP_EXISTS_CASES from apps.project.tools.copyCase import case_move_to_test, case_copy_to_test, case_to_case_copy_or_move from utils.smallTools.interfaceTools import conditionNoneToBlank +from apps.project.tool.batchTools import parse_case_content_string # 导入case的schema -from apps.project.schemas.case import CaseModelOutSchemaWithoutProblem +from apps.project.schemas.case import CaseModelOutSchemaWithoutProblem, BatchCreateCaseInputSchema @api_controller("/project", auth=JWTAuth(), permissions=[IsAuthenticated], tags=['测试用例接口']) class CaseController(ControllerBase): @@ -120,7 +122,7 @@ class CaseController(ControllerBase): @transaction.atomic def create_case(self, payload: CaseCreateInputSchema): asert_dict = payload.dict(exclude_none=True) - # 构造design_key + # 构造demand_key test_whole_key = "".join( [payload.round_key, "-", payload.dut_key, '-', payload.design_key, '-', payload.test_key]) # 查询当前key应该为多少 @@ -157,6 +159,52 @@ class CaseController(ControllerBase): CaseStep.objects.bulk_create(data_list) # type:ignore return qs + # 批量新增用例 + @route.post("/case/multi_save", url_name="case-batch-create") + @transaction.atomic + def multi_case_save(self, payload: BatchCreateCaseInputSchema): + project_obj = get_object_or_404(Project, id=payload.project_id) + user_name = self.context.request.user.name + keys = [] + demands = project_obj.ptField.all() # 当前项目所有测试项 + for case_data in payload.cases: + # 解析放在前面防止出错 + stepsOrErrorResponse = parse_case_content_string(case_data.test_step) + if isinstance(stepsOrErrorResponse, ChenResponse): + return stepsOrErrorResponse + # 查询当前测试项下case数量,以设置case的key + demand_key = case_data.parent_key + demand_obj = demands.filter(key=demand_key).first() + case_count = demand_obj.tcField.count() + key_string = ''.join([demand_key, "-", str(case_count)]) + keys.append(key_string) + case_dict = { + "ident": demand_obj.ident, + "name": case_data.name, + "key": key_string, + "initialization": case_data.initialization, + "premise": case_data.premise, + "summarize": case_data.summarize, + "designPerson": user_name, + "testPerson": user_name, + "monitorPerson": user_name, + "project": project_obj, + "round": demand_obj.round, + "dut": demand_obj.dut, + "design": demand_obj.design, + "test": demand_obj, + "exe_time": timezone.now(), + "timing_diagram": case_data.sequence, + "title": case_data.name + } + case_new_obj = Case.objects.create(**case_dict) + case_step_list = [] + for step in stepsOrErrorResponse: + case_step_list.append(CaseStep(**{"case": case_new_obj, "operation": step['operation'], + "expect": step['expect']})) + CaseStep.objects.bulk_create(case_step_list) + return ChenResponse(code=60000, status=200, data=keys, message='成功录入用例') + # 更新测试用例 @route.put("/case/update/{id}", response=CaseCreateOutSchema, url_name="case-update") @transaction.atomic @@ -283,7 +331,6 @@ class CaseController(ControllerBase): @route.post("/case/replace/", url_name='case-replace') @transaction.atomic def replace_case_step_content(self, payload: ReplaceCaseSchema): - print(payload) # 1.首先查询项目 project_obj: Project = get_object_or_404(Project, id=payload.project_id) # 2.查询[所有轮次]的selectRows的id diff --git a/apps/project/controllers/design.py b/apps/project/controllers/design.py index 27ff3ea..0fb913c 100644 --- a/apps/project/controllers/design.py +++ b/apps/project/controllers/design.py @@ -20,6 +20,7 @@ from apps.project.schemas.design import DeleteSchema, DesignFilterSchema, Design ReplaceDesignContentSchema from apps.project.tools.delete_change_key import design_delete_sub_node_key from utils.smallTools.interfaceTools import conditionNoneToBlank +from apps.project.tools.auto_create_data import auto_create_renji @api_controller("/project", auth=JWTAuth(), permissions=[IsAuthenticated], tags=['设计需求数据']) class DesignController(ControllerBase): @@ -162,7 +163,7 @@ class DesignController(ControllerBase): design_delete_sub_node_key(single_qs) return ChenResponse(message="设计需求删除成功!") - # 给复制功能级联选择器查询所有的设计需求 + # 给复制功能级联选择器查询所有的设计需求【这是查项目所有的设计需求】 @route.get("/designDemand/getRelatedDesign", url_name='dut-relatedDesign') def getRelatedDesign(self, id: int): project_qs = get_object_or_404(Project, id=id) @@ -196,3 +197,15 @@ class DesignController(ControllerBase): # 4.提交更新 replace_count = design_qs.update(**replace_kwargs) return {'count': replace_count} + + # 点击生成人机交互界面测试-注意必须要有界面的软件 + @route.get("/create_renji/", url_name='renji') + @transaction.atomic + def create_rj(self, round_id: int, project_id: int): + user_name = self.context.request.user.name # 获取当前用户名 + project_obj: Project = get_object_or_404(Project, id=project_id) + dut_qs = Dut.objects.filter(round__key=round_id, project=project_obj, type='XQ').first() + if dut_qs: + auto_create_renji(user_name, dut_qs, project_obj) + return ChenResponse(status=200, message='自动生成人机界面交互测试成功!', data=dut_qs.key) + return ChenResponse(status=402, message='您还未录入需求规格说明文档,请录入后再试') diff --git a/apps/project/controllers/testDemand.py b/apps/project/controllers/testDemand.py index abe19c2..19a43de 100644 --- a/apps/project/controllers/testDemand.py +++ b/apps/project/controllers/testDemand.py @@ -1,3 +1,5 @@ +from multiprocessing.spawn import old_main_modules + from ninja_extra import api_controller, ControllerBase, route from ninja import Query from ninja_jwt.authentication import JWTAuth @@ -17,13 +19,15 @@ from apps.project.models import Design, Dut, Round, TestDemand, TestDemandConten from apps.project.schemas.testDemand import DeleteSchema, TestDemandModelOutSchema, TestDemandFilterSchema, \ TestDemandTreeReturnSchema, TestDemandTreeInputSchema, TestDemandCreateOutSchema, \ TestDemandCreateInputSchema, ReplaceDemandContentSchema, PriorityReplaceSchema, \ - TestDemandRelatedSchema, TestDemandExistRelatedSchema, DemandCopyToDesignSchema + TestDemandRelatedSchema, TestDemandExistRelatedSchema, DemandCopyToDesignSchema, \ + TestDemandMultiCreateInputSchema # 导入ORM from apps.project.models import Project # 导入工具 from apps.project.tools.copyDemand import demand_copy_to_design from apps.project.tools.delete_change_key import demand_delete_sub_node_key from utils.smallTools.interfaceTools import conditionNoneToBlank +from apps.project.tool.batchTools import parse_test_content_string @api_controller("/project", auth=JWTAuth(), permissions=[IsAuthenticated], tags=['测试项接口']) class TestDemandController(ControllerBase): @@ -134,13 +138,13 @@ class TestDemandController(ControllerBase): asert_dict.pop("dut_key") asert_dict.pop("design_key") asert_dict.pop("testContent") - # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # 创建测试项 - 以及子项/子项步骤 qs = TestDemand.objects.create(**asert_dict) for item in payload.dict()['testContent']: content_obj = TestDemandContent.objects.create( testDemand=qs, - subName=item['subName'] + subName=item['subName'], + subDescription=item['subDescription'] ) TestDemandContentStep.objects.bulk_create([ TestDemandContentStep( @@ -151,6 +155,69 @@ class TestDemandController(ControllerBase): ]) return qs + # 批量新增测试项 + @route.post("/testDemand/multi_save", url_name="testDemand-multi-create") + @transaction.atomic + def create_multi_test_demand(self, payload: TestDemandMultiCreateInputSchema): + # 1.首先判断测试项标识是否重复 + project_qs = Project.objects.filter(id=payload.project_id).first() + designs = project_qs.psField.all() + ## 给返回response的data数据以便前端更新树状目录 + keys = [] + ## 遍历payload.demands数组 + for index, demandOne in enumerate(payload.demands): + if demandOne.ident and project_qs: + old_obj = project_qs.ptField.filter(ident=demandOne.ident).first() + if old_obj and old_obj.testType == demandOne.testType: + message_temp = f"第{index}个测试项标识重复,请修改" + return ChenResponse(status=200, code=500101, data=index, message=message_temp) + # 标识不重复就开始录入了 + for index, demand in enumerate(payload.demands): + create_sub_demands = parse_test_content_string(demand.testContent) + if isinstance(create_sub_demands, ChenResponse): + return create_sub_demands + else: + # 这说明解析成功了 + # 首先查询所属design、dut、round,方便新增 + design_obj: Design = designs.filter(key=demand.parent_key).first() # 因为前端限制必然有 + dut_obj = design_obj.dut + round_obj = design_obj.round + test_demand_count = TestDemand.objects.filter(project=project_qs, + design=design_obj).count() + key_string = ''.join([design_obj.key, "-", str(test_demand_count)]) + keys.append(key_string) + create_demand_dict = { + 'ident': demand.ident, + 'name': demand.name, + 'adequacy': demand.adequacy, + 'priority': demand.priority, + 'testType': demand.testType, + 'testMethod': demand.testMethod, + 'title': demand.name, + 'key': key_string, + 'project': project_qs, + 'round': round_obj, + 'dut': dut_obj, + 'design': design_obj, + 'testDesciption': demand.testDesciption + } + demand_created = TestDemand.objects.create(**create_demand_dict) + # 录入测试子项 + for sub in create_sub_demands: + content_obj = TestDemandContent.objects.create( + testDemand=demand_created, + subName=sub['subName'], + subDescription=sub['subDescription'] + ) + TestDemandContentStep.objects.bulk_create([ + TestDemandContentStep( + testDemandContent=content_obj, + **step.dict() if not isinstance(step, dict) else step + ) + for step in sub['subStep'] + ]) + return ChenResponse(code=200991, status=200, data=keys, message='成功录入') + # 更新测试项 @route.put("/testDemand/update/{id}", response=TestDemandCreateOutSchema, url_name="testDemand-update") @transaction.atomic @@ -184,7 +251,8 @@ class TestDemandController(ControllerBase): if item['subName']: content_obj = TestDemandContent.objects.create( testDemand=testDemand_qs, - subName=item["subName"] + subName=item["subName"], + subDescription=item["subDescription"] ) TestDemandContentStep.objects.bulk_create([ TestDemandContentStep( @@ -224,7 +292,7 @@ class TestDemandController(ControllerBase): demand_delete_sub_node_key(single_qs) # 删除后需重排子节点 return ChenResponse(message="测试需求删除成功!") - # 查询一个项目的所有测试项 + # 查询一个项目的所有测试项【当前轮次】 @route.get("/testDemand/getRelatedTestDemand", url_name="testDemand-getRelatedTestDemand") @transaction.atomic def getRelatedTestDemand(self, id: int, round: str): @@ -236,7 +304,7 @@ class TestDemandController(ControllerBase): for design in designs: design_dict = {'label': design.name, 'value': design.id, 'children': []} for test_item in design.dtField.all(): - test_item_dict = {'label': test_item.name, 'value': test_item.id} + test_item_dict = {'label': test_item.name, 'value': test_item.id, 'key': test_item.key} design_dict['children'].append(test_item_dict) data_list.append(design_dict) return ChenResponse(message='获取成功', data=data_list) diff --git a/apps/project/migrations/0018_testdemandcontent_subdescription.py b/apps/project/migrations/0018_testdemandcontent_subdescription.py new file mode 100644 index 0000000..2f2484f --- /dev/null +++ b/apps/project/migrations/0018_testdemandcontent_subdescription.py @@ -0,0 +1,18 @@ +# Generated by Django 6.0 on 2025-12-15 09:58 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('project', '0017_alter_testdemandcontentstep_id'), + ] + + operations = [ + migrations.AddField( + model_name='testdemandcontent', + name='subDescription', + field=models.CharField(blank=True, max_length=1024, null=True, verbose_name='测试子项一句话描述'), + ), + ] diff --git a/apps/project/migrations/__pycache__/0018_testdemandcontent_subdescription.cpython-313.pyc b/apps/project/migrations/__pycache__/0018_testdemandcontent_subdescription.cpython-313.pyc new file mode 100644 index 0000000..06ebad5 Binary files /dev/null and b/apps/project/migrations/__pycache__/0018_testdemandcontent_subdescription.cpython-313.pyc differ diff --git a/apps/project/models.py b/apps/project/models.py index ac451f4..7397266 100644 --- a/apps/project/models.py +++ b/apps/project/models.py @@ -13,12 +13,15 @@ class Project(CoreModel): objects = models.Manager() ident = models.CharField(max_length=64, blank=True, null=True, verbose_name="项目标识", help_text="项目标识", unique=True) # 唯一 - name = models.CharField(max_length=100, blank=True, null=True, verbose_name="项目名称", help_text="项目名称") + name = models.CharField(max_length=100, blank=True, null=True, verbose_name="项目名称", + help_text="项目名称") beginTime = models.DateField(auto_now_add=True, null=True, blank=True, help_text="开始时间", verbose_name="开始时间") - endTime = models.DateField(auto_now_add=True, null=True, blank=True, help_text="结束时间", verbose_name="结束时间") + endTime = models.DateField(auto_now_add=True, null=True, blank=True, help_text="结束时间", + verbose_name="结束时间") duty_person = models.CharField(max_length=64, verbose_name="负责人", help_text="负责人") - member = models.JSONField(null=True, blank=True, help_text="项目成员", verbose_name="项目成员", default=create_list) + member = models.JSONField(null=True, blank=True, help_text="项目成员", verbose_name="项目成员", + default=create_list) # 8月新增字段 quality_person = models.CharField(max_length=64, verbose_name="质量保证员", help_text="质量保证员") vise_person = models.CharField(max_length=64, verbose_name="质量监督员", help_text="质量监督员") @@ -30,7 +33,8 @@ class Project(CoreModel): default=create_list) plant_type = models.JSONField(null=True, blank=True, help_text="平台类型", verbose_name="平台类型", default=create_list) - report_type = models.CharField(max_length=64, blank=True, null=True, verbose_name="报告类型", help_text="报告类型") + report_type = models.CharField(max_length=64, blank=True, null=True, verbose_name="报告类型", + help_text="报告类型") language = models.JSONField(null=True, blank=True, help_text="被测语言", verbose_name="被测语言", default=create_list) standard = models.JSONField(null=True, blank=True, help_text="依据标准", verbose_name="依据标准", @@ -56,10 +60,12 @@ class Project(CoreModel): help_text="测评中心电话") test_email = models.CharField(max_length=64, blank=True, null=True, verbose_name="测评中心邮箱", help_text="测评中心邮箱") - step = models.CharField(max_length=8, blank=True, null=True, verbose_name="项目阶段", help_text="项目阶段") + step = models.CharField(max_length=8, blank=True, null=True, verbose_name="项目阶段", + help_text="项目阶段") abbreviation = models.JSONField(null=True, blank=True, help_text="缩略语", verbose_name="缩略语", default=create_list) - soft_type = models.SmallIntegerField(verbose_name='软件类型', choices=((1, '新研'), (2, '改造'), (3, '沿用')), + soft_type = models.SmallIntegerField(verbose_name='软件类型', + choices=((1, '新研'), (2, '改造'), (3, '沿用')), default=1) runtime = models.CharField(max_length=8, blank=True, null=True, verbose_name="运行环境", help_text="运行环境") @@ -85,23 +91,31 @@ class Round(CoreModel): help_text="轮次名称") beginTime = models.DateField(auto_now_add=True, null=True, blank=True, help_text="开始时间", verbose_name="开始时间") - endTime = models.DateField(auto_now_add=True, null=True, blank=True, help_text="结束时间", verbose_name="结束时间") - grade = models.CharField(max_length=64, blank=True, null=True, verbose_name="等级", help_text="等级", default='1') - best_condition_voltage = models.CharField(max_length=64, blank=True, null=True, verbose_name="最优工况电压", + endTime = models.DateField(auto_now_add=True, null=True, blank=True, help_text="结束时间", + verbose_name="结束时间") + grade = models.CharField(max_length=64, blank=True, null=True, verbose_name="等级", help_text="等级", + default='1') + best_condition_voltage = models.CharField(max_length=64, blank=True, null=True, + verbose_name="最优工况电压", help_text="最优工况电压") best_condition_tem = models.CharField(max_length=64, blank=True, null=True, verbose_name="最优工况温度", help_text="最优工况温度") - typical_condition_voltage = models.CharField(max_length=64, blank=True, null=True, verbose_name="典型工况电压", + typical_condition_voltage = models.CharField(max_length=64, blank=True, null=True, + verbose_name="典型工况电压", help_text="典型工况电压") - typical_condition_tem = models.CharField(max_length=64, blank=True, null=True, verbose_name="典型工况温度", + typical_condition_tem = models.CharField(max_length=64, blank=True, null=True, + verbose_name="典型工况温度", help_text="典型工况温度") - low_condition_voltage = models.CharField(max_length=64, blank=True, null=True, verbose_name="最低工况电压", + low_condition_voltage = models.CharField(max_length=64, blank=True, null=True, + verbose_name="最低工况电压", help_text="最低工况电压") low_condition_tem = models.CharField(max_length=64, blank=True, null=True, verbose_name="最低工况温度", help_text="最低工况温度") - project = models.ForeignKey(to="Project", db_constraint=False, related_name="pField", on_delete=models.CASCADE, + project = models.ForeignKey(to="Project", db_constraint=False, related_name="pField", + on_delete=models.CASCADE, verbose_name='归属项目', help_text='归属项目', related_query_name='pQuery') - level = models.CharField(max_length=15, verbose_name='树状级别第一级', help_text="树状级别第一级", default='0') + level = models.CharField(max_length=15, verbose_name='树状级别第一级', help_text="树状级别第一级", + default='0') key = models.CharField(max_length=15, verbose_name='给前端的树状级别', help_text="给前端的树状级别") title = models.CharField(max_length=15, verbose_name='给前端的name', help_text="给前端的name") # 新增执行地点 @@ -120,30 +134,38 @@ class Dut(CoreModel): objects = models.Manager() ident = models.CharField(max_length=64, blank=True, null=True, verbose_name="被测件标识", help_text="被测件标识") # 后面加上unique=True - type = models.CharField(max_length=16, blank=True, null=True, verbose_name="被测件类型", help_text="被测件类型") - name = models.CharField(max_length=64, blank=True, null=True, verbose_name="被测件名称", help_text="被测件名称") + type = models.CharField(max_length=16, blank=True, null=True, verbose_name="被测件类型", + help_text="被测件类型") + name = models.CharField(max_length=64, blank=True, null=True, verbose_name="被测件名称", + help_text="被测件名称") # 2025年4月28日更新,分为总函数、有效代码行数、注释行数 total_lines = models.CharField(max_length=64, blank=True, null=True, verbose_name='总行数') effective_lines = models.CharField(max_length=64, blank=True, null=True, verbose_name='有效代码行数') comment_lines = models.CharField(max_length=64, blank=True, null=True, verbose_name='注释行数') # 更新结束 - title = models.CharField(max_length=64, blank=True, null=True, verbose_name="树-名称", help_text="树-名称") + title = models.CharField(max_length=64, blank=True, null=True, verbose_name="树-名称", + help_text="树-名称") key = models.CharField(max_length=64, blank=True, null=True, verbose_name="树-key", help_text="树-key") # 被测件添加版本、发布单位、发布时间 - version = models.CharField(max_length=64, blank=True, null=True, verbose_name="发布版本", help_text="发布版本") + version = models.CharField(max_length=64, blank=True, null=True, verbose_name="发布版本", + help_text="发布版本") release_union = models.CharField(max_length=64, blank=True, null=True, verbose_name="发布版本", help_text="发布版本") release_date = models.DateField(auto_now_add=True, null=True, blank=True, help_text="发布时间", verbose_name="发布时间") # 新增用户文档的编号 - ref = models.CharField(max_length=32, blank=True, null=True, verbose_name="文档编号", help_text="文档编号") + ref = models.CharField(max_length=32, blank=True, null=True, verbose_name="文档编号", + help_text="文档编号") # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - level = models.CharField(max_length=64, blank=True, null=True, verbose_name="树-level", help_text="树-level", + level = models.CharField(max_length=64, blank=True, null=True, verbose_name="树-level", + help_text="树-level", default=1) # 默认为1 - project = models.ForeignKey(to="Project", db_constraint=False, related_name="pdField", on_delete=models.CASCADE, + project = models.ForeignKey(to="Project", db_constraint=False, related_name="pdField", + on_delete=models.CASCADE, verbose_name='归属项目', help_text='归属项目', related_query_name='pdQuery') - round = models.ForeignKey(to="Round", db_constraint=False, related_name="rdField", on_delete=models.CASCADE, + round = models.ForeignKey(to="Round", db_constraint=False, related_name="rdField", + on_delete=models.CASCADE, verbose_name='归属轮次', help_text='归属轮次', related_query_name='rdQuery') def __str__(self): @@ -159,7 +181,8 @@ class DutMetrics(models.Model): objects = models.Manager() id = ShortUUIDField(primary_key=True, help_text="id", verbose_name="id") # 外键Dut,一个Dut储存一个指标 - dut = models.OneToOneField(Dut, on_delete=models.CASCADE, related_name='metrics', related_query_name='metrics', + dut = models.OneToOneField(Dut, on_delete=models.CASCADE, related_name='metrics', + related_query_name='metrics', db_constraint=False, verbose_name='归属源代码被测件') avg_function_lines = models.IntegerField(verbose_name='平均模块大小') avg_cyclomatic = models.IntegerField(verbose_name='平均圈复杂度') @@ -173,19 +196,25 @@ class Design(CoreModel): objects = models.Manager() ident = models.CharField(max_length=64, blank=True, null=True, verbose_name="设计需求标识", help_text="设计需求标识") - name = models.CharField(max_length=64, blank=True, null=True, verbose_name="设计需求名称", help_text="设计需求名称") + name = models.CharField(max_length=64, blank=True, null=True, verbose_name="设计需求名称", + help_text="设计需求名称") demandType = models.CharField(max_length=8, blank=True, null=True, verbose_name="设计需求类型", help_text="设计需求类型") description = HTMLField(blank=True, null=True, verbose_name="设计需求描述", help_text="设计需求描述") - title = models.CharField(max_length=64, blank=True, null=True, verbose_name="树-名称", help_text="树-名称") + title = models.CharField(max_length=64, blank=True, null=True, verbose_name="树-名称", + help_text="树-名称") key = models.CharField(max_length=64, blank=True, null=True, verbose_name="round-dut-designkey", help_text="round-dut-designkey") - level = models.CharField(max_length=64, blank=True, null=True, verbose_name="树-level", help_text="树-level", + level = models.CharField(max_length=64, blank=True, null=True, verbose_name="树-level", + help_text="树-level", default=2) # 默认为2 - chapter = models.CharField(max_length=64, blank=True, verbose_name="设计需求章节号", help_text="设计需求章节号") - project = models.ForeignKey(to="Project", db_constraint=False, related_name="psField", on_delete=models.CASCADE, + chapter = models.CharField(max_length=64, blank=True, verbose_name="设计需求章节号", + help_text="设计需求章节号") + project = models.ForeignKey(to="Project", db_constraint=False, related_name="psField", + on_delete=models.CASCADE, verbose_name='归属项目', help_text='归属项目', related_query_name='psQuery') - round = models.ForeignKey(to="Round", db_constraint=False, related_name="dsField", on_delete=models.CASCADE, + round = models.ForeignKey(to="Round", db_constraint=False, related_name="dsField", + on_delete=models.CASCADE, verbose_name='归属轮次', help_text='归属轮次', related_query_name='rsQuery') dut = models.ForeignKey(to="Dut", db_constraint=False, related_name="rsField", on_delete=models.CASCADE, verbose_name='归属轮次', help_text='归属轮次', related_query_name='rsQuery') @@ -214,29 +243,42 @@ class TestDemand(CoreModel): """测试项""" ident = models.CharField(max_length=64, blank=True, null=True, verbose_name="测试需求标识", help_text="测试需求标识") - name = models.CharField(max_length=64, blank=True, null=True, verbose_name="测试需求名称", help_text="测试需求名称") - adequacy = models.CharField(max_length=256, blank=True, null=True, verbose_name="充分条件", help_text="充分条件") - priority = models.CharField(max_length=8, blank=True, null=True, verbose_name="优先级", help_text="优先级") - testType = models.CharField(max_length=8, null=True, blank=True, help_text="测试类型", verbose_name="测试类型", + name = models.CharField(max_length=64, blank=True, null=True, verbose_name="测试需求名称", + help_text="测试需求名称") + adequacy = models.CharField(max_length=256, blank=True, null=True, verbose_name="充分条件", + help_text="充分条件") + priority = models.CharField(max_length=8, blank=True, null=True, verbose_name="优先级", + help_text="优先级") + testType = models.CharField(max_length=8, null=True, blank=True, help_text="测试类型", + verbose_name="测试类型", default="1") - testMethod = models.JSONField(blank=True, help_text="测试方法", verbose_name="测试方法", default=create_list) - title = models.CharField(max_length=64, blank=True, null=True, verbose_name="树-名称", help_text="树-名称") - key = models.CharField(max_length=64, blank=True, null=True, verbose_name="round-dut-designkey-testdemand", + testMethod = models.JSONField(blank=True, help_text="测试方法", verbose_name="测试方法", + default=create_list) + title = models.CharField(max_length=64, blank=True, null=True, verbose_name="树-名称", + help_text="树-名称") + key = models.CharField(max_length=64, blank=True, null=True, + verbose_name="round-dut-designkey-testdemand", help_text="round-dut-designkey-testdemand") - level = models.CharField(max_length=64, blank=True, null=True, verbose_name="树-level", help_text="树-level", + level = models.CharField(max_length=64, blank=True, null=True, verbose_name="树-level", + help_text="树-level", default=3) # 默认为3 - project = models.ForeignKey(to="Project", db_constraint=False, related_name="ptField", on_delete=models.CASCADE, + project = models.ForeignKey(to="Project", db_constraint=False, related_name="ptField", + on_delete=models.CASCADE, verbose_name='归属项目', help_text='归属项目', related_query_name='ptQuery') - round = models.ForeignKey(to="Round", db_constraint=False, related_name="rtField", on_delete=models.CASCADE, + round = models.ForeignKey(to="Round", db_constraint=False, related_name="rtField", + on_delete=models.CASCADE, verbose_name='归属轮次', help_text='归属轮次', related_query_name='dutQuery') dut = models.ForeignKey(to="Dut", db_constraint=False, related_name="dutField", on_delete=models.CASCADE, verbose_name='归属被测件', help_text='归属被测件', related_query_name='dtQuery') - design = models.ForeignKey(to="Design", db_constraint=False, related_name="dtField", on_delete=models.CASCADE, - verbose_name='归属设计需求', help_text='归属设计需求', related_query_name='dtQuery') + design = models.ForeignKey(to="Design", db_constraint=False, related_name="dtField", + on_delete=models.CASCADE, + verbose_name='归属设计需求', help_text='归属设计需求', + related_query_name='dtQuery') otherDesign = models.ManyToManyField(to="Design", db_constraint=False, related_name="odField", related_query_name='odQuery', blank=True) # 新模版要求:测试项描述对整个测试项进行描述 - testDesciption = models.CharField(max_length=1024, blank=True, null=True, verbose_name='测试项描述', default="", + testDesciption = models.CharField(max_length=1024, blank=True, null=True, verbose_name='测试项描述', + default="", help_text='测试项描述') def __str__(self): @@ -246,11 +288,15 @@ class TestDemandContent(CoreModel): objects = models.Manager() """测试方法中的测试子项内容""" testDemand = models.ForeignKey(to="TestDemand", db_constraint=False, related_name="testQField", - on_delete=models.CASCADE, verbose_name='归属的测试项', help_text='归属的测试项', + on_delete=models.CASCADE, verbose_name='归属的测试项', + help_text='归属的测试项', related_query_name='testQField') - # 2025年4月16日去掉subDesc、condition、observe - # 4月17日修改:因为新增步骤所以把operation和expect弄到下面Model里面了,新增字段 + # 2025/4/16去掉subDesc、condition、observe + # 2025/4/17修改:因为新增步骤所以把operation和expect弄到下面Model里面了,新增字段 subName = models.CharField(max_length=1024, blank=True, null=True, verbose_name='测试子项名称') + # 2025/12/15修改:CPU新增“测试子项描述”,FPGA渲染单个 + subDescription = models.CharField(max_length=1024, blank=True, null=True, + verbose_name='测试子项一句话描述') def __str__(self): return f'测试子项:{self.subName}' @@ -260,38 +306,55 @@ class TestDemandContentStep(CoreModel): objects = models.Manager() operation = models.CharField(max_length=3072, blank=True, null=True, verbose_name='测试子项操作') expect = models.CharField(max_length=1024, blank=True, null=True, verbose_name='期望') - testDemandContent = models.ForeignKey(to="TestDemandContent", db_constraint=False, related_name="testStepField", + testDemandContent = models.ForeignKey(to="TestDemandContent", db_constraint=False, + related_name="testStepField", on_delete=models.CASCADE, verbose_name='归属的测试项', help_text='归属的测试项', related_query_name='testStepField') class Case(CoreModel): objects = models.Manager() - ident = models.CharField(max_length=64, blank=True, null=True, verbose_name="用例标识", help_text="用例标识") - name = models.CharField(max_length=64, blank=True, null=True, verbose_name="用例名称", help_text="用例名称") + ident = models.CharField(max_length=64, blank=True, null=True, verbose_name="用例标识", + help_text="用例标识") + name = models.CharField(max_length=64, blank=True, null=True, verbose_name="用例名称", + help_text="用例名称") initialization = models.CharField(max_length=128, blank=True, null=True, verbose_name="初始条件", help_text="初始化条件") - premise = models.CharField(max_length=128, blank=True, null=True, verbose_name="前提和约束", help_text="前提和约束") - summarize = models.CharField(max_length=256, blank=True, null=True, verbose_name="用例综述", help_text="用例综述") - designPerson = models.CharField(max_length=16, blank=True, null=True, verbose_name="设计人员", help_text="设计人员") - testPerson = models.CharField(max_length=16, blank=True, null=True, verbose_name="测试人员", help_text="测试人员") + premise = models.CharField(max_length=128, blank=True, null=True, verbose_name="前提和约束", + help_text="前提和约束") + summarize = models.CharField(max_length=256, blank=True, null=True, verbose_name="用例综述", + help_text="用例综述") + designPerson = models.CharField(max_length=16, blank=True, null=True, verbose_name="设计人员", + help_text="设计人员") + testPerson = models.CharField(max_length=16, blank=True, null=True, verbose_name="测试人员", + help_text="测试人员") monitorPerson = models.CharField(max_length=16, blank=True, null=True, verbose_name="审核人员", help_text="审核人员") - project = models.ForeignKey(to="Project", db_constraint=False, related_name="pcField", on_delete=models.CASCADE, + project = models.ForeignKey(to="Project", db_constraint=False, related_name="pcField", + on_delete=models.CASCADE, verbose_name='归属项目', help_text='归属项目', related_query_name='pcQuery') - isLeaf = models.BooleanField(default=True, verbose_name="树状图最后一个节点", help_text="树状图最后一个节点") - round = models.ForeignKey(to="Round", db_constraint=False, related_name="rcField", on_delete=models.CASCADE, + isLeaf = models.BooleanField(default=True, verbose_name="树状图最后一个节点", + help_text="树状图最后一个节点") + round = models.ForeignKey(to="Round", db_constraint=False, related_name="rcField", + on_delete=models.CASCADE, verbose_name='归属轮次', help_text='归属轮次', related_query_name='rcQuery') dut = models.ForeignKey(to="Dut", db_constraint=False, related_name="ducField", on_delete=models.CASCADE, verbose_name='归属被测件', help_text='归属被测件', related_query_name='ducQuery') - design = models.ForeignKey(to="Design", db_constraint=False, related_name="dcField", on_delete=models.CASCADE, - verbose_name='归属设计需求', help_text='归属设计需求', related_query_name='dcQuery') - test = models.ForeignKey(to="TestDemand", db_constraint=False, related_name="tcField", on_delete=models.CASCADE, - verbose_name='归属测试需求', help_text='归属测试需求', related_query_name='tcQuery') - title = models.CharField(max_length=64, blank=True, null=True, verbose_name="树-名称", help_text="树-名称") - key = models.CharField(max_length=64, blank=True, null=True, verbose_name="round-dut-designkey-testdemand-case", + design = models.ForeignKey(to="Design", db_constraint=False, related_name="dcField", + on_delete=models.CASCADE, + verbose_name='归属设计需求', help_text='归属设计需求', + related_query_name='dcQuery') + test = models.ForeignKey(to="TestDemand", db_constraint=False, related_name="tcField", + on_delete=models.CASCADE, + verbose_name='归属测试需求', help_text='归属测试需求', + related_query_name='tcQuery') + title = models.CharField(max_length=64, blank=True, null=True, verbose_name="树-名称", + help_text="树-名称") + key = models.CharField(max_length=64, blank=True, null=True, + verbose_name="round-dut-designkey-testdemand-case", help_text="round-dut-designkey-testdemand-case") - level = models.CharField(max_length=64, blank=True, null=True, verbose_name="树-level", help_text="树-level", + level = models.CharField(max_length=64, blank=True, null=True, verbose_name="树-level", + help_text="树-level", default=4) # 默认为4 # 2024年5月31日新增属性:执行时间 exe_time = models.DateField(blank=True, null=True, verbose_name='执行时间', help_text='执行时间') @@ -310,14 +373,17 @@ class Case(CoreModel): class CaseStep(CoreModel): objects = models.Manager() operation = HTMLField(blank=True, null=True, verbose_name="测试步骤-操作", help_text="测试步骤-操作") - expect = models.CharField(max_length=3072, blank=True, null=True, verbose_name="用例预期", help_text="用例预期") + expect = models.CharField(max_length=3072, blank=True, null=True, verbose_name="用例预期", + help_text="用例预期") result = HTMLField(blank=True, null=True, verbose_name="测试步骤-结果", help_text="测试步骤-结果") - passed = models.CharField(max_length=8, null=True, blank=True, help_text="是否通过", verbose_name="是否通过", + passed = models.CharField(max_length=8, null=True, blank=True, help_text="是否通过", + verbose_name="是否通过", default="3") # status = models.CharField(max_length=8, null=True, blank=True, help_text="执行状态", verbose_name="执行状态", # default="3") case = models.ForeignKey(to="Case", db_constraint=False, related_name="step", - on_delete=models.CASCADE, verbose_name='归属的测试用例', help_text='归属的测试用例', + on_delete=models.CASCADE, verbose_name='归属的测试用例', + help_text='归属的测试用例', related_query_name='stepQ') def __str__(self): @@ -326,34 +392,46 @@ class CaseStep(CoreModel): class Problem(CoreModel): objects = models.Manager() # ident为PT_RXXXX_ident,这里需要根据测试项类型进行排序处理 - ident = models.CharField(max_length=64, blank=True, null=True, verbose_name="问题单标识", help_text="问题单标识") - name = models.CharField(max_length=64, blank=True, null=True, verbose_name="问题单名称", help_text="问题单名称") + ident = models.CharField(max_length=64, blank=True, null=True, verbose_name="问题单标识", + help_text="问题单标识") + name = models.CharField(max_length=64, blank=True, null=True, verbose_name="问题单名称", + help_text="问题单名称") # 问题状态1-已闭环 2-开放 3-推迟 4-撤销 - status = models.CharField(max_length=8, blank=True, null=True, verbose_name="缺陷状态", help_text="缺陷状态") + status = models.CharField(max_length=8, blank=True, null=True, verbose_name="缺陷状态", + help_text="缺陷状态") # 问题等级1-一般 2-严重 3-建议 4-重大 - grade = models.CharField(max_length=8, blank=True, null=True, verbose_name="缺陷等级", help_text="缺陷等级") + grade = models.CharField(max_length=8, blank=True, null=True, verbose_name="缺陷等级", + help_text="缺陷等级") # 问题类型1-其他问题 2-文档问题 3-程序问题 4-设计问题 5-需求问题 6-数据问题 - type = models.CharField(max_length=8, blank=True, null=True, verbose_name="缺陷类型", help_text="缺陷类型") + type = models.CharField(max_length=8, blank=True, null=True, verbose_name="缺陷类型", + help_text="缺陷类型") closeMethod = models.JSONField(null=True, blank=True, help_text="闭环方式", verbose_name="闭环方式", default=create_list_1) operation = HTMLField(blank=True, null=True, verbose_name="问题描述", help_text="问题描述") result = HTMLField(blank=True, null=True, verbose_name="问题结果/影响", help_text="问题结果/影响") - postPerson = models.CharField(max_length=16, blank=True, null=True, verbose_name="提出人员", help_text="提出人员") - postDate = models.DateField(auto_now_add=True, null=True, blank=True, help_text="提单日期", verbose_name="提单日期") + postPerson = models.CharField(max_length=16, blank=True, null=True, verbose_name="提出人员", + help_text="提出人员") + postDate = models.DateField(auto_now_add=True, null=True, blank=True, help_text="提单日期", + verbose_name="提单日期") designerPerson = models.CharField(max_length=16, blank=True, null=True, verbose_name="开发人员", help_text="开发人员") designDate = models.DateField(auto_now_add=True, null=True, blank=True, help_text="确认日期", verbose_name="确认日期") - verifyPerson = models.CharField(max_length=16, blank=True, null=True, verbose_name="验证人员", help_text="验证人员") + verifyPerson = models.CharField(max_length=16, blank=True, null=True, verbose_name="验证人员", + help_text="验证人员") verifyDate = models.DateField(auto_now_add=True, null=True, blank=True, help_text="验证日期", verbose_name="验证日期") - project = models.ForeignKey(to="Project", db_constraint=False, related_name="projField", on_delete=models.CASCADE, + project = models.ForeignKey(to="Project", db_constraint=False, related_name="projField", + on_delete=models.CASCADE, verbose_name='归属项目', help_text='归属项目', related_query_name='projQuery') - case = models.ManyToManyField(to="Case", db_constraint=False, related_name="caseField", verbose_name='归属测试用例', + case = models.ManyToManyField(to="Case", db_constraint=False, related_name="caseField", + verbose_name='归属测试用例', help_text='归属测试用例-多对多', related_query_name='caseQuery') solve = models.TextField(verbose_name='开发人员填写-改正措施', - help_text='开发人员填写-改正措施,该字段需要关联“status=1”', blank=True, null=True) - analysis = HTMLField(blank=True, null=True, verbose_name="开发人员填写-原因分析", help_text="开发人员填写-原因分析") + help_text='开发人员填写-改正措施,该字段需要关联“status=1”', blank=True, + null=True) + analysis = HTMLField(blank=True, null=True, verbose_name="开发人员填写-原因分析", + help_text="开发人员填写-原因分析") effect_scope = HTMLField(blank=True, null=True, verbose_name="开发人员填写-影响域分析", help_text="开发人员填写-影响域分析") verify_result = HTMLField(blank=True, null=True, verbose_name="回归结果", help_text="回归结果") diff --git a/apps/project/schemas/__pycache__/case.cpython-313.pyc b/apps/project/schemas/__pycache__/case.cpython-313.pyc index 20cf23e..4c7354a 100644 Binary files a/apps/project/schemas/__pycache__/case.cpython-313.pyc and b/apps/project/schemas/__pycache__/case.cpython-313.pyc differ diff --git a/apps/project/schemas/__pycache__/testDemand.cpython-313.pyc b/apps/project/schemas/__pycache__/testDemand.cpython-313.pyc index a6d9664..3d724f3 100644 Binary files a/apps/project/schemas/__pycache__/testDemand.cpython-313.pyc and b/apps/project/schemas/__pycache__/testDemand.cpython-313.pyc differ diff --git a/apps/project/schemas/case.py b/apps/project/schemas/case.py index bacdbb8..6ad53c8 100644 --- a/apps/project/schemas/case.py +++ b/apps/project/schemas/case.py @@ -126,6 +126,20 @@ class CaseCreateInputSchema(Schema): # 新增时序图字段 timing_diagram: str = Field("", alias="timing_diagram") +# 批量新增测试用例 +class OneCaseBatchCreateSchema(Schema): + parent_key: str + name: str + summarize: Optional[str] = "" + initialization: Optional[str] = "" + premise: Optional[str] = "" + sequence: Optional[str] = "" # 时序图 + test_step: str + +class BatchCreateCaseInputSchema(Schema): + project_id: int = Field(..., validation_alias=AliasChoices('project_id', 'projectId')) + cases: List[OneCaseBatchCreateSchema] = [] + # 由demand创建case的输入Schema class DemandNodeSchema(Schema): project_id: int diff --git a/apps/project/schemas/testDemand.py b/apps/project/schemas/testDemand.py index f480d18..5bb8e8b 100644 --- a/apps/project/schemas/testDemand.py +++ b/apps/project/schemas/testDemand.py @@ -15,6 +15,7 @@ class TestContentStepSchema(ModelSchema): fields = ['operation', 'expect'] class TestContentSchema(ModelSchema): + subDescription: Optional[str] = "" subStep: List[TestContentStepSchema] = [] # 可能为空 class Meta: @@ -76,6 +77,8 @@ class TestDemandCreateOutSchema(ModelSchema): # 新增测试子项,单个子项的Schema class TestContentInputSchema(Schema): subName: str = None + # 2025/12/15-对CPU增加测试子项描述 + subDescription: Optional[str] = "" # 未提供时为空字符串 subStep: Optional[List[TestContentStepSchema]] = [] # 新增/更新测试项Schema @@ -95,6 +98,22 @@ class TestDemandCreateInputSchema(Schema): testType: str = Field(None, alias="testType") testDesciption: str = Field("", alias='testDesciption') +# 批量新增测试项Schema-2个Schema +class TestDemandOneInput(Schema): + parent_key: str # 直接给设计需求的key,前端去组装 + ident: str + name: str + priority: str = "1" + adequacy: str + testContent: str # 注意这个在接口里面分情况判断 + testMethod: List[str] = [] + testType: str + testDesciption: Optional[str] = "" + +class TestDemandMultiCreateInputSchema(Schema): + project_id: int + demands: List[TestDemandOneInput] + # 处理前端请求-设计需求关联测试需求(测试项) class TestDemandRelatedSchema(Schema): data: List[int] = None @@ -129,4 +148,4 @@ class ReplaceDemandContentSchema(Schema): # 优先级替换Schema class PriorityReplaceSchema(Schema): selectRows: List[int] = None - priority: str \ No newline at end of file + priority: str diff --git a/apps/project/tool/__pycache__/batchTools.cpython-313.pyc b/apps/project/tool/__pycache__/batchTools.cpython-313.pyc new file mode 100644 index 0000000..68df704 Binary files /dev/null and b/apps/project/tool/__pycache__/batchTools.cpython-313.pyc differ diff --git a/apps/project/tool/batchTools.py b/apps/project/tool/batchTools.py new file mode 100644 index 0000000..7581187 --- /dev/null +++ b/apps/project/tool/batchTools.py @@ -0,0 +1,111 @@ +import re +from utils.chen_response import ChenResponse + +def parse_test_content_string(content: str): + """ + 解析前端传来的批量新增测试项testContent字段 + """ + # 判断是否为空字符串 + if not content or not content.strip(): + return [] + create_subDemands = [] # 储存测试子项内容 + current_subDemand: None | dict = None + lines = content.strip().split("\n") + line_number = 0 + + for i, line in enumerate(lines): + line_number = i + 1 + line = line.strip() + # 跳过空行 + if not line: + continue + # 检查是否以^开头 + if line.startswith("^"): + # 标识一个测试子项开始了 + if current_subDemand: + create_subDemands.append(current_subDemand) + # 解析新测试子项 + try: + # 检查是否包含分隔符@,包含则分割 + if '@' in line: + [item_name, item_desc] = line.split("@") + else: + item_name = line + item_desc = "" + + # 判断名称是否为空 + item_name = item_name.replace("^", "", count=1) + if not item_name: + message = f"您字符串中,第{line_number}行没有测试子项名称" + return ChenResponse(status=200, code=500102, data=line_number, message=message) + + # 组装一个测试子项 + current_subDemand = { + 'subName': item_name, + 'subDescription': item_desc, + 'subStep': [] + } + except Exception as e: + message = f"您字符串中,第{line_number}行解析错误,错误原因请检查" + print('解析^行报错,后台详情:', e) + return ChenResponse(status=200, code=500103, data=line_number, message=message) + + elif '@' in line and current_subDemand is not None: + try: + [operation, expect] = line.split('@') + current_subDemand['subStep'].append({ # type:ignore + 'operation': operation, + 'expect': expect + }) + except Exception as e: + message = f"第{line_number}发现您子项步骤格式有问题,请检查" + print('解析步骤行报错,后台详情:', e) + return ChenResponse(status=200, code=500104, data=line_number, message=message) + else: + # 这里就是即没有^也没有@的情况,直接跳出本次循环即可 + continue + # 添加最后一个测试项 + if current_subDemand: + create_subDemands.append(current_subDemand) + return create_subDemands + +def parse_case_content_string(content: str): + """ + 解析前端传来的批量新增测试用例test_step字段 + """ + # 如果为空返回空列表-不会引起错误因为前端限制 + if not content or not content.strip(): + return [] + create_step = [] # 储存测试子项内容 + current_step: None | dict = None + lines = content.strip().split("\n") + line_number = 0 + for i, line in enumerate(lines): + line_number = i + 1 + line = line.strip() + # 跳过空行 + if not line: + continue + # 判断是否有“@”,如果没有则给用户报错 + if "@" not in line: + message = f"第{line_number}行没有使用@符号分割,请检查!" + return ChenResponse(status=200, code=60001, data=line_number, message=message) + # 这里必然有@,组装current_step + [operation, expect] = line.strip().split("@") + # 错误处理两种情况,操作为空,预期为空 + if not operation.strip(): + message = f"第{line_number}行@符号前面的输入内容为空,请检查!" + return ChenResponse(status=200, code=60002, data=line_number, message=message) + if not expect.strip(): + message = f"第{line_number}行@符号后面的预期为空,请检查!" + return ChenResponse(status=200, code=60003, data=line_number, message=message) + # 组装当前步骤行 + current_step = { + "operation": operation, + "expect": expect + } + if current_step: + create_step.append(current_step) + + + return create_step diff --git a/apps/project/tools/__pycache__/auto_create_data.cpython-313.pyc b/apps/project/tools/__pycache__/auto_create_data.cpython-313.pyc index 3f6705d..c5449c5 100644 Binary files a/apps/project/tools/__pycache__/auto_create_data.cpython-313.pyc and b/apps/project/tools/__pycache__/auto_create_data.cpython-313.pyc differ diff --git a/apps/project/tools/__pycache__/rj_data_cont.cpython-313.pyc b/apps/project/tools/__pycache__/rj_data_cont.cpython-313.pyc new file mode 100644 index 0000000..c920508 Binary files /dev/null and b/apps/project/tools/__pycache__/rj_data_cont.cpython-313.pyc differ diff --git a/apps/project/tools/auto_create_data.py b/apps/project/tools/auto_create_data.py index 9e52a8b..644eec5 100644 --- a/apps/project/tools/auto_create_data.py +++ b/apps/project/tools/auto_create_data.py @@ -10,6 +10,9 @@ from apps.project.models import ( CaseStep ) +# 导入人机交互界面固定数据 +from apps.project.tools.rj_data_cont import rj_data + def auto_create_jt_and_dm(user_name: str, dut_qs: Dut, project_obj: Project): """传入源代码dut以及测试人员名称username,自动在dut下面生成静态分析和代码审查设计需求、测试项、用例""" # 先查询dut_qs下面有多少design,以便写里面的key @@ -188,20 +191,22 @@ def auto_create_wd(user_name: str, dut_qs: Dut, project_obj: Project): 'testMethod': ["3"], 'title': '文档审查', 'testDesciption': '本次文档审查包括的内容如下:\a' - '1)软件研制总结报告\a' - '2)软件开发计划\a' - '3)软件运行方案说明\a' - '4)软件接口需求规格说明\a' - '5)软件系统设计说明\a' - '6)软件接口设计说明\a' - '7)软件需求规格说明\a' - '8)软件配置项设计说明\a' - '9)软件测试说明\a' - '10)软件测试报告\a' - '11)产品规格说明\a' - '12)软件版本说明\a' - '13)软件用户手册\a' - '14)固件保障手册', + '1)软件需求规格说明\a' + '2)软件详细设计说明\a' + '3)软件开发计划\a' + '4)软件配置管理计划\a' + '5)软件质量保证计划\a' + '6)软件单元测试计划\a' + '7)软件单元测试说明\a' + '8)软件单元测试报告\a' + '9)配置项测试计划\a' + '10)配置项测试说明\a' + '11)配置项测试报告\a' + '12)软件用户手册\a' + '13)软件研制总结报告\a' + '14)软件版本说明\a' + '15)软件产品规格说明\a' + '16)固件保障手册', 'key': ''.join([new_wd_design_obj.key, '-', '0']), 'level': '3', 'project': project_obj, @@ -216,7 +221,10 @@ def auto_create_wd(user_name: str, dut_qs: Dut, project_obj: Project): operation='根据文档审查表人工逐项检查,检查此项目文档的齐套性、完整性、规范性:\a' '1)使用人工审查方法,按照附录A中文档齐套性审查单检查需求类、设计类、用户类、测试类文档是否齐套;\a' '2)使用人工审查方法,按照附录A中需求规格说明审查单对软件需求规格说明逐项检查;\a' - '3)使用人工审查方法,按照附录A中软件设计文档审查单逐项检查。' + '3)使用人工审查方法,按照附录A中软件设计文档审查单逐项检查。', + expect='被测软件文档种类齐全,内容完整,描述准确,格式规范;\a' + '2)需求文档内容完整,描述准确,格式规范,文档文文一致、文实相符;\a' + '3)设计说明文档内容完整,描述准确,格式规范,文档文文一致、文实相符。', ) new_wd_case_obj = Case.objects.create( ident='WDSC', @@ -247,3 +255,74 @@ def auto_create_wd(user_name: str, dut_qs: Dut, project_obj: Project): expect='文档满足完整性、准确性、规范性和一致性的要求', result='文档检查单全部审查通过,文档内容完整、文档描述准确、' '文档格式规范、文档文文一致', ) + +def auto_create_renji(user_name: str, dut_qs: Dut, project_obj: Project): + """传入用户名、在dut下创建、项目对象,自动创建人机交互界面的设计需求、测试项、测试用例""" + # 先查询dut_qs下有多少desgin,用于设置key + design_index = dut_qs.rsField.count() + for item in rj_data: + # 创建设计需求 + rj_design_create_dict = { + 'ident': item['ident'], + 'name': item['desgin_name'], + 'demandType': '6', + 'description': item['xq_desc'], + 'title': item['desgin_name'], + 'key': ''.join([dut_qs.key, '-', str(design_index)]), + 'level': '2', + 'chapter': '/', + 'project': project_obj, + 'round': dut_qs.round, + 'dut': dut_qs + } + design_index += 1 + new_design_rj: Design = Design.objects.create(**rj_design_create_dict) + # 创建测试项 + rj_demand_create_dict = { + 'ident': item['ident'], + 'name': item['test_item_name'], + 'adequacy': item['chongfen'], + 'priority': '2', + 'testType': '12', + 'testMethod': ["4"], + 'testDesciption': '在界面进行观察与操作,对照需求规格说明的功能需求进行比对,对照用户手册进行比对', + 'title': item['test_item_name'], + 'key': ''.join([new_design_rj.key, '-', '0']), + 'level': '3', + 'project': project_obj, + 'round': new_design_rj.round, + 'dut': new_design_rj.dut, + 'design': new_design_rj, + } + new_demand_rj = TestDemand.objects.create(**rj_demand_create_dict) + new_demand_content_obj = TestDemandContent.objects.create(testDemand=new_demand_rj, + subName=item['test_item_name']) + for operation in item['test_method']: + TestDemandContentStep.objects.create(testDemandContent=new_demand_content_obj, + operation=operation['caozuo'] + , expect=operation['yuqi']) + # 创建测试用例 + new_case_rj = Case.objects.create( + ident=item['ident'], + name=item['test_item_name'], + initialization='已获取被测件的用户手册', + premise='软件可正常运行,界面初始化完成', + summarize=item['xq_desc'], + designPerson=user_name, + testPerson=user_name, + monitorPerson=user_name, + project=project_obj, + isLeaf=True, + round=new_demand_rj.round, + dut=new_demand_rj.dut, + design=new_demand_rj.design, + test=new_demand_rj, + title=item['test_item_name'], + key=''.join([new_demand_rj.key, '-', '0']), + level='4' + ) + for operation in item['test_method']: + CaseStep.objects.create(case=new_case_rj, + operation=operation['caozuo'], + expect=operation['yuqi'], + result='界面操作结果符合预期', ) diff --git a/apps/project/tools/rj_data_cont.py b/apps/project/tools/rj_data_cont.py new file mode 100644 index 0000000..37ec927 --- /dev/null +++ b/apps/project/tools/rj_data_cont.py @@ -0,0 +1,141 @@ +# 人机交互界面测试自动生成 +rj_data = [ + { + "desgin_name": "人机交互完整性", + "test_item_name": "人机交互完整性测试", + "ident": "WZXC", + "xq_desc": "测试软件人机交互界面的完整性", + "chongfen": "测试用例覆盖人机交互界面完整性子项要求的全部内容。\a" + "所有用例执行完毕,对于未执行的用例说明未执行原因。", + "test_method": [ + { + "caozuo": "检查界面菜单名称、标签名称、按键名称的完整性", + "yuqi": "名称完整" + }, + { + "caozuo": "检查界面显示区内容的完整性", + "yuqi": "显示内容完整" + }, + { + "caozuo": "检查界面菜单功能的完整性", + "yuqi": "菜单功能完整" + }, + ] + }, + { + "desgin_name": "人机交互界面一致性", + "test_item_name": "人机交互界面一致性测试", + "ident": "YZXC", + "xq_desc": "测试软件人机交互界面的一致性", + "chongfen": "测试用例覆盖人机交互界面一致性子项要求的全部内容。\a" + "所有用例执行完毕,对于未执行的用例说明未执行原因。", + "test_method": [ + { + "caozuo": "检查主界面的标题栏与使用说明书的一致性", + "yuqi": "主界面的标题栏与用户手册一致" + }, + { + "caozuo": "检查次级界面、对话框等标题与使用说书的一致性", + "yuqi": "次级界面、对话框等标题与用户手册一致" + }, + { + "caozuo": "检查界面用语与使用说明书的一致性", + "yuqi": "界面用语与用户手册一致" + }, + { + "caozuo": "检查界面的字体、颜色、位置等是否统一、字体是否对齐", + "yuqi": "界面的字体、颜色、位置等与用户手册一致" + }, + { + "caozuo": "检查同类数据的显示精度是否正确、统一", + "yuqi": "同类数据的显示精度与用户手册一致,精确并统一" + }, + ] + }, + { + "desgin_name": "人机交互界面友好性", + "test_item_name": "人机交互界面友好性测试", + "ident": "YHXC", + "xq_desc": "测试软件人机交互界面的友好性", + "chongfen": "测试用例覆盖人机交互界面友好性子项要求的全部内容。\a" + "所有用例执行完毕,对于未执行的用例说明未执行原因。", + "test_method": [ + { + "caozuo": "检查界面实时显示信息区是否实时刷新", + "yuqi": "实时刷新" + }, + { + "caozuo": "检查提示信息显示位置是否合理、提示框或弹窗是否居中显示", + "yuqi": "合理、弹窗居中" + }, + { + "caozuo": "检查界面用语、名称等是否存在错别字、乱码等", + "yuqi": "无错别字或乱码" + }, + { + "caozuo": "检查界面字符显示是否清晰", + "yuqi": "字符显示清晰" + }, + { + "caozuo": "检查界面字符或提示语是否统一、汉化", + "yuqi": "统一汉化显示" + }, + ] + }, + { + "desgin_name": "人机交互界面易操作性", + "test_item_name": "人机交互界面易操作性测试", + "ident": "YCZX", + "xq_desc": "测试软件人机交互界面的易操作性", + "chongfen": "测试用例覆盖人机交互界面易操作性子项要求的全部内容。\a" + "所有用例执行完毕,对于未执行的用例说明未执行原因。", + "test_method": [ + { + "caozuo": "检查界面菜单、图标、按键等是否分布整齐、有序", + "yuqi": "分布整齐有序" + }, + { + "caozuo": "检查菜单深度的合理性", + "yuqi": "菜单深度不超过3级" + }, + ] + }, + { + "desgin_name": "人机交互界面操作测试", + "test_item_name": "人机交互界面操作测试测试", + "ident": "CZCC", + "xq_desc": "测试软件人机交互的界面操作测试", + "chongfen": "测试用例覆盖人机交互界面操作测试子项要求的全部内容。\a" + "所有用例执行完毕,对于未执行的用例说明未执行原因。", + "test_method": [ + { + "caozuo": "检查按键、编辑框等使能情况(闪烁)", + "yuqi": "闪烁" + }, + { + "caozuo": "执行任务期间,进行按键的多处连击", + "yuqi": "不会出现假死或崩溃" + }, + { + "caozuo": "检查列表,列表中的内容允许编辑、数据变更后自动更新显示", + "yuqi": "内容允许编辑、数据变更后自动更新显示" + }, + { + "caozuo": "能够进行选择和取消,选择及取消后处理正确", + "yuqi": "能够进行选择和取消,选择及取消后处理正确" + }, + { + "caozuo": "选择或取消某个单选框后再进行复选操作", + "yuqi": "操作正确" + }, + { + "caozuo": "执行一个任务,查看界面操作及显示的正确性", + "yuqi": "界面操作及显示正确" + }, + { + "caozuo": "在一个菜单功能项执行过程中用使用按钮选择其他功能", + "yuqi": "不会出现假死或崩溃情况" + }, + ] + }, +] diff --git a/conf/base_document/form_template/dg/动态测试环境说明.docx b/conf/base_document/form_template/dg/动态测试环境说明.docx index a3d5a4a..6eef1eb 100644 Binary files a/conf/base_document/form_template/dg/动态测试环境说明.docx and b/conf/base_document/form_template/dg/动态测试环境说明.docx differ diff --git a/conf/base_document/form_template/dg/动态软件项.docx b/conf/base_document/form_template/dg/动态软件项.docx index 213d189..190492f 100644 Binary files a/conf/base_document/form_template/dg/动态软件项.docx and b/conf/base_document/form_template/dg/动态软件项.docx differ diff --git a/conf/base_document/form_template/dg/技术依据文件.docx b/conf/base_document/form_template/dg/技术依据文件.docx index f2cab7b..c6c2284 100644 Binary files a/conf/base_document/form_template/dg/技术依据文件.docx and b/conf/base_document/form_template/dg/技术依据文件.docx differ diff --git a/conf/base_document/form_template/dg/标准依据文件.docx b/conf/base_document/form_template/dg/标准依据文件.docx index 0405408..a2762d0 100644 Binary files a/conf/base_document/form_template/dg/标准依据文件.docx and b/conf/base_document/form_template/dg/标准依据文件.docx differ diff --git a/conf/base_document/form_template/dg/测评时间和地点.docx b/conf/base_document/form_template/dg/测评时间和地点.docx index 8f797ce..4e397ce 100644 Binary files a/conf/base_document/form_template/dg/测评时间和地点.docx and b/conf/base_document/form_template/dg/测评时间和地点.docx differ diff --git a/conf/base_document/form_template/dg/测试内容充分性及测试方法有效性分析.docx b/conf/base_document/form_template/dg/测试内容充分性及测试方法有效性分析.docx index 7342627..c05d6af 100644 Binary files a/conf/base_document/form_template/dg/测试内容充分性及测试方法有效性分析.docx and b/conf/base_document/form_template/dg/测试内容充分性及测试方法有效性分析.docx differ diff --git a/conf/base_document/form_template/dg/测试策略.docx b/conf/base_document/form_template/dg/测试策略.docx index e3acea7..f698332 100644 Binary files a/conf/base_document/form_template/dg/测试策略.docx and b/conf/base_document/form_template/dg/测试策略.docx differ diff --git a/conf/base_document/form_template/dg/测试级别和测试类型.docx b/conf/base_document/form_template/dg/测试级别和测试类型.docx index e83ecd5..ed7b513 100644 Binary files a/conf/base_document/form_template/dg/测试级别和测试类型.docx and b/conf/base_document/form_template/dg/测试级别和测试类型.docx differ diff --git a/conf/base_document/form_template/dg/测试项及方法.docx b/conf/base_document/form_template/dg/测试项及方法.docx index e1aa9da..2d814f2 100644 Binary files a/conf/base_document/form_template/dg/测试项及方法.docx and b/conf/base_document/form_template/dg/测试项及方法.docx differ diff --git a/conf/base_document/form_template/dg/研制总要求追踪表.docx b/conf/base_document/form_template/dg/研制总要求追踪表.docx index 7611f78..7ca3674 100644 Binary files a/conf/base_document/form_template/dg/研制总要求追踪表.docx and b/conf/base_document/form_template/dg/研制总要求追踪表.docx differ diff --git a/conf/base_document/form_template/dg/被测软件基本信息.docx b/conf/base_document/form_template/dg/被测软件基本信息.docx index 6c7a36b..f7cbc5f 100644 Binary files a/conf/base_document/form_template/dg/被测软件基本信息.docx and b/conf/base_document/form_template/dg/被测软件基本信息.docx differ diff --git a/conf/base_document/form_template/dg/需求规格说明追踪表.docx b/conf/base_document/form_template/dg/需求规格说明追踪表.docx index 3c4dd8a..192b96e 100644 Binary files a/conf/base_document/form_template/dg/需求规格说明追踪表.docx and b/conf/base_document/form_template/dg/需求规格说明追踪表.docx differ diff --git a/conf/base_document/form_template/dg/顶层技术文件.docx b/conf/base_document/form_template/dg/顶层技术文件.docx index 27b7e96..1442924 100644 Binary files a/conf/base_document/form_template/dg/顶层技术文件.docx and b/conf/base_document/form_template/dg/顶层技术文件.docx differ diff --git a/conf/base_document/form_template/products/回归测试记录.docx b/conf/base_document/form_template/products/回归测试记录.docx index 913866c..65d4486 100644 Binary files a/conf/base_document/form_template/products/回归测试记录.docx and b/conf/base_document/form_template/products/回归测试记录.docx differ diff --git a/conf/base_document/form_template/products/回归测试说明.docx b/conf/base_document/form_template/products/回归测试说明.docx index 301b0b8..75ec53c 100644 Binary files a/conf/base_document/form_template/products/回归测试说明.docx and b/conf/base_document/form_template/products/回归测试说明.docx differ diff --git a/conf/base_document/form_template/products/测评大纲.docx b/conf/base_document/form_template/products/测评大纲.docx index 067c379..fa2506b 100644 Binary files a/conf/base_document/form_template/products/测评大纲.docx and b/conf/base_document/form_template/products/测评大纲.docx differ diff --git a/conf/base_document/form_template/products/测评报告.docx b/conf/base_document/form_template/products/测评报告.docx index 05290b5..d527a5f 100644 Binary files a/conf/base_document/form_template/products/测评报告.docx and b/conf/base_document/form_template/products/测评报告.docx differ diff --git a/conf/base_document/form_template/products/测试记录.docx b/conf/base_document/form_template/products/测试记录.docx index 1b0fdcc..0bb93ad 100644 Binary files a/conf/base_document/form_template/products/测试记录.docx and b/conf/base_document/form_template/products/测试记录.docx differ diff --git a/conf/base_document/form_template/products/测试说明.docx b/conf/base_document/form_template/products/测试说明.docx index 81325ba..4552bf5 100644 Binary files a/conf/base_document/form_template/products/测试说明.docx and b/conf/base_document/form_template/products/测试说明.docx differ diff --git a/conf/base_document/form_template/products/问题单.docx b/conf/base_document/form_template/products/问题单.docx index 6d7002e..f8beeda 100644 Binary files a/conf/base_document/form_template/products/问题单.docx and b/conf/base_document/form_template/products/问题单.docx differ diff --git a/logs/root_log b/logs/root_log index 113797d..3a41c6e 100644 --- a/logs/root_log +++ b/logs/root_log @@ -439,3 +439,1110 @@ TypeError: Object of type AIPostSchema is not JSON serializable [ERROR][2025-12-04 09:55:44,899][log.py:253]Internal Server Error: /api/project/testDemand/save [ERROR][2025-12-04 09:57:37,563][log.py:253]Internal Server Error: /api/project/testDemand/save [ERROR][2025-12-04 09:58:39,189][log.py:253]Internal Server Error: /api/project/testDemand/save +[WARNING][2025-12-07 15:05:08,442][log.py:249]Unauthorized: /api/system/getInfo +[WARNING][2025-12-07 15:05:08,500][log.py:249]Unauthorized: /api/system/logout +[WARNING][2025-12-07 15:05:12,874][backend.py:91]Caught LDAPError looking up user: SERVER_DOWN({'result': -1, 'desc': "Can't contact LDAP server", 'ctrls': []}) +[WARNING][2025-12-08 10:22:48,387][log.py:249]Unauthorized: /api/system/getInfo +[WARNING][2025-12-08 10:22:48,442][log.py:249]Unauthorized: /api/system/logout +[WARNING][2025-12-08 10:22:51,885][backend.py:91]Caught LDAPError looking up user: SERVER_DOWN({'result': -1, 'desc': "Can't contact LDAP server", 'ctrls': []}) +[ERROR][2025-12-08 10:53:52,530][log.py:249]Internal Server Error: /api/project/testDemand/update/554 +[WARNING][2025-12-08 13:13:15,058][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-08 13:13:15,064][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-08 13:13:23,194][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-08 13:13:23,204][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-08 13:14:49,599][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-08 13:14:49,612][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-08 13:14:53,939][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-08 13:14:53,948][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-08 13:14:56,401][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-08 13:14:56,410][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-08 13:15:48,359][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-08 13:15:48,369][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-08 13:16:33,358][backend.py:91]Caught LDAPError looking up user: SERVER_DOWN({'result': -1, 'desc': "Can't contact LDAP server", 'ctrls': []}) +[WARNING][2025-12-08 13:16:37,452][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-08 13:16:37,464][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-08 13:16:45,773][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-08 13:16:45,783][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-08 13:18:22,383][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-08 13:18:22,450][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-08 13:20:09,088][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-08 13:20:09,097][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-09 11:15:55,519][log.py:249]Unauthorized: /api/system/getInfo +[WARNING][2025-12-09 11:15:55,577][log.py:249]Unauthorized: /api/system/logout +[WARNING][2025-12-09 11:22:22,834][backend.py:91]Caught LDAPError looking up user: SERVER_DOWN({'result': -1, 'desc': "Can't contact LDAP server", 'ctrls': []}) +[WARNING][2025-12-09 11:22:42,163][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-09 11:22:42,172][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-09 11:22:58,464][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-09 11:22:58,475][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-09 11:23:50,507][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-09 11:23:50,521][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-09 11:23:59,282][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-09 11:23:59,304][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-09 11:24:57,850][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-09 11:24:57,859][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-09 11:25:51,958][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-09 11:25:51,966][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-09 11:26:57,165][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-09 11:26:57,174][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-09 11:27:30,335][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-09 11:27:30,343][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-09 11:31:36,330][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-09 11:31:36,339][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-09 11:31:44,440][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-09 11:31:44,450][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-09 11:31:47,092][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-09 11:31:47,100][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-09 11:31:49,949][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-09 11:31:49,961][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-09 13:04:14,799][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-09 13:04:14,810][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-09 13:06:28,392][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-09 13:06:28,403][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-09 13:06:42,226][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-09 13:06:42,235][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-09 13:06:56,591][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-09 13:06:56,601][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-09 13:06:58,810][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-09 13:06:58,821][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-09 13:07:21,387][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-09 13:07:21,400][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-09 13:07:24,132][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-09 13:07:24,142][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-09 13:07:33,878][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-09 13:07:33,889][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-09 13:07:46,630][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-09 13:07:46,644][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-09 13:09:00,690][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-09 13:09:00,702][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-09 13:09:19,001][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-09 13:09:19,012][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-09 13:09:25,655][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-09 13:09:25,665][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-09 13:10:51,324][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-09 13:10:51,336][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-09 13:10:54,125][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-09 13:10:54,134][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-09 13:11:12,004][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-09 13:11:12,013][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-09 13:11:14,178][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-09 13:11:14,190][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-09 13:11:27,295][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-09 13:11:27,307][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-09 13:11:30,159][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-09 13:11:30,172][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-09 13:11:53,931][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-09 13:11:53,940][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-09 13:12:25,181][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-09 13:12:25,189][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-09 13:12:29,393][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-09 13:12:29,404][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-09 13:12:31,547][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-09 13:12:31,558][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-09 13:12:40,911][operation.py:131]"GET - DesignController[get_dut] /api/project/getDesignOne" (500, '未找到相应的数据') +[ERROR][2025-12-09 13:12:40,922][log.py:249]Internal Server Error: /api/project/getDesignOne +[WARNING][2025-12-10 09:30:38,754][log.py:249]Unauthorized: /api/system/getInfo +[WARNING][2025-12-10 09:30:38,767][log.py:249]Unauthorized: /api/system/logout +[WARNING][2025-12-10 09:30:42,017][backend.py:91]Caught LDAPError looking up user: SERVER_DOWN({'result': -1, 'desc': "Can't contact LDAP server", 'ctrls': []}) +[WARNING][2025-12-10 13:32:02,742][log.py:249]Unauthorized: /api/system/getInfo +[WARNING][2025-12-10 13:32:02,858][log.py:249]Unauthorized: /api/system/logout +[WARNING][2025-12-10 13:35:24,533][backend.py:91]Caught LDAPError looking up user: SERVER_DOWN({'result': -1, 'desc': "Can't contact LDAP server", 'ctrls': []}) +[WARNING][2025-12-11 13:58:06,698][log.py:249]Unauthorized: /api/system/getInfo +[WARNING][2025-12-11 13:58:06,755][log.py:249]Unauthorized: /api/system/logout +[WARNING][2025-12-11 13:58:12,066][backend.py:91]Caught LDAPError looking up user: SERVER_DOWN({'result': -1, 'desc': "Can't contact LDAP server", 'ctrls': []}) +[WARNING][2025-12-12 09:13:42,453][log.py:249]Unauthorized: /api/system/getInfo +[WARNING][2025-12-12 09:13:42,494][log.py:249]Unauthorized: /api/system/logout +[WARNING][2025-12-12 09:14:05,727][backend.py:91]Caught LDAPError looking up user: SERVER_DOWN({'result': -1, 'desc': "Can't contact LDAP server", 'ctrls': []}) +[WARNING][2025-12-12 10:11:40,953][operation.py:131]"POST - GenerateSeitaiController[create_dgDocument] /api/create/dgDocument" (500, '第一轮次被测件:需求规格说明可能未创建,生成文档失败') +[ERROR][2025-12-12 10:11:40,953][log.py:249]Internal Server Error: /api/create/dgDocument +[WARNING][2025-12-12 10:16:22,201][log.py:249]Bad Request: /api/project/round/delete +[WARNING][2025-12-12 16:13:07,886][log.py:249]Not Found: /api/project/create_renji/ +[WARNING][2025-12-12 16:13:14,697][log.py:249]Not Found: /api/project/create_renji/ +[WARNING][2025-12-12 16:13:29,436][log.py:249]Not Found: /api/project/create_renji/ +[WARNING][2025-12-12 16:21:44,243][log.py:249]Payment Required: /api/project/create_renji/ +[WARNING][2025-12-12 16:22:09,411][log.py:249]Payment Required: /api/project/create_renji/ +[WARNING][2025-12-12 16:23:07,595][log.py:249]Payment Required: /api/project/create_renji/ +[WARNING][2025-12-12 16:23:10,268][log.py:249]Payment Required: /api/project/create_renji/ +[WARNING][2025-12-12 16:23:24,260][log.py:249]Payment Required: /api/project/create_renji/ +[WARNING][2025-12-12 16:23:27,898][log.py:249]Payment Required: /api/project/create_renji/ +[WARNING][2025-12-12 16:24:00,791][log.py:249]Payment Required: /api/project/create_renji/ +[WARNING][2025-12-15 09:05:32,300][log.py:249]Unauthorized: /api/system/getInfo +[WARNING][2025-12-15 09:05:32,334][log.py:249]Unauthorized: /api/system/logout +[WARNING][2025-12-15 09:05:37,471][backend.py:91]Caught LDAPError looking up user: SERVER_DOWN({'result': -1, 'desc': "Can't contact LDAP server", 'ctrls': []}) +[WARNING][2025-12-15 09:33:41,980][log.py:249]Unauthorized: /api/system/getInfo +[WARNING][2025-12-15 09:33:41,992][log.py:249]Unauthorized: /api/system/logout +[WARNING][2025-12-15 09:57:02,672][operation.py:131]"GET - TestDemandController[get_test_demand_list] /api/project/getTestDemandList" (1054, "Unknown column 'project_testdemandcontent.subDescription' in 'field list'") +[ERROR][2025-12-15 09:57:02,672][errors.py:131](1054, "Unknown column 'project_testdemandcontent.subDescription' in 'field list'") +Traceback (most recent call last): + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\backends\utils.py", line 105, in _execute + return self.cursor.execute(sql, params) + ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\backends\mysql\base.py", line 78, in execute + return self.cursor.execute(query, args) + ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\MySQLdb\cursors.py", line 179, in execute + res = self._query(mogrified_query) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\MySQLdb\cursors.py", line 330, in _query + db.query(q) + ~~~~~~~~^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\MySQLdb\connections.py", line 280, in query + _mysql.connection.query(self, query) + ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^ +MySQLdb.OperationalError: (1054, "Unknown column 'project_testdemandcontent.subDescription' in 'field list'") + +The above exception was the direct cause of the following exception: + +Traceback (most recent call last): + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 212, in run + result = self.view_func(request, **ctx.kwargs["view_func_kwargs"]) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\controllers\route\route_functions.py", line 99, in as_view + result = self.route.view_func( + ctx.controller_instance, *args, **ctx.view_func_kwargs + ) + File "D:\python13\Lib\contextlib.py", line 85, in inner + return func(*args, **kwds) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja\pagination.py", line 270, in view_with_pagination + items = func(request, **kwargs) + File "E:\pycharmProjects\cdtestplant_v1\apps\project\controllers\testDemand.py", line 64, in get_test_demand_list + for step_obj in query_single.testQField.all(): + ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\models\query.py", line 390, in __iter__ + self._fetch_all() + ~~~~~~~~~~~~~~~^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\models\query.py", line 2000, in _fetch_all + self._result_cache = list(self._iterable_class(self)) + ~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\models\query.py", line 95, in __iter__ + results = compiler.execute_sql( + chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size + ) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\models\sql\compiler.py", line 1624, in execute_sql + cursor.execute(sql, params) + ~~~~~~~~~~~~~~^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\backends\utils.py", line 122, in execute + return super().execute(sql, params) + ~~~~~~~~~~~~~~~^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\backends\utils.py", line 79, in execute + return self._execute_with_wrappers( + ~~~~~~~~~~~~~~~~~~~~~~~~~~~^ + sql, params, many=False, executor=self._execute + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + ) + ^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\backends\utils.py", line 92, in _execute_with_wrappers + return executor(sql, params, many, context) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\backends\utils.py", line 100, in _execute + with self.db.wrap_database_errors: + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\utils.py", line 94, in __exit__ + raise dj_exc_value.with_traceback(traceback) from exc_value + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\backends\utils.py", line 105, in _execute + return self.cursor.execute(sql, params) + ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\backends\mysql\base.py", line 78, in execute + return self.cursor.execute(query, args) + ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\MySQLdb\cursors.py", line 179, in execute + res = self._query(mogrified_query) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\MySQLdb\cursors.py", line 330, in _query + db.query(q) + ~~~~~~~~^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\MySQLdb\connections.py", line 280, in query + _mysql.connection.query(self, query) + ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^ +django.db.utils.OperationalError: (1054, "Unknown column 'project_testdemandcontent.subDescription' in 'field list'") +[ERROR][2025-12-15 09:57:02,696][log.py:249]Internal Server Error: /api/project/getTestDemandList +[WARNING][2025-12-15 09:57:03,692][operation.py:131]"GET - TestDemandController[get_test_demand_one] /api/project/getTestDemandOne" (1054, "Unknown column 'project_testdemandcontent.subDescription' in 'field list'") +[ERROR][2025-12-15 09:57:03,692][errors.py:131](1054, "Unknown column 'project_testdemandcontent.subDescription' in 'field list'") +Traceback (most recent call last): + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\backends\utils.py", line 105, in _execute + return self.cursor.execute(sql, params) + ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\backends\mysql\base.py", line 78, in execute + return self.cursor.execute(query, args) + ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\MySQLdb\cursors.py", line 179, in execute + res = self._query(mogrified_query) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\MySQLdb\cursors.py", line 330, in _query + db.query(q) + ~~~~~~~~^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\MySQLdb\connections.py", line 280, in query + _mysql.connection.query(self, query) + ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^ +MySQLdb.OperationalError: (1054, "Unknown column 'project_testdemandcontent.subDescription' in 'field list'") + +The above exception was the direct cause of the following exception: + +Traceback (most recent call last): + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 212, in run + result = self.view_func(request, **ctx.kwargs["view_func_kwargs"]) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\controllers\route\route_functions.py", line 99, in as_view + result = self.route.view_func( + ctx.controller_instance, *args, **ctx.view_func_kwargs + ) + File "D:\python13\Lib\contextlib.py", line 85, in inner + return func(*args, **kwds) + File "E:\pycharmProjects\cdtestplant_v1\apps\project\controllers\testDemand.py", line 77, in get_test_demand_one + for step_obj in demand_qs.testQField.all(): + ~~~~~~~~~~~~~~~~~~~~~~~~^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\models\query.py", line 390, in __iter__ + self._fetch_all() + ~~~~~~~~~~~~~~~^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\models\query.py", line 2000, in _fetch_all + self._result_cache = list(self._iterable_class(self)) + ~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\models\query.py", line 95, in __iter__ + results = compiler.execute_sql( + chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size + ) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\models\sql\compiler.py", line 1624, in execute_sql + cursor.execute(sql, params) + ~~~~~~~~~~~~~~^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\backends\utils.py", line 122, in execute + return super().execute(sql, params) + ~~~~~~~~~~~~~~~^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\backends\utils.py", line 79, in execute + return self._execute_with_wrappers( + ~~~~~~~~~~~~~~~~~~~~~~~~~~~^ + sql, params, many=False, executor=self._execute + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + ) + ^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\backends\utils.py", line 92, in _execute_with_wrappers + return executor(sql, params, many, context) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\backends\utils.py", line 100, in _execute + with self.db.wrap_database_errors: + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\utils.py", line 94, in __exit__ + raise dj_exc_value.with_traceback(traceback) from exc_value + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\backends\utils.py", line 105, in _execute + return self.cursor.execute(sql, params) + ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\backends\mysql\base.py", line 78, in execute + return self.cursor.execute(query, args) + ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\MySQLdb\cursors.py", line 179, in execute + res = self._query(mogrified_query) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\MySQLdb\cursors.py", line 330, in _query + db.query(q) + ~~~~~~~~^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\MySQLdb\connections.py", line 280, in query + _mysql.connection.query(self, query) + ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^ +django.db.utils.OperationalError: (1054, "Unknown column 'project_testdemandcontent.subDescription' in 'field list'") +[ERROR][2025-12-15 09:57:03,785][log.py:249]Internal Server Error: /api/project/getTestDemandOne +[WARNING][2025-12-15 15:17:50,036][operation.py:131]"GET - GenerateControllerDG[create_xqComparison] /api/generate/create/xqComparison" ("'<' not supported between instances of 'tuple' and 'float'",) +[ERROR][2025-12-15 15:17:50,037][errors.py:131]'<' not supported between instances of 'tuple' and 'float' +Traceback (most recent call last): + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 212, in run + result = self.view_func(request, **ctx.kwargs["view_func_kwargs"]) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\controllers\route\route_functions.py", line 99, in as_view + result = self.route.view_func( + ctx.controller_instance, *args, **ctx.view_func_kwargs + ) + File "E:\pycharmProjects\cdtestplant_v1\apps\createDocument\controllers\dg.py", line 746, in create_xqComparison + print(sorted(design_list, key=chapter_key)) + ~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +TypeError: '<' not supported between instances of 'tuple' and 'float' +[ERROR][2025-12-15 15:17:50,041][log.py:249]Internal Server Error: /api/generate/create/xqComparison +[WARNING][2025-12-15 15:21:57,918][operation.py:131]"GET - GenerateControllerDG[create_xqComparison] /api/generate/create/xqComparison" ("'<' not supported between instances of 'tuple' and 'int'",) +[ERROR][2025-12-15 15:21:57,918][errors.py:131]'<' not supported between instances of 'tuple' and 'int' +Traceback (most recent call last): + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 212, in run + result = self.view_func(request, **ctx.kwargs["view_func_kwargs"]) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\controllers\route\route_functions.py", line 99, in as_view + result = self.route.view_func( + ctx.controller_instance, *args, **ctx.view_func_kwargs + ) + File "E:\pycharmProjects\cdtestplant_v1\apps\createDocument\controllers\dg.py", line 746, in create_xqComparison + print(sorted(design_list, key=chapter_key)) + ~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +TypeError: '<' not supported between instances of 'tuple' and 'int' +[ERROR][2025-12-15 15:21:57,921][log.py:249]Internal Server Error: /api/generate/create/xqComparison +[WARNING][2025-12-15 15:54:44,559][operation.py:131]"GET - GenerateControllerDG[create_xqComparison] /api/generate/create/xqComparison" ("'<' not supported between instances of 'tuple' and 'int'",) +[ERROR][2025-12-15 15:54:44,560][errors.py:131]'<' not supported between instances of 'tuple' and 'int' +Traceback (most recent call last): + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 212, in run + result = self.view_func(request, **ctx.kwargs["view_func_kwargs"]) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\controllers\route\route_functions.py", line 99, in as_view + result = self.route.view_func( + ctx.controller_instance, *args, **ctx.view_func_kwargs + ) + File "E:\pycharmProjects\cdtestplant_v1\apps\createDocument\controllers\dg.py", line 747, in create_xqComparison + design_list = sorted(design_list, key=chapter_key) +TypeError: '<' not supported between instances of 'tuple' and 'int' +[ERROR][2025-12-15 15:54:44,626][log.py:249]Internal Server Error: /api/generate/create/xqComparison +[WARNING][2025-12-15 15:55:42,690][operation.py:131]"GET - GenerateControllerDG[create_xqComparison] /api/generate/create/xqComparison" ('can only concatenate tuple (not "int") to tuple',) +[ERROR][2025-12-15 15:55:42,690][errors.py:131]can only concatenate tuple (not "int") to tuple +Traceback (most recent call last): + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 212, in run + result = self.view_func(request, **ctx.kwargs["view_func_kwargs"]) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\controllers\route\route_functions.py", line 99, in as_view + result = self.route.view_func( + ctx.controller_instance, *args, **ctx.view_func_kwargs + ) + File "E:\pycharmProjects\cdtestplant_v1\apps\createDocument\controllers\dg.py", line 747, in create_xqComparison + design_list = sorted(design_list, key=chapter_key) + File "E:\pycharmProjects\cdtestplant_v1\apps\createDocument\controllers\dg.py", line 842, in chapter_key + big_num += 1 +TypeError: can only concatenate tuple (not "int") to tuple +[ERROR][2025-12-15 15:55:42,696][log.py:249]Internal Server Error: /api/generate/create/xqComparison +[WARNING][2025-12-15 15:56:03,422][operation.py:131]"GET - GenerateControllerDG[create_xqComparison] /api/generate/create/xqComparison" ('can only concatenate tuple (not "int") to tuple',) +[ERROR][2025-12-15 15:56:03,422][errors.py:131]can only concatenate tuple (not "int") to tuple +Traceback (most recent call last): + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 212, in run + result = self.view_func(request, **ctx.kwargs["view_func_kwargs"]) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\controllers\route\route_functions.py", line 99, in as_view + result = self.route.view_func( + ctx.controller_instance, *args, **ctx.view_func_kwargs + ) + File "E:\pycharmProjects\cdtestplant_v1\apps\createDocument\controllers\dg.py", line 747, in create_xqComparison + design_list = sorted(design_list, key=chapter_key) + File "E:\pycharmProjects\cdtestplant_v1\apps\createDocument\controllers\dg.py", line 842, in chapter_key + big_num += 1 +TypeError: can only concatenate tuple (not "int") to tuple +[ERROR][2025-12-15 15:56:03,427][log.py:249]Internal Server Error: /api/generate/create/xqComparison +[WARNING][2025-12-15 15:59:24,732][operation.py:131]"GET - GenerateControllerDG[create_xqComparison] /api/generate/create/xqComparison" ("'<' not supported between instances of 'tuple' and 'int'",) +[ERROR][2025-12-15 15:59:24,738][errors.py:131]'<' not supported between instances of 'tuple' and 'int' +Traceback (most recent call last): + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 212, in run + result = self.view_func(request, **ctx.kwargs["view_func_kwargs"]) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\controllers\route\route_functions.py", line 99, in as_view + result = self.route.view_func( + ctx.controller_instance, *args, **ctx.view_func_kwargs + ) + File "E:\pycharmProjects\cdtestplant_v1\apps\createDocument\controllers\dg.py", line 747, in create_xqComparison + design_list = sorted(design_list, key=chapter_key) +TypeError: '<' not supported between instances of 'tuple' and 'int' +[ERROR][2025-12-15 15:59:24,744][log.py:249]Internal Server Error: /api/generate/create/xqComparison +[WARNING][2025-12-15 16:02:18,376][operation.py:131]"GET - GenerateControllerDG[create_xqComparison] /api/generate/create/xqComparison" ("'<' not supported between instances of 'list' and 'int'",) +[ERROR][2025-12-15 16:02:18,379][errors.py:131]'<' not supported between instances of 'list' and 'int' +Traceback (most recent call last): + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 212, in run + result = self.view_func(request, **ctx.kwargs["view_func_kwargs"]) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\controllers\route\route_functions.py", line 99, in as_view + result = self.route.view_func( + ctx.controller_instance, *args, **ctx.view_func_kwargs + ) + File "E:\pycharmProjects\cdtestplant_v1\apps\createDocument\controllers\dg.py", line 747, in create_xqComparison + design_list = sorted(design_list, key=chapter_key) +TypeError: '<' not supported between instances of 'list' and 'int' +[ERROR][2025-12-15 16:02:18,384][log.py:249]Internal Server Error: /api/generate/create/xqComparison +[WARNING][2025-12-15 16:04:13,121][operation.py:131]"GET - GenerateControllerDG[create_xqComparison] /api/generate/create/xqComparison" ("'<' not supported between instances of 'str' and 'int'",) +[ERROR][2025-12-15 16:04:13,121][errors.py:131]'<' not supported between instances of 'str' and 'int' +Traceback (most recent call last): + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 212, in run + result = self.view_func(request, **ctx.kwargs["view_func_kwargs"]) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\controllers\route\route_functions.py", line 99, in as_view + result = self.route.view_func( + ctx.controller_instance, *args, **ctx.view_func_kwargs + ) + File "E:\pycharmProjects\cdtestplant_v1\apps\createDocument\controllers\dg.py", line 747, in create_xqComparison + design_list = sorted(design_list, key=chapter_key) +TypeError: '<' not supported between instances of 'str' and 'int' +[ERROR][2025-12-15 16:04:13,127][log.py:249]Internal Server Error: /api/generate/create/xqComparison +[WARNING][2025-12-16 09:45:10,579][backend.py:91]Caught LDAPError looking up user: SERVER_DOWN({'result': -1, 'desc': "Can't contact LDAP server", 'ctrls': []}) +[WARNING][2025-12-16 10:39:22,476][operation.py:131]"GET - ProjectController[document_time_show] /api/testmanage/project/document_time_show" (500, '项目结束时间早于最后一轮次结束时间或等于开始时间,请修改项目结束时间') +[ERROR][2025-12-16 10:39:22,481][log.py:249]Internal Server Error: /api/testmanage/project/document_time_show +[WARNING][2025-12-16 10:39:38,412][operation.py:131]"GET - ProjectController[document_time_show] /api/testmanage/project/document_time_show" (500, '项目结束时间早于最后一轮次结束时间或等于开始时间,请修改项目结束时间') +[ERROR][2025-12-16 10:39:38,420][log.py:249]Internal Server Error: /api/testmanage/project/document_time_show +[WARNING][2025-12-17 09:16:51,222][log.py:249]Unauthorized: /api/system/getInfo +[WARNING][2025-12-17 09:16:51,240][log.py:249]Unauthorized: /api/system/logout +[WARNING][2025-12-17 09:17:00,834][backend.py:91]Caught LDAPError looking up user: SERVER_DOWN({'result': -1, 'desc': "Can't contact LDAP server", 'ctrls': []}) +[WARNING][2025-12-17 13:17:55,763][backend.py:91]Caught LDAPError looking up user: SERVER_DOWN({'result': -1, 'desc': "Can't contact LDAP server", 'ctrls': []}) +[WARNING][2025-12-17 13:48:07,048][operation.py:131]"POST - DesignController[multi_create_design] /api/project/designDemand/multi_save" ([{'type': 'missing', 'loc': ('body', 'payload', 'projectId'), 'msg': 'Field required'}, {'type': 'missing', 'loc': ('body', 'payload', 'key'), 'msg': 'Field required'}],) +[WARNING][2025-12-17 13:48:07,059][log.py:249]Unprocessable Content: /api/project/designDemand/multi_save +[WARNING][2025-12-17 13:58:05,302][operation.py:131]"GET - DesignController[get_design_tree] /api/project/getDesignDemandInfo" () +[ERROR][2025-12-17 13:58:05,303][errors.py:131]1 validation error for NinjaResponseSchema +response.24.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +Traceback (most recent call last): + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 214, in run + _processed_results = self._result_to_response( + request, result, ctx.response + ) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja\operation.py", line 280, in _result_to_response + validated_object = response_model.model_validate( + resp_object, context={"request": request, "response_status": status} + ) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\pydantic\main.py", line 716, in model_validate + return cls.__pydantic_validator__.validate_python( + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ + obj, + ^^^^ + ...<5 lines>... + by_name=by_name, + ^^^^^^^^^^^^^^^^ + ) + ^ +pydantic_core._pydantic_core.ValidationError: 1 validation error for NinjaResponseSchema +response.24.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +[ERROR][2025-12-17 13:58:05,307][log.py:249]Internal Server Error: /api/project/getDesignDemandInfo +[WARNING][2025-12-17 14:01:35,405][operation.py:131]"GET - DesignController[get_design_tree] /api/project/getDesignDemandInfo" () +[ERROR][2025-12-17 14:01:35,405][errors.py:131]1 validation error for NinjaResponseSchema +response.24.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +Traceback (most recent call last): + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 214, in run + _processed_results = self._result_to_response( + request, result, ctx.response + ) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja\operation.py", line 280, in _result_to_response + validated_object = response_model.model_validate( + resp_object, context={"request": request, "response_status": status} + ) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\pydantic\main.py", line 716, in model_validate + return cls.__pydantic_validator__.validate_python( + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ + obj, + ^^^^ + ...<5 lines>... + by_name=by_name, + ^^^^^^^^^^^^^^^^ + ) + ^ +pydantic_core._pydantic_core.ValidationError: 1 validation error for NinjaResponseSchema +response.24.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +[ERROR][2025-12-17 14:01:35,406][log.py:249]Internal Server Error: /api/project/getDesignDemandInfo +[WARNING][2025-12-17 14:03:00,327][operation.py:131]"GET - DesignController[get_design_tree] /api/project/getDesignDemandInfo" () +[ERROR][2025-12-17 14:03:00,327][errors.py:131]2 validation errors for NinjaResponseSchema +response.24.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +response.25.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +Traceback (most recent call last): + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 214, in run + _processed_results = self._result_to_response( + request, result, ctx.response + ) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja\operation.py", line 280, in _result_to_response + validated_object = response_model.model_validate( + resp_object, context={"request": request, "response_status": status} + ) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\pydantic\main.py", line 716, in model_validate + return cls.__pydantic_validator__.validate_python( + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ + obj, + ^^^^ + ...<5 lines>... + by_name=by_name, + ^^^^^^^^^^^^^^^^ + ) + ^ +pydantic_core._pydantic_core.ValidationError: 2 validation errors for NinjaResponseSchema +response.24.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +response.25.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +[ERROR][2025-12-17 14:03:00,327][log.py:249]Internal Server Error: /api/project/getDesignDemandInfo +[WARNING][2025-12-17 14:07:29,691][operation.py:131]"POST - DesignController[multi_create_design] /api/project/designDemand/multi_save" (1048, "Column 'chapter' cannot be null") +[ERROR][2025-12-17 14:07:29,691][errors.py:131](1048, "Column 'chapter' cannot be null") +Traceback (most recent call last): + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\backends\utils.py", line 105, in _execute + return self.cursor.execute(sql, params) + ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\backends\mysql\base.py", line 78, in execute + return self.cursor.execute(query, args) + ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\MySQLdb\cursors.py", line 179, in execute + res = self._query(mogrified_query) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\MySQLdb\cursors.py", line 330, in _query + db.query(q) + ~~~~~~~~^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\MySQLdb\connections.py", line 280, in query + _mysql.connection.query(self, query) + ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^ +MySQLdb.IntegrityError: (1048, "Column 'chapter' cannot be null") + +The above exception was the direct cause of the following exception: + +Traceback (most recent call last): + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 212, in run + result = self.view_func(request, **ctx.kwargs["view_func_kwargs"]) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\controllers\route\route_functions.py", line 99, in as_view + result = self.route.view_func( + ctx.controller_instance, *args, **ctx.view_func_kwargs + ) + File "D:\python13\Lib\contextlib.py", line 85, in inner + return func(*args, **kwds) + File "E:\pycharmProjects\cdtestplant_v1\apps\project\controllers\design.py", line 121, in multi_create_design + Design.objects.bulk_create(bulk_list) + ~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\models\manager.py", line 87, in manager_method + return getattr(self.get_queryset(), name)(*args, **kwargs) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\models\query.py", line 833, in bulk_create + returned_columns = self._batched_insert( + objs_without_pk, + ...<4 lines>... + unique_fields=unique_fields, + ) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\models\query.py", line 1956, in _batched_insert + self._insert( + ~~~~~~~~~~~~^ + item, + ^^^^^ + ...<5 lines>... + returning_fields=returning_fields, + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + ) + ^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\models\query.py", line 1918, in _insert + return query.get_compiler(using=using).execute_sql(returning_fields) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\models\sql\compiler.py", line 1925, in execute_sql + cursor.execute(sql, params) + ~~~~~~~~~~~~~~^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\backends\utils.py", line 122, in execute + return super().execute(sql, params) + ~~~~~~~~~~~~~~~^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\backends\utils.py", line 79, in execute + return self._execute_with_wrappers( + ~~~~~~~~~~~~~~~~~~~~~~~~~~~^ + sql, params, many=False, executor=self._execute + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + ) + ^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\backends\utils.py", line 92, in _execute_with_wrappers + return executor(sql, params, many, context) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\backends\utils.py", line 100, in _execute + with self.db.wrap_database_errors: + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\utils.py", line 94, in __exit__ + raise dj_exc_value.with_traceback(traceback) from exc_value + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\backends\utils.py", line 105, in _execute + return self.cursor.execute(sql, params) + ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\backends\mysql\base.py", line 78, in execute + return self.cursor.execute(query, args) + ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\MySQLdb\cursors.py", line 179, in execute + res = self._query(mogrified_query) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\MySQLdb\cursors.py", line 330, in _query + db.query(q) + ~~~~~~~~^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\MySQLdb\connections.py", line 280, in query + _mysql.connection.query(self, query) + ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^ +django.db.utils.IntegrityError: (1048, "Column 'chapter' cannot be null") +[ERROR][2025-12-17 14:07:29,713][log.py:249]Internal Server Error: /api/project/designDemand/multi_save +[WARNING][2025-12-17 14:07:35,712][operation.py:131]"POST - DesignController[multi_create_design] /api/project/designDemand/multi_save" (1048, "Column 'chapter' cannot be null") +[ERROR][2025-12-17 14:07:35,712][errors.py:131](1048, "Column 'chapter' cannot be null") +Traceback (most recent call last): + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\backends\utils.py", line 105, in _execute + return self.cursor.execute(sql, params) + ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\backends\mysql\base.py", line 78, in execute + return self.cursor.execute(query, args) + ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\MySQLdb\cursors.py", line 179, in execute + res = self._query(mogrified_query) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\MySQLdb\cursors.py", line 330, in _query + db.query(q) + ~~~~~~~~^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\MySQLdb\connections.py", line 280, in query + _mysql.connection.query(self, query) + ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^ +MySQLdb.IntegrityError: (1048, "Column 'chapter' cannot be null") + +The above exception was the direct cause of the following exception: + +Traceback (most recent call last): + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 212, in run + result = self.view_func(request, **ctx.kwargs["view_func_kwargs"]) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\controllers\route\route_functions.py", line 99, in as_view + result = self.route.view_func( + ctx.controller_instance, *args, **ctx.view_func_kwargs + ) + File "D:\python13\Lib\contextlib.py", line 85, in inner + return func(*args, **kwds) + File "E:\pycharmProjects\cdtestplant_v1\apps\project\controllers\design.py", line 121, in multi_create_design + Design.objects.bulk_create(bulk_list) + ~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\models\manager.py", line 87, in manager_method + return getattr(self.get_queryset(), name)(*args, **kwargs) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\models\query.py", line 833, in bulk_create + returned_columns = self._batched_insert( + objs_without_pk, + ...<4 lines>... + unique_fields=unique_fields, + ) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\models\query.py", line 1956, in _batched_insert + self._insert( + ~~~~~~~~~~~~^ + item, + ^^^^^ + ...<5 lines>... + returning_fields=returning_fields, + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + ) + ^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\models\query.py", line 1918, in _insert + return query.get_compiler(using=using).execute_sql(returning_fields) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\models\sql\compiler.py", line 1925, in execute_sql + cursor.execute(sql, params) + ~~~~~~~~~~~~~~^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\backends\utils.py", line 122, in execute + return super().execute(sql, params) + ~~~~~~~~~~~~~~~^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\backends\utils.py", line 79, in execute + return self._execute_with_wrappers( + ~~~~~~~~~~~~~~~~~~~~~~~~~~~^ + sql, params, many=False, executor=self._execute + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + ) + ^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\backends\utils.py", line 92, in _execute_with_wrappers + return executor(sql, params, many, context) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\backends\utils.py", line 100, in _execute + with self.db.wrap_database_errors: + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\utils.py", line 94, in __exit__ + raise dj_exc_value.with_traceback(traceback) from exc_value + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\backends\utils.py", line 105, in _execute + return self.cursor.execute(sql, params) + ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\backends\mysql\base.py", line 78, in execute + return self.cursor.execute(query, args) + ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\MySQLdb\cursors.py", line 179, in execute + res = self._query(mogrified_query) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\MySQLdb\cursors.py", line 330, in _query + db.query(q) + ~~~~~~~~^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\MySQLdb\connections.py", line 280, in query + _mysql.connection.query(self, query) + ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^ +django.db.utils.IntegrityError: (1048, "Column 'chapter' cannot be null") +[ERROR][2025-12-17 14:07:35,723][log.py:249]Internal Server Error: /api/project/designDemand/multi_save +[WARNING][2025-12-17 14:08:02,886][operation.py:131]"GET - DesignController[get_design_tree] /api/project/getDesignDemandInfo" () +[ERROR][2025-12-17 14:08:02,887][errors.py:131]2 validation errors for NinjaResponseSchema +response.24.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +response.25.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +Traceback (most recent call last): + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 214, in run + _processed_results = self._result_to_response( + request, result, ctx.response + ) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja\operation.py", line 280, in _result_to_response + validated_object = response_model.model_validate( + resp_object, context={"request": request, "response_status": status} + ) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\pydantic\main.py", line 716, in model_validate + return cls.__pydantic_validator__.validate_python( + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ + obj, + ^^^^ + ...<5 lines>... + by_name=by_name, + ^^^^^^^^^^^^^^^^ + ) + ^ +pydantic_core._pydantic_core.ValidationError: 2 validation errors for NinjaResponseSchema +response.24.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +response.25.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +[ERROR][2025-12-17 14:08:02,888][log.py:249]Internal Server Error: /api/project/getDesignDemandInfo +[WARNING][2025-12-17 14:08:21,974][operation.py:131]"GET - DesignController[get_design_tree] /api/project/getDesignDemandInfo" () +[ERROR][2025-12-17 14:08:21,974][errors.py:131]2 validation errors for NinjaResponseSchema +response.24.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +response.25.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +Traceback (most recent call last): + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 214, in run + _processed_results = self._result_to_response( + request, result, ctx.response + ) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja\operation.py", line 280, in _result_to_response + validated_object = response_model.model_validate( + resp_object, context={"request": request, "response_status": status} + ) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\pydantic\main.py", line 716, in model_validate + return cls.__pydantic_validator__.validate_python( + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ + obj, + ^^^^ + ...<5 lines>... + by_name=by_name, + ^^^^^^^^^^^^^^^^ + ) + ^ +pydantic_core._pydantic_core.ValidationError: 2 validation errors for NinjaResponseSchema +response.24.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +response.25.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +[ERROR][2025-12-17 14:08:21,976][log.py:249]Internal Server Error: /api/project/getDesignDemandInfo +[WARNING][2025-12-18 09:04:40,200][log.py:249]Unauthorized: /api/system/getInfo +[WARNING][2025-12-18 09:04:40,243][log.py:249]Unauthorized: /api/system/logout +[WARNING][2025-12-18 09:04:52,816][backend.py:91]Caught LDAPError looking up user: SERVER_DOWN({'result': -1, 'desc': "Can't contact LDAP server", 'ctrls': []}) +[WARNING][2025-12-18 15:36:58,848][operation.py:131]"POST - TestDemandController[create_multi_test_demand] /api/project/testDemand/multi_save" ([{'type': 'list_type', 'loc': ('body', 'payload', 'demands', 0, 'testContent'), 'msg': 'Input should be a valid list'}],) +[WARNING][2025-12-18 15:36:58,856][log.py:249]Unprocessable Content: /api/project/testDemand/multi_save +[WARNING][2025-12-18 17:18:11,818][operation.py:131]"POST - TestDemandController[create_multi_test_demand] /api/project/testDemand/multi_save" ("'ChenResponse' object has no attribute 'message'",) +[ERROR][2025-12-18 17:18:11,818][errors.py:131]'ChenResponse' object has no attribute 'message' +Traceback (most recent call last): + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 212, in run + result = self.view_func(request, **ctx.kwargs["view_func_kwargs"]) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\controllers\route\route_functions.py", line 99, in as_view + result = self.route.view_func( + ctx.controller_instance, *args, **ctx.view_func_kwargs + ) + File "D:\python13\Lib\contextlib.py", line 85, in inner + return func(*args, **kwds) + File "E:\pycharmProjects\cdtestplant_v1\apps\project\controllers\testDemand.py", line 176, in create_multi_test_demand + print(create_demands.message) + ^^^^^^^^^^^^^^^^^^^^^^ +AttributeError: 'ChenResponse' object has no attribute 'message' +[ERROR][2025-12-18 17:18:11,823][log.py:249]Internal Server Error: /api/project/testDemand/multi_save +[WARNING][2025-12-19 09:27:18,974][log.py:249]Unauthorized: /api/system/getInfo +[WARNING][2025-12-19 09:27:19,003][log.py:249]Unauthorized: /api/system/logout +[WARNING][2025-12-19 09:27:23,808][backend.py:91]Caught LDAPError looking up user: SERVER_DOWN({'result': -1, 'desc': "Can't contact LDAP server", 'ctrls': []}) +[WARNING][2025-12-19 11:18:04,195][log.py:249]Not Found: /api/project/getRelatedTestDemand +[WARNING][2025-12-19 11:19:38,080][log.py:249]Not Found: /api/project/getRelatedTestDemand +[WARNING][2025-12-19 11:19:42,169][log.py:249]Not Found: /api/project/getRelatedTestDemand +[WARNING][2025-12-19 14:25:44,668][log.py:249]Not Found: /api/project/case/multi_save +[WARNING][2025-12-19 14:26:17,046][operation.py:131]"POST - CaseController[multi_case_save] /api/project/case/multi_save" ([{'type': 'missing', 'loc': ('body', 'payload', 'cases', 0, 'test_step'), 'msg': 'Field required'}],) +[WARNING][2025-12-19 14:26:17,055][log.py:249]Unprocessable Content: /api/project/case/multi_save +[WARNING][2025-12-19 14:26:19,771][operation.py:131]"POST - CaseController[multi_case_save] /api/project/case/multi_save" ([{'type': 'missing', 'loc': ('body', 'payload', 'cases', 0, 'test_step'), 'msg': 'Field required'}],) +[WARNING][2025-12-19 14:26:19,781][log.py:249]Unprocessable Content: /api/project/case/multi_save +[WARNING][2025-12-19 15:36:39,268][operation.py:131]"GET - CaseController[get_case_tree] /api/project/getCaseInfo" () +[ERROR][2025-12-19 15:36:39,268][errors.py:131]2 validation errors for NinjaResponseSchema +response.0.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +response.1.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +Traceback (most recent call last): + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 214, in run + _processed_results = self._result_to_response( + request, result, ctx.response + ) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja\operation.py", line 280, in _result_to_response + validated_object = response_model.model_validate( + resp_object, context={"request": request, "response_status": status} + ) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\pydantic\main.py", line 716, in model_validate + return cls.__pydantic_validator__.validate_python( + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ + obj, + ^^^^ + ...<5 lines>... + by_name=by_name, + ^^^^^^^^^^^^^^^^ + ) + ^ +pydantic_core._pydantic_core.ValidationError: 2 validation errors for NinjaResponseSchema +response.0.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +response.1.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +[ERROR][2025-12-19 15:36:39,275][log.py:249]Internal Server Error: /api/project/getCaseInfo +[WARNING][2025-12-19 15:37:25,844][operation.py:131]"GET - CaseController[get_case_tree] /api/project/getCaseInfo" () +[ERROR][2025-12-19 15:37:25,844][errors.py:131]2 validation errors for NinjaResponseSchema +response.0.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +response.1.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +Traceback (most recent call last): + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 214, in run + _processed_results = self._result_to_response( + request, result, ctx.response + ) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja\operation.py", line 280, in _result_to_response + validated_object = response_model.model_validate( + resp_object, context={"request": request, "response_status": status} + ) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\pydantic\main.py", line 716, in model_validate + return cls.__pydantic_validator__.validate_python( + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ + obj, + ^^^^ + ...<5 lines>... + by_name=by_name, + ^^^^^^^^^^^^^^^^ + ) + ^ +pydantic_core._pydantic_core.ValidationError: 2 validation errors for NinjaResponseSchema +response.0.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +response.1.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +[ERROR][2025-12-19 15:37:25,846][log.py:249]Internal Server Error: /api/project/getCaseInfo +[WARNING][2025-12-19 15:37:26,553][operation.py:131]"GET - CaseController[get_case_tree] /api/project/getCaseInfo" () +[ERROR][2025-12-19 15:37:26,553][errors.py:131]2 validation errors for NinjaResponseSchema +response.0.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +response.1.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +Traceback (most recent call last): + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 214, in run + _processed_results = self._result_to_response( + request, result, ctx.response + ) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja\operation.py", line 280, in _result_to_response + validated_object = response_model.model_validate( + resp_object, context={"request": request, "response_status": status} + ) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\pydantic\main.py", line 716, in model_validate + return cls.__pydantic_validator__.validate_python( + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ + obj, + ^^^^ + ...<5 lines>... + by_name=by_name, + ^^^^^^^^^^^^^^^^ + ) + ^ +pydantic_core._pydantic_core.ValidationError: 2 validation errors for NinjaResponseSchema +response.0.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +response.1.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +[ERROR][2025-12-19 15:37:26,555][log.py:249]Internal Server Error: /api/project/getCaseInfo +[WARNING][2025-12-19 15:37:28,948][operation.py:131]"GET - CaseController[get_case_tree] /api/project/getCaseInfo" () +[ERROR][2025-12-19 15:37:28,948][errors.py:131]2 validation errors for NinjaResponseSchema +response.0.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +response.1.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +Traceback (most recent call last): + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 214, in run + _processed_results = self._result_to_response( + request, result, ctx.response + ) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja\operation.py", line 280, in _result_to_response + validated_object = response_model.model_validate( + resp_object, context={"request": request, "response_status": status} + ) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\pydantic\main.py", line 716, in model_validate + return cls.__pydantic_validator__.validate_python( + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ + obj, + ^^^^ + ...<5 lines>... + by_name=by_name, + ^^^^^^^^^^^^^^^^ + ) + ^ +pydantic_core._pydantic_core.ValidationError: 2 validation errors for NinjaResponseSchema +response.0.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +response.1.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +[ERROR][2025-12-19 15:37:28,949][log.py:249]Internal Server Error: /api/project/getCaseInfo +[WARNING][2025-12-19 15:44:55,327][operation.py:131]"GET - CaseController[get_case_tree] /api/project/getCaseInfo" () +[ERROR][2025-12-19 15:44:55,327][errors.py:131]1 validation error for NinjaResponseSchema +response.0.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +Traceback (most recent call last): + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 214, in run + _processed_results = self._result_to_response( + request, result, ctx.response + ) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja\operation.py", line 280, in _result_to_response + validated_object = response_model.model_validate( + resp_object, context={"request": request, "response_status": status} + ) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\pydantic\main.py", line 716, in model_validate + return cls.__pydantic_validator__.validate_python( + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ + obj, + ^^^^ + ...<5 lines>... + by_name=by_name, + ^^^^^^^^^^^^^^^^ + ) + ^ +pydantic_core._pydantic_core.ValidationError: 1 validation error for NinjaResponseSchema +response.0.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +[ERROR][2025-12-19 15:44:55,329][log.py:249]Internal Server Error: /api/project/getCaseInfo +[WARNING][2025-12-19 15:45:56,389][operation.py:131]"GET - CaseController[get_case_tree] /api/project/getCaseInfo" () +[ERROR][2025-12-19 15:45:56,389][errors.py:131]1 validation error for NinjaResponseSchema +response.0.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +Traceback (most recent call last): + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 214, in run + _processed_results = self._result_to_response( + request, result, ctx.response + ) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja\operation.py", line 280, in _result_to_response + validated_object = response_model.model_validate( + resp_object, context={"request": request, "response_status": status} + ) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\pydantic\main.py", line 716, in model_validate + return cls.__pydantic_validator__.validate_python( + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ + obj, + ^^^^ + ...<5 lines>... + by_name=by_name, + ^^^^^^^^^^^^^^^^ + ) + ^ +pydantic_core._pydantic_core.ValidationError: 1 validation error for NinjaResponseSchema +response.0.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +[ERROR][2025-12-19 15:45:56,391][log.py:249]Internal Server Error: /api/project/getCaseInfo +[WARNING][2025-12-19 15:45:57,948][operation.py:131]"GET - CaseController[get_case_tree] /api/project/getCaseInfo" () +[ERROR][2025-12-19 15:45:57,948][errors.py:131]1 validation error for NinjaResponseSchema +response.0.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +Traceback (most recent call last): + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 214, in run + _processed_results = self._result_to_response( + request, result, ctx.response + ) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja\operation.py", line 280, in _result_to_response + validated_object = response_model.model_validate( + resp_object, context={"request": request, "response_status": status} + ) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\pydantic\main.py", line 716, in model_validate + return cls.__pydantic_validator__.validate_python( + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ + obj, + ^^^^ + ...<5 lines>... + by_name=by_name, + ^^^^^^^^^^^^^^^^ + ) + ^ +pydantic_core._pydantic_core.ValidationError: 1 validation error for NinjaResponseSchema +response.0.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +[ERROR][2025-12-19 15:45:57,950][log.py:249]Internal Server Error: /api/project/getCaseInfo +[ERROR][2025-12-19 15:46:29,253][log.py:249]Internal Server Error: /api/project/case/create_by_demand +[WARNING][2025-12-19 15:47:41,071][operation.py:131]"GET - CaseController[get_case_tree] /api/project/getCaseInfo" () +[ERROR][2025-12-19 15:47:41,071][errors.py:131]1 validation error for NinjaResponseSchema +response.0.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +Traceback (most recent call last): + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 214, in run + _processed_results = self._result_to_response( + request, result, ctx.response + ) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja\operation.py", line 280, in _result_to_response + validated_object = response_model.model_validate( + resp_object, context={"request": request, "response_status": status} + ) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\pydantic\main.py", line 716, in model_validate + return cls.__pydantic_validator__.validate_python( + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ + obj, + ^^^^ + ...<5 lines>... + by_name=by_name, + ^^^^^^^^^^^^^^^^ + ) + ^ +pydantic_core._pydantic_core.ValidationError: 1 validation error for NinjaResponseSchema +response.0.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +[ERROR][2025-12-19 15:47:41,073][log.py:249]Internal Server Error: /api/project/getCaseInfo +[WARNING][2025-12-19 15:47:50,358][operation.py:131]"GET - CaseController[get_case_tree] /api/project/getCaseInfo" () +[ERROR][2025-12-19 15:47:50,358][errors.py:131]1 validation error for NinjaResponseSchema +response.0.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +Traceback (most recent call last): + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 214, in run + _processed_results = self._result_to_response( + request, result, ctx.response + ) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja\operation.py", line 280, in _result_to_response + validated_object = response_model.model_validate( + resp_object, context={"request": request, "response_status": status} + ) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\pydantic\main.py", line 716, in model_validate + return cls.__pydantic_validator__.validate_python( + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ + obj, + ^^^^ + ...<5 lines>... + by_name=by_name, + ^^^^^^^^^^^^^^^^ + ) + ^ +pydantic_core._pydantic_core.ValidationError: 1 validation error for NinjaResponseSchema +response.0.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +[ERROR][2025-12-19 15:47:50,359][log.py:249]Internal Server Error: /api/project/getCaseInfo +[WARNING][2025-12-19 15:48:19,534][operation.py:131]"GET - CaseController[get_case_tree] /api/project/getCaseInfo" () +[ERROR][2025-12-19 15:48:19,534][errors.py:131]1 validation error for NinjaResponseSchema +response.0.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +Traceback (most recent call last): + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 214, in run + _processed_results = self._result_to_response( + request, result, ctx.response + ) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja\operation.py", line 280, in _result_to_response + validated_object = response_model.model_validate( + resp_object, context={"request": request, "response_status": status} + ) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\pydantic\main.py", line 716, in model_validate + return cls.__pydantic_validator__.validate_python( + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ + obj, + ^^^^ + ...<5 lines>... + by_name=by_name, + ^^^^^^^^^^^^^^^^ + ) + ^ +pydantic_core._pydantic_core.ValidationError: 1 validation error for NinjaResponseSchema +response.0.title + Input should be a valid string [type=string_type, input_value=None, input_type=NoneType] + For further information visit https://errors.pydantic.dev/2.12/v/string_type +[ERROR][2025-12-19 15:48:19,536][log.py:249]Internal Server Error: /api/project/getCaseInfo +[WARNING][2025-12-19 15:53:11,960][log.py:249]Unauthorized: /api/system/getInfo +[WARNING][2025-12-19 15:53:12,023][log.py:249]Unauthorized: /api/system/logout +[WARNING][2025-12-19 15:53:16,809][backend.py:91]Caught LDAPError looking up user: SERVER_DOWN({'result': -1, 'desc': "Can't contact LDAP server", 'ctrls': []}) diff --git a/media/R2237/final_seitai/测评大纲.docx b/media/R2237/final_seitai/测评大纲.docx index d51bdc0..7d5169c 100644 Binary files a/media/R2237/final_seitai/测评大纲.docx and b/media/R2237/final_seitai/测评大纲.docx differ diff --git a/media/R2237/form_template/dg/技术依据文件.docx b/media/R2237/form_template/dg/技术依据文件.docx index f2cab7b..c6c2284 100644 Binary files a/media/R2237/form_template/dg/技术依据文件.docx and b/media/R2237/form_template/dg/技术依据文件.docx differ diff --git a/media/R2237/form_template/dg/标准依据文件.docx b/media/R2237/form_template/dg/标准依据文件.docx index 0405408..a2762d0 100644 Binary files a/media/R2237/form_template/dg/标准依据文件.docx and b/media/R2237/form_template/dg/标准依据文件.docx differ diff --git a/media/R2237/form_template/dg/测评时间和地点.docx b/media/R2237/form_template/dg/测评时间和地点.docx index 8f797ce..4e397ce 100644 Binary files a/media/R2237/form_template/dg/测评时间和地点.docx and b/media/R2237/form_template/dg/测评时间和地点.docx differ diff --git a/media/R2237/form_template/dg/测试内容充分性及测试方法有效性分析.docx b/media/R2237/form_template/dg/测试内容充分性及测试方法有效性分析.docx index 7342627..15a48c1 100644 Binary files a/media/R2237/form_template/dg/测试内容充分性及测试方法有效性分析.docx and b/media/R2237/form_template/dg/测试内容充分性及测试方法有效性分析.docx differ diff --git a/media/R2237/form_template/dg/测试策略.docx b/media/R2237/form_template/dg/测试策略.docx index e3acea7..f698332 100644 Binary files a/media/R2237/form_template/dg/测试策略.docx and b/media/R2237/form_template/dg/测试策略.docx differ diff --git a/media/R2237/form_template/dg/被测软件基本信息.docx b/media/R2237/form_template/dg/被测软件基本信息.docx index 6c7a36b..f7cbc5f 100644 Binary files a/media/R2237/form_template/dg/被测软件基本信息.docx and b/media/R2237/form_template/dg/被测软件基本信息.docx differ diff --git a/media/R2237/form_template/dg/顶层技术文件.docx b/media/R2237/form_template/dg/顶层技术文件.docx index 27b7e96..1442924 100644 Binary files a/media/R2237/form_template/dg/顶层技术文件.docx and b/media/R2237/form_template/dg/顶层技术文件.docx differ diff --git a/media/R2237/form_template/products/测评大纲.docx b/media/R2237/form_template/products/测评大纲.docx index 067c379..06f8a66 100644 Binary files a/media/R2237/form_template/products/测评大纲.docx and b/media/R2237/form_template/products/测评大纲.docx differ diff --git a/media/R2237/output_dir/主要功能和性能指标.docx b/media/R2237/output_dir/主要功能和性能指标.docx index f4515be..3f38ad2 100644 Binary files a/media/R2237/output_dir/主要功能和性能指标.docx and b/media/R2237/output_dir/主要功能和性能指标.docx differ diff --git a/media/R2237/output_dir/代码质量度量分析表.docx b/media/R2237/output_dir/代码质量度量分析表.docx index f3d3a85..1df0dfa 100644 Binary files a/media/R2237/output_dir/代码质量度量分析表.docx and b/media/R2237/output_dir/代码质量度量分析表.docx differ diff --git a/media/R2237/output_dir/动态测试环境说明.docx b/media/R2237/output_dir/动态测试环境说明.docx index 6f9f450..70e98d1 100644 Binary files a/media/R2237/output_dir/动态测试环境说明.docx and b/media/R2237/output_dir/动态测试环境说明.docx differ diff --git a/media/R2237/output_dir/动态硬件和固件项.docx b/media/R2237/output_dir/动态硬件和固件项.docx index 2cba5b0..54763ca 100644 Binary files a/media/R2237/output_dir/动态硬件和固件项.docx and b/media/R2237/output_dir/动态硬件和固件项.docx differ diff --git a/media/R2237/output_dir/动态软件项.docx b/media/R2237/output_dir/动态软件项.docx index cdbb8da..6bd7793 100644 Binary files a/media/R2237/output_dir/动态软件项.docx and b/media/R2237/output_dir/动态软件项.docx differ diff --git a/media/R2237/output_dir/反向需求规格追踪表.docx b/media/R2237/output_dir/反向需求规格追踪表.docx index 6c69845..f7dd66f 100644 Binary files a/media/R2237/output_dir/反向需求规格追踪表.docx and b/media/R2237/output_dir/反向需求规格追踪表.docx differ diff --git a/media/R2237/output_dir/技术依据文件.docx b/media/R2237/output_dir/技术依据文件.docx index 08ec676..a0bfcd2 100644 Binary files a/media/R2237/output_dir/技术依据文件.docx and b/media/R2237/output_dir/技术依据文件.docx differ diff --git a/media/R2237/output_dir/标准依据文件.docx b/media/R2237/output_dir/标准依据文件.docx index f76ba2d..a7734ac 100644 Binary files a/media/R2237/output_dir/标准依据文件.docx and b/media/R2237/output_dir/标准依据文件.docx differ diff --git a/media/R2237/output_dir/测评对象.docx b/media/R2237/output_dir/测评对象.docx index ded2991..b4ad0d8 100644 Binary files a/media/R2237/output_dir/测评对象.docx and b/media/R2237/output_dir/测评对象.docx differ diff --git a/media/R2237/output_dir/测评数据.docx b/media/R2237/output_dir/测评数据.docx index cb20c8d..d0dd289 100644 Binary files a/media/R2237/output_dir/测评数据.docx and b/media/R2237/output_dir/测评数据.docx differ diff --git a/media/R2237/output_dir/测评时间和地点.docx b/media/R2237/output_dir/测评时间和地点.docx index be45457..f83e8ec 100644 Binary files a/media/R2237/output_dir/测评时间和地点.docx and b/media/R2237/output_dir/测评时间和地点.docx differ diff --git a/media/R2237/output_dir/测评条件保障.docx b/media/R2237/output_dir/测评条件保障.docx index 4a7a769..6b431c5 100644 Binary files a/media/R2237/output_dir/测评条件保障.docx and b/media/R2237/output_dir/测评条件保障.docx differ diff --git a/media/R2237/output_dir/测评组织及任务分工.docx b/media/R2237/output_dir/测评组织及任务分工.docx index f9ef02a..aa91250 100644 Binary files a/media/R2237/output_dir/测评组织及任务分工.docx and b/media/R2237/output_dir/测评组织及任务分工.docx differ diff --git a/media/R2237/output_dir/测试内容充分性及测试方法有效性分析.docx b/media/R2237/output_dir/测试内容充分性及测试方法有效性分析.docx index 8b1edd1..15195fc 100644 Binary files a/media/R2237/output_dir/测试内容充分性及测试方法有效性分析.docx and b/media/R2237/output_dir/测试内容充分性及测试方法有效性分析.docx differ diff --git a/media/R2237/output_dir/测试策略.docx b/media/R2237/output_dir/测试策略.docx index 137bd6f..08fe0db 100644 Binary files a/media/R2237/output_dir/测试策略.docx and b/media/R2237/output_dir/测试策略.docx differ diff --git a/media/R2237/output_dir/测试级别和测试类型.docx b/media/R2237/output_dir/测试级别和测试类型.docx index 03d5bc5..81c43a7 100644 Binary files a/media/R2237/output_dir/测试级别和测试类型.docx and b/media/R2237/output_dir/测试级别和测试类型.docx differ diff --git a/media/R2237/output_dir/测试项及方法.docx b/media/R2237/output_dir/测试项及方法.docx index 070c68f..36eea34 100644 Binary files a/media/R2237/output_dir/测试项及方法.docx and b/media/R2237/output_dir/测试项及方法.docx differ diff --git a/media/R2237/output_dir/环境差异性分析.docx b/media/R2237/output_dir/环境差异性分析.docx index 69ceecf..04bfa65 100644 Binary files a/media/R2237/output_dir/环境差异性分析.docx and b/media/R2237/output_dir/环境差异性分析.docx differ diff --git a/media/R2237/output_dir/研制总要求追踪表.docx b/media/R2237/output_dir/研制总要求追踪表.docx index 2951b35..05e85ad 100644 Binary files a/media/R2237/output_dir/研制总要求追踪表.docx and b/media/R2237/output_dir/研制总要求追踪表.docx differ diff --git a/media/R2237/output_dir/缩略语.docx b/media/R2237/output_dir/缩略语.docx index dedc8ab..1f5a04e 100644 Binary files a/media/R2237/output_dir/缩略语.docx and b/media/R2237/output_dir/缩略语.docx differ diff --git a/media/R2237/output_dir/联系人和方式.docx b/media/R2237/output_dir/联系人和方式.docx index a658687..24d4c26 100644 Binary files a/media/R2237/output_dir/联系人和方式.docx and b/media/R2237/output_dir/联系人和方式.docx differ diff --git a/media/R2237/output_dir/被测软件基本信息.docx b/media/R2237/output_dir/被测软件基本信息.docx index bbd8760..f4c8a04 100644 Binary files a/media/R2237/output_dir/被测软件基本信息.docx and b/media/R2237/output_dir/被测软件基本信息.docx differ diff --git a/media/R2237/output_dir/被测软件接口.docx b/media/R2237/output_dir/被测软件接口.docx index c03640f..f02d017 100644 Binary files a/media/R2237/output_dir/被测软件接口.docx and b/media/R2237/output_dir/被测软件接口.docx differ diff --git a/media/R2237/output_dir/需求规格说明追踪表.docx b/media/R2237/output_dir/需求规格说明追踪表.docx index 70ff328..87635c2 100644 Binary files a/media/R2237/output_dir/需求规格说明追踪表.docx and b/media/R2237/output_dir/需求规格说明追踪表.docx differ diff --git a/media/R2237/output_dir/静态测试环境说明.docx b/media/R2237/output_dir/静态测试环境说明.docx index 7bfe4c3..aa1c932 100644 Binary files a/media/R2237/output_dir/静态测试环境说明.docx and b/media/R2237/output_dir/静态测试环境说明.docx differ diff --git a/media/R2237/output_dir/静态硬件和固件项.docx b/media/R2237/output_dir/静态硬件和固件项.docx index d50c902..8857e92 100644 Binary files a/media/R2237/output_dir/静态硬件和固件项.docx and b/media/R2237/output_dir/静态硬件和固件项.docx differ diff --git a/media/R2237/output_dir/静态软件项.docx b/media/R2237/output_dir/静态软件项.docx index 807ee85..60d9ec7 100644 Binary files a/media/R2237/output_dir/静态软件项.docx and b/media/R2237/output_dir/静态软件项.docx differ diff --git a/media/R2237/output_dir/顶层技术文件.docx b/media/R2237/output_dir/顶层技术文件.docx index c1b646c..f301cfe 100644 Binary files a/media/R2237/output_dir/顶层技术文件.docx and b/media/R2237/output_dir/顶层技术文件.docx differ diff --git a/media/R2237/temp/测评大纲.docx b/media/R2237/temp/测评大纲.docx index d46c9e0..cc38bb0 100644 Binary files a/media/R2237/temp/测评大纲.docx and b/media/R2237/temp/测评大纲.docx differ diff --git a/media/R25138/final_seitai/测评大纲.docx b/media/R25138/final_seitai/测评大纲.docx new file mode 100644 index 0000000..17d6388 Binary files /dev/null and b/media/R25138/final_seitai/测评大纲.docx differ diff --git a/media/R25138/form_template/bg/temporary/研总需归追踪_temp.docx b/media/R25138/form_template/bg/temporary/研总需归追踪_temp.docx new file mode 100644 index 0000000..2149856 Binary files /dev/null and b/media/R25138/form_template/bg/temporary/研总需归追踪_temp.docx differ diff --git a/media/R25138/form_template/bg/总体结论.docx b/media/R25138/form_template/bg/总体结论.docx new file mode 100644 index 0000000..0e8e52a Binary files /dev/null and b/media/R25138/form_template/bg/总体结论.docx differ diff --git a/media/R25138/form_template/bg/技术依据文件.docx b/media/R25138/form_template/bg/技术依据文件.docx new file mode 100644 index 0000000..a04e4ba Binary files /dev/null and b/media/R25138/form_template/bg/技术依据文件.docx differ diff --git a/media/R25138/form_template/bg/摸底清单.docx b/media/R25138/form_template/bg/摸底清单.docx new file mode 100644 index 0000000..910f097 Binary files /dev/null and b/media/R25138/form_template/bg/摸底清单.docx differ diff --git a/media/R25138/form_template/bg/测评完成情况.docx b/media/R25138/form_template/bg/测评完成情况.docx new file mode 100644 index 0000000..c996bf7 Binary files /dev/null and b/media/R25138/form_template/bg/测评完成情况.docx differ diff --git a/media/R25138/form_template/bg/测评时间和地点.docx b/media/R25138/form_template/bg/测评时间和地点.docx new file mode 100644 index 0000000..18ab5bb Binary files /dev/null and b/media/R25138/form_template/bg/测评时间和地点.docx differ diff --git a/media/R25138/form_template/bg/测试内容和结果_第一轮次.docx b/media/R25138/form_template/bg/测试内容和结果_第一轮次.docx new file mode 100644 index 0000000..18e9f80 Binary files /dev/null and b/media/R25138/form_template/bg/测试内容和结果_第一轮次.docx differ diff --git a/media/R25138/form_template/bg/测试内容和结果_第二轮次.docx b/media/R25138/form_template/bg/测试内容和结果_第二轮次.docx new file mode 100644 index 0000000..951a26e Binary files /dev/null and b/media/R25138/form_template/bg/测试内容和结果_第二轮次.docx differ diff --git a/media/R25138/form_template/bg/测试有效性充分性说明.docx b/media/R25138/form_template/bg/测试有效性充分性说明.docx new file mode 100644 index 0000000..020a48d Binary files /dev/null and b/media/R25138/form_template/bg/测试有效性充分性说明.docx differ diff --git a/media/R25138/form_template/bg/研总需归追踪.docx b/media/R25138/form_template/bg/研总需归追踪.docx new file mode 100644 index 0000000..051f263 Binary files /dev/null and b/media/R25138/form_template/bg/研总需归追踪.docx differ diff --git a/media/R25138/form_template/bg/综述.docx b/media/R25138/form_template/bg/综述.docx new file mode 100644 index 0000000..afdb36a Binary files /dev/null and b/media/R25138/form_template/bg/综述.docx differ diff --git a/media/R25138/form_template/bg/被测软件基本信息.docx b/media/R25138/form_template/bg/被测软件基本信息.docx new file mode 100644 index 0000000..7dc9a6a Binary files /dev/null and b/media/R25138/form_template/bg/被测软件基本信息.docx differ diff --git a/media/R25138/form_template/bg/软件质量评价.docx b/media/R25138/form_template/bg/软件质量评价.docx new file mode 100644 index 0000000..605e42b Binary files /dev/null and b/media/R25138/form_template/bg/软件质量评价.docx differ diff --git a/media/R25138/form_template/bg/软件问题统计.docx b/media/R25138/form_template/bg/软件问题统计.docx new file mode 100644 index 0000000..cb0a4bb Binary files /dev/null and b/media/R25138/form_template/bg/软件问题统计.docx differ diff --git a/media/R25138/form_template/bg/问题汇总表.docx b/media/R25138/form_template/bg/问题汇总表.docx new file mode 100644 index 0000000..3af92f6 Binary files /dev/null and b/media/R25138/form_template/bg/问题汇总表.docx differ diff --git a/media/R25138/form_template/bg/需求指标符合性情况.docx b/media/R25138/form_template/bg/需求指标符合性情况.docx new file mode 100644 index 0000000..91ec078 Binary files /dev/null and b/media/R25138/form_template/bg/需求指标符合性情况.docx differ diff --git a/media/R25138/form_template/dg/主要功能和性能指标.docx b/media/R25138/form_template/dg/主要功能和性能指标.docx new file mode 100644 index 0000000..b6df75e Binary files /dev/null and b/media/R25138/form_template/dg/主要功能和性能指标.docx differ diff --git a/media/R25138/form_template/dg/主要战技指标.docx b/media/R25138/form_template/dg/主要战技指标.docx new file mode 100644 index 0000000..26d6665 Binary files /dev/null and b/media/R25138/form_template/dg/主要战技指标.docx differ diff --git a/media/R25138/form_template/dg/代码质量度量分析表.docx b/media/R25138/form_template/dg/代码质量度量分析表.docx new file mode 100644 index 0000000..cd23618 Binary files /dev/null and b/media/R25138/form_template/dg/代码质量度量分析表.docx differ diff --git a/media/R25138/form_template/dg/动态测试环境说明.docx b/media/R25138/form_template/dg/动态测试环境说明.docx new file mode 100644 index 0000000..6eef1eb Binary files /dev/null and b/media/R25138/form_template/dg/动态测试环境说明.docx differ diff --git a/media/R25138/form_template/dg/动态硬件和固件项.docx b/media/R25138/form_template/dg/动态硬件和固件项.docx new file mode 100644 index 0000000..268c1f7 Binary files /dev/null and b/media/R25138/form_template/dg/动态硬件和固件项.docx differ diff --git a/media/R25138/form_template/dg/动态软件项.docx b/media/R25138/form_template/dg/动态软件项.docx new file mode 100644 index 0000000..190492f Binary files /dev/null and b/media/R25138/form_template/dg/动态软件项.docx differ diff --git a/media/R25138/form_template/dg/反向需求规格追踪表.docx b/media/R25138/form_template/dg/反向需求规格追踪表.docx new file mode 100644 index 0000000..acfa8c3 Binary files /dev/null and b/media/R25138/form_template/dg/反向需求规格追踪表.docx differ diff --git a/media/R25138/form_template/dg/技术依据文件.docx b/media/R25138/form_template/dg/技术依据文件.docx new file mode 100644 index 0000000..c6c2284 Binary files /dev/null and b/media/R25138/form_template/dg/技术依据文件.docx differ diff --git a/media/R25138/form_template/dg/标准依据文件.docx b/media/R25138/form_template/dg/标准依据文件.docx new file mode 100644 index 0000000..a2762d0 Binary files /dev/null and b/media/R25138/form_template/dg/标准依据文件.docx differ diff --git a/media/R25138/form_template/dg/测评对象.docx b/media/R25138/form_template/dg/测评对象.docx new file mode 100644 index 0000000..56f9764 Binary files /dev/null and b/media/R25138/form_template/dg/测评对象.docx differ diff --git a/media/R25138/form_template/dg/测评数据.docx b/media/R25138/form_template/dg/测评数据.docx new file mode 100644 index 0000000..bf7f29b Binary files /dev/null and b/media/R25138/form_template/dg/测评数据.docx differ diff --git a/media/R25138/form_template/dg/测评时间和地点.docx b/media/R25138/form_template/dg/测评时间和地点.docx new file mode 100644 index 0000000..4e397ce Binary files /dev/null and b/media/R25138/form_template/dg/测评时间和地点.docx differ diff --git a/media/R25138/form_template/dg/测评条件保障.docx b/media/R25138/form_template/dg/测评条件保障.docx new file mode 100644 index 0000000..4a9ed25 Binary files /dev/null and b/media/R25138/form_template/dg/测评条件保障.docx differ diff --git a/media/R25138/form_template/dg/测评组织及任务分工.docx b/media/R25138/form_template/dg/测评组织及任务分工.docx new file mode 100644 index 0000000..4340f53 Binary files /dev/null and b/media/R25138/form_template/dg/测评组织及任务分工.docx differ diff --git a/media/R25138/form_template/dg/测试内容充分性及测试方法有效性分析.docx b/media/R25138/form_template/dg/测试内容充分性及测试方法有效性分析.docx new file mode 100644 index 0000000..c05d6af Binary files /dev/null and b/media/R25138/form_template/dg/测试内容充分性及测试方法有效性分析.docx differ diff --git a/media/R25138/form_template/dg/测试策略.docx b/media/R25138/form_template/dg/测试策略.docx new file mode 100644 index 0000000..f698332 Binary files /dev/null and b/media/R25138/form_template/dg/测试策略.docx differ diff --git a/media/R25138/form_template/dg/测试级别和测试类型.docx b/media/R25138/form_template/dg/测试级别和测试类型.docx new file mode 100644 index 0000000..ed7b513 Binary files /dev/null and b/media/R25138/form_template/dg/测试级别和测试类型.docx differ diff --git a/media/R25138/form_template/dg/测试项及方法.docx b/media/R25138/form_template/dg/测试项及方法.docx new file mode 100644 index 0000000..2d814f2 Binary files /dev/null and b/media/R25138/form_template/dg/测试项及方法.docx differ diff --git a/media/R25138/form_template/dg/环境差异性分析.docx b/media/R25138/form_template/dg/环境差异性分析.docx new file mode 100644 index 0000000..02b21e6 Binary files /dev/null and b/media/R25138/form_template/dg/环境差异性分析.docx differ diff --git a/media/R25138/form_template/dg/研制总要求追踪表.docx b/media/R25138/form_template/dg/研制总要求追踪表.docx new file mode 100644 index 0000000..7611f78 Binary files /dev/null and b/media/R25138/form_template/dg/研制总要求追踪表.docx differ diff --git a/media/R25138/form_template/dg/缩略语.docx b/media/R25138/form_template/dg/缩略语.docx new file mode 100644 index 0000000..09b549f Binary files /dev/null and b/media/R25138/form_template/dg/缩略语.docx differ diff --git a/media/R25138/form_template/dg/联系人和方式.docx b/media/R25138/form_template/dg/联系人和方式.docx new file mode 100644 index 0000000..9ab57cd Binary files /dev/null and b/media/R25138/form_template/dg/联系人和方式.docx differ diff --git a/media/R25138/form_template/dg/被测软件功能.docx b/media/R25138/form_template/dg/被测软件功能.docx new file mode 100644 index 0000000..578aeec Binary files /dev/null and b/media/R25138/form_template/dg/被测软件功能.docx differ diff --git a/media/R25138/form_template/dg/被测软件基本信息.docx b/media/R25138/form_template/dg/被测软件基本信息.docx new file mode 100644 index 0000000..f7cbc5f Binary files /dev/null and b/media/R25138/form_template/dg/被测软件基本信息.docx differ diff --git a/media/R25138/form_template/dg/被测软件性能.docx b/media/R25138/form_template/dg/被测软件性能.docx new file mode 100644 index 0000000..d8c18aa Binary files /dev/null and b/media/R25138/form_template/dg/被测软件性能.docx differ diff --git a/media/R25138/form_template/dg/被测软件接口.docx b/media/R25138/form_template/dg/被测软件接口.docx new file mode 100644 index 0000000..9529c67 Binary files /dev/null and b/media/R25138/form_template/dg/被测软件接口.docx differ diff --git a/media/R25138/form_template/dg/需求规格说明追踪表.docx b/media/R25138/form_template/dg/需求规格说明追踪表.docx new file mode 100644 index 0000000..192b96e Binary files /dev/null and b/media/R25138/form_template/dg/需求规格说明追踪表.docx differ diff --git a/media/R25138/form_template/dg/静态测试环境说明.docx b/media/R25138/form_template/dg/静态测试环境说明.docx new file mode 100644 index 0000000..8074344 Binary files /dev/null and b/media/R25138/form_template/dg/静态测试环境说明.docx differ diff --git a/media/R25138/form_template/dg/静态硬件和固件项.docx b/media/R25138/form_template/dg/静态硬件和固件项.docx new file mode 100644 index 0000000..85fdffe Binary files /dev/null and b/media/R25138/form_template/dg/静态硬件和固件项.docx differ diff --git a/media/R25138/form_template/dg/静态软件项.docx b/media/R25138/form_template/dg/静态软件项.docx new file mode 100644 index 0000000..dc64c0e Binary files /dev/null and b/media/R25138/form_template/dg/静态软件项.docx differ diff --git a/media/R25138/form_template/dg/顶层技术文件.docx b/media/R25138/form_template/dg/顶层技术文件.docx new file mode 100644 index 0000000..1442924 Binary files /dev/null and b/media/R25138/form_template/dg/顶层技术文件.docx differ diff --git a/media/R25138/form_template/hjl/测试用例记录.docx b/media/R25138/form_template/hjl/测试用例记录.docx new file mode 100644 index 0000000..0e1009b Binary files /dev/null and b/media/R25138/form_template/hjl/测试用例记录.docx differ diff --git a/media/R25138/form_template/hjl/被测软件基本信息.docx b/media/R25138/form_template/hjl/被测软件基本信息.docx new file mode 100644 index 0000000..6ddc8d8 Binary files /dev/null and b/media/R25138/form_template/hjl/被测软件基本信息.docx differ diff --git a/media/R25138/form_template/hsm/temporary/第三轮用例追踪_temp.docx b/media/R25138/form_template/hsm/temporary/第三轮用例追踪_temp.docx new file mode 100644 index 0000000..2f25e93 Binary files /dev/null and b/media/R25138/form_template/hsm/temporary/第三轮用例追踪_temp.docx differ diff --git a/media/R25138/form_template/hsm/temporary/第二轮用例追踪_temp.docx b/media/R25138/form_template/hsm/temporary/第二轮用例追踪_temp.docx new file mode 100644 index 0000000..bc1d787 Binary files /dev/null and b/media/R25138/form_template/hsm/temporary/第二轮用例追踪_temp.docx differ diff --git a/media/R25138/form_template/hsm/回归测试用例概述.docx b/media/R25138/form_template/hsm/回归测试用例概述.docx new file mode 100644 index 0000000..4439f7a Binary files /dev/null and b/media/R25138/form_template/hsm/回归测试用例概述.docx differ diff --git a/media/R25138/form_template/hsm/回归测试需求.docx b/media/R25138/form_template/hsm/回归测试需求.docx new file mode 100644 index 0000000..b99716b Binary files /dev/null and b/media/R25138/form_template/hsm/回归测试需求.docx differ diff --git a/media/R25138/form_template/hsm/技术依据文件.docx b/media/R25138/form_template/hsm/技术依据文件.docx new file mode 100644 index 0000000..19e32c5 Binary files /dev/null and b/media/R25138/form_template/hsm/技术依据文件.docx differ diff --git a/media/R25138/form_template/hsm/文档概述.docx b/media/R25138/form_template/hsm/文档概述.docx new file mode 100644 index 0000000..3c2ca5d Binary files /dev/null and b/media/R25138/form_template/hsm/文档概述.docx differ diff --git a/media/R25138/form_template/hsm/测试用例.docx b/media/R25138/form_template/hsm/测试用例.docx new file mode 100644 index 0000000..6988be8 Binary files /dev/null and b/media/R25138/form_template/hsm/测试用例.docx differ diff --git a/media/R25138/form_template/hsm/用例追踪.docx b/media/R25138/form_template/hsm/用例追踪.docx new file mode 100644 index 0000000..293e7be Binary files /dev/null and b/media/R25138/form_template/hsm/用例追踪.docx differ diff --git a/media/R25138/form_template/hsm/被测软件基本信息.docx b/media/R25138/form_template/hsm/被测软件基本信息.docx new file mode 100644 index 0000000..08bb234 Binary files /dev/null and b/media/R25138/form_template/hsm/被测软件基本信息.docx differ diff --git a/media/R25138/form_template/hsm/软件更改部分.docx b/media/R25138/form_template/hsm/软件更改部分.docx new file mode 100644 index 0000000..dad9c64 Binary files /dev/null and b/media/R25138/form_template/hsm/软件更改部分.docx differ diff --git a/media/R25138/form_template/jl/测试用例记录.docx b/media/R25138/form_template/jl/测试用例记录.docx new file mode 100644 index 0000000..ffd0632 Binary files /dev/null and b/media/R25138/form_template/jl/测试用例记录.docx differ diff --git a/media/R25138/form_template/products/回归测试记录.docx b/media/R25138/form_template/products/回归测试记录.docx new file mode 100644 index 0000000..65d4486 Binary files /dev/null and b/media/R25138/form_template/products/回归测试记录.docx differ diff --git a/media/R25138/form_template/products/回归测试说明.docx b/media/R25138/form_template/products/回归测试说明.docx new file mode 100644 index 0000000..75ec53c Binary files /dev/null and b/media/R25138/form_template/products/回归测试说明.docx differ diff --git a/media/R25138/form_template/products/测评大纲.docx b/media/R25138/form_template/products/测评大纲.docx new file mode 100644 index 0000000..4d5dc87 Binary files /dev/null and b/media/R25138/form_template/products/测评大纲.docx differ diff --git a/media/R25138/form_template/products/测评报告.docx b/media/R25138/form_template/products/测评报告.docx new file mode 100644 index 0000000..d527a5f Binary files /dev/null and b/media/R25138/form_template/products/测评报告.docx differ diff --git a/media/R25138/form_template/products/测试记录.docx b/media/R25138/form_template/products/测试记录.docx new file mode 100644 index 0000000..0bb93ad Binary files /dev/null and b/media/R25138/form_template/products/测试记录.docx differ diff --git a/media/R25138/form_template/products/测试说明.docx b/media/R25138/form_template/products/测试说明.docx new file mode 100644 index 0000000..4552bf5 Binary files /dev/null and b/media/R25138/form_template/products/测试说明.docx differ diff --git a/media/R25138/form_template/products/问题单.docx b/media/R25138/form_template/products/问题单.docx new file mode 100644 index 0000000..f8beeda Binary files /dev/null and b/media/R25138/form_template/products/问题单.docx differ diff --git a/media/R25138/form_template/sm/temporary/说明追踪_temp.docx b/media/R25138/form_template/sm/temporary/说明追踪_temp.docx new file mode 100644 index 0000000..5d52c31 Binary files /dev/null and b/media/R25138/form_template/sm/temporary/说明追踪_temp.docx differ diff --git a/media/R25138/form_template/sm/技术依据文件.docx b/media/R25138/form_template/sm/技术依据文件.docx new file mode 100644 index 0000000..1bc11ce Binary files /dev/null and b/media/R25138/form_template/sm/技术依据文件.docx differ diff --git a/media/R25138/form_template/sm/测试用例.docx b/media/R25138/form_template/sm/测试用例.docx new file mode 100644 index 0000000..20c5115 Binary files /dev/null and b/media/R25138/form_template/sm/测试用例.docx differ diff --git a/media/R25138/form_template/sm/用例说明.docx b/media/R25138/form_template/sm/用例说明.docx new file mode 100644 index 0000000..abfbdd5 Binary files /dev/null and b/media/R25138/form_template/sm/用例说明.docx differ diff --git a/media/R25138/form_template/sm/说明追踪.docx b/media/R25138/form_template/sm/说明追踪.docx new file mode 100644 index 0000000..f902712 Binary files /dev/null and b/media/R25138/form_template/sm/说明追踪.docx differ diff --git a/media/R25138/form_template/wtd/问题详情表.docx b/media/R25138/form_template/wtd/问题详情表.docx new file mode 100644 index 0000000..d9d3369 Binary files /dev/null and b/media/R25138/form_template/wtd/问题详情表.docx differ diff --git a/media/R25138/output_dir/主要功能和性能指标.docx b/media/R25138/output_dir/主要功能和性能指标.docx new file mode 100644 index 0000000..8a97ddb Binary files /dev/null and b/media/R25138/output_dir/主要功能和性能指标.docx differ diff --git a/media/R25138/output_dir/代码质量度量分析表.docx b/media/R25138/output_dir/代码质量度量分析表.docx new file mode 100644 index 0000000..f70f980 Binary files /dev/null and b/media/R25138/output_dir/代码质量度量分析表.docx differ diff --git a/media/R25138/output_dir/动态测试环境说明.docx b/media/R25138/output_dir/动态测试环境说明.docx new file mode 100644 index 0000000..e246758 Binary files /dev/null and b/media/R25138/output_dir/动态测试环境说明.docx differ diff --git a/media/R25138/output_dir/动态硬件和固件项.docx b/media/R25138/output_dir/动态硬件和固件项.docx new file mode 100644 index 0000000..63953ad Binary files /dev/null and b/media/R25138/output_dir/动态硬件和固件项.docx differ diff --git a/media/R25138/output_dir/动态软件项.docx b/media/R25138/output_dir/动态软件项.docx new file mode 100644 index 0000000..f8aa8d3 Binary files /dev/null and b/media/R25138/output_dir/动态软件项.docx differ diff --git a/media/R25138/output_dir/反向需求规格追踪表.docx b/media/R25138/output_dir/反向需求规格追踪表.docx new file mode 100644 index 0000000..5c6bd7b Binary files /dev/null and b/media/R25138/output_dir/反向需求规格追踪表.docx differ diff --git a/media/R25138/output_dir/技术依据文件.docx b/media/R25138/output_dir/技术依据文件.docx new file mode 100644 index 0000000..baa6053 Binary files /dev/null and b/media/R25138/output_dir/技术依据文件.docx differ diff --git a/media/R25138/output_dir/标准依据文件.docx b/media/R25138/output_dir/标准依据文件.docx new file mode 100644 index 0000000..232c65a Binary files /dev/null and b/media/R25138/output_dir/标准依据文件.docx differ diff --git a/media/R25138/output_dir/测评对象.docx b/media/R25138/output_dir/测评对象.docx new file mode 100644 index 0000000..211b91b Binary files /dev/null and b/media/R25138/output_dir/测评对象.docx differ diff --git a/media/R25138/output_dir/测评数据.docx b/media/R25138/output_dir/测评数据.docx new file mode 100644 index 0000000..1a1c707 Binary files /dev/null and b/media/R25138/output_dir/测评数据.docx differ diff --git a/media/R25138/output_dir/测评时间和地点.docx b/media/R25138/output_dir/测评时间和地点.docx new file mode 100644 index 0000000..3994f46 Binary files /dev/null and b/media/R25138/output_dir/测评时间和地点.docx differ diff --git a/media/R25138/output_dir/测评条件保障.docx b/media/R25138/output_dir/测评条件保障.docx new file mode 100644 index 0000000..82ab440 Binary files /dev/null and b/media/R25138/output_dir/测评条件保障.docx differ diff --git a/media/R25138/output_dir/测评组织及任务分工.docx b/media/R25138/output_dir/测评组织及任务分工.docx new file mode 100644 index 0000000..6cea28e Binary files /dev/null and b/media/R25138/output_dir/测评组织及任务分工.docx differ diff --git a/media/R25138/output_dir/测试内容充分性及测试方法有效性分析.docx b/media/R25138/output_dir/测试内容充分性及测试方法有效性分析.docx new file mode 100644 index 0000000..f71a8ff Binary files /dev/null and b/media/R25138/output_dir/测试内容充分性及测试方法有效性分析.docx differ diff --git a/media/R25138/output_dir/测试策略.docx b/media/R25138/output_dir/测试策略.docx new file mode 100644 index 0000000..6a93460 Binary files /dev/null and b/media/R25138/output_dir/测试策略.docx differ diff --git a/media/R25138/output_dir/测试级别和测试类型.docx b/media/R25138/output_dir/测试级别和测试类型.docx new file mode 100644 index 0000000..ad8adc3 Binary files /dev/null and b/media/R25138/output_dir/测试级别和测试类型.docx differ diff --git a/media/R25138/output_dir/测试项及方法.docx b/media/R25138/output_dir/测试项及方法.docx new file mode 100644 index 0000000..acd2d93 Binary files /dev/null and b/media/R25138/output_dir/测试项及方法.docx differ diff --git a/media/R25138/output_dir/环境差异性分析.docx b/media/R25138/output_dir/环境差异性分析.docx new file mode 100644 index 0000000..dfc58b6 Binary files /dev/null and b/media/R25138/output_dir/环境差异性分析.docx differ diff --git a/media/R25138/output_dir/研制总要求追踪表.docx b/media/R25138/output_dir/研制总要求追踪表.docx new file mode 100644 index 0000000..e21871b Binary files /dev/null and b/media/R25138/output_dir/研制总要求追踪表.docx differ diff --git a/media/R25138/output_dir/缩略语.docx b/media/R25138/output_dir/缩略语.docx new file mode 100644 index 0000000..349478d Binary files /dev/null and b/media/R25138/output_dir/缩略语.docx differ diff --git a/media/R25138/output_dir/联系人和方式.docx b/media/R25138/output_dir/联系人和方式.docx new file mode 100644 index 0000000..b544630 Binary files /dev/null and b/media/R25138/output_dir/联系人和方式.docx differ diff --git a/media/R25138/output_dir/被测软件基本信息.docx b/media/R25138/output_dir/被测软件基本信息.docx new file mode 100644 index 0000000..01c796a Binary files /dev/null and b/media/R25138/output_dir/被测软件基本信息.docx differ diff --git a/media/R25138/output_dir/被测软件接口.docx b/media/R25138/output_dir/被测软件接口.docx new file mode 100644 index 0000000..5f794d0 Binary files /dev/null and b/media/R25138/output_dir/被测软件接口.docx differ diff --git a/media/R25138/output_dir/需求规格说明追踪表.docx b/media/R25138/output_dir/需求规格说明追踪表.docx new file mode 100644 index 0000000..ea2947c Binary files /dev/null and b/media/R25138/output_dir/需求规格说明追踪表.docx differ diff --git a/media/R25138/output_dir/静态测试环境说明.docx b/media/R25138/output_dir/静态测试环境说明.docx new file mode 100644 index 0000000..775953c Binary files /dev/null and b/media/R25138/output_dir/静态测试环境说明.docx differ diff --git a/media/R25138/output_dir/静态硬件和固件项.docx b/media/R25138/output_dir/静态硬件和固件项.docx new file mode 100644 index 0000000..2686f2d Binary files /dev/null and b/media/R25138/output_dir/静态硬件和固件项.docx differ diff --git a/media/R25138/output_dir/静态软件项.docx b/media/R25138/output_dir/静态软件项.docx new file mode 100644 index 0000000..21c5526 Binary files /dev/null and b/media/R25138/output_dir/静态软件项.docx differ diff --git a/media/R25138/output_dir/顶层技术文件.docx b/media/R25138/output_dir/顶层技术文件.docx new file mode 100644 index 0000000..465cbae Binary files /dev/null and b/media/R25138/output_dir/顶层技术文件.docx differ diff --git a/media/R25138/reuse/basic_doc.docx b/media/R25138/reuse/basic_doc.docx new file mode 100644 index 0000000..1e42259 Binary files /dev/null and b/media/R25138/reuse/basic_doc.docx differ diff --git a/media/R25138/reuse/主要功能和性能指标.docx b/media/R25138/reuse/主要功能和性能指标.docx new file mode 100644 index 0000000..bc54b17 Binary files /dev/null and b/media/R25138/reuse/主要功能和性能指标.docx differ diff --git a/media/R25138/reuse/代码质量度量分析表.docx b/media/R25138/reuse/代码质量度量分析表.docx new file mode 100644 index 0000000..41af986 Binary files /dev/null and b/media/R25138/reuse/代码质量度量分析表.docx differ diff --git a/media/R25138/reuse/动态测试环境说明.docx b/media/R25138/reuse/动态测试环境说明.docx new file mode 100644 index 0000000..ed720aa Binary files /dev/null and b/media/R25138/reuse/动态测试环境说明.docx differ diff --git a/media/R25138/reuse/动态硬件和固件项.docx b/media/R25138/reuse/动态硬件和固件项.docx new file mode 100644 index 0000000..92426c1 Binary files /dev/null and b/media/R25138/reuse/动态硬件和固件项.docx differ diff --git a/media/R25138/reuse/动态软件项.docx b/media/R25138/reuse/动态软件项.docx new file mode 100644 index 0000000..10e97ed Binary files /dev/null and b/media/R25138/reuse/动态软件项.docx differ diff --git a/media/R25138/reuse/反向需求规格追踪表.docx b/media/R25138/reuse/反向需求规格追踪表.docx new file mode 100644 index 0000000..99af7e6 Binary files /dev/null and b/media/R25138/reuse/反向需求规格追踪表.docx differ diff --git a/media/R25138/reuse/技术依据文件.docx b/media/R25138/reuse/技术依据文件.docx new file mode 100644 index 0000000..66dee59 Binary files /dev/null and b/media/R25138/reuse/技术依据文件.docx differ diff --git a/media/R25138/reuse/标准依据文件.docx b/media/R25138/reuse/标准依据文件.docx new file mode 100644 index 0000000..9bfe3e5 Binary files /dev/null and b/media/R25138/reuse/标准依据文件.docx differ diff --git a/media/R25138/reuse/测评对象.docx b/media/R25138/reuse/测评对象.docx new file mode 100644 index 0000000..9239412 Binary files /dev/null and b/media/R25138/reuse/测评对象.docx differ diff --git a/media/R25138/reuse/测评数据.docx b/media/R25138/reuse/测评数据.docx new file mode 100644 index 0000000..eab2e88 Binary files /dev/null and b/media/R25138/reuse/测评数据.docx differ diff --git a/media/R25138/reuse/测评时间和地点.docx b/media/R25138/reuse/测评时间和地点.docx new file mode 100644 index 0000000..f3eeee5 Binary files /dev/null and b/media/R25138/reuse/测评时间和地点.docx differ diff --git a/media/R25138/reuse/测评条件保障.docx b/media/R25138/reuse/测评条件保障.docx new file mode 100644 index 0000000..2e97802 Binary files /dev/null and b/media/R25138/reuse/测评条件保障.docx differ diff --git a/media/R25138/reuse/测评组织及任务分工.docx b/media/R25138/reuse/测评组织及任务分工.docx new file mode 100644 index 0000000..47bdefd Binary files /dev/null and b/media/R25138/reuse/测评组织及任务分工.docx differ diff --git a/media/R25138/reuse/测试内容充分性及测试方法有效性分析.docx b/media/R25138/reuse/测试内容充分性及测试方法有效性分析.docx new file mode 100644 index 0000000..0efc5f0 Binary files /dev/null and b/media/R25138/reuse/测试内容充分性及测试方法有效性分析.docx differ diff --git a/media/R25138/reuse/测试策略.docx b/media/R25138/reuse/测试策略.docx new file mode 100644 index 0000000..6855e1b Binary files /dev/null and b/media/R25138/reuse/测试策略.docx differ diff --git a/media/R25138/reuse/测试级别和测试类型.docx b/media/R25138/reuse/测试级别和测试类型.docx new file mode 100644 index 0000000..f0b01e1 Binary files /dev/null and b/media/R25138/reuse/测试级别和测试类型.docx differ diff --git a/media/R25138/reuse/测试项及方法.docx b/media/R25138/reuse/测试项及方法.docx new file mode 100644 index 0000000..d69e006 Binary files /dev/null and b/media/R25138/reuse/测试项及方法.docx differ diff --git a/media/R25138/reuse/环境差异性分析.docx b/media/R25138/reuse/环境差异性分析.docx new file mode 100644 index 0000000..47f9e2a Binary files /dev/null and b/media/R25138/reuse/环境差异性分析.docx differ diff --git a/media/R25138/reuse/研制总要求追踪表.docx b/media/R25138/reuse/研制总要求追踪表.docx new file mode 100644 index 0000000..e944c4b Binary files /dev/null and b/media/R25138/reuse/研制总要求追踪表.docx differ diff --git a/media/R25138/reuse/联系人和方式.docx b/media/R25138/reuse/联系人和方式.docx new file mode 100644 index 0000000..56d47b7 Binary files /dev/null and b/media/R25138/reuse/联系人和方式.docx differ diff --git a/media/R25138/reuse/被测软件基本信息.docx b/media/R25138/reuse/被测软件基本信息.docx new file mode 100644 index 0000000..175bc10 Binary files /dev/null and b/media/R25138/reuse/被测软件基本信息.docx differ diff --git a/media/R25138/reuse/被测软件接口.docx b/media/R25138/reuse/被测软件接口.docx new file mode 100644 index 0000000..00d0394 Binary files /dev/null and b/media/R25138/reuse/被测软件接口.docx differ diff --git a/media/R25138/reuse/需求规格说明追踪表.docx b/media/R25138/reuse/需求规格说明追踪表.docx new file mode 100644 index 0000000..5a117b5 Binary files /dev/null and b/media/R25138/reuse/需求规格说明追踪表.docx differ diff --git a/media/R25138/reuse/静态测试环境说明.docx b/media/R25138/reuse/静态测试环境说明.docx new file mode 100644 index 0000000..070c176 Binary files /dev/null and b/media/R25138/reuse/静态测试环境说明.docx differ diff --git a/media/R25138/reuse/静态硬件和固件项.docx b/media/R25138/reuse/静态硬件和固件项.docx new file mode 100644 index 0000000..4ea01db Binary files /dev/null and b/media/R25138/reuse/静态硬件和固件项.docx differ diff --git a/media/R25138/reuse/静态软件项.docx b/media/R25138/reuse/静态软件项.docx new file mode 100644 index 0000000..bcd1c14 Binary files /dev/null and b/media/R25138/reuse/静态软件项.docx differ diff --git a/media/R25138/reuse/顶层技术文件.docx b/media/R25138/reuse/顶层技术文件.docx new file mode 100644 index 0000000..957a331 Binary files /dev/null and b/media/R25138/reuse/顶层技术文件.docx differ diff --git a/media/R25138/temp/测评大纲.docx b/media/R25138/temp/测评大纲.docx new file mode 100644 index 0000000..17d6388 Binary files /dev/null and b/media/R25138/temp/测评大纲.docx differ diff --git a/requirements.txt b/requirements.txt index f8c48f0..9e1fa91 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,20 +1,20 @@ -Django~=5.2.9 +Django~=6.0 django-auth-ldap~=5.2.0 asgiref~=3.11.0 sqlparse~=0.5.4 # 基础包 mysqlclient~=2.2.7 -orjson~=3.11.4 +orjson~=3.11.5 lxml~=6.0.2 typing_extensions~=4.15.0 # 必须whl安装的包 python-ldap~=3.4.4 # 项目包 django-environ~=0.12.0 -django-ninja~=1.5.0 +django-ninja~=1.5.1 pydantic~=2.12.5 pydantic-core~=2.41.5 -django-ninja-extra~=0.30.6 +django-ninja-extra~=0.30.8 django-ninja-jwt~=5.4.2 django-tinymce~=5.0.0 PyJWT~=2.10.1 diff --git a/utils/__pycache__/chen_response.cpython-313.pyc b/utils/__pycache__/chen_response.cpython-313.pyc index 0c40034..a32cd1b 100644 Binary files a/utils/__pycache__/chen_response.cpython-313.pyc and b/utils/__pycache__/chen_response.cpython-313.pyc differ diff --git a/utils/chen_response.py b/utils/chen_response.py index 906aa7d..47c91ca 100644 --- a/utils/chen_response.py +++ b/utils/chen_response.py @@ -13,6 +13,7 @@ class DateEncoder(json.JSONEncoder): ## 重写django的HttpResponse,注意返回的是axios里面的data!!! class ChenResponse(HttpResponse): def __init__(self, data=None, message='success', code=200, *args, **kwargs): + self.message = message if data is None: data = {} std_data = {