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": [],
        }