fix: need_purchase 时微信回复文案不再误报"授权成功"

handle_scan() 原先只返回场景是否绑定成功,导致无可用授权的用户扫码后
微信里收到"授权成功"、而 MFC 轮询拿到 need_purchase,提示不一致。

改为返回 authorized / need_purchase / invalid 三种结果,与 /auth/status
的 status 取值保持一致,wechat.py 据此选择回复文案。
This commit is contained in:
gjm committed 2026-09-26 23:58:20 +08:00
1 parent ab1f2e68d3
commit a798fbad60
2 files changed
+22 -12

No files matched your search

+14 -8
View File
@@ -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 只被处理一次。
"""
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:
await conn.rollback()
return False
return "invalid"
if scene_row["status"] == "authorized":
# 重复扫码:只处理第一次,后续忽略
await conn.rollback()
return False
return "invalid"
if not scene_row["not_expired"]:
await cur.execute(
@@ -141,10 +144,12 @@ async def handle_scan(scene_str: str, openid: str) -> bool:
(scene_row["id"],),
)
await conn.commit()
return False
return "invalid"
user_id = await _find_or_create_user(cur, openid)
await _grant_free_authorization(cur, user_id)
# 免费授权发完后仍无可用授权 → 需要充值(阶段 3)
has_auth = await _get_active_authorization(cur, user_id) is not None
await cur.execute(
"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()
logger.info("扫码授权成功 scene_str=%s openid=%s", scene_str, openid)
return True
result = "authorized" if has_auth else "need_purchase"
logger.info("扫码完成 scene_str=%s openid=%s 结果=%s", scene_str, openid, result)
return result
except Exception:
await conn.rollback()
raise
+8 -4
View File
@@ -126,10 +126,14 @@ async def _handle_scan_event(
# 无场景值的普通关注
return _reply_text(from_user, to_user, "欢迎关注!")
authorized = await auth.handle_scan(scene_str, from_user)
if authorized:
return _reply_text(from_user, to_user, "授权成功,请返回电脑端继续操作。")
return _reply_text(from_user, to_user, "二维码已失效或已被使用,请在电脑端刷新后重新扫码。")
result = await auth.handle_scan(scene_str, from_user)
if result == "authorized":
reply = "授权成功,请返回电脑端继续操作。"
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: