修复:测试记录序号、测评报告统计、富文本渲染word字符问题
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -19,7 +19,7 @@ from utils.util import get_str_dict, get_list_dict, create_problem_grade_str, cr
|
||||
create_demand_summary, create_problem_type_str, create_problem_table, create_problem_type_table, \
|
||||
get_str_abbr
|
||||
# 根据轮次生成测评内容文档context
|
||||
from apps.createDocument.extensions.content_result_tool import create_round_context
|
||||
from apps.createDocument.extensions.content_result_tool import create_round_context, create_influence_context
|
||||
from apps.createDocument.extensions.zhui import create_bg_round1_zhui
|
||||
from apps.createDocument.extensions.solve_problem import create_one_problem_dit
|
||||
from utils.path_utils import project_path
|
||||
@@ -354,9 +354,11 @@ class GenerateControllerBG(ControllerBase):
|
||||
# 每个轮次都需要生成一个测试内容和标题
|
||||
project_path_str = project_path(id)
|
||||
for round_str in round_str_list:
|
||||
context = create_round_context(project_obj, round_str)
|
||||
context, round_obj = create_round_context(project_obj, round_str)
|
||||
template_path = Path.cwd() / 'media' / project_path_str / 'form_template' / 'bg' / '测试内容和结果_第二轮次.docx'
|
||||
doc = DocxTemplate(template_path)
|
||||
# ~~~额外添加:除第一轮次的影响域分析~~~
|
||||
context['influence'] = create_influence_context(doc, round_obj, project_obj)
|
||||
doc.render(context, autoescape=True)
|
||||
try:
|
||||
doc.save(
|
||||
@@ -442,7 +444,7 @@ class GenerateControllerBG(ControllerBase):
|
||||
design_dict['demands'] = '\a'.join(demand_list)
|
||||
# 通过还是未通过
|
||||
design_dict['pass'] = '通过'
|
||||
design_dict['index'] = design_index
|
||||
design_dict['index'] = design_index # noqa
|
||||
data_list.append(design_dict)
|
||||
design_index += 1
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ from ninja.errors import HttpError
|
||||
from ninja_extra import ControllerBase, api_controller, route
|
||||
from django.db import transaction
|
||||
from django.db.models import Q
|
||||
from docxtpl import DocxTemplate, InlineImage, Subdoc
|
||||
from docxtpl import DocxTemplate, InlineImage
|
||||
from pathlib import Path
|
||||
from utils.chen_response import ChenResponse
|
||||
# 导入数据库ORM
|
||||
@@ -82,12 +82,12 @@ class GenerateControllerDG(ControllerBase, FragementToolsMixin):
|
||||
for tm_item in single_qs.testMethod:
|
||||
if tm_item == dict_item_qs.key:
|
||||
testmethod_str += dict_item_qs.title + " "
|
||||
# 富文本解析
|
||||
# ***Inspect-start:检查设计需求的描述是否为空***
|
||||
if single_qs.design.description == '':
|
||||
design_info = single_qs.design.ident + '-' + single_qs.design.name
|
||||
self.logger.write_warning_log('测试项', f'设计需求中的描述为空,请检查 -> {design_info}')
|
||||
# ***Inspect-end***
|
||||
# 富文本解析
|
||||
html_parser = RichParser(single_qs.design.description)
|
||||
desc_list = html_parser.get_final_list(doc)
|
||||
# 查询关联design以及普通design
|
||||
@@ -110,7 +110,8 @@ class GenerateControllerDG(ControllerBase, FragementToolsMixin):
|
||||
"test_demand_content": content_list,
|
||||
"testMethod": testmethod_str.strip(),
|
||||
"adequacy": single_qs.adequacy.replace("\n", "\a"),
|
||||
"testDesciption": single_qs.testDesciption.replace("\n", "\a"), # 测试项描述
|
||||
# 测试项描述FPGA或'静态分析'、'文档审查'、'代码审查'
|
||||
"testDesciption": single_qs.testDesciption.replace("\n", "\a"),
|
||||
"testType": get_testType(single_qs.testType, 'testType'),
|
||||
}
|
||||
list_list[type_index].append(testdemand_dict)
|
||||
@@ -470,11 +471,11 @@ class GenerateControllerDG(ControllerBase, FragementToolsMixin):
|
||||
|
||||
# 通用生成静态软件项、静态硬件项、动态软件项、动态硬件信息的context,包含fontnote和table
|
||||
@classmethod
|
||||
def create_table_context(cls, table_data: list[list[str]], doc: DocxTemplate) -> Subdoc:
|
||||
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 # 多渲染序号列
|
||||
cols = len(table_data[0]) + 1 # 多渲染一个序号列
|
||||
table = subdoc.add_table(rows=rows, cols=cols)
|
||||
# 单元格处理
|
||||
for row in range(rows):
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from pathlib import Path
|
||||
from copy import deepcopy
|
||||
from typing import Union, TypedDict, Optional
|
||||
from typing import Union
|
||||
from ninja_extra import api_controller, ControllerBase, route
|
||||
from django.db import transaction
|
||||
from django.shortcuts import get_object_or_404
|
||||
@@ -20,6 +20,7 @@ from apps.createDocument.extensions.util import delete_dir_files
|
||||
from apps.createDocument.extensions.parse_rich_text import RichParser
|
||||
from apps.createDocument.extensions.documentTime import DocTime
|
||||
from utils.util import get_str_abbr
|
||||
from apps.createDocument.extensions.content_result_tool import create_influence_context
|
||||
# 导入生成日志记录模块
|
||||
from apps.createSeiTaiDocument.extensions.logger import GenerateLogger
|
||||
# 导入排序
|
||||
@@ -236,35 +237,9 @@ class GenerateControllerHSM(ControllerBase):
|
||||
message=f'您第{chinese_round_name[int(hround.key)]}轮次中缺少源代码版本信息,请添加')
|
||||
last_dm_version = last_round_so_dut.version
|
||||
now_dm_version = so_dut.version
|
||||
# 这里插入影响域分析部分
|
||||
## 先查找是否有影响域分析填写
|
||||
area_qs = InfluenceArea.objects.filter(round=hround)
|
||||
## 如果存在则查询items
|
||||
item_render_list = []
|
||||
if area_qs.exists():
|
||||
area_obj = area_qs.first()
|
||||
items_qs = area_obj.influence_items.all()
|
||||
if items_qs.exists():
|
||||
index = 1
|
||||
for item in items_qs:
|
||||
# 1.处理关联case - 找第一轮cases
|
||||
case_str_list = []
|
||||
for case in project_obj.pcField.filter(key__in=item.effect_cases):
|
||||
case_ident_index = str(int(case.key.split("-")[-1]) + 1).zfill(3)
|
||||
case_str_list.append("_".join(["YL", get_str_abbr(case.test.testType, "testType"), case.ident, case_ident_index]))
|
||||
# 2.处理富文本框
|
||||
parser = RichParser(item.change_des)
|
||||
item_dict = {
|
||||
"change_type": item.change_type,
|
||||
"change_influ": item.change_influ,
|
||||
"case_str_list": case_str_list,
|
||||
"change_des": parser.get_final_list(doc, img_size=40, height=30), # 富文本未处理
|
||||
"index": str(index),
|
||||
}
|
||||
index = index + 1
|
||||
item_render_list.append(item_dict)
|
||||
# 将影响域分析加入context
|
||||
context_round['influence'] = item_render_list # noqa
|
||||
# 这里插入影响域分析部分,并加入context
|
||||
context_round['influence'] = create_influence_context(doc, hround, project_obj) # noqa
|
||||
context_round['influence'] = None
|
||||
# 如果存在这个轮次的需求文档,则查询上个版本
|
||||
last_xq_version = ""
|
||||
if xq_dut:
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,7 +1,9 @@
|
||||
from apps.project.models import Project
|
||||
from apps.project.models import Project, Round, InfluenceArea
|
||||
from docxtpl import DocxTemplate
|
||||
from utils.util import *
|
||||
from utils.chen_response import ChenResponse
|
||||
from django.db.models import Q
|
||||
from apps.createDocument.extensions.parse_rich_text import RichParser
|
||||
|
||||
def create_round_context(project_obj: Project, round_id: str):
|
||||
"""根据轮次,生成测评报告中的测评结果"""
|
||||
@@ -77,4 +79,37 @@ def create_round_context(project_obj: Project, round_id: str):
|
||||
'r2_dynamic_str': r2_dynamic_str,
|
||||
'round_id': round_chinese[round_id],
|
||||
}
|
||||
return context
|
||||
return context, round_obj
|
||||
|
||||
# ~~~影响域分析:内容返回influence的render_list~~~
|
||||
def create_influence_context(doc: DocxTemplate, round_obj: Round, project_obj: Project) -> None | list:
|
||||
area_qs = InfluenceArea.objects.filter(round=round_obj)
|
||||
item_render_list = []
|
||||
## 如果存在则查询items
|
||||
if area_qs.exists():
|
||||
area_obj = area_qs.first()
|
||||
items_qs = area_obj.influence_items.all()
|
||||
if items_qs.exists():
|
||||
index = 1
|
||||
for item in items_qs:
|
||||
# 1.处理关联case - 找第一轮cases
|
||||
case_str_list = []
|
||||
for case in project_obj.pcField.filter(key__in=item.effect_cases):
|
||||
case_ident_index = str(int(case.key.split("-")[-1]) + 1).zfill(3)
|
||||
case_str_list.append("_".join(["YL", get_str_abbr(case.test.testType, "testType"), case.ident, case_ident_index]))
|
||||
# 2.处理富文本框
|
||||
parser = RichParser(item.change_des)
|
||||
item_dict = {
|
||||
"change_type": item.change_type,
|
||||
"change_influ": item.change_influ,
|
||||
"case_str_list": case_str_list,
|
||||
"change_des": parser.get_final_list(doc, img_size=40, height=30), # 富文本未处理
|
||||
"index": str(index),
|
||||
}
|
||||
index = index + 1
|
||||
item_render_list.append(item_dict)
|
||||
|
||||
if len(item_render_list) > 0:
|
||||
return item_render_list
|
||||
else:
|
||||
return None
|
||||
|
||||
@@ -22,6 +22,8 @@ class RichParser:
|
||||
# 最终的解析后的列表
|
||||
self.data_list = []
|
||||
self.line_parse()
|
||||
# 匹配“表1-3”或“表1”等字符的正则
|
||||
self.biao_pattern = re.compile(r"表\d+(?:-\d+)?")
|
||||
|
||||
# 1.函数:将self.bs.contents去掉\n,获取每行数据
|
||||
def remove_n_in_contents(self):
|
||||
@@ -127,6 +129,13 @@ class RichParser:
|
||||
for oneline in self.data_list:
|
||||
if isinstance(oneline, list) or oneline.startswith("data:image/png;base64"):
|
||||
continue
|
||||
else:
|
||||
final_list.append(oneline)
|
||||
cleaned_line = oneline
|
||||
cleaned_line = re.sub(r'\s+', '', cleaned_line)
|
||||
cleaned_line = cleaned_line.replace(')', ')')
|
||||
cleaned_line = cleaned_line.strip()
|
||||
# 去掉以“表3”的行
|
||||
if self.biao_pattern.search(cleaned_line):
|
||||
continue
|
||||
if cleaned_line:
|
||||
final_list.append(cleaned_line)
|
||||
return final_list
|
||||
|
||||
@@ -95,3 +95,4 @@ def delete_dir_files(path: Path) -> Any:
|
||||
for file in path.iterdir():
|
||||
if file.is_file():
|
||||
file.unlink()
|
||||
|
||||
|
||||
Binary file not shown.
@@ -182,6 +182,8 @@ def auto_create_wd(user_name: str, dut_qs: Dut, project_obj: Project):
|
||||
}
|
||||
new_wd_design_obj: Design = Design.objects.create(**wd_design_create_dict)
|
||||
# 1.1.1.自动创建demand文档审查
|
||||
is_JD = (project_obj.report_type == '9')
|
||||
test_des = "本次三方文档审查内容包括软件需求规格说明、软件设计说明等"
|
||||
wd_demand_create_dict = {
|
||||
'ident': 'WDSC',
|
||||
'name': '文档审查',
|
||||
@@ -206,7 +208,7 @@ def auto_create_wd(user_name: str, dut_qs: Dut, project_obj: Project):
|
||||
'13)软件研制总结报告\a'
|
||||
'14)软件版本说明\a'
|
||||
'15)软件产品规格说明\a'
|
||||
'16)固件保障手册',
|
||||
'16)固件保障手册' if is_JD else test_des,
|
||||
'key': ''.join([new_wd_design_obj.key, '-', '0']),
|
||||
'level': '3',
|
||||
'project': project_obj,
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
1151
logs/root_log
1151
logs/root_log
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -16,7 +16,7 @@ dependencies = [
|
||||
"django-shortuuidfield>=0.1.3",
|
||||
"django-tinymce>=5.0.0",
|
||||
"docxcompose",
|
||||
"docxtpl>=0.20.2",
|
||||
"docxtpl[subdoc]>=0.20.2",
|
||||
"faker>=40.4.0",
|
||||
"ipykernel>=7.2.0",
|
||||
"lizard>=1.21.0",
|
||||
@@ -27,6 +27,7 @@ dependencies = [
|
||||
"pandas>=3.0.0",
|
||||
"python-docx>=1.2.0",
|
||||
"python-ldap",
|
||||
"setuptools<=81.0.0",
|
||||
"ua-parser-builtins>=202601",
|
||||
"user-agents>=2.2.0",
|
||||
"waitress>=3.0.2",
|
||||
|
||||
23
uv.lock
generated
23
uv.lock
generated
@@ -81,7 +81,7 @@ dependencies = [
|
||||
{ name = "django-shortuuidfield" },
|
||||
{ name = "django-tinymce" },
|
||||
{ name = "docxcompose" },
|
||||
{ name = "docxtpl" },
|
||||
{ name = "docxtpl", extra = ["subdoc"] },
|
||||
{ name = "faker" },
|
||||
{ name = "ipykernel" },
|
||||
{ name = "lizard" },
|
||||
@@ -92,6 +92,7 @@ dependencies = [
|
||||
{ name = "pandas" },
|
||||
{ name = "python-docx" },
|
||||
{ name = "python-ldap" },
|
||||
{ name = "setuptools" },
|
||||
{ name = "ua-parser-builtins" },
|
||||
{ name = "user-agents" },
|
||||
{ name = "waitress" },
|
||||
@@ -110,7 +111,7 @@ requires-dist = [
|
||||
{ name = "django-shortuuidfield", specifier = ">=0.1.3" },
|
||||
{ name = "django-tinymce", specifier = ">=5.0.0" },
|
||||
{ name = "docxcompose" },
|
||||
{ name = "docxtpl", specifier = ">=0.20.2" },
|
||||
{ name = "docxtpl", extras = ["subdoc"], specifier = ">=0.20.2" },
|
||||
{ name = "faker", specifier = ">=40.4.0" },
|
||||
{ name = "ipykernel", specifier = ">=7.2.0" },
|
||||
{ name = "lizard", specifier = ">=1.21.0" },
|
||||
@@ -121,6 +122,7 @@ requires-dist = [
|
||||
{ name = "pandas", specifier = ">=3.0.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 = "<=81.0.0" },
|
||||
{ name = "ua-parser-builtins", specifier = ">=202601" },
|
||||
{ name = "user-agents", specifier = ">=2.2.0" },
|
||||
{ name = "waitress", specifier = ">=3.0.2" },
|
||||
@@ -389,6 +391,11 @@ wheels = [
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/a4/ad/e07939d8e020e513d3860400413ba1e0e06102c469639b440d921337efef/docxtpl-0.20.2-py3-none-any.whl", hash = "sha256:626d5c570a46a62b2ca73b4d08f1c240fa031a5bc45371e1466a4fe184923d10" },
|
||||
]
|
||||
|
||||
[package.optional-dependencies]
|
||||
subdoc = [
|
||||
{ name = "docxcompose" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "email-validator"
|
||||
version = "2.3.0"
|
||||
@@ -1051,11 +1058,11 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "setuptools"
|
||||
version = "80.10.2"
|
||||
version = "81.0.0"
|
||||
source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
|
||||
sdist = { url = "https://mirrors.aliyun.com/pypi/packages/76/95/faf61eb8363f26aa7e1d762267a8d602a1b26d4f3a1e758e92cb3cb8b054/setuptools-80.10.2.tar.gz", hash = "sha256:8b0e9d10c784bf7d262c4e5ec5d4ec94127ce206e8738f29a437945fbc219b70" }
|
||||
sdist = { url = "https://mirrors.aliyun.com/pypi/packages/0d/1c/73e719955c59b8e424d015ab450f51c0af856ae46ea2da83eba51cc88de1/setuptools-81.0.0.tar.gz", hash = "sha256:487b53915f52501f0a79ccfd0c02c165ffe06631443a886740b91af4b7a5845a" }
|
||||
wheels = [
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/94/b8/f1f62a5e3c0ad2ff1d189590bfa4c46b4f3b6e49cef6f26c6ee4e575394d/setuptools-80.10.2-py3-none-any.whl", hash = "sha256:95b30ddfb717250edb492926c92b5221f7ef3fbcc2b07579bcd4a27da21d0173" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/e1/e3/c164c88b2e5ce7b24d667b9bd83589cf4f3520d97cad01534cd3c4f55fdb/setuptools-81.0.0-py3-none-any.whl", hash = "sha256:fdd925d5c5d9f62e4b74b30d6dd7828ce236fd6ed998a08d81de62ce5a6310d6" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1209,9 +1216,9 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "wcwidth"
|
||||
version = "0.5.3"
|
||||
version = "0.6.0"
|
||||
source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
|
||||
sdist = { url = "https://mirrors.aliyun.com/pypi/packages/c2/62/a7c072fbfefb2980a00f99ca994279cb9ecf310cb2e6b2a4d2a28fe192b3/wcwidth-0.5.3.tar.gz", hash = "sha256:53123b7af053c74e9fe2e92ac810301f6139e64379031f7124574212fb3b4091" }
|
||||
sdist = { url = "https://mirrors.aliyun.com/pypi/packages/35/a2/8e3becb46433538a38726c948d3399905a4c7cabd0df578ede5dc51f0ec2/wcwidth-0.6.0.tar.gz", hash = "sha256:cdc4e4262d6ef9a1a57e018384cbeb1208d8abbc64176027e2c2455c81313159" }
|
||||
wheels = [
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/3c/c1/d73f12f8cdb1891334a2ccf7389eed244d3941e74d80dd220badb937f3fb/wcwidth-0.5.3-py3-none-any.whl", hash = "sha256:d584eff31cd4753e1e5ff6c12e1edfdb324c995713f75d26c29807bb84bf649e" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/68/5a/199c59e0a824a3db2b89c5d2dade7ab5f9624dbf6448dc291b46d5ec94d3/wcwidth-0.6.0-py3-none-any.whl", hash = "sha256:1a3a1e510b553315f8e146c54764f4fb6264ffad731b3d78088cdb1478ffbdad" },
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user