diff --git a/apps/createDocument/controllers/__pycache__/dg.cpython-313.pyc b/apps/createDocument/controllers/__pycache__/dg.cpython-313.pyc index ec2fee1..b6805c4 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__/hsm.cpython-313.pyc b/apps/createDocument/controllers/__pycache__/hsm.cpython-313.pyc index 34257b7..7278c42 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/dg.py b/apps/createDocument/controllers/dg.py index 7917e71..d738fe9 100644 --- a/apps/createDocument/controllers/dg.py +++ b/apps/createDocument/controllers/dg.py @@ -31,7 +31,8 @@ from apps.createSeiTaiDocument.extensions.logger import GenerateLogger # 导入mixins-处理文档片段 from apps.createDocument.extensions.mixins import FragementToolsMixin # 导入工具 -from apps.createDocument.extensions.tools import demand_sort_by_designKey, set_table_border_by_cell_position, set_cell_margins +from apps.createDocument.extensions.tools import demand_sort_by_designKey, set_table_border_by_cell_position +from apps.createDocument.extensions.table_creator import create_table_context, RoundType, uniform_static_dynamic_response # @api_controller("/generate", tags=['生成大纲文档'], auth=JWTAuth(), permissions=[IsAuthenticated]) @api_controller("/generate", tags=['生成大纲文档']) @@ -483,101 +484,10 @@ class GenerateControllerDG(ControllerBase, FragementToolsMixin): except PermissionError as e: return ChenResponse(status=400, code=400, message="模版文件已打开,请关闭后再试,{0}".format(e)) - # 通用生成静态软件项、静态硬件项、动态软件项、动态硬件信息、测评数据的context,包含fontnote和table - @classmethod - def create_table_context(cls, table_data: list[list[str]], doc: DocxTemplate): - """注意:该函数会增加一列序号列,并且支持单元格内回车换行(段落换行)""" - subdoc = doc.new_subdoc() - rows = len(table_data) - cols = len(table_data[0]) + 1 - table = subdoc.add_table(rows=rows, cols=cols) - - # 单元格处理 - for row in range(rows): - for col in range(cols): - cell = table.cell(row, col) - set_cell_margins(cell, left=100, right=100, top=100, bottom=100) - - # 获取要显示的文本内容(字符串或按行拆分后的列表) - if col == 0: - # 序号列 - lines = ["序号"] if row == 0 else [str(row)] - else: - raw_text = table_data[row][col - 1] - # 按换行符 \n 拆分为多个段落 - lines = raw_text.split('\n') if raw_text else [''] - - # 清空单元格原有段落(add_table 默认有一个段落) - cell.text = "" - # 删除默认段落,稍后统一添加 - for para in cell.paragraphs: - p = para._element - p.getparent().remove(p) - - # 逐个添加段落 - for i, line in enumerate(lines): - if i == 0: - para = cell.add_paragraph(line) - else: - para = cell.add_paragraph(line) - - # 设置段落对齐(第一列居中,其他左对齐,可根据需要调整) - if col == 0: - para.alignment = WD_ALIGN_PARAGRAPH.CENTER - else: - para.alignment = WD_ALIGN_PARAGRAPH.LEFT - - # 对第一行(表头)设置黑体字体 - if row == 0: - for run in para.runs: - run.font.name = '黑体' - run._element.rPr.rFonts.set(qn('w:eastAsia'), '黑体') - run.font.bold = False - # 表头段落居中(覆盖前面的 left) - para.alignment = WD_ALIGN_PARAGRAPH.CENTER - - # 垂直居中 - cell.vertical_alignment = WD_ALIGN_VERTICAL.CENTER - - # 设置序号列宽度 - for cell in table.columns[0].cells: - cell.width = Mm(15) - for para in cell.paragraphs: - para.alignment = WD_ALIGN_PARAGRAPH.CENTER - - # 表格居中 - table.alignment = WD_ALIGN_PARAGRAPH.CENTER - # 设置表格外边框 - set_table_border_by_cell_position(table) - return subdoc - - # 统一静态软件项、静态硬件项、动态软件项、动态硬件信息的word生成 - 模版模式 - @classmethod - def uniform_static_dynamic_response(cls, id: int, filename: str, r_filename: str, model) -> ChenResponse | None: - project_obj = get_object_or_404(Project, id=id) - input_path = Path.cwd() / 'media' / project_path(id) / 'form_template' / 'dg' / filename - doc = DocxTemplate(input_path) - qs = model.objects.filter(project=project_obj) - if qs.exists(): - obj = qs.first() - table_data = obj.table - subdoc = cls.create_table_context(table_data, doc) - context = { - 'fontnote': obj.fontnote, - 'table': subdoc, - } - doc.render(context, autoescape=True) - try: - doc.save(Path.cwd() / "media" / project_path(id) / "output_dir" / r_filename) - return ChenResponse(status=200, code=200, message="文档生成成功!") - except PermissionError as e: - return ChenResponse(status=400, code=400, message="模版文件已打开,请关闭后再试,{0}".format(e)) - return None - # 静态软件项 @route.get('/create/static_soft', url_name='create-static_soft') - def create_static_soft(self, id: int): - res = self.uniform_static_dynamic_response(id, '静态软件项_2.docx', '静态软件项.docx', StaticSoftItem) + def create_static_soft(self, id: int, current_round: RoundType = "0"): + res = uniform_static_dynamic_response(id, '静态软件项_2.docx', '静态软件项.docx', StaticSoftItem, current_round) if res is not None: return res @@ -592,8 +502,11 @@ class GenerateControllerDG(ControllerBase, FragementToolsMixin): # 静态硬件和固件项 @route.get('/create/static_hard', url_name='create-static_hard') - def create_static_hard(self, id: int): - res = self.uniform_static_dynamic_response(id, '静态硬件和固件项_2.docx', '静态硬件和固件项.docx', StaticSoftHardware) + def create_static_hard(self, id: int, current_round: RoundType = "0"): + res = uniform_static_dynamic_response(id, '静态硬件和固件项_2.docx', + '静态硬件和固件项.docx', + StaticSoftHardware, + current_round) if res is not None: return res @@ -632,8 +545,8 @@ class GenerateControllerDG(ControllerBase, FragementToolsMixin): # 动态软件项 @route.get('/create/dynamic_soft', url_name='create-dynamic_soft') - def create_dynamic_soft(self, id: int): - res = self.uniform_static_dynamic_response(id, '动态软件项_2.docx', '动态软件项.docx', DynamicSoftTable) + def create_dynamic_soft(self, id: int, current_round: RoundType = "0"): + res = uniform_static_dynamic_response(id, '动态软件项_2.docx', '动态软件项.docx', DynamicSoftTable, current_round) if res is not None: return res @@ -650,9 +563,9 @@ class GenerateControllerDG(ControllerBase, FragementToolsMixin): # 动态硬件项 @route.get('/create/dynamic_hard', url_name='create-dynamic_hard') - def create_dynamic_hard(self, id: int): - res = self.uniform_static_dynamic_response(id, '动态硬件和固件项_2.docx', - '动态硬件和固件项.docx', DynamicHardwareTable) + def create_dynamic_hard(self, id: int, current_round: RoundType = "0"): + res = uniform_static_dynamic_response(id, '动态硬件和固件项_2.docx', + '动态硬件和固件项.docx', DynamicHardwareTable, current_round) if res is not None: return res @@ -667,9 +580,9 @@ class GenerateControllerDG(ControllerBase, FragementToolsMixin): # 测试数据 @route.get('/create/test_data', url_name='create-test_data') - def create_test_data(self, id: int): - res = self.uniform_static_dynamic_response(id, '测评数据_2.docx', - '测评数据.docx', EvaluateData) + def create_test_data(self, id: int, current_round: RoundType = "0"): + res = uniform_static_dynamic_response(id, '测评数据_2.docx', + '测评数据.docx', EvaluateData, current_round) if res is not None: return res # 老内容 @@ -692,7 +605,7 @@ class GenerateControllerDG(ControllerBase, FragementToolsMixin): if qs.exists(): obj = qs.first() table_data = obj.table - subdoc = self.create_table_context(table_data, doc) + subdoc = create_table_context(table_data, doc) context = { "description": obj.description, "table": subdoc, diff --git a/apps/createDocument/controllers/hsm.py b/apps/createDocument/controllers/hsm.py index b57243f..f138667 100644 --- a/apps/createDocument/controllers/hsm.py +++ b/apps/createDocument/controllers/hsm.py @@ -24,6 +24,9 @@ from apps.createDocument.extensions.content_result_tool import create_influence_ from apps.createSeiTaiDocument.extensions.logger import GenerateLogger # 导入排序 from apps.createDocument.extensions.tools import demand_sort_by_designKey +# 导入静态软件项、静态硬件项、动态软件项、动态硬件项、测评数据辅助函数和模型 +from apps.createDocument.extensions.table_creator import uniform_static_dynamic_response, RoundType +from apps.project.models import StaticSoftItem, StaticSoftHardware, DynamicSoftTable, DynamicHardwareTable, EvaluateData chinese_round_name: list = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十'] @@ -42,6 +45,38 @@ class GenerateControllerHSM(ControllerBase): except PermissionError: return ChenResponse(code=400, status=400, message='另一个程序正在占用文件,请关闭后重试') + # ~~~新增5个接口,回归测试说明的~~~ + # 静态软件项 + @route.get('/create/static_soft', url_name='create-static_soft-hsm') + def create_hsm_static_soft(self, id: int, current_round: RoundType = "0"): + return uniform_static_dynamic_response(id, '静态软件项_2.docx', '静态软件项.docx', StaticSoftItem, current_round, isHsm=True) + + # 静态硬件和固件项 + @route.get('/create/static_hard', url_name='create-static_hard-hsm') + def create_hsm_static_hard(self, id: int, current_round: RoundType = "0"): + return uniform_static_dynamic_response(id, '静态硬件和固件项_2.docx', + '静态硬件和固件项.docx', + StaticSoftHardware, + current_round) + + # 动态软件项 + @route.get('/create/dynamic_soft', url_name='create-dynamic_soft-hsm') + def create_hsm_dynamic_soft(self, id: int, current_round: RoundType = "0"): + return uniform_static_dynamic_response(id, '动态软件项_2.docx', '动态软件项.docx', DynamicSoftTable, current_round, isHsm=True) + + # 动态硬件项 + @route.get('/create/dynamic_hard', url_name='create-dynamic_hard-hsm') + def create_hsm_dynamic_hard(self, id: int, current_round: RoundType = "0"): + return uniform_static_dynamic_response(id, '动态硬件和固件项_2.docx', + '动态硬件和固件项.docx', DynamicHardwareTable, current_round, isHsm=True) + + # 测试数据 + @route.get('/create/test_data', url_name='create-test_data-hsm') + def create_hsm_test_data(self, id: int, current_round: RoundType = "0"): + return uniform_static_dynamic_response(id, '测评数据_2.docx', + '测评数据.docx', EvaluateData, current_round, isHsm=True) + + # ~~~5个接口:end~~~ @route.get("/create/basicInformation", url_name="create-basicInformation") @transaction.atomic def create_basicInformation(self, id: int): diff --git a/apps/createDocument/extensions/__pycache__/documentTime.cpython-313.pyc b/apps/createDocument/extensions/__pycache__/documentTime.cpython-313.pyc index 95185b8..86370b1 100644 Binary files a/apps/createDocument/extensions/__pycache__/documentTime.cpython-313.pyc and b/apps/createDocument/extensions/__pycache__/documentTime.cpython-313.pyc differ diff --git a/apps/createDocument/extensions/__pycache__/table_creator.cpython-313.pyc b/apps/createDocument/extensions/__pycache__/table_creator.cpython-313.pyc new file mode 100644 index 0000000..9cbe71c Binary files /dev/null and b/apps/createDocument/extensions/__pycache__/table_creator.cpython-313.pyc differ diff --git a/apps/createDocument/extensions/documentTime.py b/apps/createDocument/extensions/documentTime.py index 9cb77e0..c569c90 100644 --- a/apps/createDocument/extensions/documentTime.py +++ b/apps/createDocument/extensions/documentTime.py @@ -1,207 +1,209 @@ -# 本模块主要以项目开始时间、结束时间、轮次开始时间、结束时间计算文档中的各个时间 -from datetime import timedelta, date -from apps.project.models import Project -from django.shortcuts import get_object_or_404 -from ninja.errors import HttpError # 从代码抛出该异常,被ninja截取变为response - -def format_remove_heng(dateT: date) -> str: - """该函数将date对象的横杠-去掉,输出str""" - return str(dateT).replace('-', '') - -def times_by_cover_time(cover_time: date) -> dict: - """该函数为每个产品文档根据封面时间,渲染签署页时间、文档变更记录时间""" - return { - 'preparation_time_no_format': cover_time - timedelta(days=2), - 'preparation_time': format_remove_heng(cover_time - timedelta(days=2)), # 拟制时间:为编制结束时间-2天 - 'inspect_time': format_remove_heng(cover_time - timedelta(days=1)), # 校对时间:为编制时间+1天 - 'auditing_time': format_remove_heng(cover_time), - 'ratify_time': format_remove_heng(cover_time), - 'create_doc_time': format_remove_heng(cover_time - timedelta(days=2)), - 'doc_v1_time': format_remove_heng(cover_time) - } - -class DocTime: - def __init__(self, project_id: int): - self.project = get_object_or_404(Project, id=project_id) - # 用户录入时间-项目 - self.p_start = self.project.beginTime # 被测件接收时间/ - self.p_end = self.project.endTime # 大纲测评时间周期结束时间/ - # 遍历轮次时间-多个 - self.round_count = self.project.pField.count() - self.round_time = [] # 轮次按顺序排序 - for round in self.project.pField.all(): - self.round_time.append({ - 'start': round.beginTime, - 'end': round.endTime, - 'location': round.location - }) - # ~~~~由上面时间二次计算得出时间~~~~ -> TODO:可由用户设置间隔时间!!!! - self.dg_bz_start = self.p_start + timedelta(days=1) # 大纲编制开始时间,项目开始时间+1天 - self.dg_bz_end = self.dg_bz_start + timedelta(days=6) # 大纲编制结束时间,大纲编制开始+6天 - self.test_sj_start = self.dg_bz_end + timedelta(days=1) # 测评设计与实现时间,在大纲编制结束+1天 - self.test_sj_end = self.test_sj_start + timedelta(days=5) # 测评设计与实现结束,在开始+5天 - # ~~~~储存每个文档的cover_time~~~~ - self.dg_cover_time = self.dg_bz_end - self.sm_cover_time = self.test_sj_end - self.jl_cover_time = self.round_time[0]['end'] - self.wtd_cover_time = self.round_time[-1]['end'] - - # 该函数生成大纲文档片段-测评时间和地点的时间和地点信息 - def dg_address_time(self): - """直接返回context去渲染""" - # 需要判断round_time是否有值 - if len(self.round_time) <= 0: - raise HttpError(status_code=400, message='您还未创建轮次时间,请填写后生成') - return { - 'start_year': self.p_start.year, - 'start_month': self.p_start.month, - 'end_year': self.p_end.year, - 'end_month': self.p_end.month, - 'beginTime_strf': format_remove_heng(self.p_start), - 'dgCompileStart': format_remove_heng(self.dg_bz_start), - 'dgCompileEnd': format_remove_heng(self.dg_bz_end), - 'designStart': format_remove_heng(self.test_sj_start), - 'designEnd': format_remove_heng(self.test_sj_end), - 'location': self.round_time[0]['location'] - } - - # 该函数生成报告文档片段-测评时间和地点【注意使用了dg_address_time -> 所以后续有修改注意前导】 - def bg_address_time(self): - if len(self.round_time) <= 0: - raise HttpError(status_code=400, message='您还未创建轮次时间,请填写后生成') - # 先使用大纲的时间行数作为前三行 - cname = ['首轮测试', '第二轮测试', '第三轮测试', '第四轮测试', '第五轮测试', '第六轮测试', '第七轮测试', - '第八轮测试', '第九轮测试', '第十轮测试'] - dg_address_time = self.dg_address_time() - round_time_list = [] - index = 0 - for round_dict in self.round_time: - one_dict = { - 'name': cname[index], - 'start': format_remove_heng(round_dict['start']), - 'end': format_remove_heng(round_dict['end']), - 'location': round_dict['location'] - } - index += 1 - round_time_list.append(one_dict) - return { - 'begin_year': dg_address_time['start_year'], - 'begin_month': dg_address_time['start_month'], - 'end_year': dg_address_time['end_year'], - 'end_month': dg_address_time['end_month'], - 'begin_time': dg_address_time['beginTime_strf'], - 'dg_weave_start_date': dg_address_time['dgCompileStart'], - 'dg_weave_end_date': dg_address_time['dgCompileEnd'], - 'sj_weave_start_date': dg_address_time['designStart'], - 'sj_weave_end_date': dg_address_time['designEnd'], - 'round_time_list': round_time_list, - # 测评总结 -> 依据项目结束时间-7 ~ 项目结束时间 - 'summary_start_date': format_remove_heng(self.p_end - timedelta(days=7)), - 'summary_end_date': format_remove_heng(self.p_end), - } - - # 生成报告中测评完成情况 -> 必须依据其他内容生成时间【注意使用了bg_address_time -> 所以后续有修改注意前导】 - def bg_completion_situation(self): - bg_timer_dict = self.bg_address_time() - xq_fx_time_end = self.dg_bz_start + timedelta(days=2) - ch_time_start = xq_fx_time_end + timedelta(days=1) - ch_time_end = self.dg_bz_end - if len(self.round_time) < 1: - raise HttpError(status_code=400, message='您还未创建第一轮测试的时间,请填写后再生成') - return { - 'start_time_year': bg_timer_dict['begin_year'], - 'start_time_month': bg_timer_dict['begin_month'], - 'xq_fx_time_start_year': self.dg_bz_start.year, - 'xq_fx_time_start_month': self.dg_bz_start.month, - 'xq_fx_time_start_day': self.dg_bz_start.day, - 'xq_fx_time_end_year': xq_fx_time_end.year, # 需求分析结束时间是大纲编制开始+2 - 'xq_fx_time_end_month': xq_fx_time_end.month, - 'xq_fx_time_end_day': xq_fx_time_end.day, - 'ch_start_year': ch_time_start.year, - 'ch_start_month': ch_time_start.month, - 'ch_start_day': ch_time_start.day, - 'ch_end_year': ch_time_end.year, - 'ch_end_month': ch_time_end.month, - 'ch_end_day': ch_time_end.day, - 'sj_start_year': self.test_sj_start.year, - 'sj_start_month': self.test_sj_start.month, - 'sj_start_day': self.test_sj_start.day, - 'sj_end_year': self.test_sj_end.year, - 'sj_end_month': self.test_sj_end.month, - 'sj_end_day': self.test_sj_end.day, - 'end_time_year': self.p_end.year, - 'end_time_month': self.p_end.month, - 'exec_start_time_year': self.round_time[0]['start'].year, - 'exec_start_time_month': self.round_time[0]['start'].month, - 'exec_start_time_day': self.round_time[0]['start'].day, - 'exec_end_time_year': self.round_time[0]['end'].year, - 'exec_end_time_month': self.round_time[0]['end'].month, - 'exec_end_time_day': self.round_time[0]['end'].day, - } - - # 该函数生成最终大纲的时间 - def dg_final_time(self): - cover_time = self.dg_bz_end - context = times_by_cover_time(cover_time) - context.update(cover_time=cover_time.strftime("%Y年%m月%d日")) - # 新增给大纲模版10.2章节context - context.update(basic_line1=cover_time.strftime("%Y年%m月"), basic_line2=self.p_end.strftime("%Y年%m月")) - # 新增给大纲模版10.3.2章节的context - sm_context = self.sm_final_time() - context.update(sm_end_time=sm_context['preparation_time_no_format'].strftime("%Y年%m月")) - return context - - # 该函数生成说明文档的时间 -> 依据项目时间而非用户第一轮填写时间! - def sm_final_time(self): - cover_time = self.test_sj_end # 封面时间:为大纲时间中“测评设计与实现”结束时间 - context = times_by_cover_time(cover_time) - context.update(cover_time=cover_time.strftime("%Y年%m月%d日")) - return context - - # 该函数生成记录文档的时间 -> 依据第一轮测试用户填写的事件 - def jl_final_time(self): - if len(self.round_time) < 1: - raise HttpError(status_code=400, message='您还未创建第一轮测试的时间,请填写后再生成') - cover_time = self.round_time[0]['end'] # 封面时间为用户填写第一轮结束时间 - context = times_by_cover_time(cover_time) - context.update(cover_time=cover_time.strftime("%Y年%m月%d日")) - return context - - # 问题单的时间 -> 依据最后一轮次的结束时间+1天 - def wtd_final_time(self): - if len(self.round_time) < 1: - raise HttpError(status_code=400, message='您还未创建第一轮测试的时间,请填写后再生成') - cover_time = self.round_time[-1]['end'] - context = times_by_cover_time(cover_time) - context.update(cover_time=cover_time.strftime("%Y年%m月%d日")) - return context - - # 回归测试说明时间 -> 根据第二轮、第三轮...的开始时间 - def hsm_final_time(self, round_key: str): - if len(self.round_time) < int(round_key) + 1: - raise HttpError(status_code=400, message='您填写的回归轮次时间不正确,请填写后再生成') - cover_time = self.round_time[int(round_key)]['start'] - context = times_by_cover_time(cover_time) - context.update(cover_time=cover_time.strftime("%Y年%m月%d日")) - return context - - # 回归测试记录时间 -> 根据第二轮、第三轮...的结束时间 - def hjl_final_time(self, round_key: str) -> dict: - if len(self.round_time) < int(round_key) + 1: - raise HttpError(status_code=400, message='您填写的回归轮次时间不正确,请填写后再生成') - cover_time = self.round_time[int(round_key)]['end'] - context = times_by_cover_time(cover_time) - context.update(cover_time=cover_time.strftime("%Y年%m月%d日")) - return context - - # 生成报告非过程时间 -> 根据项目结束时间来定 - def bg_final_time(self) -> dict: - if len(self.round_time) <= 0: - raise HttpError(status_code=400, message='您还未创建轮次时间,请填写后生成') - cover_time = self.p_end - # 这里做判断,如果项目结束时间/最后一轮结束时间 - if cover_time < self.round_time[-1]['end']: - raise HttpError(500, message='项目结束时间早于最后一轮次结束时间或等于开始时间,请修改项目结束时间') - context = times_by_cover_time(cover_time) - context.update(cover_time=cover_time.strftime("%Y年%m月%d日")) - return context +# 本模块主要以项目开始时间、结束时间、轮次开始时间、结束时间计算文档中的各个时间 +from datetime import timedelta, date +from apps.project.models import Project +from django.shortcuts import get_object_or_404 +from ninja.errors import HttpError # 从代码抛出该异常,被ninja截取变为response +from utils.codes import PROJECT_ENDTIME_ERROR_CODE + +def format_remove_heng(dateT: date) -> str: + """该函数将date对象的横杠-去掉,输出str""" + return str(dateT).replace('-', '') + +def times_by_cover_time(cover_time: date) -> dict: + """该函数为每个产品文档根据封面时间,渲染签署页时间、文档变更记录时间""" + return { + 'preparation_time_no_format': cover_time - timedelta(days=2), + 'preparation_time': format_remove_heng(cover_time - timedelta(days=2)), # 拟制时间:为编制结束时间-2天 + 'inspect_time': format_remove_heng(cover_time - timedelta(days=1)), # 校对时间:为编制时间+1天 + 'auditing_time': format_remove_heng(cover_time), + 'ratify_time': format_remove_heng(cover_time), + 'create_doc_time': format_remove_heng(cover_time - timedelta(days=2)), + 'doc_v1_time': format_remove_heng(cover_time) + } + +class DocTime: + def __init__(self, project_id: int): + self.project = get_object_or_404(Project, id=project_id) + # 用户录入时间-项目 + self.p_start = self.project.beginTime # 被测件接收时间/ + self.p_end = self.project.endTime # 大纲测评时间周期结束时间/ + # 遍历轮次时间-多个 + self.round_count = self.project.pField.count() + self.round_time = [] # 轮次按顺序排序 + for round in self.project.pField.all(): + self.round_time.append({ + 'start': round.beginTime, + 'end': round.endTime, + 'location': round.location + }) + # ~~~~由上面时间二次计算得出时间~~~~ -> TODO:可由用户设置间隔时间!!!! + self.dg_bz_start = self.p_start + timedelta(days=1) # 大纲编制开始时间,项目开始时间+1天 + self.dg_bz_end = self.dg_bz_start + timedelta(days=6) # 大纲编制结束时间,大纲编制开始+6天 + self.test_sj_start = self.dg_bz_end + timedelta(days=1) # 测评设计与实现时间,在大纲编制结束+1天 + self.test_sj_end = self.test_sj_start + timedelta(days=5) # 测评设计与实现结束,在开始+5天 + # ~~~~储存每个文档的cover_time~~~~ + self.dg_cover_time = self.dg_bz_end + self.sm_cover_time = self.test_sj_end + self.jl_cover_time = self.round_time[0]['end'] + self.wtd_cover_time = self.round_time[-1]['end'] + + # 该函数生成大纲文档片段-测评时间和地点的时间和地点信息 + def dg_address_time(self): + """直接返回context去渲染""" + # 需要判断round_time是否有值 + if len(self.round_time) <= 0: + raise HttpError(status_code=400, message='您还未创建轮次时间,请填写后生成') + return { + 'start_year': self.p_start.year, + 'start_month': self.p_start.month, + 'end_year': self.p_end.year, + 'end_month': self.p_end.month, + 'beginTime_strf': format_remove_heng(self.p_start), + 'dgCompileStart': format_remove_heng(self.dg_bz_start), + 'dgCompileEnd': format_remove_heng(self.dg_bz_end), + 'designStart': format_remove_heng(self.test_sj_start), + 'designEnd': format_remove_heng(self.test_sj_end), + 'location': self.round_time[0]['location'] + } + + # 该函数生成报告文档片段-测评时间和地点【注意使用了dg_address_time -> 所以后续有修改注意前导】 + def bg_address_time(self): + if len(self.round_time) <= 0: + raise HttpError(status_code=400, message='您还未创建轮次时间,请填写后生成') + # 先使用大纲的时间行数作为前三行 + cname = ['首轮测试', '第二轮测试', '第三轮测试', '第四轮测试', '第五轮测试', '第六轮测试', '第七轮测试', + '第八轮测试', '第九轮测试', '第十轮测试'] + dg_address_time = self.dg_address_time() + round_time_list = [] + index = 0 + for round_dict in self.round_time: + one_dict = { + 'name': cname[index], + 'start': format_remove_heng(round_dict['start']), + 'end': format_remove_heng(round_dict['end']), + 'location': round_dict['location'] + } + index += 1 + round_time_list.append(one_dict) + return { + 'begin_year': dg_address_time['start_year'], + 'begin_month': dg_address_time['start_month'], + 'end_year': dg_address_time['end_year'], + 'end_month': dg_address_time['end_month'], + 'begin_time': dg_address_time['beginTime_strf'], + 'dg_weave_start_date': dg_address_time['dgCompileStart'], + 'dg_weave_end_date': dg_address_time['dgCompileEnd'], + 'sj_weave_start_date': dg_address_time['designStart'], + 'sj_weave_end_date': dg_address_time['designEnd'], + 'round_time_list': round_time_list, + # 测评总结 -> 依据项目结束时间-7 ~ 项目结束时间 + 'summary_start_date': format_remove_heng(self.p_end - timedelta(days=7)), + 'summary_end_date': format_remove_heng(self.p_end), + } + + # 生成报告中测评完成情况 -> 必须依据其他内容生成时间【注意使用了bg_address_time -> 所以后续有修改注意前导】 + def bg_completion_situation(self): + bg_timer_dict = self.bg_address_time() + xq_fx_time_end = self.dg_bz_start + timedelta(days=2) + ch_time_start = xq_fx_time_end + timedelta(days=1) + ch_time_end = self.dg_bz_end + if len(self.round_time) < 1: + raise HttpError(status_code=400, message='您还未创建第一轮测试的时间,请填写后再生成') + return { + 'start_time_year': bg_timer_dict['begin_year'], + 'start_time_month': bg_timer_dict['begin_month'], + 'xq_fx_time_start_year': self.dg_bz_start.year, + 'xq_fx_time_start_month': self.dg_bz_start.month, + 'xq_fx_time_start_day': self.dg_bz_start.day, + 'xq_fx_time_end_year': xq_fx_time_end.year, # 需求分析结束时间是大纲编制开始+2 + 'xq_fx_time_end_month': xq_fx_time_end.month, + 'xq_fx_time_end_day': xq_fx_time_end.day, + 'ch_start_year': ch_time_start.year, + 'ch_start_month': ch_time_start.month, + 'ch_start_day': ch_time_start.day, + 'ch_end_year': ch_time_end.year, + 'ch_end_month': ch_time_end.month, + 'ch_end_day': ch_time_end.day, + 'sj_start_year': self.test_sj_start.year, + 'sj_start_month': self.test_sj_start.month, + 'sj_start_day': self.test_sj_start.day, + 'sj_end_year': self.test_sj_end.year, + 'sj_end_month': self.test_sj_end.month, + 'sj_end_day': self.test_sj_end.day, + 'end_time_year': self.p_end.year, + 'end_time_month': self.p_end.month, + 'exec_start_time_year': self.round_time[0]['start'].year, + 'exec_start_time_month': self.round_time[0]['start'].month, + 'exec_start_time_day': self.round_time[0]['start'].day, + 'exec_end_time_year': self.round_time[0]['end'].year, + 'exec_end_time_month': self.round_time[0]['end'].month, + 'exec_end_time_day': self.round_time[0]['end'].day, + } + + # 该函数生成最终大纲的时间 + def dg_final_time(self): + cover_time = self.dg_bz_end + context = times_by_cover_time(cover_time) + context.update(cover_time=cover_time.strftime("%Y年%m月%d日")) + # 新增给大纲模版10.2章节context + context.update(basic_line1=cover_time.strftime("%Y年%m月"), basic_line2=self.p_end.strftime("%Y年%m月")) + # 新增给大纲模版10.3.2章节的context + sm_context = self.sm_final_time() + context.update(sm_end_time=sm_context['preparation_time_no_format'].strftime("%Y年%m月")) + return context + + # 该函数生成说明文档的时间 -> 依据项目时间而非用户第一轮填写时间! + def sm_final_time(self): + cover_time = self.test_sj_end # 封面时间:为大纲时间中“测评设计与实现”结束时间 + context = times_by_cover_time(cover_time) + context.update(cover_time=cover_time.strftime("%Y年%m月%d日")) + return context + + # 该函数生成记录文档的时间 -> 依据第一轮测试用户填写的事件 + def jl_final_time(self): + if len(self.round_time) < 1: + raise HttpError(status_code=400, message='您还未创建第一轮测试的时间,请填写后再生成') + cover_time = self.round_time[0]['end'] # 封面时间为用户填写第一轮结束时间 + context = times_by_cover_time(cover_time) + context.update(cover_time=cover_time.strftime("%Y年%m月%d日")) + return context + + # 问题单的时间 -> 依据最后一轮次的结束时间+1天 + def wtd_final_time(self): + if len(self.round_time) < 1: + raise HttpError(status_code=400, message='您还未创建第一轮测试的时间,请填写后再生成') + cover_time = self.round_time[-1]['end'] + context = times_by_cover_time(cover_time) + context.update(cover_time=cover_time.strftime("%Y年%m月%d日")) + return context + + # 回归测试说明时间 -> 根据第二轮、第三轮...的开始时间 + def hsm_final_time(self, round_key: str): + if len(self.round_time) < int(round_key) + 1: + raise HttpError(status_code=400, message='您填写的回归轮次时间不正确,请填写后再生成') + cover_time = self.round_time[int(round_key)]['start'] + context = times_by_cover_time(cover_time) + context.update(cover_time=cover_time.strftime("%Y年%m月%d日")) + return context + + # 回归测试记录时间 -> 根据第二轮、第三轮...的结束时间 + def hjl_final_time(self, round_key: str) -> dict: + if len(self.round_time) < int(round_key) + 1: + raise HttpError(status_code=400, message='您填写的回归轮次时间不正确,请填写后再生成') + cover_time = self.round_time[int(round_key)]['end'] + context = times_by_cover_time(cover_time) + context.update(cover_time=cover_time.strftime("%Y年%m月%d日")) + return context + + # 生成报告非过程时间 -> 根据项目结束时间来定 + def bg_final_time(self) -> dict: + if len(self.round_time) <= 0: + raise HttpError(status_code=400, message='您还未创建轮次时间,请填写后生成') + cover_time = self.p_end + # 这里做判断,如果项目结束时间/最后一轮结束时间 + if cover_time < self.round_time[-1]['end']: + # 注意系统对HttpError异常重新处理,所以该处status_code看api.py文件 + raise HttpError(PROJECT_ENDTIME_ERROR_CODE, message='项目结束时间早于最后一轮次结束时间或等于开始时间,请修改项目结束时间') + context = times_by_cover_time(cover_time) + context.update(cover_time=cover_time.strftime("%Y年%m月%d日")) + return context diff --git a/apps/createDocument/extensions/table_creator.py b/apps/createDocument/extensions/table_creator.py new file mode 100644 index 0000000..bf98d13 --- /dev/null +++ b/apps/createDocument/extensions/table_creator.py @@ -0,0 +1,146 @@ +from pathlib import Path +from typing import Literal +from docxtpl import DocxTemplate +from docx.enum.text import WD_ALIGN_PARAGRAPH +from docx.enum.table import WD_ALIGN_VERTICAL +from docx.oxml.ns import qn +from docx.shared import Mm +from apps.createDocument.extensions.tools import set_table_border_by_cell_position, set_cell_margins +from utils.path_utils import project_path +from utils.chen_response import ChenResponse +from django.shortcuts import get_object_or_404 +from apps.project.models import Project, Round +from django.db.models import QuerySet + +# 创建当前轮次别名 +RoundType = Literal["0", "not0", "last"] +chinese_round_name: list = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十'] + +# 通用生成静态软件项、静态硬件项、动态软件项、动态硬件信息、测评数据的context,包含fontnote和table +def create_table_context(table_data: list[list[str]], doc: DocxTemplate, rounds_map: list[list[str]] = None, + current_round: str = None): + """ + 注意:该函数会增加一列序号列,并且支持单元格内回车换行(段落换行) + 传入当前轮次以及rounds_map来过滤一些其他轮次的数据,为None则不过滤 + """ + # 过滤数据处理 + if rounds_map is not None and current_round is not None and current_round != 'last': + filtered_data = [] + for i, row in enumerate(table_data): + # 第一行作为表头,始终保留 + if i == 0: + filtered_data.append(row) + else: + # 检查该行是否属于当前轮次 + if current_round in rounds_map[i]: + filtered_data.append(row) + # table_data先替换后再执行下方生成表格 + table_data = filtered_data + + subdoc = doc.new_subdoc() + rows = len(table_data) + cols = len(table_data[0]) + 1 + table = subdoc.add_table(rows=rows, cols=cols) + + # 单元格处理 + for row in range(rows): + for col in range(cols): + cell = table.cell(row, col) # 从上倒下,从左到右取cell + set_cell_margins(cell, left=100, right=100, top=100, bottom=100) + + # 获取要显示的文本内容(字符串或按行拆分后的列表) + if col == 0: + # 序号列 + lines = ["序号"] if row == 0 else [str(row)] + else: + raw_text = table_data[row][col - 1] + # 按换行符 \n 拆分为多个段落 + lines = raw_text.split('\n') if raw_text else [''] + + # 清空单元格原有段落(add_table 默认有一个段落) + cell.text = "" + # 删除默认段落,稍后统一添加 + for para in cell.paragraphs: + p = para._element + p.getparent().remove(p) + + # 逐个添加段落 + for i, line in enumerate(lines): + if i == 0: + para = cell.add_paragraph(line) + else: + para = cell.add_paragraph(line) + + # 设置段落对齐(第一列居中,其他左对齐,可根据需要调整) + if col == 0: + para.alignment = WD_ALIGN_PARAGRAPH.CENTER + else: + para.alignment = WD_ALIGN_PARAGRAPH.LEFT + + # 对第一行(表头)设置黑体字体 + if row == 0: + for run in para.runs: + run.font.name = '黑体' + run._element.rPr.rFonts.set(qn('w:eastAsia'), '黑体') + run.font.bold = False + # 表头段落居中(覆盖前面的 left) + para.alignment = WD_ALIGN_PARAGRAPH.CENTER + + # 垂直居中 + cell.vertical_alignment = WD_ALIGN_VERTICAL.CENTER + + # 设置序号列宽度 + for cell in table.columns[0].cells: + cell.width = Mm(15) + for para in cell.paragraphs: + para.alignment = WD_ALIGN_PARAGRAPH.CENTER + + # 表格居中 + table.alignment = WD_ALIGN_PARAGRAPH.CENTER + # 设置表格外边框 + set_table_border_by_cell_position(table) + return subdoc + +# 统一静态软件项、静态硬件项、动态软件项、动态硬件信息、测评数据5个的word生成 - 模版模式 +def uniform_static_dynamic_response(id: int, filename: str, r_filename: str, model, + current_round: str = "0", isHsm: bool = None) -> ChenResponse | None: + """ 通过形参isHsm判断是否是回归测试说明 """ + project_obj = get_object_or_404(Project, id=id) + input_path = Path.cwd() / 'media' / project_path(id) / 'form_template' / 'dg' / filename # 取相同模版 + doc = DocxTemplate(input_path) + qs = model.objects.filter(project=project_obj) + if qs.exists(): + obj = qs.first() + table_data = obj.table + # 回归测试说明生成多轮次回归测试说明的5个接口分支 + if isHsm: + hround_list: QuerySet[Round] = project_obj.pField.exclude(key='0') + for hround in hround_list: + round_key = hround.key + cname = chinese_round_name[int(round_key)] # 取中文:一、二、三... + # key就是current_round,这里就解决文件名和那个的问题 + subdoc = create_table_context(table_data, doc, obj.rounds_map, round_key) + context = { + 'fontnote': obj.fontnote, + 'table': subdoc, + } + doc.render(context, autoescape=True) + try: + doc.save(Path.cwd() / "media" / project_path(id) / "output_dir/hsm" / "".join([f"第{cname}轮", r_filename])) + except PermissionError as e: + return ChenResponse(status=400, code=400, message="模版文件已打开,请关闭后再试,{0}".format(e)) + return ChenResponse(status=200,code=200,message="多个轮次5接口渲染完毕,文档生成完毕") + + # 新增:传入rounds_map进行渲染 + subdoc = create_table_context(table_data, doc, obj.rounds_map, current_round) + context = { + 'fontnote': obj.fontnote, + 'table': subdoc, + } + doc.render(context, autoescape=True) + try: + doc.save(Path.cwd() / "media" / project_path(id) / "output_dir" / r_filename) + return ChenResponse(status=200, code=200, message="文档生成成功!") + except PermissionError as e: + return ChenResponse(status=400, code=400, message="模版文件已打开,请关闭后再试,{0}".format(e)) + return None diff --git a/apps/project/__pycache__/models.cpython-313.pyc b/apps/project/__pycache__/models.cpython-313.pyc index 4909e6d..017dad8 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__/project.cpython-313.pyc b/apps/project/controllers/__pycache__/project.cpython-313.pyc index 1b0e2ef..d80729a 100644 Binary files a/apps/project/controllers/__pycache__/project.cpython-313.pyc and b/apps/project/controllers/__pycache__/project.cpython-313.pyc differ diff --git a/apps/project/controllers/project.py b/apps/project/controllers/project.py index 198924f..2239f23 100644 --- a/apps/project/controllers/project.py +++ b/apps/project/controllers/project.py @@ -460,7 +460,12 @@ class ProjectController(ControllerBase): item_qs = self.get_model_from_category(category).objects.filter(project=project_obj) if item_qs.exists(): item_obj = item_qs.first() - return ChenResponse(status=200, code=25001, data={"table": item_obj.table, "fontnote": item_obj.fontnote}) + if item_obj: + return ChenResponse(status=200, code=25001, data={ + "table": item_obj.table, + "fontnote": item_obj.fontnote, + "rounds": item_obj.rounds_map or [] + }) return ChenResponse(status=200, code=25002, data=None) # ~~~静态软件项、静态硬件项、动态软件项、动态硬件项、测评数据 - 新增或修改~~~ @@ -470,10 +475,21 @@ class ProjectController(ControllerBase): project_obj = self.get_project_by_id(data.id) model = self.get_model_from_category(data.category) item_qs = model.objects.filter(project=project_obj) + # 处理rounds_map + rounds = data.rounds + if rounds is None: + rounds = [["0"]] * len(data.table) + if item_qs.exists(): # 如果存在则修改 item_qs.delete() - model.objects.create(project=project_obj, table=data.table, fontnote=data.fontnote) + model.objects.create( + project=project_obj, + table=data.table, + fontnote=data.fontnote, + rounds_map=rounds, + ) + return ChenResponse(status=200, code=20000, message="保存成功") # ~~~环境差异性分析 - 获取~~~ @route.get("/get_env_analysis/") diff --git a/apps/project/migrations/0036_dynamichardwaretable_rounds_map_and_more.py b/apps/project/migrations/0036_dynamichardwaretable_rounds_map_and_more.py new file mode 100644 index 0000000..f553377 --- /dev/null +++ b/apps/project/migrations/0036_dynamichardwaretable_rounds_map_and_more.py @@ -0,0 +1,43 @@ +# Generated by Django 6.0.4 on 2026-04-23 18:15 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('project', '0035_design_is_bidirectional'), + ] + + operations = [ + migrations.AddField( + model_name='dynamichardwaretable', + name='rounds_map', + field=models.JSONField(blank=True, default=list, help_text='二维数组,每个内层数组是该行选中的轮次索引(字符串)', verbose_name='轮次数据'), + ), + migrations.AddField( + model_name='dynamicsofttable', + name='rounds_map', + field=models.JSONField(blank=True, default=list, help_text='二维数组,每个内层数组是该行选中的轮次索引(字符串)', verbose_name='轮次数据'), + ), + migrations.AddField( + model_name='evaluatedata', + name='rounds_map', + field=models.JSONField(blank=True, default=list, help_text='二维数组,每个内层数组是该行选中的轮次索引(字符串)', verbose_name='轮次数据'), + ), + migrations.AddField( + model_name='staticsofthardware', + name='rounds_map', + field=models.JSONField(blank=True, default=list, help_text='二维数组,每个内层数组是该行选中的轮次索引(字符串)', verbose_name='轮次数据'), + ), + migrations.AlterField( + model_name='project', + name='beginTime', + field=models.DateField(blank=True, help_text='开始时间', null=True, verbose_name='开始时间'), + ), + migrations.AlterField( + model_name='project', + name='endTime', + field=models.DateField(blank=True, help_text='结束时间', null=True, verbose_name='结束时间'), + ), + ] diff --git a/apps/project/migrations/0037_staticsoftitem_rounds_map.py b/apps/project/migrations/0037_staticsoftitem_rounds_map.py new file mode 100644 index 0000000..1be88b3 --- /dev/null +++ b/apps/project/migrations/0037_staticsoftitem_rounds_map.py @@ -0,0 +1,18 @@ +# Generated by Django 6.0.4 on 2026-04-23 18:19 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('project', '0036_dynamichardwaretable_rounds_map_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='staticsoftitem', + name='rounds_map', + field=models.JSONField(blank=True, default=list, help_text='二维数组,每个内层数组是该行选中的轮次索引(字符串)', verbose_name='轮次数据'), + ), + ] diff --git a/apps/project/migrations/__pycache__/0036_dynamichardwaretable_rounds_map_and_more.cpython-313.pyc b/apps/project/migrations/__pycache__/0036_dynamichardwaretable_rounds_map_and_more.cpython-313.pyc new file mode 100644 index 0000000..3c01645 Binary files /dev/null and b/apps/project/migrations/__pycache__/0036_dynamichardwaretable_rounds_map_and_more.cpython-313.pyc differ diff --git a/apps/project/migrations/__pycache__/0037_staticsoftitem_rounds_map.cpython-313.pyc b/apps/project/migrations/__pycache__/0037_staticsoftitem_rounds_map.cpython-313.pyc new file mode 100644 index 0000000..33f4ef5 Binary files /dev/null and b/apps/project/migrations/__pycache__/0037_staticsoftitem_rounds_map.cpython-313.pyc differ diff --git a/apps/project/models.py b/apps/project/models.py index 8b6f547..acb31df 100644 --- a/apps/project/models.py +++ b/apps/project/models.py @@ -499,6 +499,12 @@ class StaticSoftItem(models.Model): verbose_name="关联项目", help_text="关联项目") table = models.JSONField(verbose_name="储存表格二维数组", help_text="储存表格二维数组", default=default_json_value) fontnote = models.CharField(max_length=256, null=True, default="", verbose_name="题注", help_text="数据的题注说明") + rounds_map = models.JSONField( + verbose_name="轮次数据", + help_text="二维数组,每个内层数组是该行选中的轮次索引(字符串)", + default=list, + blank=True, + ) class Meta: db_table = 'project_static_soft_item' @@ -511,6 +517,12 @@ class StaticSoftHardware(models.Model): verbose_name="关联项目", help_text="关联项目") table = models.JSONField(verbose_name="储存表格二维数组", help_text="储存表格二维数组", default=default_json_value) fontnote = models.CharField(max_length=256, null=True, default="", verbose_name="题注", help_text="数据的题注说明") + rounds_map = models.JSONField( + verbose_name="轮次数据", + help_text="二维数组,每个内层数组是该行选中的轮次索引(字符串)", + default=list, + blank=True, + ) class Meta: db_table = 'project_static_hardware' @@ -523,6 +535,12 @@ class DynamicSoftTable(models.Model): verbose_name="关联项目", help_text="关联项目") table = models.JSONField(verbose_name="储存表格二维数组", help_text="储存表格二维数组", default=default_json_value) fontnote = models.CharField(max_length=256, null=True, default="", verbose_name="题注", help_text="数据的题注说明") + rounds_map = models.JSONField( + verbose_name="轮次数据", + help_text="二维数组,每个内层数组是该行选中的轮次索引(字符串)", + default=list, + blank=True, + ) class Meta: db_table = 'project_dynamic_soft_item' @@ -535,6 +553,12 @@ class DynamicHardwareTable(models.Model): verbose_name="关联项目", help_text="关联项目") table = models.JSONField(verbose_name="储存表格二维数组", help_text="储存表格二维数组", default=default_json_value) fontnote = models.CharField(max_length=256, null=True, default="", verbose_name="题注", help_text="数据的题注说明") + rounds_map = models.JSONField( + verbose_name="轮次数据", + help_text="二维数组,每个内层数组是该行选中的轮次索引(字符串)", + default=list, + blank=True, + ) class Meta: db_table = 'project_dynamic_hardware' @@ -547,6 +571,12 @@ class EvaluateData(models.Model): verbose_name="关联项目", help_text="关联项目") table = models.JSONField(verbose_name="储存表格二维数组", help_text="储存表格二维数组", default=default_json_value) fontnote = models.CharField(max_length=256, null=True, default="", verbose_name="题注", help_text="数据的题注说明") + rounds_map = models.JSONField( + verbose_name="轮次数据", + help_text="二维数组,每个内层数组是该行选中的轮次索引(字符串)", + default=list, + blank=True, + ) class Meta: db_table = 'project_evaluate_data' diff --git a/apps/project/schemas/__pycache__/project.cpython-313.pyc b/apps/project/schemas/__pycache__/project.cpython-313.pyc index 89d890c..b44af43 100644 Binary files a/apps/project/schemas/__pycache__/project.cpython-313.pyc and b/apps/project/schemas/__pycache__/project.cpython-313.pyc differ diff --git a/apps/project/schemas/project.py b/apps/project/schemas/project.py index cc559ce..6472590 100644 --- a/apps/project/schemas/project.py +++ b/apps/project/schemas/project.py @@ -62,6 +62,7 @@ class StaticDynamicData(Schema): category: str table: list[list[str]] fontnote: Optional[str] = "" + rounds: Optional[List[List[str]]] = None # 允许不传递 # ~~~环境差异性分析~~~ class EnvAnalysisSchema(Schema): diff --git a/cdtestplant_v1/__pycache__/api.cpython-313.pyc b/cdtestplant_v1/__pycache__/api.cpython-313.pyc index d378947..a62d315 100644 Binary files a/cdtestplant_v1/__pycache__/api.cpython-313.pyc and b/cdtestplant_v1/__pycache__/api.cpython-313.pyc differ diff --git a/cdtestplant_v1/api.py b/cdtestplant_v1/api.py index 303b7c7..43d0703 100644 --- a/cdtestplant_v1/api.py +++ b/cdtestplant_v1/api.py @@ -1,9 +1,12 @@ from utils.chen_ninja import ChenNinjaAPI +from ninja.errors import HttpError # 导入orjson解析器,渲染器,提升性能 from cdtestplant_v1.parser import MyParser from cdtestplant_v1.renderer import MyRenderer # swagger-ui配置 from ninja import Swagger +# 错误码 +from utils.codes import PROJECT_ENDTIME_ERROR_CODE api = ChenNinjaAPI( title="测试管理平台API", @@ -14,5 +17,14 @@ api = ChenNinjaAPI( docs=Swagger({"persistAuthorization": True}) ) +# 捕获HttpError - 注意这种方式不过create_response函数,需自己定义 +@api.exception_handler(HttpError) +def in_program_exception_handler(request, exc): + # HttpError的status_code这里处理为自定义码,而非HTTP协议的 + data = {} + if exc.status_code is PROJECT_ENDTIME_ERROR_CODE: + data['flag'] = PROJECT_ENDTIME_ERROR_CODE + return api.create_response(request, status=500, message=exc.message, data=data) + # 自动寻找每个app下面controllers.py中被@api_controller修饰的类 api.auto_discover_controllers() diff --git a/logs/root_log b/logs/root_log index df905a8..9bed670 100644 --- a/logs/root_log +++ b/logs/root_log @@ -1,27 +1,5 @@ -[WARNING][2026-04-22 09:45:35,603][log.py:249]Unauthorized: /api/system/getInfo -[WARNING][2026-04-22 09:45:35,677][log.py:249]Unauthorized: /api/system/logout -[WARNING][2026-04-22 09:45:39,967][backend.py:91]Caught LDAPError looking up user: SERVER_DOWN({'result': -1, 'desc': "Can't contact LDAP server", 'ctrls': []}) -[WARNING][2026-04-22 11:03:49,239][operation.py:136]"PUT - DesignController[update_design] /api/project/editDesignDemand/4030" (1048, "Column 'is_bidirectional' cannot be null") -[ERROR][2026-04-22 11:03:49,239][errors.py:131](1048, "Column 'is_bidirectional' 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 286, in query - _mysql.connection.query(self, query) - ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^ -MySQLdb.IntegrityError: (1048, "Column 'is_bidirectional' cannot be null") - -The above exception was the direct cause of the following exception: - +[WARNING][2026-04-23 15:28:58,739][operation.py:136]"GET - ProjectController[document_time_show] /api/testmanage/project/document_time_show" (500412, '项目结束时间早于最后一轮次结束时间或等于开始时间,请修改项目结束时间') +[ERROR][2026-04-23 15:28:58,748][log.py:249]Internal Server Error: /api/testmanage/project/document_time_show Traceback (most recent call last): File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 217, in run result = self.view_func(request, **ctx.kwargs["view_func_kwargs"]) @@ -31,79 +9,43 @@ Traceback (most recent call last): ) File "D:\programs\uv\python\cpython-3.13.11-windows-x86_64-none\Lib\contextlib.py", line 85, in inner return func(*args, **kwds) - File "E:\pycharmProjects\cdtestplant_v1\apps\project\controllers\design.py", line 148, in update_design - design_qs.save() - ~~~~~~~~~~~~~~^^ - File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\models\base.py", line 874, in save - self.save_base( - ~~~~~~~~~~~~~~^ - using=using, - ^^^^^^^^^^^^ - ...<2 lines>... - update_fields=update_fields, - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - ) - ^ - File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\models\base.py", line 966, in save_base - updated = self._save_table( - raw, - ...<4 lines>... - update_fields, - ) - File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\models\base.py", line 1110, in _save_table - results = self._do_update( - base_qs, - ...<5 lines>... - returning_fields, - ) - File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\models\base.py", line 1213, in _do_update - return filtered._update(values, returning_fields) - ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^ - File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\models\query.py", line 1327, in _update - return query.get_compiler(self.db).execute_returning_sql(returning_fields) - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^ - File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\models\sql\compiler.py", line 2140, in execute_returning_sql - row_count = self.execute_sql(ROW_COUNT) - File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\models\sql\compiler.py", line 2111, in execute_sql - row_count = super().execute_sql(result_type) - 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 286, in query - _mysql.connection.query(self, query) - ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^ -django.db.utils.IntegrityError: (1048, "Column 'is_bidirectional' cannot be null") -[ERROR][2026-04-22 11:03:49,254][log.py:249]Internal Server Error: /api/project/editDesignDemand/4030 -[WARNING][2026-04-22 11:23:22,342][operation.py:136]"POST - DesignController[create_design] /api/project/designDemand/save" ("Design() got unexpected keyword arguments: 'forward_source', 'forward_destination', 'forward_description', 'reverse_source', 'reverse_destination', 'reverse_description'",) -[ERROR][2026-04-22 11:23:22,342][errors.py:131]Design() got unexpected keyword arguments: 'forward_source', 'forward_destination', 'forward_description', 'reverse_source', 'reverse_destination', 'reverse_description' + File "E:\pycharmProjects\cdtestplant_v1\apps\project\controllers\project.py", line 271, in document_time_show + time = time_return_to(id) + File "E:\pycharmProjects\cdtestplant_v1\apps\project\tool\timeList.py", line 94, in time_return_to + temp_dict = time_parser.bg_final_time() + File "E:\pycharmProjects\cdtestplant_v1\apps\createDocument\extensions\documentTime.py", line 206, in bg_final_time + raise HttpError(PROJECT_ENDTIME_ERROR_CODE, message='项目结束时间早于最后一轮次结束时间或等于开始时间,请修改项目结束时间') +ninja.errors.HttpError: 项目结束时间早于最后一轮次结束时间或等于开始时间,请修改项目结束时间 + +During handling of the above exception, another exception occurred: + +Traceback (most recent call last): + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\core\handlers\exception.py", line 55, in inner + response = get_response(request) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\core\handlers\base.py", line 198, in _get_response + response = wrapped_callback(request, *callback_args, **callback_kwargs) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja\operation.py", line 661, in sync_view_wrapper + return self._sync_view(request, *args, **kwargs) + ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 322, in _sync_view + return super(PathView, self)._sync_view(request, *args, **kwargs) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja\operation.py", line 673, in _sync_view + return operation.run(request, *a, **kw) + ~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 231, in run + return self.api.on_exception(request, e) + ~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja\main.py", line 617, in on_exception + return handler(request, exc) + File "E:\pycharmProjects\cdtestplant_v1\cdtestplant_v1\api.py", line 24, in in_program_exception_handler + if exc.detail is PROJECT_ENDTIME_ERROR_CODE: + ^^^^^^^^^^ +AttributeError: 'HttpError' object has no attribute 'detail' +[WARNING][2026-04-23 15:29:14,430][operation.py:136]"GET - ProjectController[document_time_show] /api/testmanage/project/document_time_show" (500412, '项目结束时间早于最后一轮次结束时间或等于开始时间,请修改项目结束时间') +[ERROR][2026-04-23 15:29:14,438][log.py:249]Internal Server Error: /api/testmanage/project/document_time_show +[WARNING][2026-04-23 15:30:11,756][operation.py:136]"GET - ProjectController[document_time_show] /api/testmanage/project/document_time_show" (500412, '项目结束时间早于最后一轮次结束时间或等于开始时间,请修改项目结束时间') +[ERROR][2026-04-23 15:30:11,772][log.py:249]Internal Server Error: /api/testmanage/project/document_time_show Traceback (most recent call last): File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 217, in run result = self.view_func(request, **ctx.kwargs["view_func_kwargs"]) @@ -113,21 +55,88 @@ Traceback (most recent call last): ) File "D:\programs\uv\python\cpython-3.13.11-windows-x86_64-none\Lib\contextlib.py", line 85, in inner return func(*args, **kwds) - File "E:\pycharmProjects\cdtestplant_v1\apps\project\controllers\design.py", line 116, in create_design - qs = Design.objects.create(**asert_dict) - 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 667, in create - obj = self.model(**kwargs) - File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\db\models\base.py", line 590, in __init__ - raise TypeError( - ...<2 lines>... - ) -TypeError: Design() got unexpected keyword arguments: 'forward_source', 'forward_destination', 'forward_description', 'reverse_source', 'reverse_destination', 'reverse_description' -[ERROR][2026-04-22 11:23:22,347][log.py:249]Internal Server Error: /api/project/designDemand/save -[WARNING][2026-04-22 13:13:59,640][operation.py:136]"GET - GenerateControllerDG[create_interface] /api/generate/create/interface" ("'Design' object has no attribute 'source'",) -[ERROR][2026-04-22 13:13:59,640][errors.py:131]'Design' object has no attribute 'source' + File "E:\pycharmProjects\cdtestplant_v1\apps\project\controllers\project.py", line 271, in document_time_show + time = time_return_to(id) + File "E:\pycharmProjects\cdtestplant_v1\apps\project\tool\timeList.py", line 94, in time_return_to + temp_dict = time_parser.bg_final_time() + File "E:\pycharmProjects\cdtestplant_v1\apps\createDocument\extensions\documentTime.py", line 206, in bg_final_time + raise HttpError(PROJECT_ENDTIME_ERROR_CODE, message='项目结束时间早于最后一轮次结束时间或等于开始时间,请修改项目结束时间') +ninja.errors.HttpError: 项目结束时间早于最后一轮次结束时间或等于开始时间,请修改项目结束时间 + +During handling of the above exception, another exception occurred: + +Traceback (most recent call last): + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\core\handlers\exception.py", line 55, in inner + response = get_response(request) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\django\core\handlers\base.py", line 198, in _get_response + response = wrapped_callback(request, *callback_args, **callback_kwargs) + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja\operation.py", line 661, in sync_view_wrapper + return self._sync_view(request, *args, **kwargs) + ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 322, in _sync_view + return super(PathView, self)._sync_view(request, *args, **kwargs) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja\operation.py", line 673, in _sync_view + return operation.run(request, *a, **kw) + ~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 231, in run + return self.api.on_exception(request, e) + ~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja\main.py", line 617, in on_exception + return handler(request, exc) + File "E:\pycharmProjects\cdtestplant_v1\cdtestplant_v1\api.py", line 26, in in_program_exception_handler + return api.create_response(request, status=500, message=exc.message) + ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +TypeError: ChenNinjaAPI.create_response() missing 1 required positional argument: 'data' +[WARNING][2026-04-23 15:31:00,940][operation.py:136]"GET - ProjectController[document_time_show] /api/testmanage/project/document_time_show" (500412, '项目结束时间早于最后一轮次结束时间或等于开始时间,请修改项目结束时间') +[ERROR][2026-04-23 15:31:00,948][log.py:249]Internal Server Error: /api/testmanage/project/document_time_show +[WARNING][2026-04-23 15:31:09,568][operation.py:136]"GET - ProjectController[document_time_show] /api/testmanage/project/document_time_show" (500412, '项目结束时间早于最后一轮次结束时间或等于开始时间,请修改项目结束时间') +[ERROR][2026-04-23 15:31:09,578][log.py:249]Internal Server Error: /api/testmanage/project/document_time_show +[WARNING][2026-04-23 15:34:41,469][operation.py:136]"GET - ProjectController[document_time_show] /api/testmanage/project/document_time_show" (500412, '项目结束时间早于最后一轮次结束时间或等于开始时间,请修改项目结束时间') +[ERROR][2026-04-23 15:34:41,477][log.py:249]Internal Server Error: /api/testmanage/project/document_time_show +[WARNING][2026-04-23 15:34:45,816][operation.py:136]"GET - ProjectController[document_time_show] /api/testmanage/project/document_time_show" (500412, '项目结束时间早于最后一轮次结束时间或等于开始时间,请修改项目结束时间') +[ERROR][2026-04-23 15:34:45,824][log.py:249]Internal Server Error: /api/testmanage/project/document_time_show +[WARNING][2026-04-23 15:34:50,470][operation.py:136]"GET - ProjectController[document_time_show] /api/testmanage/project/document_time_show" (500412, '项目结束时间早于最后一轮次结束时间或等于开始时间,请修改项目结束时间') +[ERROR][2026-04-23 15:34:50,480][log.py:249]Internal Server Error: /api/testmanage/project/document_time_show +[WARNING][2026-04-23 15:34:55,380][operation.py:136]"GET - ProjectController[document_time_show] /api/testmanage/project/document_time_show" (500412, '项目结束时间早于最后一轮次结束时间或等于开始时间,请修改项目结束时间') +[ERROR][2026-04-23 15:34:55,388][log.py:249]Internal Server Error: /api/testmanage/project/document_time_show +[WARNING][2026-04-23 15:34:58,806][operation.py:136]"GET - ProjectController[document_time_show] /api/testmanage/project/document_time_show" (500412, '项目结束时间早于最后一轮次结束时间或等于开始时间,请修改项目结束时间') +[ERROR][2026-04-23 15:34:58,814][log.py:249]Internal Server Error: /api/testmanage/project/document_time_show +[WARNING][2026-04-23 15:35:14,656][operation.py:136]"GET - ProjectController[document_time_show] /api/testmanage/project/document_time_show" (500412, '项目结束时间早于最后一轮次结束时间或等于开始时间,请修改项目结束时间') +[ERROR][2026-04-23 15:35:14,664][log.py:249]Internal Server Error: /api/testmanage/project/document_time_show +[WARNING][2026-04-23 15:35:41,998][operation.py:136]"GET - ProjectController[document_time_show] /api/testmanage/project/document_time_show" (500412, '项目结束时间早于最后一轮次结束时间或等于开始时间,请修改项目结束时间') +[ERROR][2026-04-23 15:35:42,007][log.py:249]Internal Server Error: /api/testmanage/project/document_time_show +[WARNING][2026-04-23 15:38:50,737][operation.py:136]"GET - ProjectController[document_time_show] /api/testmanage/project/document_time_show" (500412, '项目结束时间早于最后一轮次结束时间或等于开始时间,请修改项目结束时间') +[ERROR][2026-04-23 15:38:50,745][log.py:249]Internal Server Error: /api/testmanage/project/document_time_show +[WARNING][2026-04-23 15:43:24,757][operation.py:136]"GET - ProjectController[document_time_show] /api/testmanage/project/document_time_show" (500412, '项目结束时间早于最后一轮次结束时间或等于开始时间,请修改项目结束时间') +[ERROR][2026-04-23 15:43:24,765][log.py:249]Internal Server Error: /api/testmanage/project/document_time_show +[WARNING][2026-04-23 15:44:02,062][operation.py:136]"GET - ProjectController[document_time_show] /api/testmanage/project/document_time_show" (500412, '项目结束时间早于最后一轮次结束时间或等于开始时间,请修改项目结束时间') +[ERROR][2026-04-23 15:44:02,071][log.py:249]Internal Server Error: /api/testmanage/project/document_time_show +[WARNING][2026-04-23 15:44:21,790][operation.py:136]"GET - ProjectController[document_time_show] /api/testmanage/project/document_time_show" (500412, '项目结束时间早于最后一轮次结束时间或等于开始时间,请修改项目结束时间') +[ERROR][2026-04-23 15:44:21,798][log.py:249]Internal Server Error: /api/testmanage/project/document_time_show +[WARNING][2026-04-23 15:44:32,220][operation.py:136]"GET - ProjectController[document_time_show] /api/testmanage/project/document_time_show" (500412, '项目结束时间早于最后一轮次结束时间或等于开始时间,请修改项目结束时间') +[ERROR][2026-04-23 15:44:32,227][log.py:249]Internal Server Error: /api/testmanage/project/document_time_show +[WARNING][2026-04-23 15:46:42,165][operation.py:136]"GET - ProjectController[document_time_show] /api/testmanage/project/document_time_show" (500412, '项目结束时间早于最后一轮次结束时间或等于开始时间,请修改项目结束时间') +[ERROR][2026-04-23 15:46:42,174][log.py:249]Internal Server Error: /api/testmanage/project/document_time_show +[WARNING][2026-04-23 15:47:01,501][operation.py:136]"GET - ProjectController[document_time_show] /api/testmanage/project/document_time_show" (500412, '项目结束时间早于最后一轮次结束时间或等于开始时间,请修改项目结束时间') +[ERROR][2026-04-23 15:47:01,509][log.py:249]Internal Server Error: /api/testmanage/project/document_time_show +[WARNING][2026-04-23 15:47:40,712][operation.py:136]"GET - ProjectController[document_time_show] /api/testmanage/project/document_time_show" (500412, '项目结束时间早于最后一轮次结束时间或等于开始时间,请修改项目结束时间') +[ERROR][2026-04-23 15:47:40,722][log.py:249]Internal Server Error: /api/testmanage/project/document_time_show +[WARNING][2026-04-23 15:47:43,095][operation.py:136]"GET - ProjectController[document_time_show] /api/testmanage/project/document_time_show" (500412, '项目结束时间早于最后一轮次结束时间或等于开始时间,请修改项目结束时间') +[ERROR][2026-04-23 15:47:43,103][log.py:249]Internal Server Error: /api/testmanage/project/document_time_show +[WARNING][2026-04-23 15:53:49,660][operation.py:136]"GET - ProjectController[document_time_show] /api/testmanage/project/document_time_show" (500412, '项目结束时间早于最后一轮次结束时间或等于开始时间,请修改项目结束时间') +[ERROR][2026-04-23 15:53:49,667][log.py:249]Internal Server Error: /api/testmanage/project/document_time_show +[WARNING][2026-04-23 15:54:00,089][operation.py:136]"GET - ProjectController[document_time_show] /api/testmanage/project/document_time_show" (500412, '项目结束时间早于最后一轮次结束时间或等于开始时间,请修改项目结束时间') +[ERROR][2026-04-23 15:54:00,097][log.py:249]Internal Server Error: /api/testmanage/project/document_time_show +[WARNING][2026-04-23 15:56:58,912][operation.py:136]"GET - ProjectController[document_time_show] /api/testmanage/project/document_time_show" (500412, '项目结束时间早于最后一轮次结束时间或等于开始时间,请修改项目结束时间') +[ERROR][2026-04-23 15:56:58,918][log.py:249]Internal Server Error: /api/testmanage/project/document_time_show +[WARNING][2026-04-23 15:58:44,243][operation.py:136]"POST - GenerateSeitaiController[create_bgDocument] /api/create/bgDocument" (500412, '项目结束时间早于最后一轮次结束时间或等于开始时间,请修改项目结束时间') +[ERROR][2026-04-23 15:58:44,244][log.py:249]Internal Server Error: /api/create/bgDocument +[WARNING][2026-04-24 13:56:12,151][log.py:249]Unauthorized: /api/system/getInfo +[WARNING][2026-04-24 13:56:12,209][log.py:249]Unauthorized: /api/system/logout +[WARNING][2026-04-24 13:56:16,702][backend.py:91]Caught LDAPError looking up user: SERVER_DOWN({'result': -1, 'desc': "Can't contact LDAP server", 'ctrls': []}) +[WARNING][2026-04-24 14:06:28,243][operation.py:136]"GET - GenerateControllerDG[create_static_soft] /api/generate/create/static_soft" ('GenerateControllerDG.create_table_context() takes 3 positional arguments but 4 were given',) +[ERROR][2026-04-24 14:06:28,243][errors.py:131]GenerateControllerDG.create_table_context() takes 3 positional arguments but 4 were given Traceback (most recent call last): File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 217, in run result = self.view_func(request, **ctx.kwargs["view_func_kwargs"]) @@ -135,8 +144,107 @@ Traceback (most recent call last): result = self.route.view_func( ctx.controller_instance, *args, **ctx.view_func_kwargs ) - File "E:\pycharmProjects\cdtestplant_v1\apps\createDocument\controllers\dg.py", line 417, in create_interface - 'source': interface.source, - ^^^^^^^^^^^^^^^^ -AttributeError: 'Design' object has no attribute 'source' -[ERROR][2026-04-22 13:13:59,650][log.py:249]Internal Server Error: /api/generate/create/interface + File "E:\pycharmProjects\cdtestplant_v1\apps\createDocument\controllers\dg.py", line 581, in create_static_soft + res = self.uniform_static_dynamic_response(id, '静态软件项_2.docx', '静态软件项.docx', StaticSoftItem) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\apps\createDocument\controllers\dg.py", line 565, in uniform_static_dynamic_response + subdoc = cls.create_table_context(table_data, doc, obj.rounds_map) +TypeError: GenerateControllerDG.create_table_context() takes 3 positional arguments but 4 were given +[ERROR][2026-04-24 14:06:28,258][log.py:249]Internal Server Error: /api/generate/create/static_soft +[WARNING][2026-04-24 14:06:28,259][operation.py:136]"GET - GenerateControllerDG[create_static_hard] /api/generate/create/static_hard" ('GenerateControllerDG.create_table_context() takes 3 positional arguments but 4 were given',) +[ERROR][2026-04-24 14:06:28,274][errors.py:131]GenerateControllerDG.create_table_context() takes 3 positional arguments but 4 were given +Traceback (most recent call last): + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 217, 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 108, 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 597, in create_static_hard + res = self.uniform_static_dynamic_response(id, '静态硬件和固件项_2.docx', '静态硬件和固件项.docx', StaticSoftHardware) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\apps\createDocument\controllers\dg.py", line 565, in uniform_static_dynamic_response + subdoc = cls.create_table_context(table_data, doc, obj.rounds_map) +TypeError: GenerateControllerDG.create_table_context() takes 3 positional arguments but 4 were given +[ERROR][2026-04-24 14:06:28,278][log.py:249]Internal Server Error: /api/generate/create/static_hard +[WARNING][2026-04-24 14:06:28,316][operation.py:136]"GET - GenerateControllerDG[create_dynamic_soft] /api/generate/create/dynamic_soft" ('GenerateControllerDG.create_table_context() takes 3 positional arguments but 4 were given',) +[ERROR][2026-04-24 14:06:28,316][errors.py:131]GenerateControllerDG.create_table_context() takes 3 positional arguments but 4 were given +Traceback (most recent call last): + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 217, 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 108, 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 637, in create_dynamic_soft + res = self.uniform_static_dynamic_response(id, '动态软件项_2.docx', '动态软件项.docx', DynamicSoftTable) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\apps\createDocument\controllers\dg.py", line 565, in uniform_static_dynamic_response + subdoc = cls.create_table_context(table_data, doc, obj.rounds_map) +TypeError: GenerateControllerDG.create_table_context() takes 3 positional arguments but 4 were given +[ERROR][2026-04-24 14:06:28,319][log.py:249]Internal Server Error: /api/generate/create/dynamic_soft +[WARNING][2026-04-24 14:06:28,324][operation.py:136]"GET - GenerateControllerDG[create_test_data] /api/generate/create/test_data" ('GenerateControllerDG.create_table_context() takes 3 positional arguments but 4 were given',) +[WARNING][2026-04-24 14:06:28,324][operation.py:136]"GET - GenerateControllerDG[create_dynamic_hard] /api/generate/create/dynamic_hard" ('GenerateControllerDG.create_table_context() takes 3 positional arguments but 4 were given',) +[ERROR][2026-04-24 14:06:28,326][errors.py:131]GenerateControllerDG.create_table_context() takes 3 positional arguments but 4 were given +Traceback (most recent call last): + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 217, 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 108, 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 672, in create_test_data + res = self.uniform_static_dynamic_response(id, '测评数据_2.docx', + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^ + '测评数据.docx', EvaluateData) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\apps\createDocument\controllers\dg.py", line 565, in uniform_static_dynamic_response + subdoc = cls.create_table_context(table_data, doc, obj.rounds_map) +TypeError: GenerateControllerDG.create_table_context() takes 3 positional arguments but 4 were given +[ERROR][2026-04-24 14:06:28,326][errors.py:131]GenerateControllerDG.create_table_context() takes 3 positional arguments but 4 were given +Traceback (most recent call last): + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 217, 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 108, 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 655, in create_dynamic_hard + res = self.uniform_static_dynamic_response(id, '动态硬件和固件项_2.docx', + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + '动态硬件和固件项.docx', DynamicHardwareTable) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "E:\pycharmProjects\cdtestplant_v1\apps\createDocument\controllers\dg.py", line 565, in uniform_static_dynamic_response + subdoc = cls.create_table_context(table_data, doc, obj.rounds_map) +TypeError: GenerateControllerDG.create_table_context() takes 3 positional arguments but 4 were given +[ERROR][2026-04-24 14:06:28,336][log.py:249]Internal Server Error: /api/generate/create/dynamic_hard +[ERROR][2026-04-24 14:06:28,336][log.py:249]Internal Server Error: /api/generate/create/test_data +[WARNING][2026-04-24 14:09:36,188][operation.py:136]"GET - GenerateControllerDG[create_env_diff] /api/generate/create/env_diff" ("GenerateControllerDG.create_table_context() missing 1 required positional argument: 'rounds_map'",) +[ERROR][2026-04-24 14:09:36,188][errors.py:131]GenerateControllerDG.create_table_context() missing 1 required positional argument: 'rounds_map': Did you fail to use functools.wraps() in a decorator? +Traceback (most recent call last): + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 217, 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 108, 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 697, in create_env_diff + subdoc = self.create_table_context(table_data, doc) +TypeError: GenerateControllerDG.create_table_context() missing 1 required positional argument: 'rounds_map': Did you fail to use functools.wraps() in a decorator? +[ERROR][2026-04-24 14:09:36,192][log.py:249]Internal Server Error: /api/generate/create/env_diff +[WARNING][2026-04-24 14:43:28,969][operation.py:136]"POST - GenerateSeitaiController[create_bgDocument] /api/create/bgDocument" (500412, '项目结束时间早于最后一轮次结束时间或等于开始时间,请修改项目结束时间') +[ERROR][2026-04-24 14:43:28,969][log.py:249]Internal Server Error: /api/create/bgDocument +[WARNING][2026-04-24 15:11:55,484][operation.py:136]"GET - GenerateControllerDG[create_env_diff] /api/generate/create/env_diff" ("'GenerateControllerDG' object has no attribute 'create_table_context'",) +[ERROR][2026-04-24 15:11:55,484][errors.py:131]'GenerateControllerDG' object has no attribute 'create_table_context' +Traceback (most recent call last): + File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 217, 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 108, 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 633, in create_env_diff + subdoc = self.create_table_context(table_data, doc) + ^^^^^^^^^^^^^^^^^^^^^^^^^ +AttributeError: 'GenerateControllerDG' object has no attribute 'create_table_context' +[ERROR][2026-04-24 15:11:55,488][log.py:249]Internal Server Error: /api/generate/create/env_diff diff --git a/media/R2601/final_seitai/测评大纲.docx b/media/R2601/final_seitai/测评大纲.docx index b245d46..98108d7 100644 Binary files a/media/R2601/final_seitai/测评大纲.docx and b/media/R2601/final_seitai/测评大纲.docx differ diff --git a/media/R2601/final_seitai/测评报告.docx b/media/R2601/final_seitai/测评报告.docx index 7a915cf..51cae8b 100644 Binary files a/media/R2601/final_seitai/测评报告.docx and b/media/R2601/final_seitai/测评报告.docx differ diff --git a/media/R2601/final_seitai/测试说明.docx b/media/R2601/final_seitai/测试说明.docx index b0997a7..bcb33e1 100644 Binary files a/media/R2601/final_seitai/测试说明.docx and b/media/R2601/final_seitai/测试说明.docx differ diff --git a/media/R2601/final_seitai/第三轮回归测试说明.docx b/media/R2601/final_seitai/第三轮回归测试说明.docx new file mode 100644 index 0000000..3a6e9d1 Binary files /dev/null and b/media/R2601/final_seitai/第三轮回归测试说明.docx differ diff --git a/media/R2601/final_seitai/第二轮回归测试说明.docx b/media/R2601/final_seitai/第二轮回归测试说明.docx index 8a17107..7ea0d77 100644 Binary files a/media/R2601/final_seitai/第二轮回归测试说明.docx and b/media/R2601/final_seitai/第二轮回归测试说明.docx differ diff --git a/media/R2601/form_template/bg/temporary/研总需归追踪_temp.docx b/media/R2601/form_template/bg/temporary/研总需归追踪_temp.docx index ca3a258..11b3307 100644 Binary files a/media/R2601/form_template/bg/temporary/研总需归追踪_temp.docx and b/media/R2601/form_template/bg/temporary/研总需归追踪_temp.docx differ diff --git a/media/R2601/form_template/hsm/temporary/第三轮用例追踪_temp.docx b/media/R2601/form_template/hsm/temporary/第三轮用例追踪_temp.docx index 2f25e93..81cae1c 100644 Binary files a/media/R2601/form_template/hsm/temporary/第三轮用例追踪_temp.docx and b/media/R2601/form_template/hsm/temporary/第三轮用例追踪_temp.docx differ diff --git a/media/R2601/form_template/hsm/temporary/第二轮用例追踪_temp.docx b/media/R2601/form_template/hsm/temporary/第二轮用例追踪_temp.docx index a5e0dff..a0c927a 100644 Binary files a/media/R2601/form_template/hsm/temporary/第二轮用例追踪_temp.docx and b/media/R2601/form_template/hsm/temporary/第二轮用例追踪_temp.docx differ diff --git a/media/R2601/form_template/sm/temporary/说明追踪_temp.docx b/media/R2601/form_template/sm/temporary/说明追踪_temp.docx index 53992f8..fd43fdf 100644 Binary files a/media/R2601/form_template/sm/temporary/说明追踪_temp.docx and b/media/R2601/form_template/sm/temporary/说明追踪_temp.docx differ diff --git a/media/R2601/output_dir/bg/总体结论.docx b/media/R2601/output_dir/bg/总体结论.docx index 6ce00dc..42368c4 100644 Binary files a/media/R2601/output_dir/bg/总体结论.docx and b/media/R2601/output_dir/bg/总体结论.docx differ diff --git a/media/R2601/output_dir/bg/技术依据文件.docx b/media/R2601/output_dir/bg/技术依据文件.docx index 7a521be..150c99b 100644 Binary files a/media/R2601/output_dir/bg/技术依据文件.docx and b/media/R2601/output_dir/bg/技术依据文件.docx differ diff --git a/media/R2601/output_dir/bg/摸底清单.docx b/media/R2601/output_dir/bg/摸底清单.docx index d1cdfb6..64aa353 100644 Binary files a/media/R2601/output_dir/bg/摸底清单.docx and b/media/R2601/output_dir/bg/摸底清单.docx differ diff --git a/media/R2601/output_dir/bg/测评完成情况.docx b/media/R2601/output_dir/bg/测评完成情况.docx index 8433378..0951b79 100644 Binary files a/media/R2601/output_dir/bg/测评完成情况.docx and b/media/R2601/output_dir/bg/测评完成情况.docx differ diff --git a/media/R2601/output_dir/bg/测评时间和地点.docx b/media/R2601/output_dir/bg/测评时间和地点.docx index 607efc8..a6c33ca 100644 Binary files a/media/R2601/output_dir/bg/测评时间和地点.docx and b/media/R2601/output_dir/bg/测评时间和地点.docx differ diff --git a/media/R2601/output_dir/bg/测试内容和结果_第一轮次.docx b/media/R2601/output_dir/bg/测试内容和结果_第一轮次.docx index 17476b2..2659096 100644 Binary files a/media/R2601/output_dir/bg/测试内容和结果_第一轮次.docx and b/media/R2601/output_dir/bg/测试内容和结果_第一轮次.docx differ diff --git a/media/R2601/output_dir/bg/测试内容和结果_第二轮次.docx b/media/R2601/output_dir/bg/测试内容和结果_第二轮次.docx index 4df2f95..bd10b83 100644 Binary files a/media/R2601/output_dir/bg/测试内容和结果_第二轮次.docx and b/media/R2601/output_dir/bg/测试内容和结果_第二轮次.docx differ diff --git a/media/R2601/output_dir/bg/测试有效性充分性说明.docx b/media/R2601/output_dir/bg/测试有效性充分性说明.docx index f81e939..45b9169 100644 Binary files a/media/R2601/output_dir/bg/测试有效性充分性说明.docx and b/media/R2601/output_dir/bg/测试有效性充分性说明.docx differ diff --git a/media/R2601/output_dir/bg/研总需归追踪.docx b/media/R2601/output_dir/bg/研总需归追踪.docx index dcf3b86..acf8d04 100644 Binary files a/media/R2601/output_dir/bg/研总需归追踪.docx and b/media/R2601/output_dir/bg/研总需归追踪.docx differ diff --git a/media/R2601/output_dir/bg/综述.docx b/media/R2601/output_dir/bg/综述.docx index cfc0511..9a9d64a 100644 Binary files a/media/R2601/output_dir/bg/综述.docx and b/media/R2601/output_dir/bg/综述.docx differ diff --git a/media/R2601/output_dir/bg/被测软件基本信息.docx b/media/R2601/output_dir/bg/被测软件基本信息.docx index 991c03c..79a1d41 100644 Binary files a/media/R2601/output_dir/bg/被测软件基本信息.docx and b/media/R2601/output_dir/bg/被测软件基本信息.docx differ diff --git a/media/R2601/output_dir/bg/软件质量评价.docx b/media/R2601/output_dir/bg/软件质量评价.docx index eccbef6..82109b3 100644 Binary files a/media/R2601/output_dir/bg/软件质量评价.docx and b/media/R2601/output_dir/bg/软件质量评价.docx differ diff --git a/media/R2601/output_dir/bg/软件问题统计.docx b/media/R2601/output_dir/bg/软件问题统计.docx index a866fca..81fb6b8 100644 Binary files a/media/R2601/output_dir/bg/软件问题统计.docx and b/media/R2601/output_dir/bg/软件问题统计.docx differ diff --git a/media/R2601/output_dir/bg/问题汇总表.docx b/media/R2601/output_dir/bg/问题汇总表.docx index 11aa177..11bc659 100644 Binary files a/media/R2601/output_dir/bg/问题汇总表.docx and b/media/R2601/output_dir/bg/问题汇总表.docx differ diff --git a/media/R2601/output_dir/bg/需求指标符合性情况.docx b/media/R2601/output_dir/bg/需求指标符合性情况.docx index c547e3a..b367cae 100644 Binary files a/media/R2601/output_dir/bg/需求指标符合性情况.docx and b/media/R2601/output_dir/bg/需求指标符合性情况.docx differ diff --git a/media/R2601/output_dir/hsm/第三轮动态硬件和固件项.docx b/media/R2601/output_dir/hsm/第三轮动态硬件和固件项.docx new file mode 100644 index 0000000..421f4e5 Binary files /dev/null and b/media/R2601/output_dir/hsm/第三轮动态硬件和固件项.docx differ diff --git a/media/R2601/output_dir/hsm/第三轮动态软件项.docx b/media/R2601/output_dir/hsm/第三轮动态软件项.docx new file mode 100644 index 0000000..ed5f1f9 Binary files /dev/null and b/media/R2601/output_dir/hsm/第三轮动态软件项.docx differ diff --git a/media/R2601/output_dir/hsm/第三轮回归测试用例概述.docx b/media/R2601/output_dir/hsm/第三轮回归测试用例概述.docx new file mode 100644 index 0000000..67a5c3a Binary files /dev/null and b/media/R2601/output_dir/hsm/第三轮回归测试用例概述.docx differ diff --git a/media/R2601/output_dir/hsm/第三轮回归测试需求.docx b/media/R2601/output_dir/hsm/第三轮回归测试需求.docx new file mode 100644 index 0000000..15c1299 Binary files /dev/null and b/media/R2601/output_dir/hsm/第三轮回归测试需求.docx differ diff --git a/media/R2601/output_dir/hsm/第三轮技术依据文件.docx b/media/R2601/output_dir/hsm/第三轮技术依据文件.docx new file mode 100644 index 0000000..c3d43c5 Binary files /dev/null and b/media/R2601/output_dir/hsm/第三轮技术依据文件.docx differ diff --git a/media/R2601/output_dir/hsm/第三轮文档概述.docx b/media/R2601/output_dir/hsm/第三轮文档概述.docx new file mode 100644 index 0000000..b9d5147 Binary files /dev/null and b/media/R2601/output_dir/hsm/第三轮文档概述.docx differ diff --git a/media/R2601/output_dir/hsm/第三轮测评数据.docx b/media/R2601/output_dir/hsm/第三轮测评数据.docx new file mode 100644 index 0000000..5557b3c Binary files /dev/null and b/media/R2601/output_dir/hsm/第三轮测评数据.docx differ diff --git a/media/R2601/output_dir/hsm/第三轮测试用例.docx b/media/R2601/output_dir/hsm/第三轮测试用例.docx new file mode 100644 index 0000000..cdc98da Binary files /dev/null and b/media/R2601/output_dir/hsm/第三轮测试用例.docx differ diff --git a/media/R2601/output_dir/hsm/第三轮用例追踪.docx b/media/R2601/output_dir/hsm/第三轮用例追踪.docx new file mode 100644 index 0000000..bea1d41 Binary files /dev/null and b/media/R2601/output_dir/hsm/第三轮用例追踪.docx differ diff --git a/media/R2601/output_dir/hsm/第三轮被测软件基本信息.docx b/media/R2601/output_dir/hsm/第三轮被测软件基本信息.docx new file mode 100644 index 0000000..c173438 Binary files /dev/null and b/media/R2601/output_dir/hsm/第三轮被测软件基本信息.docx differ diff --git a/media/R2601/output_dir/hsm/第三轮软件更改部分.docx b/media/R2601/output_dir/hsm/第三轮软件更改部分.docx new file mode 100644 index 0000000..f31220f Binary files /dev/null and b/media/R2601/output_dir/hsm/第三轮软件更改部分.docx differ diff --git a/media/R2601/output_dir/hsm/第三轮静态软件项.docx b/media/R2601/output_dir/hsm/第三轮静态软件项.docx new file mode 100644 index 0000000..c3ca584 Binary files /dev/null and b/media/R2601/output_dir/hsm/第三轮静态软件项.docx differ diff --git a/media/R2601/output_dir/hsm/第二轮动态硬件和固件项.docx b/media/R2601/output_dir/hsm/第二轮动态硬件和固件项.docx new file mode 100644 index 0000000..421f4e5 Binary files /dev/null and b/media/R2601/output_dir/hsm/第二轮动态硬件和固件项.docx differ diff --git a/media/R2601/output_dir/hsm/第二轮动态软件项.docx b/media/R2601/output_dir/hsm/第二轮动态软件项.docx new file mode 100644 index 0000000..ed5f1f9 Binary files /dev/null and b/media/R2601/output_dir/hsm/第二轮动态软件项.docx differ diff --git a/media/R2601/output_dir/hsm/第二轮回归测试用例概述.docx b/media/R2601/output_dir/hsm/第二轮回归测试用例概述.docx index 03ea522..8ecc208 100644 Binary files a/media/R2601/output_dir/hsm/第二轮回归测试用例概述.docx and b/media/R2601/output_dir/hsm/第二轮回归测试用例概述.docx differ diff --git a/media/R2601/output_dir/hsm/第二轮回归测试需求.docx b/media/R2601/output_dir/hsm/第二轮回归测试需求.docx index f755bae..22cf97f 100644 Binary files a/media/R2601/output_dir/hsm/第二轮回归测试需求.docx and b/media/R2601/output_dir/hsm/第二轮回归测试需求.docx differ diff --git a/media/R2601/output_dir/hsm/第二轮技术依据文件.docx b/media/R2601/output_dir/hsm/第二轮技术依据文件.docx index dab83d0..4ae2753 100644 Binary files a/media/R2601/output_dir/hsm/第二轮技术依据文件.docx and b/media/R2601/output_dir/hsm/第二轮技术依据文件.docx differ diff --git a/media/R2601/output_dir/hsm/第二轮文档概述.docx b/media/R2601/output_dir/hsm/第二轮文档概述.docx index 7713e37..f1f1844 100644 Binary files a/media/R2601/output_dir/hsm/第二轮文档概述.docx and b/media/R2601/output_dir/hsm/第二轮文档概述.docx differ diff --git a/media/R2601/output_dir/hsm/第二轮测评数据.docx b/media/R2601/output_dir/hsm/第二轮测评数据.docx new file mode 100644 index 0000000..5557b3c Binary files /dev/null and b/media/R2601/output_dir/hsm/第二轮测评数据.docx differ diff --git a/media/R2601/output_dir/hsm/第二轮测试用例.docx b/media/R2601/output_dir/hsm/第二轮测试用例.docx index c3d27ff..1e0f3bb 100644 Binary files a/media/R2601/output_dir/hsm/第二轮测试用例.docx and b/media/R2601/output_dir/hsm/第二轮测试用例.docx differ diff --git a/media/R2601/output_dir/hsm/第二轮用例追踪.docx b/media/R2601/output_dir/hsm/第二轮用例追踪.docx index 41e6a6b..00fc145 100644 Binary files a/media/R2601/output_dir/hsm/第二轮用例追踪.docx and b/media/R2601/output_dir/hsm/第二轮用例追踪.docx differ diff --git a/media/R2601/output_dir/hsm/第二轮被测软件基本信息.docx b/media/R2601/output_dir/hsm/第二轮被测软件基本信息.docx index 49c2862..35d6244 100644 Binary files a/media/R2601/output_dir/hsm/第二轮被测软件基本信息.docx and b/media/R2601/output_dir/hsm/第二轮被测软件基本信息.docx differ diff --git a/media/R2601/output_dir/hsm/第二轮软件更改部分.docx b/media/R2601/output_dir/hsm/第二轮软件更改部分.docx index 04d4b82..51e37a5 100644 Binary files a/media/R2601/output_dir/hsm/第二轮软件更改部分.docx and b/media/R2601/output_dir/hsm/第二轮软件更改部分.docx differ diff --git a/media/R2601/output_dir/hsm/第二轮静态软件项.docx b/media/R2601/output_dir/hsm/第二轮静态软件项.docx new file mode 100644 index 0000000..71b5de3 Binary files /dev/null and b/media/R2601/output_dir/hsm/第二轮静态软件项.docx differ diff --git a/media/R2601/output_dir/sm/技术依据文件.docx b/media/R2601/output_dir/sm/技术依据文件.docx index ee028d7..4db3f28 100644 Binary files a/media/R2601/output_dir/sm/技术依据文件.docx and b/media/R2601/output_dir/sm/技术依据文件.docx differ diff --git a/media/R2601/output_dir/sm/测试用例.docx b/media/R2601/output_dir/sm/测试用例.docx index 8e7dc98..865cd98 100644 Binary files a/media/R2601/output_dir/sm/测试用例.docx and b/media/R2601/output_dir/sm/测试用例.docx differ diff --git a/media/R2601/output_dir/sm/用例说明.docx b/media/R2601/output_dir/sm/用例说明.docx index 6536608..6fa0670 100644 Binary files a/media/R2601/output_dir/sm/用例说明.docx and b/media/R2601/output_dir/sm/用例说明.docx differ diff --git a/media/R2601/output_dir/sm/说明追踪.docx b/media/R2601/output_dir/sm/说明追踪.docx index 328401c..f1512db 100644 Binary files a/media/R2601/output_dir/sm/说明追踪.docx and b/media/R2601/output_dir/sm/说明追踪.docx differ diff --git a/media/R2601/output_dir/主要功能和性能指标.docx b/media/R2601/output_dir/主要功能和性能指标.docx index e482959..7af7094 100644 Binary files a/media/R2601/output_dir/主要功能和性能指标.docx and b/media/R2601/output_dir/主要功能和性能指标.docx differ diff --git a/media/R2601/output_dir/代码质量度量分析表.docx b/media/R2601/output_dir/代码质量度量分析表.docx index 8a082cc..fb7b8c9 100644 Binary files a/media/R2601/output_dir/代码质量度量分析表.docx and b/media/R2601/output_dir/代码质量度量分析表.docx differ diff --git a/media/R2601/output_dir/动态测试环境说明.docx b/media/R2601/output_dir/动态测试环境说明.docx index cc49744..18a10d6 100644 Binary files a/media/R2601/output_dir/动态测试环境说明.docx and b/media/R2601/output_dir/动态测试环境说明.docx differ diff --git a/media/R2601/output_dir/动态硬件和固件项.docx b/media/R2601/output_dir/动态硬件和固件项.docx index dfd027d..755ec1f 100644 Binary files a/media/R2601/output_dir/动态硬件和固件项.docx and b/media/R2601/output_dir/动态硬件和固件项.docx differ diff --git a/media/R2601/output_dir/动态软件项.docx b/media/R2601/output_dir/动态软件项.docx index 61c387e..3caafa8 100644 Binary files a/media/R2601/output_dir/动态软件项.docx and b/media/R2601/output_dir/动态软件项.docx differ diff --git a/media/R2601/output_dir/反向需求规格追踪表.docx b/media/R2601/output_dir/反向需求规格追踪表.docx index 26301eb..d0b7119 100644 Binary files a/media/R2601/output_dir/反向需求规格追踪表.docx and b/media/R2601/output_dir/反向需求规格追踪表.docx differ diff --git a/media/R2601/output_dir/技术依据文件.docx b/media/R2601/output_dir/技术依据文件.docx index 72a3baa..d355c09 100644 Binary files a/media/R2601/output_dir/技术依据文件.docx and b/media/R2601/output_dir/技术依据文件.docx differ diff --git a/media/R2601/output_dir/标准依据文件.docx b/media/R2601/output_dir/标准依据文件.docx index 710286e..5508875 100644 Binary files a/media/R2601/output_dir/标准依据文件.docx and b/media/R2601/output_dir/标准依据文件.docx differ diff --git a/media/R2601/output_dir/测评对象.docx b/media/R2601/output_dir/测评对象.docx index d7af169..9dfffb1 100644 Binary files a/media/R2601/output_dir/测评对象.docx and b/media/R2601/output_dir/测评对象.docx differ diff --git a/media/R2601/output_dir/测评数据.docx b/media/R2601/output_dir/测评数据.docx index b0db87d..2a0be35 100644 Binary files a/media/R2601/output_dir/测评数据.docx and b/media/R2601/output_dir/测评数据.docx differ diff --git a/media/R2601/output_dir/测评时间和地点.docx b/media/R2601/output_dir/测评时间和地点.docx index 48d5324..303dead 100644 Binary files a/media/R2601/output_dir/测评时间和地点.docx and b/media/R2601/output_dir/测评时间和地点.docx differ diff --git a/media/R2601/output_dir/测评条件保障.docx b/media/R2601/output_dir/测评条件保障.docx index 3337cfd..50716ec 100644 Binary files a/media/R2601/output_dir/测评条件保障.docx and b/media/R2601/output_dir/测评条件保障.docx differ diff --git a/media/R2601/output_dir/测评组织及任务分工.docx b/media/R2601/output_dir/测评组织及任务分工.docx index bb48cf4..e58fc67 100644 Binary files a/media/R2601/output_dir/测评组织及任务分工.docx and b/media/R2601/output_dir/测评组织及任务分工.docx differ diff --git a/media/R2601/output_dir/测试内容充分性及测试方法有效性分析.docx b/media/R2601/output_dir/测试内容充分性及测试方法有效性分析.docx index ee22751..8b2f906 100644 Binary files a/media/R2601/output_dir/测试内容充分性及测试方法有效性分析.docx and b/media/R2601/output_dir/测试内容充分性及测试方法有效性分析.docx differ diff --git a/media/R2601/output_dir/测试策略.docx b/media/R2601/output_dir/测试策略.docx index 0ec8512..f918b03 100644 Binary files a/media/R2601/output_dir/测试策略.docx and b/media/R2601/output_dir/测试策略.docx differ diff --git a/media/R2601/output_dir/测试级别和测试类型.docx b/media/R2601/output_dir/测试级别和测试类型.docx index ce1a769..ff6d869 100644 Binary files a/media/R2601/output_dir/测试级别和测试类型.docx and b/media/R2601/output_dir/测试级别和测试类型.docx differ diff --git a/media/R2601/output_dir/测试项及方法.docx b/media/R2601/output_dir/测试项及方法.docx index d35959e..c83a0d6 100644 Binary files a/media/R2601/output_dir/测试项及方法.docx and b/media/R2601/output_dir/测试项及方法.docx differ diff --git a/media/R2601/output_dir/环境差异性分析.docx b/media/R2601/output_dir/环境差异性分析.docx index c5af310..d8ebdf3 100644 Binary files a/media/R2601/output_dir/环境差异性分析.docx and b/media/R2601/output_dir/环境差异性分析.docx differ diff --git a/media/R2601/output_dir/研制总要求追踪表.docx b/media/R2601/output_dir/研制总要求追踪表.docx index 93ae895..fa36a6c 100644 Binary files a/media/R2601/output_dir/研制总要求追踪表.docx and b/media/R2601/output_dir/研制总要求追踪表.docx differ diff --git a/media/R2601/output_dir/缩略语.docx b/media/R2601/output_dir/缩略语.docx index cc98ecc..e2d28f3 100644 Binary files a/media/R2601/output_dir/缩略语.docx and b/media/R2601/output_dir/缩略语.docx differ diff --git a/media/R2601/output_dir/联系人和方式.docx b/media/R2601/output_dir/联系人和方式.docx index e629fb8..5dc149c 100644 Binary files a/media/R2601/output_dir/联系人和方式.docx and b/media/R2601/output_dir/联系人和方式.docx differ diff --git a/media/R2601/output_dir/被测软件基本信息.docx b/media/R2601/output_dir/被测软件基本信息.docx index 841592f..fb5cb62 100644 Binary files a/media/R2601/output_dir/被测软件基本信息.docx and b/media/R2601/output_dir/被测软件基本信息.docx differ diff --git a/media/R2601/output_dir/被测软件接口.docx b/media/R2601/output_dir/被测软件接口.docx index fa071fb..f0bedb9 100644 Binary files a/media/R2601/output_dir/被测软件接口.docx and b/media/R2601/output_dir/被测软件接口.docx differ diff --git a/media/R2601/output_dir/需求规格说明追踪表.docx b/media/R2601/output_dir/需求规格说明追踪表.docx index eb61a9d..5e07eb7 100644 Binary files a/media/R2601/output_dir/需求规格说明追踪表.docx and b/media/R2601/output_dir/需求规格说明追踪表.docx differ diff --git a/media/R2601/output_dir/静态测试环境说明.docx b/media/R2601/output_dir/静态测试环境说明.docx index 5ab5593..a4ebb71 100644 Binary files a/media/R2601/output_dir/静态测试环境说明.docx and b/media/R2601/output_dir/静态测试环境说明.docx differ diff --git a/media/R2601/output_dir/静态硬件和固件项.docx b/media/R2601/output_dir/静态硬件和固件项.docx index 3f494bc..2f42515 100644 Binary files a/media/R2601/output_dir/静态硬件和固件项.docx and b/media/R2601/output_dir/静态硬件和固件项.docx differ diff --git a/media/R2601/output_dir/静态软件项.docx b/media/R2601/output_dir/静态软件项.docx index 0de87d3..af54bc7 100644 Binary files a/media/R2601/output_dir/静态软件项.docx and b/media/R2601/output_dir/静态软件项.docx differ diff --git a/media/R2601/output_dir/顶层技术文件.docx b/media/R2601/output_dir/顶层技术文件.docx index ad3c900..f893b94 100644 Binary files a/media/R2601/output_dir/顶层技术文件.docx and b/media/R2601/output_dir/顶层技术文件.docx differ diff --git a/media/R2601/temp/测评大纲.docx b/media/R2601/temp/测评大纲.docx index 3ae6844..00241e4 100644 Binary files a/media/R2601/temp/测评大纲.docx and b/media/R2601/temp/测评大纲.docx differ diff --git a/media/R2601/temp/测评报告.docx b/media/R2601/temp/测评报告.docx index e33e95c..4f37640 100644 Binary files a/media/R2601/temp/测评报告.docx and b/media/R2601/temp/测评报告.docx differ diff --git a/media/R2601/temp/测试说明.docx b/media/R2601/temp/测试说明.docx index a66aff9..d3e480c 100644 Binary files a/media/R2601/temp/测试说明.docx and b/media/R2601/temp/测试说明.docx differ diff --git a/media/R2601/temp/第三轮回归测试说明.docx b/media/R2601/temp/第三轮回归测试说明.docx new file mode 100644 index 0000000..6f8fdbb Binary files /dev/null and b/media/R2601/temp/第三轮回归测试说明.docx differ diff --git a/media/R2601/temp/第二轮回归测试说明.docx b/media/R2601/temp/第二轮回归测试说明.docx index f3fe3fa..a835aa1 100644 Binary files a/media/R2601/temp/第二轮回归测试说明.docx and b/media/R2601/temp/第二轮回归测试说明.docx differ diff --git a/pyproject.toml b/pyproject.toml index 551410e..b7244ca 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,13 +19,13 @@ dependencies = [ "docxtpl[subdoc]>=0.20.2", "faker>=40.13.0", "ipykernel>=7.2.0", - "lizard>=1.21.6", + "lizard>=1.22.1", "mysqlclient>=2.2.7", "ninja-schema>=0.14.3", "numpy==2.4.4", "orjson>=3.11.8", "pandas>=3.0.2", - "pyinstaller>=6.19.0", + "pyinstaller>=6.20.0", "python-docx>=1.2.0", "python-ldap", "setuptools<=82.0.1", diff --git a/utils/__pycache__/chen_ninja.cpython-313.pyc b/utils/__pycache__/chen_ninja.cpython-313.pyc index f47f4b2..8cad6e7 100644 Binary files a/utils/__pycache__/chen_ninja.cpython-313.pyc and b/utils/__pycache__/chen_ninja.cpython-313.pyc differ diff --git a/utils/__pycache__/codes.cpython-313.pyc b/utils/__pycache__/codes.cpython-313.pyc index ea8bc24..41e6beb 100644 Binary files a/utils/__pycache__/codes.cpython-313.pyc and b/utils/__pycache__/codes.cpython-313.pyc differ diff --git a/utils/codes.py b/utils/codes.py index e92abbb..ca0c43a 100644 --- a/utils/codes.py +++ b/utils/codes.py @@ -1,7 +1,12 @@ -# 确定响应codes的枚举类型 -# 1.账号账户和密码错误的code -> status:部分401 -HTTP_USER_PASSWORD_ERROR_CODE: int = 40001 -# 2.传给后端的数据越界 -HTTP_INDEX_ERROR: int = 40038 -# 3.当右键测试项时,如果测试项下面已经有用例了 -HTTP_EXISTS_CASES:int = 40031 +# ~~~~确定响应codes的枚举类型~~~~ +# 1.账号账户和密码错误的code -> status:部分401 +HTTP_USER_PASSWORD_ERROR_CODE: int = 40001 +# 2.传给后端的数据越界 +HTTP_INDEX_ERROR: int = 40038 +# 3.当右键测试项时,如果测试项下面已经有用例了 +HTTP_EXISTS_CASES:int = 40031 + + +# ~~~~下面是HttpError的status_code对应的错误信息~~~~ +# 1.项目看板-项目结束时间早于最后一个轮次结束时间 +PROJECT_ENDTIME_ERROR_CODE: int = 500412 diff --git a/uv.lock b/uv.lock index 02215f9..2b26187 100644 --- a/uv.lock +++ b/uv.lock @@ -126,7 +126,7 @@ requires-dist = [ { name = "docxtpl", extras = ["subdoc"], specifier = ">=0.20.2" }, { name = "faker", specifier = ">=40.13.0" }, { name = "ipykernel", specifier = ">=7.2.0" }, - { name = "lizard", specifier = ">=1.21.6" }, + { name = "lizard", specifier = ">=1.22.1" }, { name = "lxml", specifier = ">=6.1.0" }, { name = "mysqlclient", specifier = ">=2.2.7" }, { name = "ninja-schema", specifier = ">=0.14.3" }, @@ -134,7 +134,7 @@ requires-dist = [ { name = "orjson", specifier = ">=3.11.8" }, { name = "pandas", specifier = ">=3.0.2" }, { name = "pydantic", specifier = ">=2.13.3" }, - { name = "pyinstaller", specifier = ">=6.19.0" }, + { name = "pyinstaller", specifier = ">=6.20.0" }, { name = "python-docx", specifier = ">=1.2.0" }, { name = "python-ldap", path = "python_ldap-3.4.5-cp313-cp313-win_amd64.whl" }, { name = "setuptools", specifier = "<=82.0.1" }, @@ -448,11 +448,11 @@ wheels = [ [[package]] name = "idna" -version = "3.12" +version = "3.13" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/22/12/2948fbe5513d062169bd91f7d7b1cd97bc8894f32946b71fa39f6e63ca0c/idna-3.12.tar.gz", hash = "sha256:724e9952cc9e2bd7550ea784adb098d837ab5267ef67a1ab9cf7846bdbdd8254" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/ce/cc/762dfb036166873f0059f3b7de4565e1b5bc3d6f28a414c13da27e442f99/idna-3.13.tar.gz", hash = "sha256:585ea8fe5d69b9181ec1afba340451fba6ba764af97026f92a91d4eef164a242" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/53/b2/acc33950394b3becb2b664741a0c0889c7ef9f9ffbfa8d47eddb53a50abd/idna-3.12-py3-none-any.whl", hash = "sha256:60ffaa1858fac94c9c124728c24fcde8160f3fb4a7f79aa8cdd33a9d1af60a67" }, + { url = "https://mirrors.aliyun.com/pypi/packages/5d/13/ad7d7ca3808a898b4612b6fe93cde56b53f3034dcde235acb1f0e1df24c6/idna-3.13-py3-none-any.whl", hash = "sha256:892ea0cde124a99ce773decba204c5552b69c3c67ffd5f232eb7696135bc8bb3" }, ] [[package]] @@ -576,15 +576,15 @@ wheels = [ [[package]] name = "lizard" -version = "1.21.6" +version = "1.22.1" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "pathspec" }, { name = "pygments" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/6d/e6/c9ffd177f15905835e076570d6aebc7b8944b2f15f810aef7e93dede8b76/lizard-1.21.6.tar.gz", hash = "sha256:2b05a65754faefc91bda8db03ca75fada5efd827235244c74bf90274270eed65" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/b3/c7/776f75710b0033d69249b45ed571f8a314c1a8980c1d3c64e3c12f541869/lizard-1.22.1.tar.gz", hash = "sha256:29fe26f3746f8539227ba909a6143c749548690271e13a3f73204b22e2e62590" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/7c/80/778b6274e0e45bcae98ad6d63a000a1e74edd6a82f57815300bd084dd606/lizard-1.21.6-py2.py3-none-any.whl", hash = "sha256:15de71e63a9a6fcd0c2228eacac42067c4803604d5fae1d72417e3bff7c720eb" }, + { url = "https://mirrors.aliyun.com/pypi/packages/45/aa/54d9292917f0f9cc684fd053f879e3e8292bf4bc40e984d542dbfe393063/lizard-1.22.1-py2.py3-none-any.whl", hash = "sha256:cc629472d4b031f7692bd7f7e78d2574029008148fba75e45f3592774c8e7420" }, ] [[package]] @@ -798,11 +798,11 @@ wheels = [ [[package]] name = "pathspec" -version = "1.0.4" +version = "1.1.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/fa/36/e27608899f9b8d4dff0617b2d9ab17ca5608956ca44461ac14ac48b44015/pathspec-1.0.4.tar.gz", hash = "sha256:0210e2ae8a21a9137c0d470578cb0e595af87edaa6ebf12ff176f14a02e0e645" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/2e/17/9c3094b822982b9f1ea666d8580ce59000f61f87c1663556fb72031ad9ec/pathspec-1.1.0.tar.gz", hash = "sha256:f5d7c555da02fd8dde3e4a2354b6aba817a89112fa8f333f7917a2a4834dd080" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl", hash = "sha256:fb6ae2fd4e7c921a165808a552060e722767cfa526f99ca5156ed2ce45a5c723" }, + { url = "https://mirrors.aliyun.com/pypi/packages/fa/c9/8eed0486f074e9f1ca7f8ce5ad663e65f12fdab344028d658fa1b03d35e0/pathspec-1.1.0-py3-none-any.whl", hash = "sha256:574b128f7456bd899045ccd142dd446af7e6cfd0072d63ad73fbc55fbb4aaa42" }, ] [[package]] @@ -988,7 +988,7 @@ wheels = [ [[package]] name = "pyinstaller" -version = "6.19.0" +version = "6.20.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "altgraph" }, @@ -999,19 +999,19 @@ dependencies = [ { name = "pywin32-ctypes", marker = "sys_platform == 'win32'" }, { name = "setuptools" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/c8/63/fd62472b6371d89dc138d40c36d87a50dc2de18a035803bbdc376b4ffac4/pyinstaller-6.19.0.tar.gz", hash = "sha256:ec73aeb8bd9b7f2f1240d328a4542e90b3c6e6fbc106014778431c616592a865" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/46/60/d03d52e6690d4e9caf333dcd14550cde634ce6c118b3bc8fa3112c3186fd/pyinstaller-6.20.0.tar.gz", hash = "sha256:95c5c7e03d5d61e9dfb8ef259c699cf492bb1041beb6dbe83696608cec07347a" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/e3/eb/23374721fecfa72677e79800921cb6aceefa6ba48574dc404f3f6c6c3be7/pyinstaller-6.19.0-py3-none-macosx_10_13_universal2.whl", hash = "sha256:4190e76b74f0c4b5c5f11ac360928cd2e36ec8e3194d437bf6b8648c7bc0c134" }, - { url = "https://mirrors.aliyun.com/pypi/packages/cd/7e/dfd724b0b533f5aaec0ee5df406fe2319987ed6964480a706f85478b12ea/pyinstaller-6.19.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:8bd68abd812d8a6ba33b9f1810e91fee0f325969733721b78151f0065319ca11" }, - { url = "https://mirrors.aliyun.com/pypi/packages/88/c9/ee3a4101c31f26344e66896c73c1fd6ed8282bf871473365b7f8674af406/pyinstaller-6.19.0-py3-none-manylinux2014_i686.whl", hash = "sha256:1ec54ef967996ca61dacba676227e2b23219878ccce5ee9d6f3aada7b8ed8abf" }, - { url = "https://mirrors.aliyun.com/pypi/packages/da/0a/fc77e9f861be8cf300ac37155f59cc92aff99b29f2ddd78546f563a5b5a6/pyinstaller-6.19.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:4ab2bb52e58448e14ddf9450601bdedd66800465043501c1d8f1cab87b60b122" }, - { url = "https://mirrors.aliyun.com/pypi/packages/6d/e3/6872e020ee758afe0b821663858492c10745608b07150e5e2c824a5b3e1c/pyinstaller-6.19.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:da6d5c6391ccefe73554b9fa29b86001c8e378e0f20c2a4004f836ba537eff63" }, - { url = "https://mirrors.aliyun.com/pypi/packages/53/60/b8db5f1a4b0fb228175f2ea0aa33f949adcc097fbe981cc524f9faf85777/pyinstaller-6.19.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:a0fc5f6b3c55aa54353f0c74ffa59b1115433c1850c6f655d62b461a2ed6cbbe" }, - { url = "https://mirrors.aliyun.com/pypi/packages/6f/4d/63b0600f2694e9141b83129fbc1c488ec84d5a0770b1448ec154dcd0fee9/pyinstaller-6.19.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:e649ba6bd1b0b89b210ad92adb5fbdc8a42dd2c5ca4f72ef3a0bfec83a424b83" }, - { url = "https://mirrors.aliyun.com/pypi/packages/01/d4/e812ad36178093a0e9fd4b8127577748dd85b0cb71de912229dca21fd741/pyinstaller-6.19.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:481a909c8e60c8692fc60fcb1344d984b44b943f8bc9682f2fcdae305ad297e6" }, - { url = "https://mirrors.aliyun.com/pypi/packages/52/03/b2c2ee41fb8e10fd2a45d21f5ec2ef25852cfb978dbf762972eed59e3d63/pyinstaller-6.19.0-py3-none-win32.whl", hash = "sha256:3c5c251054fe4cfaa04c34a363dcfbf811545438cb7198304cd444756bc2edd2" }, - { url = "https://mirrors.aliyun.com/pypi/packages/9c/d3/6d5e62b8270e2b53a6065e281b3a7785079b00e9019c8019952828dd1669/pyinstaller-6.19.0-py3-none-win_amd64.whl", hash = "sha256:b5bb6536c6560330d364d91522250f254b107cf69129d9cbcd0e6727c570be33" }, - { url = "https://mirrors.aliyun.com/pypi/packages/81/65/458cd523308a101a22fd2742893405030cc24994cc74b1b767cecf137160/pyinstaller-6.19.0-py3-none-win_arm64.whl", hash = "sha256:c2d5a539b0bfe6159d5522c8c70e1c0e487f22c2badae0f97d45246223b798ea" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d0/e4/e228d6d1bbb7fd62dc660a8fb202a583b023d3a3624ca95d1a9290ee4d6a/pyinstaller-6.20.0-py3-none-macosx_10_13_universal2.whl", hash = "sha256:bf3be4e1284ee78ddccba5e29f99443a12a7b4673168288ffc4c9d38c6f7b90e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ce/bd/afb631bcb3f9040efebd4f6d067f0828b51710818f69fb41a2d4b7787f52/pyinstaller-6.20.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:72ae9c1fdea134afa791f58bdc9a1934d5c7609753c111e0026bfc272b32b712" }, + { url = "https://mirrors.aliyun.com/pypi/packages/76/08/0729a5bac14754150e5d83b39d87d842eb42b0bffcaa03dbad6252e23a39/pyinstaller-6.20.0-py3-none-manylinux2014_i686.whl", hash = "sha256:1031bcc307f3fbeffd4e162723e64d46dbf591c82dd0997413afb2a07328b941" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e6/82/bc0ee4c7b97db1958eb651e0da9fb1e672e5ae53ca8867fd97701de52906/pyinstaller-6.20.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:8df3b3f347659fa2562d8d193a98ad4600133b8b8d07c268df89e4154376750e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/3d/e7/770002d6aaa54173881cb2c49bb195ba67b97bf39bac1cdf320f28401629/pyinstaller-6.20.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:b0d3cc9dd8120d448459bd3880a12e2f9774c51443af49047801446377999a59" }, + { url = "https://mirrors.aliyun.com/pypi/packages/fe/db/68ba1fccb71278b2124fb90b37b7c8c0bc4c1173fba45b94466df3d9cb7f/pyinstaller-6.20.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:03696bb6350177c6bc23bcaf78e71a33c4a89b6754dd90d1be2f318e978c918b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/03/0f/ac77ffa996a56be3d5c8f85734a007f8347240691657f9704e7de2527fa3/pyinstaller-6.20.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:6357f1699f6af84f37e7367f031d4f68abdba65543b83990c9e8f5a4cebed0b7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e0/56/1ee91c3a2bc10ca1f36da10a6fd55ff7efc4dec367171eb25992a827874f/pyinstaller-6.20.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:0ab39c690abad26ba148e8f664f0478acc82a733997f4f22e757774832802da9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d7/55/ae264339996953c4cdf9d89d916a0a8fa26a83cf917a742fff8b9d5f3fe8/pyinstaller-6.20.0-py3-none-win32.whl", hash = "sha256:9a7637e8e44b4387b13667fdcaac86ab6b29c446c16d34d8401539b81838759c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/76/8c/300f57578882cce259bfb5ae56fda3b69caa3fe9df40a176c719920ea6e2/pyinstaller-6.20.0-py3-none-win_amd64.whl", hash = "sha256:d588844e890ee80c4365867f98146636e1849bbca8e4284bbf0c809aff0f161a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8a/ea/b2f8e1642aecda78c0b75c7321f708e49e10bb3c00dd4f148c40761a1527/pyinstaller-6.20.0-py3-none-win_arm64.whl", hash = "sha256:bd53282c0a73e5c95573e1ddc8e5d564d4932bec91efbaed4dc5fdff9c2ae7f2" }, ] [[package]]