7fd70a264d
- 服务号网页授权(WX_MP_APPID/SECRET,区别于 App 的 WECHAT_APP_ID):
落地页 base 静默拿 openid;点「领券」补 userinfo 拿昵称头像(交互触发避快照页)
- 新表 cps_wx_user + cps_click 加 openid + 迁移;integrations/wx_oauth
- /c/{code} 授权链路 + 回调 /wx/oauth/cb + cookie 免重复授权;click 带 openid
- admin 群详情加「群内微信用户」(领券画像)端点
- 下单归因到人需 user-level sid,本期只做身份+领券侧
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
44 lines
1.4 KiB
Python
44 lines
1.4 KiB
Python
"""cps_wx_user 数据访问:按 openid upsert。"""
|
|
from __future__ import annotations
|
|
|
|
from sqlalchemy import func, select
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.models.cps_wx_user import CpsWxUser
|
|
|
|
|
|
def get_by_openid(db: Session, openid: str) -> CpsWxUser | None:
|
|
return db.execute(
|
|
select(CpsWxUser).where(CpsWxUser.openid == openid)
|
|
).scalar_one_or_none()
|
|
|
|
|
|
def upsert(
|
|
db: Session, *, openid: str, code: str | None = None, group_id: int | None = None,
|
|
nickname: str | None = None, headimgurl: str | None = None, unionid: str | None = None,
|
|
) -> CpsWxUser:
|
|
"""按 openid upsert。
|
|
|
|
- 首次:建行,记来源 code/group。
|
|
- 已存在:仅在传入非 None 时更新昵称/头像/unionid(base 阶段为 None,不覆盖已有画像);
|
|
并刷新 last_seen(显式 set,因 onupdate 仅在字段有变更时触发)。
|
|
"""
|
|
u = get_by_openid(db, openid)
|
|
if u is None:
|
|
u = CpsWxUser(
|
|
openid=openid, first_code=code, first_group_id=group_id,
|
|
nickname=nickname, headimgurl=headimgurl, unionid=unionid,
|
|
)
|
|
db.add(u)
|
|
else:
|
|
if nickname is not None:
|
|
u.nickname = nickname
|
|
if headimgurl is not None:
|
|
u.headimgurl = headimgurl
|
|
if unionid is not None:
|
|
u.unionid = unionid
|
|
u.last_seen = func.now()
|
|
db.commit()
|
|
db.refresh(u)
|
|
return u
|