Files
certificate-system/backend/app/services/learner_identity.py
2026-08-14 11:37:09 +08:00

58 lines
1.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import re
from sqlalchemy.orm import Session
from app.models import Learner, LearnerNameHistory
class LearnerIdentityConflict(ValueError):
pass
def normalize_name(value: str) -> str:
return " ".join(value.strip().split())
def normalize_phone(value: str) -> str:
phone = re.sub(r"[\s-]", "", value.strip())
if phone.startswith("+86"):
phone = phone[3:]
elif phone.startswith("0086"):
phone = phone[4:]
if not re.fullmatch(r"1\d{10}", phone):
raise ValueError("手机号格式错误请填写11位中国大陆手机号")
return phone
def resolve_learner(
db: Session,
name: str,
phone: str,
*,
source: str,
create_if_missing: bool = True,
) -> tuple[Learner | None, bool]:
normalized_name = normalize_name(name)
normalized_phone = normalize_phone(phone)
if not normalized_name:
raise ValueError("姓名不能为空")
learner = db.query(Learner).filter(Learner.phone == normalized_phone, Learner.status != "deleted").first()
if learner:
if normalize_name(learner.current_name) != normalized_name:
raise LearnerIdentityConflict(
f"手机号 {normalized_phone} 已属于学员“{learner.current_name}”,与本次姓名“{normalized_name}”不一致"
)
if learner.status != "active":
raise LearnerIdentityConflict(f"学员“{normalized_name}”当前已停用,请先在学员管理中启用")
return learner, False
if not create_if_missing:
return None, False
learner = Learner(phone=normalized_phone, current_name=normalized_name)
db.add(learner)
db.flush()
db.add(LearnerNameHistory(learner_id=learner.id, name=normalized_name, source=source))
return learner, True