新增:影响域分析-软件更改部分

This commit is contained in:
2026-02-08 15:10:43 +08:00
parent a76cd8674c
commit 2f58bdc668
55 changed files with 112 additions and 22 deletions

View File

@@ -1,6 +1,6 @@
from pathlib import Path
from copy import deepcopy
from typing import Union
from typing import Union, TypedDict, Optional
from ninja_extra import api_controller, ControllerBase, route
from django.db import transaction
from django.shortcuts import get_object_or_404
@@ -240,26 +240,31 @@ class GenerateControllerHSM(ControllerBase):
## 先查找是否有影响域分析填写
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():
# 遍历items
item_render_list = []
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": item.change_des, # 富文本未处理
"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
# 如果存在这个轮次的需求文档,则查询上个版本
last_xq_version = ""
if xq_dut:

View File

@@ -7,7 +7,7 @@ from bs4.element import Tag, NavigableString
import base64
import io
from docxtpl import InlineImage
from docx.shared import Mm, Cm
from docx.shared import Mm
import re
# text.replace('\xa0', ' '))
@@ -82,11 +82,12 @@ class RichParser:
if isinstance(oneline, list):
final_list.append({'isTable': True, 'data': oneline})
continue
if oneline.startswith("data:image/png;base64"):
if oneline.startswith("data:image/png;base64") or oneline.startswith("data:image/jpeg;base64,") or oneline.startswith(
"data:image/jpg;base64,"):
base64_bytes = base64.b64decode(oneline.replace("data:image/png;base64,", ""))
# ~~~设置了固定宽度、高度~~~
final_list.append(
InlineImage(doc, io.BytesIO(base64_bytes), width=Mm(img_size), height=Mm(height)))
inline_image = InlineImage(doc, io.BytesIO(base64_bytes), width=Mm(img_size), height=Mm(height))
final_list.append(inline_image)
else:
final_list.append(oneline)
if len(final_list) <= 0:

View File

@@ -405,7 +405,7 @@ class CaseController(ControllerBase):
# dut -> design
data_list = []
for dut in previous_round_obj.rdField.all():
dut_dict = {'label': dut.name, 'value': dut.id, 'children': []}
dut_dict = {'label': dut.name, 'value': dut.id, 'key': dut.key, 'children': []}
for design in dut.rsField.all():
design_dict = {'label': design.name, 'value': design.id, 'key': design.key, 'children': []}
for case in design.dcField.all():

View File

@@ -114,7 +114,6 @@ class RoundController(ControllerBase):
@route.post("/round/create_influence", url_name="round-influence-create")
@transaction.atomic
def post_influence(self, data: InfluenceInputSchema):
print(data)
round_obj = Round.objects.filter(project_id=data.id, key=data.round_key).first()
influence_area_qs = InfluenceArea.objects.filter(round=round_obj)
if influence_area_qs.exists():

View File

