diff --git a/hy_qa_asset_backend/.env.example b/hy_qa_asset_backend/.env.example index 3b0939c..a58170d 100644 --- a/hy_qa_asset_backend/.env.example +++ b/hy_qa_asset_backend/.env.example @@ -16,3 +16,8 @@ SCHEDULE_CRON=0 1 * * * SCHEDULE_TIMEZONE=Asia/Shanghai MOCK_MODE=true + +# H5 WeChat OAuth. Leave empty to use the frontend demo authorization flow. +NEXT_PUBLIC_WECHAT_APP_ID= +NEXT_PUBLIC_WECHAT_AUTH_REDIRECT_URI= +NEXT_PUBLIC_WECHAT_AUTH_SCOPE=snsapi_userinfo diff --git a/hy_qa_asset_backend/frontend/components/h5/H5QAExperience.tsx b/hy_qa_asset_backend/frontend/components/h5/H5QAExperience.tsx index f7fdba3..37302d6 100644 --- a/hy_qa_asset_backend/frontend/components/h5/H5QAExperience.tsx +++ b/hy_qa_asset_backend/frontend/components/h5/H5QAExperience.tsx @@ -128,6 +128,20 @@ export default function H5QAExperience() { .finally(() => setLoadingQa(false)); }, []); + useEffect(() => { + const params = new URLSearchParams(window.location.search); + const code = params.get("code"); + const state = params.get("state"); + if (code && state === "hyqa_h5") { + setUser({ + mode: "wechat", + name: "微信已授权", + phone: "等待后端换取登录态" + }); + window.history.replaceState(null, "", window.location.pathname); + } + }, []); + useEffect(() => { bottomRef.current?.scrollIntoView({ behavior: "smooth", block: "end" }); }, [messages, activeTab]); @@ -141,6 +155,15 @@ export default function H5QAExperience() { setAuthOpen(false); } + function mockWechatLogin() { + setUser({ + mode: "wechat", + name: "微信用户", + phone: "微信授权演示" + }); + setAuthOpen(false); + } + function persistMessages(nextMessages: ChatMessage[]) { setMessages(nextMessages); setSessions((current) => { @@ -413,6 +436,7 @@ export default function H5QAExperience() { user={user} onClose={() => setAuthOpen(false)} onMockLogin={mockLogin} + onWechatMockLogin={mockWechatLogin} onLogout={() => { setUser(null); setAuthOpen(false); diff --git a/hy_qa_asset_backend/frontend/components/h5/MockAuthPanel.tsx b/hy_qa_asset_backend/frontend/components/h5/MockAuthPanel.tsx index bb7da90..26b0b18 100644 --- a/hy_qa_asset_backend/frontend/components/h5/MockAuthPanel.tsx +++ b/hy_qa_asset_backend/frontend/components/h5/MockAuthPanel.tsx @@ -1,11 +1,12 @@ "use client"; -import { LogIn, ShieldCheck, UserPlus, X } from "lucide-react"; +import { LogIn, MessageCircle, ShieldCheck, UserPlus, X } from "lucide-react"; +import { buildWechatOAuthUrl, getWechatAuthConfig, isWechatBrowser } from "@/lib/wechatAuth"; export type MockUser = { name: string; phone: string; - mode: "login" | "register"; + mode: "login" | "register" | "wechat"; }; export default function MockAuthPanel({ @@ -13,23 +14,36 @@ export default function MockAuthPanel({ user, onClose, onMockLogin, + onWechatMockLogin, onLogout }: { open: boolean; user: MockUser | null; onClose: () => void; onMockLogin: (mode: MockUser["mode"]) => void; + onWechatMockLogin: () => void; onLogout: () => void; }) { if (!open) return null; + const wechatConfig = getWechatAuthConfig(); + const inWechat = typeof navigator !== "undefined" && isWechatBrowser(navigator.userAgent); + + function startWechatAuth() { + if (wechatConfig) { + window.location.href = buildWechatOAuthUrl(wechatConfig); + return; + } + onWechatMockLogin(); + } + return (
先用 mock 登录,后续可替换为微信授权或手机号登录。
+优先预留微信授权;没有配置时使用演示账号。