import { useEffect, useState } from "react"; import { getWechatMP, saveWechatMP, GATEWAY, type WechatMPConfig } from "../api"; // 运维 · 登录设置:微信公众号扫码登录(带参二维码 + 关注/扫码事件)。 // AppSecret 明文回显(单管理员后台,方便核对/复制;密文仍加密入库)。 export function LoginConfigPage() { const [cfg, setCfg] = useState(null); const [appid, setAppid] = useState(""); const [token, setToken] = useState(""); const [secret, setSecret] = useState(""); // 留空=沿用已存 const [welcome, setWelcome] = useState(""); const [busy, setBusy] = useState(false); const [err, setErr] = useState(""); const [ok, setOk] = useState(false); useEffect(() => { getWechatMP() .then((c) => { setCfg(c); setAppid(c.appid); setToken(c.token); setSecret(c.app_secret); setWelcome(c.welcome); }) .catch((e) => setErr((e as Error).message)); }, []); const save = async () => { if (busy) return; setBusy(true); setErr(""); setOk(false); try { const r = await saveWechatMP({ appid: appid.trim(), app_secret: secret, token: token.trim(), welcome: welcome.trim() }); setCfg((c) => (c ? { ...c, appid: appid.trim(), token: token.trim(), app_secret: secret, welcome: welcome.trim(), enabled: r.enabled } : c)); setOk(true); } catch (e) { setErr((e as Error).message); } finally { setBusy(false); } }; // 回调 URL 用当前后端地址推断(生产 GATEWAY 为空串=同源,显示成本域名) const origin = GATEWAY || (typeof window !== "undefined" ? window.location.origin : ""); const callbackURL = origin.replace(/:\d+$/, "") + "/wx/mp/callback"; return (

登录设置 · 微信扫码

公众号扫码登录(登录即引导关注)。AppSecret 加密入库、后台明文可见,随时可换

公众号配置

{cfg?.enabled ? ( 已启用 ) : ( 未启用(三项齐全才生效) )}