File size: 5,155 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
"""
法律文书生成系统 - 文件夹模板模型

本模块定义文件夹模板相关的数据模型.
"""

from __future__ import annotations

from typing import TYPE_CHECKING, Any, ClassVar

from django.db import models
from django.utils.translation import gettext_lazy as _

from .choices import DocumentCaseStage, DocumentCaseType, DocumentContractType, FolderTemplateType, LegalStatusMatchMode

if TYPE_CHECKING:
    from django.db.models.fields.related_descriptors import RelatedManager

    from .document_template import DocumentTemplateFolderBinding


class FolderTemplate(models.Model):
    """
    文件夹模板

    定义不同案件类型和阶段所需的文件夹结构.
    结构以 JSON 格式存储,支持无限层级嵌套.

    Requirements: 1.1, 1.3, 7.1
    """

    id: int

    name = models.CharField(max_length=100, verbose_name=_("模板名称"))
    template_type = models.CharField(
        max_length=20,
        choices=FolderTemplateType.choices,
        verbose_name=_("模板类型"),
        help_text=_("选择此模板用于合同还是案件"),
    )
    case_types: Any = models.JSONField(
        default=list, verbose_name=_("案件类型"), help_text=_("JSON 数组,如 ['civil', 'criminal'],支持多选")
    )
    case_stages: Any = models.JSONField(
        default=list, verbose_name=_("案件阶段"), help_text=_("JSON 数组,如 ['first_trial', 'second_trial'],支持多选")
    )
    contract_types: Any = models.JSONField(
        default=list, verbose_name=_("合同类型"), help_text=_("JSON 数组,如 ['civil', 'criminal'],支持多选")
    )
    legal_statuses: Any = models.JSONField(
        default=list,
        blank=True,
        verbose_name=_("我方诉讼地位"),
        help_text=_("可单选或多选;为空表示匹配任意诉讼地位"),
    )
    legal_status_match_mode = models.CharField(
        max_length=16,
        choices=LegalStatusMatchMode.choices,
        default=LegalStatusMatchMode.ANY,
        verbose_name=_("诉讼地位匹配模式"),
    )
    structure: Any = models.JSONField(
        default=dict, verbose_name=_("文件夹结构"), help_text=_("JSON 格式的文件夹层级结构")
    )
    is_default = models.BooleanField(default=False, verbose_name=_("是否默认模板"))
    is_active = models.BooleanField(default=True, verbose_name=_("是否启用"))
    created_at = models.DateTimeField(auto_now_add=True, verbose_name=_("创建时间"))
    updated_at = models.DateTimeField(auto_now=True, verbose_name=_("更新时间"))

    if TYPE_CHECKING:
        document_bindings: RelatedManager[DocumentTemplateFolderBinding]

    class Meta:
        app_label = "documents"
        verbose_name = _("文件夹模板")
        verbose_name_plural = _("文件夹模板")
        ordering: ClassVar = ["-updated_at"]
        indexes: ClassVar = [
            models.Index(fields=["is_active"]),
            models.Index(fields=["is_default"]),
        ]

    def __str__(self) -> str:
        template_type_display = dict(FolderTemplateType.choices).get(self.template_type, self.template_type)
        case_types_display = self._get_types_display(self.case_types, DocumentCaseType)
        return f"{self.name} ({template_type_display} - {case_types_display})"

    def _get_types_display(self, types_list: list[Any], choices_class: type[models.TextChoices]) -> str:
        """获取类型列表的显示文本"""
        if not types_list:
            return "-"  # 空值显示为"-"而非"通用"
        if len(types_list) == 1:
            return dict(choices_class.choices).get(types_list[0], types_list[0])
        return f"{len(types_list)}种类型"

    @property
    def template_type_display(self) -> str:
        """模板类型显示"""
        return str(dict(FolderTemplateType.choices).get(self.template_type, self.template_type))

    @property
    def case_types_display(self) -> str:
        """案件类型显示"""
        return self._get_types_display(self.case_types, DocumentCaseType)

    @property
    def case_stages_display(self) -> str:
        """案件阶段显示"""
        return self._get_types_display(self.case_stages, DocumentCaseStage)

    @property
    def contract_types_display(self) -> str:
        """合同类型显示"""
        return self._get_types_display(self.contract_types, DocumentContractType)

    @property
    def case_type(self) -> str | None:
        values = self.case_types or []
        return values[0] if values else None

    @property
    def case_stage(self) -> Any:
        values = self.case_stages or []
        return values[0] if values else None

    def get_legal_statuses_display(self) -> str:
        """获取诉讼地位的显示文本"""
        from apps.core.models.enums import LegalStatus

        choices = dict(LegalStatus.choices)
        statuses = self.legal_statuses or []
        labels = [str(choices.get(code, code)) for code in statuses]
        return "、".join([x for x in labels if x])

    @property
    def legal_statuses_display(self) -> str:
        """诉讼地位显示属性"""
        return self.get_legal_statuses_display() or "-"