fix: 扫码OAuth回调页改为'登录成功'自动确认,不再误导用户等待手动确认

This commit is contained in:
Simon
2026-07-08 22:00:17 +08:00
parent 400ce3ddcb
commit 9bb080d5f2
+23 -36
View File
@@ -236,59 +236,46 @@ async def scan_qrcode(
f"employee_id={result['employee_id']}, name={result['name']}" f"employee_id={result['employee_id']}, name={result['name']}"
) )
# GET 请求(企微 OAuth 回调)→ 重定向到前端选择页 # GET 请求(企微 OAuth 回调)→ 已自动确认,显示成功页 + 自动关闭
# 因为企微 OAuth 流程不在这个端点完成最终登录,只标记 scanned,
# 等用户在坐席端点 confirm 后才能拿到 token。
# 但企微 WebView 期望看到跳转后的页面,所以这里给个提示页。
from fastapi.responses import HTMLResponse from fastapi.responses import HTMLResponse
if final_code is not None and final_ticket is not None and body is None: if final_code is not None and final_ticket is not None and body is None:
# GET 模式:渲染一个 "扫码成功" 的 HTML 提示页 + 引导用户到登录页 user_name = result.get('name', '')
html = f"""<!DOCTYPE html> html = f"""<!DOCTYPE html>
<html lang="zh-CN"> <html lang="zh-CN">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>扫码成功 - IT智能服务台</title> <title>登录成功 - IT智能服务台</title>
<style> <style>
* {{ margin: 0; padding: 0; box-sizing: border-box; }} * {{ margin: 0; padding: 0; box-sizing: border-box; }}
body {{ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 20px; }} body {{ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: linear-gradient(135deg, #07C160 0%, #06AD56 100%); min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 20px; }}
.card {{ background: rgba(255,255,255,0.95); border-radius: 20px; padding: 48px 40px; max-width: 360px; width: 100%; text-align: center; box-shadow: 0 20px 60px rgba(0,0,0,0.3); }} .card {{ background: rgba(255,255,255,0.95); border-radius: 20px; padding: 48px 40px; max-width: 360px; width: 100%; text-align: center; box-shadow: 0 20px 60px rgba(0,0,0,0.3); }}
.logo {{ width: 80px; height: 80px; margin-bottom: 24px; }} .check {{ width: 64px; height: 64px; margin: 0 auto 16px; }}
.title {{ color: #1f2937; font-size: 28px; font-weight: 600; margin-bottom: 8px; }} .title {{ color: #1f2937; font-size: 24px; font-weight: 600; margin-bottom: 8px; }}
.subtitle {{ color: #6b7280; font-size: 14px; line-height: 1.6; margin-bottom: 24px; }} .subtitle {{ color: #6b7280; font-size: 14px; margin-bottom: 24px; }}
.status {{ display: inline-flex; align-items: center; gap: 8px; background: #dcfce7; color: #166534; padding: 12px 24px; border-radius: 50px; font-size: 14px; font-weight: 500; margin-bottom: 24px; }} .status {{ display: inline-flex; align-items: center; gap: 6px; background: #dcfce7; color: #166534; padding: 10px 20px; border-radius: 50px; font-size: 14px; font-weight: 500; }}
.spinner {{ width: 20px; height: 20px; border: 2px solid #86efac; border-top-color: #166534; border-radius: 50%; animation: spin 1s linear infinite; }}
@keyframes spin {{ to {{ transform: rotate(360deg); }} }}
.tips {{ background: #f3f4f6; border-radius: 12px; padding: 16px; text-align: left; }}
.tips-title {{ color: #374151; font-size: 13px; font-weight: 600; margin-bottom: 8px; }}
.tips-item {{ color: #6b7280; font-size: 12px; line-height: 1.8; display: flex; align-items: flex-start; gap: 6px; }}
.tips-item::before {{ content: ''; color: #9ca3af; }}
.footer {{ margin-top: 24px; color: #9ca3af; font-size: 12px; }} .footer {{ margin-top: 24px; color: #9ca3af; font-size: 12px; }}
</style> </style>
</head> </head>
<body> <body>
<div class="card"> <div class="card">
<svg class="logo" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg class="check" viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="80" height="80" rx="16" fill="#07C160"/> <circle cx="32" cy="32" r="30" fill="#07C160" stroke="#06AD56" stroke-width="4"/>
<path d="M24 40c0-8.837 7.163-16 16-16s16 7.163 16 16-7.163 16-16 16-16-7.163-16-16zm16 0c0 4.418 3.582 8 8 8s8-3.582 8-8-3.582-8-8-8-8-3.582-8-8z" fill="white"/> <path d="M20 32l8 8 16-16" stroke="white" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M24 28c0-6.627 5.373-12 12-12s12 5.373 12 12V40c0 6.627-5.373 12-12 12s-12-5.373-12-12z" fill="white" opacity="0.7"/>
<circle cx="40" cy="48" r="4" fill="white"/>
<rect x="36" y="54" width="8" height="12" rx="2" fill="white"/>
</svg> </svg>
<h1 class="title">扫码成功</h1> <h1 class="title">登录成功</h1>
<div class="status"> <div class="status">已自动确认登录</div>
<span class="spinner"></span> <p class="subtitle">你好,{user_name}<br>请返回电脑端查看</p>
等待确认登录... <div class="footer">页面可安全关闭 · 税友集团</div>
</div>
<p class="subtitle">请在电脑端的登录页面点击<br><strong style="color:#07C160">「确认登录」</strong> 按钮完成登录</p>
<div class="tips">
<div class="tips-title">📋 操作指引</div>
<div class="tips-item">已在电脑上打开登录页面</div>
<div class="tips-item">点击页面上的「确认登录」按钮</div>
<div class="tips-item">登录成功后可关闭此页面</div>
</div>
<div class="footer">IT智能服务台 · 税友集团</div>
</div> </div>
<script>
// 尝试关闭企微 WebView(如果支持的话)
setTimeout(function() {{
if (typeof wx !== 'undefined' && wx.closeWindow) {{
wx.closeWindow();
}}
}}, 1500);
</script>
</body> </body>
</html>""" </html>"""
return HTMLResponse(content=html, status_code=200) return HTMLResponse(content=html, status_code=200)