diff --git a/miniprogram/src/pages/mine/index.jsx b/miniprogram/src/pages/mine/index.jsx index 72867cf..454bed0 100644 --- a/miniprogram/src/pages/mine/index.jsx +++ b/miniprogram/src/pages/mine/index.jsx @@ -2,7 +2,7 @@ import { View, Text, Button, Input, Image } from '@tarojs/components'; import Taro from '@tarojs/taro'; import { useState, useEffect } from 'react'; import { useTabIndex } from '@/utils/tab'; -import { isAuthed, getUser, logout, wxLogin, phoneLogin, bindPhone, sendCode, wxPhoneBind, updateProfile, getMe, mpQrConfirm } from '@/utils/auth'; +import { isAuthed, getUser, logout, wxLogin, phoneLogin, bindPhone, sendCode, wxPhoneBind, updateProfile, getMe } from '@/utils/auth'; import { getMyBookings, checkIn, parseIso, BK_STATUS_OPTIONS, BK_TOPIC_OPTIONS, BK_SOURCE_OPTIONS } from '@/utils/booking'; import Skeleton from '@/components/skeleton'; import CountdownBox from '@/components/CountdownBox'; @@ -200,8 +200,6 @@ export default function Mine() { const [pTopics, setPTopics] = useState((user && user.topics) || []); const [pSource, setPSource] = useState((user && user.source) || ''); const [saving, setSaving] = useState(false); - const [scanBusy, setScanBusy] = useState(false); - const [scanErr, setScanErr] = useState(''); useEffect(() => { setPName((user && user.name) || ''); setPStatus((user && user.status) || ''); @@ -264,23 +262,6 @@ export default function Mine() { Taro.showToast({ title: '已退出登录', icon: 'none' }); }; - /* ============ 跨端口扫码登录:扫电脑/网页登录页二维码 → 小程序确认 ============ */ - const onScanLogin = async () => { - setScanErr(''); setScanBusy(true); - try { - const res = await Taro.scanCode(); // 扫其它端口登录页的「小程序扫码」二维码 - const str = res.result || ''; - const m = str.match(/[?&]scene=([^&#]+)/); // 二维码内容=跨端口 login url,含 scene - if (!m) throw new Error('无效的扫码登录二维码'); - const scene = decodeURIComponent(m[1]); - const { code } = await Taro.login(); // 微信登录 code - await mpQrConfirm(scene, code); // 确认 → 目标端口轮询取到登录令牌 - Taro.showToast({ title: '已登录目标端口,请回电脑/网页查看', icon: 'none' }); - } catch (e) { - setScanErr((e && e.message) || '扫码登录失败'); - } finally { setScanBusy(false); } - }; - /* ============ 未登录:登录入口 ============ */ if (!user || !isAuthed()) { return ( @@ -354,12 +335,10 @@ export default function Mine() { - {/* 跨端口扫码登录:扫电脑/网页登录页的「小程序扫码」二维码 → 用本小程序确认登录该端口 */} + {/* 跨端口扫码登录:由电脑/网页登录页展示「小程序码」,微信扫码自动进入小程序授权页确认 */} - 跨端口登录 - 在电脑/网页登录页点「小程序扫码」,用本小程序「扫一扫」即可登录该端口 - - {scanErr && {scanErr}} + 登录其它端 + 在电脑/网页登录页点「小程序扫码」,用微信扫一扫,进入小程序授权页确认即可登录 {/* 下一场活动倒计时(个人信息卡之后显示;取最早的待参加且未开始的报名场次) */} diff --git a/miniprogram/src/pages/scan-login/index.jsx b/miniprogram/src/pages/scan-login/index.jsx index 6857e71..8af2850 100644 --- a/miniprogram/src/pages/scan-login/index.jsx +++ b/miniprogram/src/pages/scan-login/index.jsx @@ -1,6 +1,6 @@ import { View, Text, Button, Input } from '@tarojs/components'; -import Taro, { useDidShow } from '@tarojs/taro'; -import { useState } from 'react'; +import Taro from '@tarojs/taro'; +import { useState, useEffect } from 'react'; import { isAuthed, wxLogin, phoneLogin, sendCode, mpQrConfirm } from '@/utils/auth'; import './index.scss'; @@ -20,13 +20,18 @@ export default function ScanLogin() { const [gateCode, setGateCode] = useState(''); const [cd, setCd] = useState(0); - useDidShow(() => { - const opts = Taro.getEnterOptionsSync(); - const q = (opts && opts.query) || {}; - const s = String(q.scene || opts.scene || ''); - setScene(s); - setDone(false); setMsg(''); - }); + // 冷启动/扫码进入:纯 React useEffect 读当前实例参数(wxacode 的 scene 在 router.params.scene)。 + // 不再用 useLoad/useDidShow 等 Taro 元钩子(其内部在原生计时器里调度 React hook,会触发 + // "Invalid attempt to destruct non-iterable" → 页面黑屏)。 + useEffect(() => { + try { + const inst = Taro.getCurrentInstance(); + const router = (inst && inst.router) || {}; + const params = (router && (router.params || router.query)) || {}; + const s = String(params.scene || router.scene || ''); + if (s) setScene(s); + } catch { /* 忽略取参异常 */ } + }, []); const wxLoginNow = async () => { setBusy(true); setMsg(''); @@ -47,7 +52,8 @@ export default function ScanLogin() { const r = await sendCode(gatePhone); setMsg(`验证码已发送${r.debugCode ? `(演示 ${r.debugCode})` : ''}`); setCd(60); - const t = window.setInterval(() => setCd((c) => (c <= 1 ? (window.clearInterval(t), 0) : c - 1)), 1000); + // 小程序无 window,用全局 setInterval/clearInterval(源码里 window.* 会导致运行时 ReferenceError) + const t = setInterval(() => setCd((c) => (c <= 1 ? (clearInterval(t), 0) : c - 1)), 1000); } catch (e) { setMsg((e && e.message) || '发送失败'); } finally { setBusy(false); } }; @@ -106,7 +112,7 @@ export default function ScanLogin() { {done ? '✓' : '✅'} {done ? '已完成' : '确认扫码操作'} - {done ? msg : `确认使用当前微信账号${scene.includes('bind') || true ? '' : ''}在你操作的端口${scene ? '' : ' '}完成登录 / 绑定?`} + {done ? msg : `确认使用当前微信账号在你操作的端口完成登录 / 绑定?`} {!done && scene && 请求 #{scene.slice(0, 12)}} {!done && (