import { postUserWxMiniAuth } from '@/api/user' import { saveAuthSession } from '@/utils/session' /** 微信开发者工具在游客模式/未登录等场景下返回的占位 code,不能用于 code2Session */ const WX_MOCK_LOGIN_CODE = 'the code is a mock one' function isValidWxLoginCode(code) { return typeof code === 'string' && code.length > 0 && code !== WX_MOCK_LOGIN_CODE && !/\s/.test(code) } /** 读取当前运行环境的小程序 AppID(以开发者工具/真机实际生效为准) */ function getRuntimeWxAppId() { // #ifdef MP-WEIXIN try { return wx.getAccountInfoSync?.()?.miniProgram?.appId || '' } catch { return '' } // #endif // #ifndef MP-WEIXIN return '' // #endif } function getWxLoginFailureTip(code) { const runtimeAppId = getRuntimeWxAppId() if (runtimeAppId === 'touristappid') { return '微信开发者工具处于游客模式,请切换为真实 AppID' } if (code === WX_MOCK_LOGIN_CODE) { if (!runtimeAppId) { return '请用微信开发者工具打开 dist/dev/mp-weixin 目录' } return '开发者工具未返回真实 code,请确认已登录微信且非游客模式' } return '未获取到微信登录凭证' } /** * 微信小程序:`wx.login` → `/user/wxMiniAuth` → 写入 token * @param {{ silent?: boolean }} [opts] silent=true:不触发全局 loading、不弹业务/网络失败 Toast(适合 App 启动静默登录) * @returns {Promise} 是否登录成功 */ export async function tryWxMiniProgramAuth(opts = {}) { const silent = opts.silent === true const reqExtra = silent ? { skipLoading: true, skipBizToast: true } : undefined const loginRes = await new Promise((resolve, reject) => { // #ifdef MP-WEIXIN wx.login({ success: resolve, fail: reject, }) // #endif // #ifndef MP-WEIXIN reject(new Error('仅支持微信小程序登录')) // #endif }) if (!isValidWxLoginCode(loginRes?.code)) { const runtimeAppId = getRuntimeWxAppId() console.warn('[wxMiniAuth] 无效登录凭证', { code: loginRes?.code, runtimeAppId, errMsg: loginRes?.errMsg, }) if (!silent) { uni.showToast({ title: getWxLoginFailureTip(loginRes?.code), icon: 'none', duration: 3500 }) } return false } const res = await postUserWxMiniAuth({ code: loginRes.code }, reqExtra) if (res && res.code === 200 && res.data) { saveAuthSession(res.data) return true } return false }