380 lines
9.3 KiB
Vue
380 lines
9.3 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';
|
||
import http from '@/request/request.js';
|
||
import pagesConfig from '@/pages.json';
|
||
|
||
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.exuid = params.exuid || '';
|
||
if(this.queryState) this.$store.dispatch('setCurrentUid', (params.state || '').replace(/^uid/, '') || '');
|
||
|
||
|
||
this.handleAuth();
|
||
},
|
||
onUnload() {
|
||
if (this._t) {
|
||
clearTimeout(this._t);
|
||
this._t = null;
|
||
}
|
||
},
|
||
methods: {
|
||
getBaseUrl() {
|
||
// return 'https://point.agrimedia.cn';
|
||
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 获取用户信息
|
||
http.get(`${baseUrl}/api/user`, null, {
|
||
header: { 'authori-zation': `Bearer ${this.Token}` }
|
||
}).then(this.handleUserInfo).catch(this.handleUserError);
|
||
} else if (this.code && this.queryState) {
|
||
// 场景2:淘宝授权回调(带 code + state)
|
||
http.get(`${baseUrl}/api/taobao/execute`, {
|
||
code: this.code,
|
||
state: this.queryState
|
||
}).then(res => {
|
||
const data = res.data || {};
|
||
this.setAuthData(data.relation_id, data.tbk_pid);
|
||
this.showSuccess('授权已完成,跳转中...');
|
||
}).catch(err => {
|
||
console.error('授权失败:', err);
|
||
const result = err.raw?.data;
|
||
const msg = result?.msg || result?.message || err.message || '授权处理失败,请重新授权';
|
||
this.showFail(msg);
|
||
});
|
||
} else if (this.exuid) {
|
||
// 场景3:三方uid授权
|
||
this.$store.dispatch('setIsThirdParty', true);
|
||
|
||
http.get(`${baseUrl}/api/taobao/third/relation_id`, {
|
||
uid: this.exuid
|
||
}).then(this.handleUserInfo).catch(this.handleUserError);
|
||
}else{
|
||
this.showFail('授权链接异常,请重新授权!');
|
||
}
|
||
},
|
||
|
||
handleUserInfo(res) {
|
||
const data = res.data || {};
|
||
const relationId = Number(data.relation_id);
|
||
const uid = data.uid;
|
||
const pid = data.tbk_pid;
|
||
if (relationId) {
|
||
// 其实无论是否授权过,都请求都会返回有值的 pid,但是只有授权过才能正常使用
|
||
this.setAuthData(relationId, pid);
|
||
|
||
// 此处为处理跳转指定页面逻辑
|
||
const app = getApp();
|
||
const params = app.globalData.urlParams || {};
|
||
if (params?.page_uri && this.isValidPagePath(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('获取用户信息失败!');
|
||
}
|
||
},
|
||
|
||
handleUserError(err) {
|
||
console.error('获取用户信息失败:', err);
|
||
const msg = err.raw?.data?.msg || err.raw?.data?.message || err.message || '获取用户信息失败,请检查网络';
|
||
this.showFail(msg);
|
||
},
|
||
|
||
setAuthData(relationId, pid) {
|
||
this.$store.dispatch('setRelationId', relationId);
|
||
this.$store.dispatch('setPid', pid || 'mm_284380119_1881450385_111415850448');
|
||
},
|
||
|
||
isValidPagePath(pageUri) {
|
||
if (!pageUri) return false;
|
||
let path = pageUri.startsWith('/') ? pageUri.slice(1) : pageUri;
|
||
const queryIndex = path.indexOf('?');
|
||
if (queryIndex !== -1) {
|
||
path = path.slice(0, queryIndex);
|
||
}
|
||
return pagesConfig.pages.some(page => page.path === path);
|
||
},
|
||
|
||
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);
|
||
this.goHome()
|
||
},
|
||
|
||
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>
|