fix: need_purchase 时微信回复文案不再误报"授权成功"
handle_scan() 原先只返回场景是否绑定成功,导致无可用授权的用户扫码后 微信里收到"授权成功"、而 MFC 轮询拿到 need_purchase,提示不一致。 改为返回 authorized / need_purchase / invalid 三种结果,与 /auth/status 的 status 取值保持一致,wechat.py 据此选择回复文案。
This commit is contained in:
1 parent
ab1f2e68d3
commit
a798fbad60
2 files changed
+22
-12
No files matched your search
@@ -107,11 +107,14 @@ async def get_status(scene: str = Query(..., description="create_scene 返回的
|
|||||||
# 业务逻辑
|
# 业务逻辑
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
async def handle_scan(scene_str: str, openid: str) -> bool:
|
async def handle_scan(scene_str: str, openid: str) -> str:
|
||||||
"""
|
"""
|
||||||
处理扫码事件。
|
处理扫码事件,返回结果(取值与 /auth/status 的 status 一致):
|
||||||
|
|
||||||
|
- "authorized" 场景绑定成功,且用户有可用授权
|
||||||
|
- "need_purchase" 场景绑定成功,但用户没有可用授权(需充值)
|
||||||
|
- "invalid" 场景不存在、已过期,或已被处理过(重复扫码)
|
||||||
|
|
||||||
返回 True 表示本次扫码完成授权,False 表示场景无效、已过期或已被处理。
|
|
||||||
整个流程在事务内完成,并对 scene 行加排他锁,保证同一 scene 只被处理一次。
|
整个流程在事务内完成,并对 scene 行加排他锁,保证同一 scene 只被处理一次。
|
||||||
"""
|
"""
|
||||||
async with db.acquire() as conn:
|
async with db.acquire() as conn:
|
||||||
@@ -127,12 +130,12 @@ async def handle_scan(scene_str: str, openid: str) -> bool:
|
|||||||
|
|
||||||
if scene_row is None:
|
if scene_row is None:
|
||||||
await conn.rollback()
|
await conn.rollback()
|
||||||
return False
|
return "invalid"
|
||||||
|
|
||||||
if scene_row["status"] == "authorized":
|
if scene_row["status"] == "authorized":
|
||||||
# 重复扫码:只处理第一次,后续忽略
|
# 重复扫码:只处理第一次,后续忽略
|
||||||
await conn.rollback()
|
await conn.rollback()
|
||||||
return False
|
return "invalid"
|
||||||
|
|
||||||
if not scene_row["not_expired"]:
|
if not scene_row["not_expired"]:
|
||||||
await cur.execute(
|
await cur.execute(
|
||||||
@@ -141,10 +144,12 @@ async def handle_scan(scene_str: str, openid: str) -> bool:
|
|||||||
(scene_row["id"],),
|
(scene_row["id"],),
|
||||||
)
|
)
|
||||||
await conn.commit()
|
await conn.commit()
|
||||||
return False
|
return "invalid"
|
||||||
|
|
||||||
user_id = await _find_or_create_user(cur, openid)
|
user_id = await _find_or_create_user(cur, openid)
|
||||||
await _grant_free_authorization(cur, user_id)
|
await _grant_free_authorization(cur, user_id)
|
||||||
|
# 免费授权发完后仍无可用授权 → 需要充值(阶段 3)
|
||||||
|
has_auth = await _get_active_authorization(cur, user_id) is not None
|
||||||
|
|
||||||
await cur.execute(
|
await cur.execute(
|
||||||
"UPDATE auth_scenes SET status = 'authorized', user_id = %s, authorized_at = NOW() "
|
"UPDATE auth_scenes SET status = 'authorized', user_id = %s, authorized_at = NOW() "
|
||||||
@@ -160,8 +165,9 @@ async def handle_scan(scene_str: str, openid: str) -> bool:
|
|||||||
)
|
)
|
||||||
|
|
||||||
await conn.commit()
|
await conn.commit()
|
||||||
logger.info("扫码授权成功 scene_str=%s openid=%s", scene_str, openid)
|
result = "authorized" if has_auth else "need_purchase"
|
||||||
return True
|
logger.info("扫码完成 scene_str=%s openid=%s 结果=%s", scene_str, openid, result)
|
||||||
|
return result
|
||||||
except Exception:
|
except Exception:
|
||||||
await conn.rollback()
|
await conn.rollback()
|
||||||
raise
|
raise
|
||||||
|
|||||||
@@ -126,10 +126,14 @@ async def _handle_scan_event(
|
|||||||
# 无场景值的普通关注
|
# 无场景值的普通关注
|
||||||
return _reply_text(from_user, to_user, "欢迎关注!")
|
return _reply_text(from_user, to_user, "欢迎关注!")
|
||||||
|
|
||||||
authorized = await auth.handle_scan(scene_str, from_user)
|
result = await auth.handle_scan(scene_str, from_user)
|
||||||
if authorized:
|
if result == "authorized":
|
||||||
return _reply_text(from_user, to_user, "授权成功,请返回电脑端继续操作。")
|
reply = "授权成功,请返回电脑端继续操作。"
|
||||||
return _reply_text(from_user, to_user, "二维码已失效或已被使用,请在电脑端刷新后重新扫码。")
|
elif result == "need_purchase":
|
||||||
|
reply = "当前无可用授权,请返回电脑端按提示操作。"
|
||||||
|
else:
|
||||||
|
reply = "二维码已失效或已被使用,请在电脑端刷新后重新扫码。"
|
||||||
|
return _reply_text(from_user, to_user, reply)
|
||||||
|
|
||||||
|
|
||||||
def _parse_scene_key(event_key: str, is_subscribe: bool) -> str:
|
def _parse_scene_key(event_key: str, is_subscribe: bool) -> str:
|
||||||
|
|||||||
Reference in new issue
Block a user