72 lines
2.3 KiB
JavaScript
72 lines
2.3 KiB
JavaScript
/**
|
|
* 识糖小课堂独立登录适配层。复用主小程序账号,但不依赖 tongji 其他页面代码。
|
|
*/
|
|
export function useGameAuth(proxy) {
|
|
let loginPromise = null
|
|
|
|
function hasToken() {
|
|
return !!String(uni.getStorageSync('token') || '').trim()
|
|
}
|
|
|
|
function clearToken() {
|
|
uni.removeStorageSync('token')
|
|
}
|
|
|
|
function wxLoginCode() {
|
|
return new Promise((resolve, reject) => {
|
|
uni.login({
|
|
provider: 'weixin',
|
|
success: (res) => res?.code ? resolve(res.code) : reject(new Error('微信登录未返回 code')),
|
|
fail: reject
|
|
})
|
|
})
|
|
}
|
|
|
|
async function loginWithCode(code) {
|
|
const res = await proxy.apiUrl({
|
|
url: '/api/login/mnpLogin',
|
|
method: 'POST',
|
|
data: { code }
|
|
}, false)
|
|
if (res?.code !== 1 || !res.data?.token) {
|
|
clearToken()
|
|
throw new Error(res?.msg || '登录失败')
|
|
}
|
|
uni.setStorageSync('token', res.data.token)
|
|
uni.setStorageSync('userData', res.data)
|
|
return true
|
|
}
|
|
|
|
async function verifyOrLogin() {
|
|
if (hasToken()) {
|
|
try {
|
|
const res = await proxy.apiUrl({ url: '/api/user/info', method: 'POST' }, false)
|
|
if (res?.code === 1 && res.data) {
|
|
uni.setStorageSync('userData', res.data)
|
|
return true
|
|
}
|
|
// 只有明确的登录失效才重新换取 token;其他业务错误先保留原登录。
|
|
if (res?.code !== -1) return true
|
|
} catch (_) {
|
|
// 断网不清除仍可能有效的 token,成绩由离线队列稍后补传。
|
|
return true
|
|
}
|
|
clearToken()
|
|
}
|
|
const code = await wxLoginCode()
|
|
return loginWithCode(code)
|
|
}
|
|
|
|
async function ensureLoggedIn() {
|
|
if (loginPromise) return loginPromise
|
|
loginPromise = verifyOrLogin()
|
|
.then(ok => !!ok)
|
|
.catch(() => false)
|
|
// 只合并同时发生的登录;成功结果不能永久缓存,否则 token 过期后无法恢复。
|
|
.finally(() => { loginPromise = null })
|
|
return loginPromise
|
|
}
|
|
|
|
return { ensureLoggedIn }
|
|
}
|