370 lines
9.1 KiB
Vue
370 lines
9.1 KiB
Vue
<template>
|
||
<view class="auth-page">
|
||
<view class="auth-box">
|
||
<!-- 加载中 -->
|
||
<template v-if="status === 'loading'">
|
||
<view class="auth-icon">
|
||
<uni-icons type="spinner-cycle" size="72" color="#EC0208" class="spin-animation" />
|
||
</view>
|
||
<view class="auth-title">{{ title }}</view>
|
||
<view class="auth-desc">{{ desc }}</view>
|
||
</template>
|
||
|
||
<!-- 成功 -->
|
||
<template v-if="status === 'success'">
|
||
<view class="auth-icon">
|
||
<uni-icons type="checkmarkempty" size="72" color="#07c160" />
|
||
</view>
|
||
<view class="auth-title">{{ title }}</view>
|
||
<view class="auth-desc">{{ desc }}</view>
|
||
</template>
|
||
|
||
<!-- 失败 -->
|
||
<template v-if="status === 'fail'">
|
||
<view class="auth-icon">
|
||
<uni-icons type="closeempty" size="72" color="#ee0a24" />
|
||
</view>
|
||
<view class="auth-title">{{ title }}</view>
|
||
<view class="auth-desc">{{ desc }}</view>
|
||
</template>
|
||
|
||
<!-- 复制链接 -->
|
||
<template v-if="status === 'CopyUrl'">
|
||
<view class="auth-icon">
|
||
<uni-icons type="link" size="72" color="#1989fa" />
|
||
</view>
|
||
<view class="auth-title">{{ title }}</view>
|
||
<view class="auth-desc">{{ desc }}</view>
|
||
<button class="auth-btn auth-btn--primary" v-if="CopyLink" @click="copyText">
|
||
<uni-icons type="compose" size="16" color="#ffffff" />
|
||
<text class="btn-text">复制授权地址</text>
|
||
</button>
|
||
</template>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import { getEnvironment } from '@/utils/env.js';
|
||
|
||
export default {
|
||
data() {
|
||
return {
|
||
client_id: '30004725',
|
||
status: 'loading',
|
||
title: '正在完成授权...',
|
||
desc: '正在处理授权逻辑...',
|
||
CopyLink: false,
|
||
Token: '',
|
||
code: '',
|
||
queryState: '',
|
||
_t: null
|
||
}
|
||
},
|
||
computed: {
|
||
currentUid() {
|
||
return this.$store.getters.currentUid
|
||
}
|
||
},
|
||
onLoad() {
|
||
const app = getApp();
|
||
const params = app.globalData.urlParams || {};
|
||
|
||
this.Token = params.token || '';
|
||
this.code = params.code || '';
|
||
this.queryState = params.state || '';
|
||
this.$store.dispatch('setCurrentUid', (params.state || '').replace(/^uid/, '') || '')
|
||
|
||
this.handleAuth();
|
||
},
|
||
onUnload() {
|
||
if (this._t) {
|
||
clearTimeout(this._t);
|
||
this._t = null;
|
||
}
|
||
},
|
||
methods: {
|
||
getBaseUrl() {
|
||
return window.location.origin;
|
||
// // #ifdef H5
|
||
// return window.location.origin;
|
||
// // #endif
|
||
// // #ifndef H5
|
||
// // 非 H5 平台(小程序/App)需配置为已备案的 H5 域名
|
||
// return 'https://tpoint.agrimedia.cn';
|
||
// // #endif
|
||
},
|
||
|
||
handleAuth() {
|
||
const baseUrl = this.getBaseUrl();
|
||
if (this.Token) {
|
||
// 场景1:授权检测,通过 token 获取用户信息
|
||
uni.request({
|
||
url: baseUrl + '/api/user',
|
||
header: {
|
||
'authori-zation': `Bearer ${this.Token}`
|
||
},
|
||
success: (res) => {
|
||
if (res.statusCode === 200 && res.data) {
|
||
const data = res.data.data || {};
|
||
const relationId = data.relation_id;
|
||
const uid = data.uid;
|
||
if (relationId) {
|
||
// 已授权
|
||
this.$store.dispatch('setRelationId', relationId);
|
||
const app = getApp();
|
||
const params = app.globalData.urlParams || {};
|
||
if(params.page_uri) {
|
||
uni.navigateTo({
|
||
url: params.page_uri
|
||
});
|
||
}else{
|
||
this.goHome();
|
||
}
|
||
} else if (uid) {
|
||
// 未授权
|
||
this.$store.dispatch('setCurrentUid', uid);
|
||
this.Environment();
|
||
} else {
|
||
this.showFail('获取用户信息失败!');
|
||
}
|
||
} else {
|
||
this.showFail(res.data?.msg || res.data?.message || '获取用户信息失败');
|
||
}
|
||
},
|
||
fail: (err) => {
|
||
console.error('获取用户信息失败:', err);
|
||
this.showFail('获取用户信息失败,请检查网络');
|
||
}
|
||
});
|
||
} else if (this.code && this.queryState) {
|
||
// 场景2:淘宝授权回调(带 code + state)
|
||
uni.request({
|
||
url: baseUrl + '/api/taobao/execute',
|
||
data: {
|
||
code: this.code,
|
||
state: this.queryState
|
||
},
|
||
success: (res) => {
|
||
if (res.statusCode === 200 && res.data) {
|
||
const result = res.data;
|
||
// 兼容 status / code 两种业务状态码
|
||
const status = Number(result.status != null ? result.status : result.code);
|
||
if (status === 200 || status === 1) {
|
||
const data = result.data || {};
|
||
this.$store.dispatch('setRelationId', data.relation_id);
|
||
this.showSuccess('授权已完成,跳转中...');
|
||
} else {
|
||
this.showFail(result.msg || result.message || '授权处理失败,请重新授权');
|
||
}
|
||
} else {
|
||
this.showFail('授权处理失败,请重新授权');
|
||
}
|
||
},
|
||
fail: (err) => {
|
||
console.error('授权失败:', err);
|
||
this.showFail('授权处理失败,请重新授权');
|
||
}
|
||
});
|
||
} else {
|
||
this.showFail('授权链接异常,请重新授权!');
|
||
// this.$store.dispatch('setRelationId', '123456789');
|
||
// this.showSuccess('授权已完成,跳转中...');
|
||
}
|
||
},
|
||
|
||
goHome() {
|
||
if (this._t) {
|
||
clearTimeout(this._t);
|
||
this._t = null;
|
||
};
|
||
|
||
uni.reLaunch({
|
||
url: '/pages/index/index'
|
||
});
|
||
// const url = '/affiliate-activity/pages/index/index';
|
||
|
||
// // #ifdef H5
|
||
// window.location.href = url;
|
||
// return;
|
||
// // #endif
|
||
|
||
// uni.reLaunch({
|
||
// url: url
|
||
// });
|
||
},
|
||
|
||
showFail(message) {
|
||
this.status = 'fail';
|
||
this.title = '授权失败';
|
||
this.desc = message || '请重新授权或返回首页';
|
||
},
|
||
|
||
showSuccess(message) {
|
||
this.status = 'success';
|
||
this.title = '授权成功';
|
||
this.desc = message;
|
||
this._t = setTimeout(() => this.goHome(), 500);
|
||
},
|
||
|
||
CopyStatus(message) {
|
||
this.status = 'CopyUrl';
|
||
this.title = '';
|
||
this.desc = message || '请点击下方按钮复制授权地址';
|
||
},
|
||
|
||
Environment() {
|
||
const env = getEnvironment();
|
||
const uid = `uid${this.currentUid}`;
|
||
const redirectUri = this.getRedirectUri();
|
||
const authUrl = `https://oauth.taobao.com/authorize?response_type=code&client_id=${this.client_id}&redirect_uri=${encodeURIComponent(redirectUri)}&state=${uid}&view=wap`;
|
||
|
||
if (env.isBrowser || env.isAppWebview) {
|
||
// 浏览器/APP WebView:直接跳转授权
|
||
// #ifdef H5
|
||
window.location.href = authUrl;
|
||
// #endif
|
||
|
||
// #ifdef APP-PLUS
|
||
plus.runtime.openURL(authUrl);
|
||
// #endif
|
||
} else if (env.isWechatWebview || env.isWechatH5 || env.isWechatMiniProgram) {
|
||
// 微信/小程序环境:显示复制按钮
|
||
this.CopyStatus('请复制授权地址到浏览器打开');
|
||
this.CopyLink = true;
|
||
} else {
|
||
// 其他平台默认显示复制按钮
|
||
this.CopyStatus('请复制授权地址到浏览器打开');
|
||
this.CopyLink = true;
|
||
}
|
||
},
|
||
|
||
copyText() {
|
||
const uid = `uid${this.currentUid}`;
|
||
const redirectUri = this.getRedirectUri();
|
||
const text = `https://oauth.taobao.com/authorize?response_type=code&client_id=${this.client_id}&redirect_uri=${encodeURIComponent(redirectUri)}&state=${uid}&view=wap`;
|
||
|
||
uni.setClipboardData({
|
||
data: text,
|
||
success: () => {
|
||
uni.showToast({
|
||
title: '授权链接已复制',
|
||
icon: 'success'
|
||
});
|
||
},
|
||
fail: () => {
|
||
uni.showToast({
|
||
title: '复制失败,请手动复制',
|
||
icon: 'none'
|
||
});
|
||
}
|
||
});
|
||
},
|
||
|
||
getRedirectUri() {
|
||
const baseUrl = this.getBaseUrl();
|
||
return baseUrl + '/affiliate-activity/pages/auth/auth';
|
||
},
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.auth-page {
|
||
min-height: 100vh;
|
||
background: linear-gradient(180deg, #f0f2f5 0%, #f7f8fa 100%);
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 60rpx;
|
||
}
|
||
|
||
.auth-box {
|
||
background: #ffffff;
|
||
border-radius: 24rpx;
|
||
padding: 100rpx 56rpx 80rpx;
|
||
width: 100%;
|
||
max-width: 640rpx;
|
||
text-align: center;
|
||
box-shadow: 0 8rpx 40rpx rgba(0, 0, 0, 0.06);
|
||
}
|
||
|
||
.auth-icon {
|
||
margin: 0 auto 40rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
height: 100rpx;
|
||
}
|
||
|
||
.spin-animation {
|
||
animation: spin 1.2s linear infinite;
|
||
}
|
||
|
||
@keyframes spin {
|
||
0% {
|
||
transform: rotate(0deg);
|
||
}
|
||
|
||
100% {
|
||
transform: rotate(360deg);
|
||
}
|
||
}
|
||
|
||
.auth-title {
|
||
font-size: 44rpx;
|
||
color: #1a1a1a;
|
||
margin: 24rpx 0 20rpx;
|
||
font-weight: 600;
|
||
letter-spacing: 2rpx;
|
||
}
|
||
|
||
.auth-desc {
|
||
font-size: 28rpx;
|
||
color: #666666;
|
||
margin-bottom: 56rpx;
|
||
line-height: 1.8;
|
||
padding: 0 20rpx;
|
||
}
|
||
|
||
.auth-btn {
|
||
margin-top: 32rpx;
|
||
height: 96rpx;
|
||
line-height: 96rpx;
|
||
background: #ffffff;
|
||
color: #333333;
|
||
border: 2rpx solid #e0e0e0;
|
||
border-radius: 48rpx;
|
||
font-size: 30rpx;
|
||
padding: 0 48rpx;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 12rpx;
|
||
transition: all 0.2s ease;
|
||
}
|
||
|
||
.auth-btn:active {
|
||
transform: scale(0.98);
|
||
opacity: 0.9;
|
||
}
|
||
|
||
.auth-btn::after {
|
||
border: none;
|
||
}
|
||
|
||
.auth-btn--primary {
|
||
background: linear-gradient(135deg, #ff715a, #ff416c);
|
||
color: #ffffff;
|
||
border: none;
|
||
box-shadow: 0 8rpx 24rpx rgba(255, 65, 108, 0.25);
|
||
}
|
||
|
||
.btn-text {
|
||
color: inherit;
|
||
font-size: 30rpx;
|
||
font-weight: 500;
|
||
}
|
||
</style>
|