| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 |
- from urllib.parse import urlparse
- from sqlalchemy import select
- from sqlalchemy.ext.asyncio import AsyncSession
- from app.models.visitor import VisitorInfo
- from app.models.domain import MonitoredDomain
- from app.schemas.visitor import VisitorInfoCreate
- from app.services.sms import send_sms_code, generate_verify_code
- import logging
- logger = logging.getLogger(__name__)
- def _extract_domain_from_referer(referer: str | None) -> str | None:
- """从 Referer 头提取域名"""
- if not referer:
- return None
- try:
- parsed = urlparse(referer)
- host = parsed.hostname
- if not host:
- host = referer.strip().rstrip("/")
- if not host:
- return None
- netloc = parsed.netloc if parsed.netloc else host
- return host, netloc
- except Exception:
- return None
- async def store_visitor_info(
- db: AsyncSession, referer: str | None, payload: VisitorInfoCreate
- ) -> dict:
- """通过 Referer 匹配域名,存储联系人信息。同一域名覆盖更新。"""
- result = _extract_domain_from_referer(referer)
- if not result:
- return {"success": False, "message": "缺少或无效的 Referer 头"}
- referer_host, referer_netloc = result
- # 匹配监控域名(支持多种存储格式)
- domain_result = await db.execute(
- select(MonitoredDomain).where(
- MonitoredDomain.is_active == True,
- MonitoredDomain.domain.in_([
- referer_netloc,
- referer_host,
- f"http://{referer_netloc}",
- f"https://{referer_netloc}",
- ]),
- )
- )
- domain = domain_result.scalars().first()
- if not domain:
- return {"success": False, "message": "未找到匹配的域名"}
- # Upsert 联系人信息
- existing = await db.execute(
- select(VisitorInfo).where(VisitorInfo.domain_id == domain.id)
- )
- visitor = existing.scalar_one_or_none()
- if visitor:
- visitor.name = payload.name
- visitor.phone = payload.phone
- visitor.email = payload.email
- else:
- visitor = VisitorInfo(
- domain_id=domain.id,
- name=payload.name,
- phone=payload.phone,
- email=payload.email,
- )
- db.add(visitor)
- await db.commit()
- # 发送验证码短信,并将验证码返回给请求者
- code = None
- if payload.phone:
- code = generate_verify_code()
- await send_sms_code(payload.phone, code)
- return {"success": True, "message": "联系人信息已保存", "domain": domain.domain, "code": code}
|