File size: 5,876 Bytes
b4f2238 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | """文件模板初始化服务"""
import logging
from typing import Any
from django.db import transaction
from apps.documents.models import DocumentTemplate, DocumentTemplateFolderBinding, FolderTemplate
from apps.documents.storage import resolve_docx_template_path
from .complete_defaults import get_complete_default_data
logger = logging.getLogger(__name__)
class DocumentTemplateInitService:
"""文件模板初始化服务"""
def _find_missing_docx_files(self, document_templates: list[dict[str, Any]]) -> list[str]:
missing_files: list[str] = []
for template_data in document_templates:
file_path_obj = template_data.get("file_path")
if not isinstance(file_path_obj, str):
continue
relative_file_path = file_path_obj.strip()
if not relative_file_path:
continue
try:
absolute_file_path = resolve_docx_template_path(relative_file_path)
except ValueError:
missing_files.append(relative_file_path)
continue
if not absolute_file_path.exists():
missing_files.append(relative_file_path)
return missing_files
@transaction.atomic
def initialize_default_templates(self) -> dict[str, Any]:
"""
初始化默认文件模板(完整版)
包含:
1. 文件夹模板
2. 文件模板
3. 文件模板与文件夹的绑定关系
Returns:
包含各项创建和跳过数量的字典
"""
data = get_complete_default_data()
missing_files = self._find_missing_docx_files(data["document_templates"])
if missing_files:
logger.warning("默认模板初始化失败:缺失 %s 个 docx 模板文件", len(missing_files))
return {
"success": False,
"error_code": "missing_docx_files",
"missing_files": missing_files,
"folder_created": 0,
"folder_skipped": 0,
"doc_created": 0,
"doc_skipped": 0,
"binding_created": 0,
"binding_skipped": 0,
}
folder_created = 0
folder_skipped = 0
doc_created = 0
doc_skipped = 0
binding_created = 0
binding_skipped = 0
# 1. 初始化文件夹模板
folder_map: dict[str, Any] = {}
for folder_data in data["folder_templates"]:
existing = FolderTemplate.objects.filter(name=folder_data["name"]).first()
if existing:
logger.info(f"跳过已存在的文件夹模板: {folder_data['name']}")
folder_skipped += 1
folder_map[folder_data["name"]] = existing
else:
folder = FolderTemplate.objects.create(**folder_data)
logger.info(f"创建文件夹模板: {folder_data['name']}")
folder_created += 1
folder_map[folder_data["name"]] = folder
# 2. 初始化文件模板
doc_map: dict[str, Any] = {}
for template_data in data["document_templates"]:
existing_doc = DocumentTemplate.objects.filter(
name=template_data["name"], template_type=template_data["template_type"]
).first()
if existing_doc:
logger.info(f"跳过已存在的文件模板: {template_data['name']}")
doc_skipped += 1
doc_map[template_data["name"]] = existing_doc
else:
doc = DocumentTemplate.objects.create(**template_data)
logger.info(f"创建文件模板: {template_data['name']}")
doc_created += 1
doc_map[template_data["name"]] = doc
# 3. 初始化绑定关系
for binding_data in data["bindings"]:
doc_name = binding_data["document_template_name"]
folder_name = binding_data["folder_template_name"]
node_id = binding_data["folder_node_id"]
if doc_name not in doc_map or folder_name not in folder_map:
logger.warning(f"跳过绑定(模板不存在): {doc_name} -> {folder_name}")
continue
doc = doc_map[doc_name]
folder = folder_map[folder_name]
existing_binding = DocumentTemplateFolderBinding.objects.filter(
document_template=doc, folder_template=folder, folder_node_id=node_id
).exists()
if existing_binding:
logger.info(f"跳过已存在的绑定: {doc_name} -> {folder_name}")
binding_skipped += 1
else:
# 计算文件夹路径
from apps.documents.services.template.contract_template.binding_service import (
DocumentTemplateBindingService,
)
binding_service = DocumentTemplateBindingService()
folder_node_path = binding_service.calculate_folder_path(folder, node_id)
DocumentTemplateFolderBinding.objects.create(
document_template=doc,
folder_template=folder,
folder_node_id=node_id,
folder_node_path=folder_node_path,
)
logger.info(f"创建绑定: {doc_name} -> {folder_name} (路径: {folder_node_path})")
binding_created += 1
return {
"success": True,
"folder_created": folder_created,
"folder_skipped": folder_skipped,
"doc_created": doc_created,
"doc_skipped": doc_skipped,
"binding_created": binding_created,
"binding_skipped": binding_skipped,
"missing_files": [],
}
|