智慧教务系统
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

331 lines
6.9 KiB

<template>
<view class="container">
<!-- 顶部导航 -->
<view class="nav-bar">
<view class="nav-title">微信账号绑定</view>
<view class="nav-close" @click="closePage">
<fui-icon name="close" :size="40" color="#333"></fui-icon>
</view>
</view>
<!-- 微信授权webview -->
<web-view
v-if="authUrl"
:src="authUrl"
@message="handleWebviewMessage"
@error="handleWebviewError">
</web-view>
<!-- 绑定表单 -->
<view class="bind-form" v-if="showBindForm">
<view class="form-title">完成账号绑定</view>
<view class="form-subtitle">请输入手机号和验证码完成绑定</view>
<view class="form-item">
<fui-input
placeholder="请输入手机号"
v-model="phone"
type="number"
backgroundColor="#f8f8f8">
</fui-input>
</view>
<view class="form-item">
<fui-input
placeholder="请输入验证码"
v-model="smsCode"
backgroundColor="#f8f8f8">
<fui-button
:background="canSendSms ? '#00be8c' : '#ccc'"
:disabled="!canSendSms"
width="200rpx"
height="60rpx"
:size="24"
@click="sendSmsCode">
{{ smsButtonText }}
</fui-button>
</fui-input>
</view>
<view class="form-item">
<fui-button
background="#00be8c"
radius="5rpx"
@click="submitBind"
:disabled="!canSubmit">
确认绑定
</fui-button>
</view>
</view>
</view>
</template>
<script>
import apiRoute from '@/api/apiRoute.js';
export default {
data() {
return {
authUrl: '',
miniOpenid: '',
wechatOpenid: '',
phone: '',
smsCode: '',
showBindForm: false,
smsCountdown: 0,
smsTimer: null
}
},
computed: {
canSendSms() {
return this.phone.length === 11 && this.smsCountdown === 0;
},
canSubmit() {
return this.phone.length === 11 && this.smsCode.length > 0 && this.wechatOpenid;
},
smsButtonText() {
return this.smsCountdown > 0 ? `${this.smsCountdown}s` : '获取验证码';
}
},
onLoad(options) {
this.authUrl = decodeURIComponent(options.auth_url || '');
this.miniOpenid = options.mini_openid || '';
if (!this.authUrl || !this.miniOpenid) {
uni.showToast({
title: '参数错误',
icon: 'none'
});
setTimeout(() => {
this.closePage();
}, 1500);
return;
}
// 监听URL变化,检测是否完成授权
this.checkAuthCallback();
},
onShow() {
// 页面显示时检查是否有授权回调参数
this.checkUrlParams();
},
onUnload() {
if (this.smsTimer) {
clearInterval(this.smsTimer);
}
},
methods: {
// 检查授权回调
checkAuthCallback() {
// 定时检查URL变化,模拟检测授权完成
setTimeout(() => {
// 模拟授权完成,显示绑定表单
// 实际项目中这里应该通过webview的URL变化或消息来判断
this.showBindFormWithDelay();
}, 3000); // 3秒后显示绑定表单,给用户足够时间完成微信授权
},
// 检查URL参数
checkUrlParams() {
// 这里可以检查页面参数,判断是否从微信授权回调返回
const pages = getCurrentPages();
const currentPage = pages[pages.length - 1];
if (currentPage && currentPage.options) {
const { code, state } = currentPage.options;
if (code && state) {
// 有授权回调参数,处理授权结果
this.handleAuthCallback(code, state);
}
}
},
// 延迟显示绑定表单
showBindFormWithDelay() {
// 模拟获取到微信公众号openid
this.wechatOpenid = 'mock_wechat_openid_' + Date.now();
this.showBindForm = true;
uni.showToast({
title: '微信授权成功,请完成绑定',
icon: 'success'
});
},
// 处理授权回调
async handleAuthCallback(code, state) {
try {
// 这里应该调用后端接口处理授权回调
// 暂时模拟处理
this.wechatOpenid = 'wechat_openid_from_callback';
this.showBindForm = true;
} catch (error) {
console.error('处理授权回调失败:', error);
uni.showToast({
title: '授权失败',
icon: 'none'
});
}
},
// 处理webview消息
handleWebviewMessage(event) {
console.log('收到webview消息:', event);
// 这里可以处理来自webview的消息
},
// 处理webview错误
handleWebviewError(event) {
console.error('webview错误:', event);
uni.showToast({
title: '授权页面加载失败',
icon: 'none'
});
},
// 发送短信验证码
async sendSmsCode() {
if (!this.canSendSms) return;
try {
const res = await apiRoute.common_forgetPassword({
phone: this.phone,
type: 'bind' // 绑定类型
});
if (res && res.code === 1) {
uni.showToast({
title: '验证码已发送',
icon: 'success'
});
this.startCountdown();
} else {
uni.showToast({
title: res.msg || '发送失败',
icon: 'none'
});
}
} catch (error) {
console.error('发送验证码失败:', error);
uni.showToast({
title: '发送失败,请重试',
icon: 'none'
});
}
},
// 开始倒计时
startCountdown() {
this.smsCountdown = 60;
this.smsTimer = setInterval(() => {
this.smsCountdown--;
if (this.smsCountdown <= 0) {
clearInterval(this.smsTimer);
this.smsTimer = null;
}
}, 1000);
},
// 提交绑定
async submitBind() {
if (!this.canSubmit) return;
try {
uni.showLoading({
title: '绑定中...'
});
const params = {
mini_openid: this.miniOpenid,
wechat_openid: this.wechatOpenid,
phone: this.phone,
code: this.smsCode
};
const res = await apiRoute.wechatBind(params);
uni.hideLoading();
if (res && res.code === 1) {
uni.showToast({
title: '绑定成功',
icon: 'success'
});
setTimeout(() => {
// 绑定成功后返回登录页面并自动登录
uni.navigateBack();
// 通知登录页面绑定成功
uni.$emit('wechatBindSuccess');
}, 1500);
} else {
uni.showToast({
title: res.msg || '绑定失败',
icon: 'none'
});
}
} catch (error) {
uni.hideLoading();
console.error('绑定失败:', error);
uni.showToast({
title: '绑定失败,请重试',
icon: 'none'
});
}
},
// 关闭页面
closePage() {
uni.navigateBack();
}
}
}
</script>
<style lang="less" scoped>
.container {
height: 100vh;
background-color: #fff;
}
.nav-bar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 20rpx 30rpx;
border-bottom: 1rpx solid #eee;
position: relative;
z-index: 999;
}
.nav-title {
font-size: 36rpx;
font-weight: bold;
color: #333;
}
.nav-close {
padding: 10rpx;
}
.bind-form {
padding: 60rpx 30rpx;
}
.form-title {
font-size: 48rpx;
font-weight: bold;
color: #333;
text-align: center;
margin-bottom: 20rpx;
}
.form-subtitle {
font-size: 28rpx;
color: #666;
text-align: center;
margin-bottom: 60rpx;
}
.form-item {
margin-bottom: 40rpx;
}
</style>