重构学员证书签发与批量导入流程

This commit is contained in:
Certificate System
2026-08-14 11:37:09 +08:00
parent 522f529c6a
commit 5e33657268
16 changed files with 1047 additions and 370 deletions

View File

@@ -2,15 +2,39 @@ from dataclasses import dataclass
from pathlib import Path
@dataclass(frozen=True)
class CertificateFieldDefinition:
key: str
label: str
field_type: str
required: bool
example: str
description: str
def to_dict(self) -> dict[str, object]:
return {
"key": self.key,
"label": self.label,
"field_type": self.field_type,
"required": self.required,
"example": self.example,
"description": self.description,
}
@dataclass(frozen=True)
class CertificateTemplateDefinition:
code: str
name: str
description: str
asset_filename: str
dynamic_fields: tuple[str, ...]
fields: tuple[CertificateFieldDefinition, ...]
status: str = "active"
@property
def dynamic_fields(self) -> tuple[str, ...]:
return tuple(field.label for field in self.fields)
@property
def asset_path(self) -> Path:
return Path(__file__).resolve().parents[1] / "assets" / self.asset_filename
@@ -20,7 +44,8 @@ class CertificateTemplateDefinition:
"code": self.code,
"name": self.name,
"description": self.description,
"dynamic_fields": list(self.dynamic_fields),
"dynamic_fields": [field.label for field in self.fields],
"fields": [field.to_dict() for field in self.fields],
"preview_url": f"/api/admin/certificate-templates/{self.code}/preview",
"status": self.status,
}
@@ -35,14 +60,26 @@ CERTIFICATE_TEMPLATES = {
name="经典结业证书",
description="通用课程结业证书,正文包含课程名称、阶段、课程时间和发证日期。",
asset_filename="certificate-template.png",
dynamic_fields=("姓名", "课程名称", "阶段名称", "课程开始日期", "课程结束日期", "发证日期"),
fields=(
CertificateFieldDefinition("learner_name", "姓名", "text", True, "张三", "证书持有人真实姓名"),
CertificateFieldDefinition("course_name", "课程名称", "text", True, "智慧赋能疗愈师", "证书正文中的课程名称"),
CertificateFieldDefinition("stage_name", "阶段名称", "text", True, "初级", "证书正文中的课程阶段"),
CertificateFieldDefinition("course_start_date", "课程开始日期", "date", True, "2026-06-01", "课程实际开始日期"),
CertificateFieldDefinition("course_end_date", "课程结束日期", "date", True, "2026-06-30", "课程实际结束日期"),
CertificateFieldDefinition("issue_date", "发证日期", "date", True, "2026-07-05", "证书签发日期"),
),
),
PRACTICE_CAMP_TEMPLATE_CODE: CertificateTemplateDefinition(
code=PRACTICE_CAMP_TEMPLATE_CODE,
name="实修大本营结业证书",
description="人本智慧五个月线上实修大本营专用版,只填写姓名、课程开始日期、课程结束日期和发证日期。",
asset_filename="certificate-template-practice-camp.png",
dynamic_fields=("姓名", "课程开始日期", "课程结束日期", "发证日期"),
fields=(
CertificateFieldDefinition("learner_name", "姓名", "text", True, "张三", "证书持有人真实姓名"),
CertificateFieldDefinition("course_start_date", "课程开始日期", "date", True, "2026-03-01", "课程实际开始日期"),
CertificateFieldDefinition("course_end_date", "课程结束日期", "date", True, "2026-08-31", "课程实际结束日期"),
CertificateFieldDefinition("issue_date", "发证日期", "date", True, "2026-09-05", "证书签发日期"),
),
),
}
@@ -59,3 +96,7 @@ def get_certificate_template(code: str | None) -> CertificateTemplateDefinition:
if not template.asset_path.exists():
raise FileNotFoundError(f"证书模板图片不存在:{template.asset_filename}")
return template
def certificate_field_keys(template: CertificateTemplateDefinition) -> set[str]:
return {field.key for field in template.fields}