@@ -596,3 +596,88 @@ ValueError: Cannot assign "<QuerySet [<InfluenceArea: InfluenceArea object (195)
[WARNING][2026-02-07 15:20:44,503][log.py:249]Unprocessable Content: /api/project/round/create_influence
[WARNING][2026-02-07 15:21:39,506][operation.py:131]"POST - RoundController[post_influence] /api/project/round/create_influence" ([{'type': 'string_type', 'loc': ('body', 'data', 'item_list', 0, 'effect_cases', 0), 'msg': 'Input should be a valid string'}, {'type': 'string_type', 'loc': ('body', 'data', 'item_list', 0, 'effect_cases', 1), 'msg': 'Input should be a valid string'}, {'type': 'string_type', 'loc': ('body', 'data', 'item_list', 0, 'effect_cases', 2), 'msg': 'Input should be a valid string'}, {'type': 'string_type', 'loc': ('body', 'data', 'item_list', 0, 'effect_cases', 3), 'msg': 'Input should be a valid string'}],)
[WARNING][2026-02-07 15:21:39,515][log.py:249]Unprocessable Content: /api/project/round/create_influence
[WARNING][2026-02-08 13:53:10,479][log.py:249]Unauthorized: /api/system/getInfo
[WARNING][2026-02-08 13:53:10,577][log.py:249]Unauthorized: /api/system/logout
[WARNING][2026-02-08 13:53:14,760][backend.py:91]Caught LDAPError looking up user: SERVER_DOWN({'result': -1, 'desc': "Can't contact LDAP server", 'ctrls': []})
[WARNING][2026-02-08 13:53:32,251][operation.py:131]"GET - GenerateControllerHSM[create_changePart] /api/generateHSM/create/changePart" ("RichParser.get_final_list() missing 1 required positional argument: 'doc'",)
[ERROR][2026-02-08 13:53:32,252][errors.py:131]RichParser.get_final_list() missing 1 required positional argument: 'doc': 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 212, in run
result = self.view_func(request, **ctx.kwargs["view_func_kwargs"])
File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\controllers\route\route_functions.py", line 108, in as_view
result = self.route.view_func(
ctx.controller_instance, *args, **ctx.view_func_kwargs
)
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\createDocument\controllers\hsm.py", line 257, in create_changePart
print(parser.get_final_list())
~~~~~~~~~~~~~~~~~~~~~^^
TypeError: RichParser.get_final_list() missing 1 required positional argument: 'doc': Did you fail to use functools.wraps() in a decorator?
[ERROR][2026-02-08 13:53:32,259][log.py:249]Internal Server Error: /api/generateHSM/create/changePart
[WARNING][2026-02-08 15:04:43,157][operation.py:131]"GET - GenerateControllerHSM[create_changePart] /api/generateHSM/create/changePart" ("Expected an expression, got 'end of print statement'",)
[ERROR][2026-02-08 15:04:43,157][errors.py:131]Expected an expression, got 'end of print statement'
Traceback (most recent call last):
File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 212, in run
result = self.view_func(request, **ctx.kwargs["view_func_kwargs"])
File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\controllers\route\route_functions.py", line 108, in as_view
result = self.route.view_func(
ctx.controller_instance, *args, **ctx.view_func_kwargs
)
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\createDocument\controllers\hsm.py", line 285, in create_changePart
doc.render(context_round, autoescape=True)
~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\docxtpl\template.py", line 489, in render
xml_src = self.build_xml(context, jinja_env)
File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\docxtpl\template.py", line 436, in build_xml
xml = self.render_xml_part(xml, self.docx._part, context, jinja_env)
File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\docxtpl\template.py", line 322, in render_xml_part
raise exc
File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\docxtpl\template.py", line 310, in render_xml_part
template = jinja_env.from_string(src_xml)
File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\jinja2\environment.py", line 1111, in from_string
return cls.from_code(self, self.compile(source), gs, None)
~~~~~~~~~~~~^^^^^^^^
File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\jinja2\environment.py", line 771, in compile
self.handle_exception(source=source_hint)
~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\jinja2\environment.py", line 942, in handle_exception
raise rewrite_traceback_stack(source=source)
File "<unknown>", line 16, in template
jinja2.exceptions.TemplateSyntaxError: Expected an expression, got 'end of print statement'
[ERROR][2026-02-08 15:04:43,182][log.py:249]Internal Server Error: /api/generateHSM/create/changePart
[WARNING][2026-02-08 15:05:05,418][operation.py:131]"GET - GenerateControllerHSM[create_changePart] /api/generateHSM/create/changePart" ("Expected an expression, got 'end of print statement'",)
[ERROR][2026-02-08 15:05:05,419][errors.py:131]Expected an expression, got 'end of print statement'
Traceback (most recent call last):
File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\operation.py", line 212, in run
result = self.view_func(request, **ctx.kwargs["view_func_kwargs"])
File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\ninja_extra\controllers\route\route_functions.py", line 108, in as_view
result = self.route.view_func(
ctx.controller_instance, *args, **ctx.view_func_kwargs
)
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\createDocument\controllers\hsm.py", line 285, in create_changePart
doc.render(context_round, autoescape=True)
~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\docxtpl\template.py", line 489, in render
xml_src = self.build_xml(context, jinja_env)
File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\docxtpl\template.py", line 436, in build_xml
xml = self.render_xml_part(xml, self.docx._part, context, jinja_env)
File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\docxtpl\template.py", line 322, in render_xml_part
raise exc
File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\docxtpl\template.py", line 310, in render_xml_part
template = jinja_env.from_string(src_xml)
File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\jinja2\environment.py", line 1111, in from_string
return cls.from_code(self, self.compile(source), gs, None)
~~~~~~~~~~~~^^^^^^^^
File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\jinja2\environment.py", line 771, in compile
self.handle_exception(source=source_hint)
~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
File "E:\pycharmProjects\cdtestplant_v1\.venv\Lib\site-packages\jinja2\environment.py", line 942, in handle_exception
raise rewrite_traceback_stack(source=source)
File "<unknown>", line 16, in template
jinja2.exceptions.TemplateSyntaxError: Expected an expression, got 'end of print statement'
[ERROR][2026-02-08 15:05:05,438][log.py:249]Internal Server Error: /api/generateHSM/create/changePart

Binary file not shown.

View File

