feat: 云闪付入口 token 自动登录及权益状态恢复

- 新增 open-api/hhService/tokenDecode 封装,URL 带 token 时自动解码登录并刷新资格
- 解码失败降级为手机号登录,并用 replaceState 清除地址栏 token 防泄露
- 权益页已登录未认证时自动恢复认证状态,认证取消后停留认证页

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
jacobxu666
2026-08-27 15:17:08 +08:00
co-authored by Claude Haiku 4.5
parent 8d57cf7f92
commit 06e8223c27
4 changed files with 105 additions and 4 deletions
+50 -1
View File
@@ -212,11 +212,46 @@
this.lat = loc.lat
}
this.checkAuthResult()
// xuchao: 本地无认证缓存时自动查询后端恢复已认证状态
this.autoRecoverStatus()
if (this.status === 'info') {
this.loadRightsList()
}
},
methods: {
// xuchao: 已登录但本地无认证缓存时,仅传手机号查询资格以恢复状态(不带证件号,避免触发被动认证)
autoRecoverStatus() {
if (this.status !== 'auth') return
// xuchao: 用户主动发起过认证流程时,取消后应停留在认证页,不自动恢复
if (uni.getStorageSync('authFlowStarted')) return
const phone = uni.getStorageSync('phone')
if (!phone) return
this.$u.api.getEligibility({
phone: phone
}).then(res => {
if (res.errcode !== 0 || !res.data) return
uni.setStorageSync('isAuth', res.data.isAuth)
uni.setStorageSync('hasWin', res.data.hasWin)
uni.setStorageSync('cardNumber', res.data.cardNumber)
uni.setStorageSync('expiresTime', res.data.expiresTime)
// xuchao: 自动恢复成功,清除流程标记
uni.removeStorageSync('authFlowStarted')
if (res.data.isAuth) {
this.status = res.data.hasWin ? 'info' : 'noWin'
if (this.status === 'info') {
this.loadRightsList()
}
}
})
},
// xuchao: 认证取消/未通过:清理旧认证缓存并标记流程已发起,取消后应停留认证页
markAuthCanceled() {
uni.removeStorageSync('isAuth')
uni.removeStorageSync('hasWin')
uni.removeStorageSync('cardNumber')
uni.removeStorageSync('expiresTime')
uni.setStorageSync('authFlowStarted', true)
},
checkAuthResult() {
const url = new URL(window.location.href)
let responseStr = url.searchParams.get('response')
@@ -261,6 +296,8 @@
uni.setStorageSync('hasWin', eRes.data.hasWin)
uni.setStorageSync('cardNumber', eRes.data.cardNumber)
uni.setStorageSync('expiresTime', eRes.data.expiresTime)
// xuchao: 认证成功,清除流程标记
uni.removeStorageSync('authFlowStarted')
if (eRes.data.isAuth) {
this.status = eRes.data.hasWin ? 'info' : 'noWin'
if (this.status === 'info') {
@@ -270,6 +307,8 @@
}
})
} else {
// xuchao: 实名未通过视为取消认证,清理缓存并标记
this.markAuthCanceled()
uni.showToast({
title: '认证未通过',
icon: 'none'
@@ -288,6 +327,8 @@
})
})
} else {
// xuchao: 未返回认证回调视为取消认证,清理缓存并标记
this.markAuthCanceled()
uni.showToast({
title: '认证未通过',
icon: 'none'
@@ -324,6 +365,8 @@
}
uni.setStorageSync('authName', this.form.realName)
uni.setStorageSync('authIdNo', this.form.idNumber)
// xuchao: 标记已发起认证流程,取消后停留在认证页,不自动恢复
uni.setStorageSync('authFlowStarted', true)
this.loadAliyunSDK().then(() => {
const metaInfo = JSON.stringify(window.getMetaInfo())
const returnUrl = window.location.origin + window.location.pathname +
@@ -467,7 +510,13 @@
})
},
goBack() {
uni.navigateBack()
// xuchao: 直接通过链接进入(无历史栈)时回到首页
const pages = getCurrentPages()
if (pages.length > 1) {
uni.navigateBack()
} else {
uni.reLaunch({ url: '/pages/index/index' })
}
}
}
}