fix(weixin): 二维码回退用qrUrl生成 + 每次点击重新发全新码(修'过期')
用户实测: qrcode原始串编码微信扫出纯字符串(qrcode得用qrUrl liteapp链接); 过期的真正原因 是复用旧二维码(微信码有效期极短)。修: 二维码改回用 qrUrl(liteapp链接)生成; StartLogin 把复用窗口从90s降到5s(仅防连点),否则每次'扫码登录/刷新'都取消旧会话重发全新码——永远新鲜可扫。 build/vet/test+前端build 全绿,已部署。
This commit is contained in:
1 parent
b6b258498c
commit
bef398d47a
2 files changed
+12
-10
No files matched your search
@@ -120,7 +120,7 @@ export function WeixinLogin({
|
||||
.finally(() => setBusy(null));
|
||||
};
|
||||
|
||||
const showQR = status === "waiting" || qrCode !== "";
|
||||
const showQR = status === "waiting" || qrUrl !== "";
|
||||
|
||||
return (
|
||||
<Surface gap="sm" className="space-y-3">
|
||||
@@ -147,8 +147,8 @@ export function WeixinLogin({
|
||||
|
||||
{showQR ? (
|
||||
<div className="space-y-2">
|
||||
{qrCode ? (
|
||||
<QrImage value={qrCode} />
|
||||
{qrUrl ? (
|
||||
<QrImage value={qrUrl} />
|
||||
) : (
|
||||
<Notice tone="warn">二维码暂不可用,请点击「刷新二维码」重试。</Notice>
|
||||
)}
|
||||
|
||||
@@ -51,10 +51,11 @@ type loginSession struct {
|
||||
done chan error
|
||||
}
|
||||
|
||||
// qrRefreshTTL bounds how long a WeChat bot QR is usable before StartLogin re-mints
|
||||
// a fresh one. iLink bot QRs are short-lived; an idempotent StartLogin must not keep
|
||||
// serving a long-expired QR (the user would scan it and get "二维码过期").
|
||||
const qrRefreshTTL = 90 * time.Second
|
||||
// qrReuseWindow is how long a just-minted QR is reused on an immediate re-click
|
||||
// before StartLogin re-mints a fresh one. WeChat bot QRs are short-lived, so a
|
||||
// "扫码登录/刷新二维码" click must yield a brand-new code — reusing an old QR is
|
||||
// exactly what makes WeChat report "二维码过期".
|
||||
const qrReuseWindow = 5 * time.Second
|
||||
|
||||
// StartLogin begins a scan-login and returns the QR code to display. It is
|
||||
// idempotent: when a login is already in progress it returns the current QR
|
||||
@@ -70,9 +71,10 @@ func (a *Adapter) StartLogin(ctx context.Context) (LoginQR, error) {
|
||||
return LoginQR{}, ErrAlreadyLoggedIn
|
||||
}
|
||||
if sess := a.loginSession; sess != nil {
|
||||
// Idempotent for a fresh QR, but re-mint once the current QR has aged past
|
||||
// qrRefreshTTL so the panel's 刷新二维码 always yields a scannable code.
|
||||
if time.Since(sess.startedAt) < qrRefreshTTL {
|
||||
// Reuse only within a tiny window (a literal double-click); otherwise re-mint
|
||||
// a brand-new QR so the panel's "扫码登录/刷新二维码" never serves a stale,
|
||||
// expired WeChat code. The old poll goroutine is cancelled.
|
||||
if time.Since(sess.startedAt) < qrReuseWindow {
|
||||
return LoginQR{Qrcode: sess.qrcode, Image: sess.image}, nil
|
||||
}
|
||||
if sess.cancel != nil {
|
||||
|
||||
Reference in new issue
Block a user