268 lines
11 KiB
Python
268 lines
11 KiB
Python
#!/usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
"""
|
|
文档生成Schema定义
|
|
"""
|
|
from datetime import datetime
|
|
from typing import Optional, List, Dict, Any
|
|
|
|
from pydantic import BaseModel, ConfigDict, Field
|
|
|
|
|
|
# ==================== 文档模板 ====================
|
|
|
|
class PageMargin(BaseModel):
|
|
"""页边距配置"""
|
|
top: int = 20
|
|
right: int = 20
|
|
bottom: int = 20
|
|
left: int = 20
|
|
|
|
|
|
class SealPosition(BaseModel):
|
|
"""签章位置配置"""
|
|
seal_type: str = Field(..., description="签章类型: company/department/personal/signature")
|
|
position_type: str = Field(default="fixed", description="定位方式: fixed/relative")
|
|
x: int = Field(default=0, description="X坐标(mm)")
|
|
y: int = Field(default=0, description="Y坐标(mm)")
|
|
page: int = Field(default=-1, description="页码(-1表示最后一页)")
|
|
width: int = Field(default=40, description="宽度(mm)")
|
|
height: int = Field(default=40, description="高度(mm)")
|
|
field_name: Optional[str] = Field(default=None, description="关联字段名(用于手写签名)")
|
|
|
|
|
|
class CalculationField(BaseModel):
|
|
"""计算字段配置"""
|
|
name: str = Field(..., description="字段名")
|
|
label: str = Field(default="", description="字段标签")
|
|
formula: str = Field(..., description="计算公式,如: quantity * unit_price")
|
|
format: str = Field(default="number", description="格式化类型: number/money/percent/chinese")
|
|
decimal_places: int = Field(default=2, description="小数位数")
|
|
|
|
|
|
class AggregationField(BaseModel):
|
|
"""聚合字段配置"""
|
|
name: str = Field(..., description="字段名")
|
|
label: str = Field(default="", description="字段标签")
|
|
source: str = Field(..., description="数据源(子表名)")
|
|
field: str = Field(..., description="聚合字段")
|
|
function: str = Field(default="sum", description="聚合函数: sum/avg/max/min/count")
|
|
format: str = Field(default="number", description="格式化类型: number/money/percent/chinese")
|
|
decimal_places: int = Field(default=2, description="小数位数")
|
|
|
|
|
|
class CalculationRules(BaseModel):
|
|
"""计算规则配置"""
|
|
fields: List[CalculationField] = Field(default_factory=list, description="计算字段列表")
|
|
aggregations: List[AggregationField] = Field(default_factory=list, description="聚合字段列表")
|
|
|
|
|
|
class DocumentTemplateBase(BaseModel):
|
|
"""文档模板基础Schema"""
|
|
name: str = Field(..., min_length=1, max_length=100, description="模板名称")
|
|
code: str = Field(..., min_length=1, max_length=100, pattern=r"^[a-zA-Z][a-zA-Z0-9_]*$", description="模板编码(字母开头,只能包含字母、数字和下划线)")
|
|
category: str = Field(default="other", description="分类")
|
|
description: Optional[str] = Field(default="", description="描述")
|
|
|
|
form_code: Optional[str] = Field(default=None, description="关联表单编码")
|
|
workflow_code: Optional[str] = Field(default=None, description="关联流程编码")
|
|
|
|
template_type: str = Field(default="designer", description="模板类型: designer/html")
|
|
template_content: Optional[str] = Field(default=None, description="模板内容")
|
|
template_css: Optional[str] = Field(default=None, description="自定义CSS")
|
|
|
|
page_size: str = Field(default="A4", description="页面大小")
|
|
page_orientation: str = Field(default="portrait", description="页面方向")
|
|
page_margin: Optional[PageMargin] = Field(default_factory=PageMargin, description="页边距")
|
|
|
|
watermark_enabled: bool = Field(default=False, description="是否启用水印")
|
|
watermark_text: Optional[str] = Field(default=None, description="水印文字")
|
|
watermark_type: str = Field(default="text", description="水印类型")
|
|
watermark_image_id: Optional[str] = Field(default=None, description="水印图片ID")
|
|
watermark_opacity: int = Field(default=30, ge=0, le=100, description="水印透明度")
|
|
watermark_angle: int = Field(default=-45, description="水印角度")
|
|
|
|
seal_enabled: bool = Field(default=False, description="是否启用签章")
|
|
seal_positions: Optional[List[SealPosition]] = Field(default=None, description="签章位置配置")
|
|
|
|
header_enabled: bool = Field(default=False, description="是否启用页眉")
|
|
header_template: Optional[str] = Field(default=None, description="页眉模板")
|
|
footer_enabled: bool = Field(default=False, description="是否启用页脚")
|
|
footer_template: Optional[str] = Field(default=None, description="页脚模板")
|
|
show_page_number: bool = Field(default=True, description="是否显示页码")
|
|
|
|
calculation_rules: Optional[CalculationRules] = Field(default=None, description="计算规则配置")
|
|
|
|
|
|
class DocumentTemplateCreate(DocumentTemplateBase):
|
|
"""创建文档模板"""
|
|
application_id: Optional[str] = Field(default=None, description="所属应用ID")
|
|
|
|
|
|
class DocumentTemplateUpdate(BaseModel):
|
|
"""更新文档模板"""
|
|
name: Optional[str] = Field(default=None, max_length=100, description="模板名称")
|
|
category: Optional[str] = Field(default=None, description="分类")
|
|
description: Optional[str] = Field(default=None, description="描述")
|
|
|
|
form_code: Optional[str] = Field(default=None, description="关联表单编码")
|
|
workflow_code: Optional[str] = Field(default=None, description="关联流程编码")
|
|
|
|
template_type: Optional[str] = Field(default=None, description="模板类型")
|
|
template_content: Optional[str] = Field(default=None, description="模板内容")
|
|
template_css: Optional[str] = Field(default=None, description="自定义CSS")
|
|
|
|
page_size: Optional[str] = Field(default=None, description="页面大小")
|
|
page_orientation: Optional[str] = Field(default=None, description="页面方向")
|
|
page_margin: Optional[PageMargin] = Field(default=None, description="页边距")
|
|
|
|
watermark_enabled: Optional[bool] = Field(default=None, description="是否启用水印")
|
|
watermark_text: Optional[str] = Field(default=None, description="水印文字")
|
|
watermark_type: Optional[str] = Field(default=None, description="水印类型")
|
|
watermark_image_id: Optional[str] = Field(default=None, description="水印图片ID")
|
|
watermark_opacity: Optional[int] = Field(default=None, description="水印透明度")
|
|
watermark_angle: Optional[int] = Field(default=None, description="水印角度")
|
|
|
|
seal_enabled: Optional[bool] = Field(default=None, description="是否启用签章")
|
|
seal_positions: Optional[List[SealPosition]] = Field(default=None, description="签章位置配置")
|
|
|
|
header_enabled: Optional[bool] = Field(default=None, description="是否启用页眉")
|
|
header_template: Optional[str] = Field(default=None, description="页眉模板")
|
|
footer_enabled: Optional[bool] = Field(default=None, description="是否启用页脚")
|
|
footer_template: Optional[str] = Field(default=None, description="页脚模板")
|
|
show_page_number: Optional[bool] = Field(default=None, description="是否显示页码")
|
|
|
|
calculation_rules: Optional[CalculationRules] = Field(default=None, description="计算规则配置")
|
|
|
|
status: Optional[str] = Field(default=None, description="状态")
|
|
|
|
|
|
class DocumentTemplateOut(DocumentTemplateBase):
|
|
"""文档模板输出"""
|
|
id: str
|
|
application_id: Optional[str] = None
|
|
calculation_rules: Optional[Dict[str, Any]] = None
|
|
status: str = "draft"
|
|
is_builtin: bool = False
|
|
version: int = 1
|
|
sys_create_datetime: Optional[datetime] = None
|
|
sys_update_datetime: Optional[datetime] = None
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
class DocumentTemplateListOut(BaseModel):
|
|
"""文档模板列表输出"""
|
|
id: str
|
|
name: str
|
|
code: str
|
|
category: str
|
|
description: Optional[str] = None
|
|
form_code: Optional[str] = None
|
|
workflow_code: Optional[str] = None
|
|
status: str = "draft"
|
|
is_builtin: bool = False
|
|
version: int = 1
|
|
sys_create_datetime: Optional[datetime] = None
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
# ==================== 导入导出 ====================
|
|
|
|
class DocumentTemplateImportCheckIn(BaseModel):
|
|
"""单据模板导入预检查"""
|
|
code: str = Field(..., description="模板编码")
|
|
|
|
|
|
class DocumentTemplateImportCheckOut(BaseModel):
|
|
"""单据模板导入预检查结果"""
|
|
code_exists: bool = Field(..., description="模板编码是否已存在")
|
|
can_import: bool = Field(..., description="是否可以直接导入")
|
|
|
|
|
|
class DocumentTemplateImportIn(DocumentTemplateBase):
|
|
"""单据模板配置导入"""
|
|
application_id: Optional[str] = Field(None, description="所属应用ID")
|
|
|
|
|
|
# ==================== 生成的文档 ====================
|
|
|
|
class GeneratedDocumentOut(BaseModel):
|
|
"""生成的文档输出"""
|
|
id: str
|
|
template_id: str
|
|
template_code: Optional[str] = None
|
|
template_name: Optional[str] = None
|
|
|
|
form_code: Optional[str] = None
|
|
form_data_id: Optional[str] = None
|
|
workflow_code: Optional[str] = None
|
|
instance_id: Optional[str] = None
|
|
|
|
document_name: str
|
|
document_no: Optional[str] = None
|
|
|
|
file_id: str
|
|
file_size: int = 0
|
|
page_count: int = 1
|
|
|
|
generate_type: str = "manual"
|
|
generator_id: Optional[str] = None
|
|
generator_name: Optional[str] = None
|
|
|
|
status: str = "generated"
|
|
download_count: int = 0
|
|
|
|
sealed: bool = False
|
|
seal_info: Optional[Dict[str, Any]] = None
|
|
|
|
sys_create_datetime: Optional[datetime] = None
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
class GenerateDocumentIn(BaseModel):
|
|
"""生成文档请求"""
|
|
template_id: str = Field(..., description="模板ID")
|
|
form_data_id: Optional[str] = Field(default=None, description="表单数据ID")
|
|
instance_id: Optional[str] = Field(default=None, description="流程实例ID")
|
|
document_name: Optional[str] = Field(default=None, description="文档名称(可选)")
|
|
seal_ids: Optional[List[str]] = Field(default=None, description="要使用的签章ID列表")
|
|
signature_file_ids: Optional[Dict[str, str]] = Field(default=None, description="手写签名文件ID映射")
|
|
|
|
|
|
class BatchGenerateDocumentIn(BaseModel):
|
|
"""批量生成文档请求"""
|
|
template_id: str = Field(..., description="模板ID")
|
|
form_data_ids: List[str] = Field(..., description="表单数据ID列表")
|
|
|
|
|
|
# ==================== 预览 ====================
|
|
|
|
class PreviewDocumentIn(BaseModel):
|
|
"""预览文档请求"""
|
|
template_id: Optional[str] = Field(default=None, description="模板ID(与template_content二选一)")
|
|
template_content: Optional[str] = Field(default=None, description="模板内容JSON(与template_id二选一)")
|
|
calculation_rules: Optional[Dict[str, Any]] = Field(default=None, description="计算规则配置(用于未保存的模板预览)")
|
|
form_data_id: Optional[str] = Field(default=None, description="表单数据ID")
|
|
instance_id: Optional[str] = Field(default=None, description="流程实例ID")
|
|
test_data: Optional[Dict[str, Any]] = Field(default=None, description="测试数据(优先使用)")
|
|
|
|
|
|
# ==================== 通用响应 ====================
|
|
|
|
class TemplateCategory(BaseModel):
|
|
"""模板分类"""
|
|
value: str
|
|
label: str
|
|
count: int = 0
|
|
|
|
|
|
class DocumentStats(BaseModel):
|
|
"""文档统计"""
|
|
total_templates: int = 0
|
|
published_templates: int = 0
|
|
total_documents: int = 0
|
|
today_documents: int = 0
|