fc / apps /documents /models /external_template.py
jun2024's picture
Upload 2241 files
b4f2238 verified
Raw History Blame Contribute Delete
5.59 kB
"""
外部模板模型
本模块定义外部模板 (ExternalTemplate) 数据模型,
用于存储法院、破产管理人等机构提供的 Word 模板文件及其元数据.
"""
from __future__ import annotations
import logging
from typing import ClassVar
from django.db import models
from django.utils.translation import gettext_lazy as _
from .choices import FillType, TemplateStatus
logger: logging.Logger = logging.getLogger(__name__)
class ExternalTemplate(models.Model):
"""
外部模板
存储法院、破产管理人、仲裁委员会等机构提供的 Word 模板文件.
通过结构指纹 (SHA-256) 去重, 支持 LLM 字段映射分析.
数据隔离基于 law_firm (律所级别共享).
Requirements: 1.1, 1.3, 1.4, 1.5, 1.6, 3.1, 3.4, 8.1, 8.2,
9.1, 9.2, 11.4, 11.5, 12.1, 13.1, 13.2, 13.3
"""
id: int
name = models.CharField(
max_length=255,
verbose_name=_("模板名称"),
)
source_name = models.CharField(
max_length=255,
blank=True,
default="",
verbose_name=_("来源机构"),
help_text=_("法院名称或其他机构名称"),
)
file_path = models.CharField(
max_length=500,
verbose_name=_("文件路径"),
help_text=_("相对于 MEDIA_ROOT 的存储路径"),
)
original_filename = models.CharField(
max_length=255,
verbose_name=_("原始文件名"),
)
file_size = models.PositiveIntegerField(
verbose_name=_("文件大小(字节)"),
)
structure_fingerprint = models.CharField(
max_length=64,
blank=True,
default="",
db_index=True,
verbose_name=_("结构指纹"),
help_text=_("基于模板 XML 结构计算的 SHA-256 哈希值"),
)
structure_json = models.JSONField(
default=dict,
blank=True,
verbose_name=_("提取的结构JSON"),
)
status = models.CharField(
max_length=20,
choices=TemplateStatus.choices,
default=TemplateStatus.UPLOADED,
verbose_name=_("状态"),
)
mapping_source = models.ForeignKey(
"self",
on_delete=models.SET_NULL,
null=True,
blank=True,
verbose_name=_("映射来源模板"),
help_text=_("结构指纹匹配时复用映射的原始模板"),
)
version = models.PositiveIntegerField(
default=1,
verbose_name=_("版本号"),
)
is_active = models.BooleanField(
default=True,
verbose_name=_("是否活跃"),
)
uploaded_by = models.ForeignKey(
"organization.Lawyer",
on_delete=models.SET_NULL,
null=True,
verbose_name=_("上传者"),
related_name="uploaded_external_templates",
)
law_firm = models.ForeignKey(
"organization.LawFirm",
on_delete=models.CASCADE,
verbose_name=_("所属律所"),
related_name="external_templates",
)
status_changed_at = models.DateTimeField(
auto_now=True,
verbose_name=_("状态变更时间"),
)
created_at = models.DateTimeField(
auto_now_add=True,
verbose_name=_("创建时间"),
)
updated_at = models.DateTimeField(
auto_now=True,
verbose_name=_("更新时间"),
)
class Meta:
app_label = "documents"
verbose_name = _("外部模板")
verbose_name_plural = _("外部模板")
ordering: ClassVar = ["-updated_at"]
indexes: ClassVar = [
models.Index(fields=["law_firm", "source_name"]),
models.Index(fields=["law_firm", "is_active"]),
models.Index(fields=["structure_fingerprint"]),
models.Index(fields=["status"]),
]
def __str__(self) -> str:
return self.name
class ExternalTemplateFieldMapping(models.Model):
"""
外部模板字段映射
存储 LLM 分析生成的字段映射关系, 将模板中的可填充位置
通过语义标签(semantic_label)标识, 填充时由 LLM 根据案件数据自动取值。
Requirements: 4.3, 4.4, 4.5, 5.1, 5.2, 5.3, 5.5, 12.1
"""
id: int
template = models.ForeignKey(
ExternalTemplate,
on_delete=models.CASCADE,
related_name="field_mappings",
verbose_name=_("关联模板"),
)
position_locator = models.JSONField(
verbose_name=_("位置定位器"),
)
position_description = models.CharField(
max_length=500,
blank=True,
default="",
verbose_name=_("位置描述"),
)
semantic_label = models.CharField(
max_length=255,
verbose_name=_("语义标签"),
)
fill_type = models.CharField(
max_length=30,
choices=FillType.choices,
default=FillType.TEXT,
verbose_name=_("填充类型"),
)
sort_order = models.PositiveIntegerField(
default=0,
verbose_name=_("排序"),
)
created_at = models.DateTimeField(
auto_now_add=True,
verbose_name=_("创建时间"),
)
updated_at = models.DateTimeField(
auto_now=True,
verbose_name=_("更新时间"),
)
class Meta:
app_label = "documents"
verbose_name = _("字段映射")
verbose_name_plural = _("字段映射")
ordering: ClassVar = ["sort_order", "id"]
indexes: ClassVar = [
models.Index(fields=["template", "sort_order"]),
]
def __str__(self) -> str:
return f"{self.template.name} - {self.semantic_label}"