"""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