initial commit

This commit is contained in:
2025-04-29 18:09:00 +08:00
commit 4faed52de5
690 changed files with 13481 additions and 0 deletions

View File

@@ -0,0 +1,38 @@
import os, io
from typing import List
import zipfile
from pathlib import Path
from django.conf import settings
from utils.path_utils import project_path
from utils.chen_response import ChenResponse
from django.http import FileResponse, HttpResponse
main_download_path = Path(settings.BASE_DIR) / 'media'
def get_file_respone(id: int, file_name: str | List[str]):
"""将生成文档下载响应"""
# 1.如果传入的是str直接是文件名
if isinstance(file_name, str):
file_name = "".join([file_name, '.docx'])
file_abs_path = main_download_path / project_path(id) / 'final_seitai' / file_name
if not file_abs_path.is_file():
return ChenResponse(status=404, code=404, message="文档未生成或生成错误!")
response = FileResponse(open(file_abs_path, 'rb'))
response['Content-Type'] = 'application/octet-stream'
response['Content-Disposition'] = f"attachment; filename={file_name}.docx"
return response
# 2.如果传入的是列表,多个文件名
elif isinstance(file_name, list):
file_name_list = file_name
zip_buffer = io.BytesIO()
with zipfile.ZipFile(zip_buffer, 'w', zipfile.ZIP_DEFLATED) as zip_file:
for file_name in file_name_list:
file_name = "".join([file_name, '.docx'])
file_abs_path = main_download_path / project_path(id) / 'final_seitai' / file_name
zip_file.write(file_abs_path, os.path.basename(file_abs_path))
zip_buffer.seek(0)
response = HttpResponse(zip_buffer, content_type='application/zip')
response['Content-Disposition'] = 'attachment; filename="回归测试说明文档.zip"'
return response
else:
return ChenResponse(code=500, status=500, message='下载文档出现错误,确认是否有多个轮次内容')

View File

@@ -0,0 +1,31 @@
import logging
from conf.logConfig import LOG_GENERATE_FILE
generate_logger = logging.getLogger("generate_document_logger")
class GenerateLogger(object):
instance = None
# 单例模式
def __new__(cls, *args, **kwargs):
if cls.instance is None:
cls.instance = object.__new__(cls)
return cls.instance
else:
return cls.instance
def __init__(self, model: str = '通用文档'):
self.logger = generate_logger
# 模块属性
self.model = model
def write_warning_log(self, fragment: str, message: str):
"""警告日志记录暂时简单点model和message"""
whole_message = f"[{self.model}模块][{fragment}]片段:{message}"
self.logger.warning(whole_message)
@staticmethod
def delete_one_logs():
"""删除生成文档logger的日志记录"""
with open(LOG_GENERATE_FILE, 'w') as f:
f.truncate()

View File

@@ -0,0 +1,44 @@
from docx.oxml.ns import qn # qn作用是元素的.tag属性自动帮你处理namespace
from docx.shape import InlineShape
from apps.createSeiTaiDocument.docXmlUtils import (
Demand_table_xqms,
Timing_diagram_width,
Test_result_width,
Horizatal_width
)
def set_shape_size(shape: InlineShape):
"""调用下面辅助函数,判断字典{'in_table': True, 'row_idx': 10, 'col_idx': 3}来设置大小"""
shape_location = get_shape_location(shape)
# 先判断是否在table中
if shape_location['in_table']:
# 在table中看是否是第一列第一列则是时序图
if shape_location['col_idx'] == 0:
# 在第一列:说明是时序图
shape.width = Timing_diagram_width
else:
shape.width = Test_result_width
else:
shape.width = Horizatal_width
def get_shape_location(shape: InlineShape):
"""传入图片直接处理注意是python-docx库不是docxtpl"""
# 获取父元素链
parent_chain = list(shape._inline.iterancestors())
# 检查是否在表格中
for elem in parent_chain:
if elem.tag == qn("w:tbl"):
# 获取表格对象
tbl = elem
# 获取行对象并计算行索引
tr = next(e for e in parent_chain if e.tag == qn('w:tr'))
row_idx = tbl.index(tr)
# 获取单元格对象并计算列索引
tc = next(e for e in parent_chain if e.tag == qn('w:tc'))
col_idx = tr.index(tc)
return {
'in_table': True,
'row_idx': row_idx,
'col_idx': col_idx
}
return {'in_table': False}