@@ -17,8 +17,8 @@ dependencies = [
"django-tinymce>=5.0.0",
"docxcompose",
"docxtpl>=0.20.2",
"faker==40.1.2",
"ipykernel>=7.1.0",
"faker>=40.4.0",
"ipykernel>=7.2.0",
"lizard>=1.21.0",
"mysqlclient>=2.2.7",
"ninja-schema>=0.14.3",

16
uv.lock generated
View File

@@ -111,8 +111,8 @@ requires-dist = [
{ name = "django-tinymce", specifier = ">=5.0.0" },
{ name = "docxcompose" },
{ name = "docxtpl", specifier = ">=0.20.2" },
{ name = "faker", specifier = "==40.1.2" },
{ name = "ipykernel", specifier = ">=7.1.0" },
{ name = "faker", specifier = ">=40.4.0" },
{ name = "ipykernel", specifier = ">=7.2.0" },
{ name = "lizard", specifier = ">=1.21.0" },
{ name = "mysqlclient", specifier = ">=2.2.7" },
{ name = "ninja-schema", specifier = ">=0.14.3" },
@@ -413,14 +413,14 @@ wheels = [
[[package]]
name = "faker"
version = "40.1.2"
version = "40.4.0"
source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
dependencies = [
{ name = "tzdata", marker = "sys_platform == 'win32'" },
]
sdist = { url = "https://mirrors.aliyun.com/pypi/packages/5e/77/1c3ff07b6739b9a1d23ca01ec0a90a309a33b78e345a3eb52f9ce9240e36/faker-40.1.2.tar.gz", hash = "sha256:b76a68163aa5f171d260fc24827a8349bc1db672f6a665359e8d0095e8135d30" }
sdist = { url = "https://mirrors.aliyun.com/pypi/packages/fc/7e/dccb7013c9f3d66f2e379383600629fec75e4da2698548bdbf2041ea4b51/faker-40.4.0.tar.gz", hash = "sha256:76f8e74a3df28c3e2ec2caafa956e19e37a132fdc7ea067bc41783affcfee364" }
wheels = [
{ url = "https://mirrors.aliyun.com/pypi/packages/46/ec/91a434c8a53d40c3598966621dea9c50512bec6ce8e76fa1751015e74cef/faker-40.1.2-py3-none-any.whl", hash = "sha256:93503165c165d330260e4379fd6dc07c94da90c611ed3191a0174d2ab9966a42" },
{ url = "https://mirrors.aliyun.com/pypi/packages/ac/63/58efa67c10fb27810d34351b7a10f85f109a7f7e2a07dc3773952459c47b/faker-40.4.0-py3-none-any.whl", hash = "sha256:486d43c67ebbb136bc932406418744f9a0bdf2c07f77703ea78b58b77e9aa443" },
]
[[package]]
@@ -443,7 +443,7 @@ wheels = [
[[package]]
name = "ipykernel"
version = "7.1.0"
version = "7.2.0"
source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
dependencies = [
{ name = "appnope", marker = "sys_platform == 'darwin'" },
@@ -460,9 +460,9 @@ dependencies = [
{ name = "tornado" },
{ name = "traitlets" },
]
sdist = { url = "https://mirrors.aliyun.com/pypi/packages/b9/a4/4948be6eb88628505b83a1f2f40d90254cab66abf2043b3c40fa07dfce0f/ipykernel-7.1.0.tar.gz", hash = "sha256:58a3fc88533d5930c3546dc7eac66c6d288acde4f801e2001e65edc5dc9cf0db" }
sdist = { url = "https://mirrors.aliyun.com/pypi/packages/ca/8d/b68b728e2d06b9e0051019640a40a9eb7a88fcd82c2e1b5ce70bef5ff044/ipykernel-7.2.0.tar.gz", hash = "sha256:18ed160b6dee2cbb16e5f3575858bc19d8f1fe6046a9a680c708494ce31d909e" }
wheels = [
{ url = "https://mirrors.aliyun.com/pypi/packages/a3/17/20c2552266728ceba271967b87919664ecc0e33efca29c3efc6baf88c5f9/ipykernel-7.1.0-py3-none-any.whl", hash = "sha256:763b5ec6c5b7776f6a8d7ce09b267693b4e5ce75cb50ae696aaefb3c85e1ea4c" },
{ url = "https://mirrors.aliyun.com/pypi/packages/82/b9/e73d5d9f405cba7706c539aa8b311b49d4c2f3d698d9c12f815231169c71/ipykernel-7.2.0-py3-none-any.whl", hash = "sha256:3bbd4420d2b3cc105cbdf3756bfc04500b1e52f090a90716851f3916c62e1661" },
]
[[package]]