Files
Django/utils/pdd_order_validator.py

89 lines
3.2 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 datetime import date, timedelta
# 用户复制错误时的引导文案
PDD_ORDER_ID_HELP = (
'请在拼多多 App我的 → 我的订单 → 点开对应订单 → 复制「订单编号」后粘贴,'
'不要粘贴分享链接或网页地址。'
)
PDD_ORDER_ID_ERROR = '拼多多订单号格式不正确,' + PDD_ORDER_ID_HELP
def _parse_date_prefix(prefix: str):
"""解析订单号前 6 位 YYMMDD 或前 8 位 YYYYMMDD返回 date 或 None。"""
if len(prefix) >= 8 and prefix[:8].isdigit():
y = int(prefix[:4])
if 2010 <= y <= 2035:
m, d = int(prefix[4:6]), int(prefix[6:8])
try:
return date(y, m, d)
except ValueError:
pass
if len(prefix) >= 6 and prefix[:6].isdigit():
yy, m, d = int(prefix[:2]), int(prefix[2:4]), int(prefix[4:6])
y = 2000 + yy if yy < 100 else yy
try:
return date(y, m, d)
except ValueError:
return None
return None
def validate_pdd_order_id(raw: str) -> tuple[bool, str]:
"""
校验拼多多订单号。
允许字母数字组合(含国际单 XP 前缀等),拒绝 URL/链接/token 误填。
"""
order_id = str(raw or '').strip()
if not order_id:
return False, '拼多多订单号不能为空'
lower = order_id.lower()
if re.search(r'https?://', lower) or '://' in lower:
return False, '请勿粘贴网页链接,请填写拼多多订单编号。' + PDD_ORDER_ID_HELP
if '/' in order_id or '?' in order_id or '#' in order_id:
return False, PDD_ORDER_ID_ERROR
if re.search(r'(order|dingdan)/[a-z0-9]{8,}', lower):
return False, '检测到派单链接内容,请填写拼多多订单编号。' + PDD_ORDER_ID_HELP
if len(order_id) < 12 or len(order_id) > 32:
return False, PDD_ORDER_ID_ERROR
if not re.match(r'^[A-Za-z0-9\-]+$', order_id):
return False, PDD_ORDER_ID_ERROR
if not re.search(r'\d', order_id):
return False, PDD_ORDER_ID_ERROR
# 国际清关等 XP 前缀
if order_id.upper().startswith('XP'):
if len(order_id) < 10:
return False, PDD_ORDER_ID_ERROR
return True, ''
# 须以数字开头(常见为年份/日期段)
if not order_id[0].isdigit():
return False, PDD_ORDER_ID_ERROR
order_date = _parse_date_prefix(order_id)
if order_date is not None:
today = date.today()
if order_date > today + timedelta(days=1):
return False, '订单号日期异常(不能晚于今天),请核对拼多多订单编号。'
if order_date < today - timedelta(days=730):
return False, '订单号日期过旧,请核对是否为当前拼多多订单编号。'
return True, ''
def validate_cn_mobile(raw: str, required: bool = False) -> tuple[bool, str]:
"""中国大陆手机号校验;默认选填,空值通过。"""
phone = str(raw or '').strip()
if not phone:
if required:
return False, '手机号不能为空'
return True, ''
if not re.match(r'^1[3-9]\d{9}$', phone):
return False, '请输入正确的11位中国大陆手机号'
return True, ''