"""CPS 群发短链(cps_link)+ 点击事件(cps_click)。 群发券链接套一层我们自己的短链 `/c/{code}`:用户点 → 记一条 cps_click → 302 跳 target_url(美团短链,微信可打开)。据此统计点击 PV/UV(按群/活动/时段),配合 cps_order 的下单/佣金做"点击→下单→佣金"漏斗。group_id/sid 在 cps_click 里冗余一份,统计直接按 群聚合点击、不必 join cps_link。 """ from __future__ import annotations from datetime import datetime from sqlalchemy import DateTime, Integer, String, func from sqlalchemy.orm import Mapped, mapped_column from app.db.base import Base class CpsLink(Base): __tablename__ = "cps_link" id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) # 短码:发群链接 /c/{code} 的 code,全局唯一。 code: Mapped[str] = mapped_column(String(16), unique=True, index=True, nullable=False) group_id: Mapped[int] = mapped_column(Integer, index=True, nullable=False) activity_id: Mapped[int] = mapped_column(Integer, index=True, nullable=False) sid: Mapped[str] = mapped_column(String(64), index=True, nullable=False) platform: Mapped[str] = mapped_column(String(20), nullable=False, default="meituan") # 302 跳转目标(美团短链,微信内可打开并唤起 App)。 target_url: Mapped[str] = mapped_column(String(1024), nullable=False) created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), server_default=func.now(), nullable=False ) def __repr__(self) -> str: # pragma: no cover return f"" class CpsClick(Base): __tablename__ = "cps_click" id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) link_id: Mapped[int] = mapped_column(Integer, index=True, nullable=False) group_id: Mapped[int] = mapped_column(Integer, index=True, nullable=False) # 冗余,按群聚合快 sid: Mapped[str] = mapped_column(String(64), index=True, nullable=False) # 冗余 ip: Mapped[str | None] = mapped_column(String(64), nullable=True) ua: Mapped[str | None] = mapped_column(String(512), nullable=True) clicked_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), server_default=func.now(), index=True, nullable=False ) def __repr__(self) -> str: # pragma: no cover return f""