"""手机号国际格式规范化。""" from __future__ import annotations import re from rest_framework import serializers _NON_DIGIT = re.compile(r"\D+") def normalize_phone(value: str | None, *, required: bool = False) -> str: """ 规范化为 E.164 风格:+ 后仅数字,例如 +8613800138000。 兼容历史国内 11 位号:1 开头则补 +86。 """ raw = (value or "").strip().replace(" ", "").replace("-", "").replace("(", "").replace(")", "") if not raw: if required: raise serializers.ValidationError("手机号必填") return "" if raw.startswith("+"): digits = _NON_DIGIT.sub("", raw[1:]) elif raw.isdigit() and len(raw) == 11 and raw.startswith("1"): # 兼容旧数据 / 未选区号的国内号 digits = "86" + raw else: raise serializers.ValidationError("请使用国际格式手机号,如 +8613800138000") if not digits or len(digits) < 6 or len(digits) > 15: raise serializers.ValidationError("手机号格式不正确") return f"+{digits}"