196 lines
4.2 KiB
Vue
196 lines
4.2 KiB
Vue
<template>
|
||
<view class="page">
|
||
<view class="content">
|
||
<view v-if="loading" class="text">
|
||
正在为您领取权益,请稍候…
|
||
</view>
|
||
<view v-else>
|
||
<view class="result-icon success" v-if="success">
|
||
领取成功
|
||
</view>
|
||
<view class="result-icon fail" v-else>
|
||
领取失败
|
||
</view>
|
||
<view class="text msg">
|
||
{{ message }}
|
||
</view>
|
||
<button class="back-btn" type="primary" @click="goBack">
|
||
返回会员中心
|
||
</button>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
export default {
|
||
data() {
|
||
return {
|
||
loading: true, // 是否加载中 / 正在领取
|
||
success: false, // 是否领取成功
|
||
message: '' // 提示文案
|
||
}
|
||
},
|
||
onLoad(options) {
|
||
this.handleParams(options || {})
|
||
},
|
||
methods: {
|
||
// 解析二维码/链接参数,获取编码
|
||
handleParams(options) {
|
||
let code = ''
|
||
|
||
// 直接带 code 参数
|
||
if (options.code) {
|
||
code = options.code
|
||
} else if (options.q) {
|
||
// 微信扫码普通二维码时通常是 q 参数,需要先 decode
|
||
const q = decodeURIComponent(options.q)
|
||
// 兼容两种情况:
|
||
// 1. q 为完整链接,形如 xxx?c=XXX
|
||
// 2. q 就是编码本身
|
||
const match = q.match(/c=([^&]+)/)
|
||
code = match ? match[1] : q
|
||
}
|
||
|
||
if (!code) {
|
||
this.loading = false
|
||
this.success = false
|
||
this.message = '未获取到兑换编码,请确认二维码是否正确'
|
||
return
|
||
}
|
||
|
||
this.useGiftCode(code)
|
||
},
|
||
|
||
// 静默登录(仅用 wx.login 的 code 换 token,不弹授权)
|
||
silentLogin() {
|
||
return new Promise((resolve) => {
|
||
// #ifdef MP-WEIXIN
|
||
wx.login({
|
||
success: (res) => {
|
||
if (!res.code) {
|
||
resolve(false)
|
||
return
|
||
}
|
||
const data = { loginCode: res.code, appId: this.$store.state.appid }
|
||
this.$u.post('/wxLogin', data).then((loginRes) => {
|
||
if (loginRes.code === 200) {
|
||
uni.setStorageSync('token', loginRes.token)
|
||
resolve(true)
|
||
} else {
|
||
resolve(false)
|
||
}
|
||
}).catch(() => resolve(false))
|
||
},
|
||
fail: () => resolve(false)
|
||
})
|
||
// #endif
|
||
// #ifndef MP-WEIXIN
|
||
resolve(false)
|
||
// #endif
|
||
})
|
||
},
|
||
|
||
// 跳转到登录页,登录成功后带参数回到本页重新领取
|
||
goLoginWithRedirect(code) {
|
||
const backUrl = '/page_user/yonghuewmlq?code=' + encodeURIComponent(code)
|
||
uni.navigateTo({
|
||
url: '/pages/login/login?redirect=' + encodeURIComponent(backUrl)
|
||
})
|
||
},
|
||
|
||
// 调用领取接口
|
||
useGiftCode(code) {
|
||
this.loading = true
|
||
this.$u.post(`/app/vipUser/useGiftCode?code=${encodeURIComponent(code)}`).then(res => {
|
||
if (res.code === 200) {
|
||
this.loading = false
|
||
this.success = true
|
||
this.message = res.msg || '领取成功,已发放至您的会员账户'
|
||
return
|
||
}
|
||
if (res.code === 401) {
|
||
// 先尝试静默登录,再决定是否跳登录页
|
||
this.silentLogin().then((silentOk) => {
|
||
if (silentOk) {
|
||
// 静默登录成功,用新 token 再领一次
|
||
this.useGiftCode(code)
|
||
} else {
|
||
this.loading = false
|
||
this.goLoginWithRedirect(code)
|
||
}
|
||
})
|
||
return
|
||
}
|
||
this.loading = false
|
||
this.success = false
|
||
this.message = res.msg || '领取失败,请稍后再试'
|
||
})
|
||
.catch(() => {
|
||
this.loading = false
|
||
this.success = false
|
||
this.message = '网络异常,请稍后重试'
|
||
})
|
||
},
|
||
|
||
// 返回会员中心
|
||
goBack() {
|
||
uni.navigateTo({
|
||
url: '/page_fenbao/huiyuan/myhuiyuan?tyep=99'
|
||
})
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.page {
|
||
min-height: 100vh;
|
||
background: #f7f8fa;
|
||
display: flex;
|
||
justify-content: center;
|
||
}
|
||
|
||
.content {
|
||
width: 640rpx;
|
||
padding: 60rpx 40rpx 80rpx;
|
||
border-radius: 24rpx;
|
||
text-align: center;
|
||
margin-top: 300rpx;
|
||
}
|
||
|
||
.result-icon {
|
||
font-size: 40rpx;
|
||
font-weight: 600;
|
||
margin-bottom: 24rpx;
|
||
}
|
||
|
||
.result-icon.success {
|
||
color: #19be6b;
|
||
}
|
||
|
||
.result-icon.fail {
|
||
color: #fa3534;
|
||
}
|
||
|
||
.text {
|
||
font-size: 28rpx;
|
||
color: #606266;
|
||
line-height: 1.6;
|
||
}
|
||
|
||
.msg {
|
||
margin-bottom: 40rpx;
|
||
}
|
||
|
||
.back-btn {
|
||
width: 100%;
|
||
height: 88rpx;
|
||
line-height: 88rpx;
|
||
border-radius: 44rpx;
|
||
background: #2979ff;
|
||
color: #ffffff;
|
||
font-size: 30rpx;
|
||
margin-top: 200rpx;
|
||
}
|
||
</style> |