Browse Source

增加登录扫码相关交互

pull/14/head
zq 1 month ago
parent
commit
5bff69dfd5
  1. 183
      src/views/login.vue

183
src/views/login.vue

@ -4,8 +4,12 @@
<div class="index_rootContainer">
<b class="title">扫码登录</b>
<p class="sub_title mt32">打开 <b>微信</b> 扫码登录</p>
<div class=" mb32">
<vue-qr :text="url" :size="192" :dot-scale="1"></vue-qr>
<div class=" mb32" v-if="status == 'waiting'">
<vue-qr :text="qrCodeUrl" :size="192" :dot-scale="1"></vue-qr>
</div>
<div class="refreshCode" v-if="status == 'expired'" @click="refreshCode">
<i class="el-icon-refresh"></i>
刷新二维码
</div>
<!-- :logo-src="logoUrl"
:logo-scale="0.2" -->
@ -43,15 +47,155 @@ export default {
},
data() {
return {
url: 'https://example.com',
logoUrl: '/path/to/logo.png',
checked: false
checked: true,
qrCodeUrl: 'https://example.com',
token: '',
status: 'expired', // waiting, scanned, confirmed, expired, error
loginTime:'',
}
},
created(){
// this.generateQRCode()
},
beforeDestroy() {
this.clearTimers();
},
methods: {
jumpDoc() {
}
},
//
refreshCode() {
},
async generateQRCode() {
this.status = 'waiting';
this.qrCodeUrl = '';
try {
await this.$http('POST', '/api/admin/generate_qrcode', {
device_type: 'web',
timestamp: Date.now()
}).then(response => {
this.token = response.data.token;
this.qrCodeUrl = response.data.qr_code_url;
//
this.startPolling();
// 5
this.setExpireTimer();
}).catch(error => {
console.error('生成二维码失败:', error);
this.status = 'error';
});
} catch (error) {
console.error('生成二维码失败:', error);
this.status = 'error';
}
},
//
startPolling() {
this.clearTimers();
this.pollInterval = setInterval(async () => {
if (this.status === 'confirmed' || this.status === 'expired' || this.status === 'error') {
this.clearTimers();
return;
}
try {
await this.$http('POST', '/api/admin/check_scan_status', {
token: this.token
}).then(response => {
this.status = response.data.status;
if (response.data.status === 'scanned') {
//
setTimeout(() => {
this.handleLoginConfirm();
}, 2000);
} else if (response.data.status === 'confirmed') {
this.handleLoginSuccess(response.data);
} else if (response.data.status === 'expired') {
this.status = 'expired';
this.clearTimers();
}
}).catch(error => {
console.error('检查扫码状态失败:', error);
this.status = 'error';
this.clearTimers();
});
} catch (error) {
console.error('检查扫码状态失败:', error);
this.status = 'error';
this.clearTimers();
}
}, 2000);
},
//
async handleLoginConfirm() {
try {
await this.$http('POST', '/api/admin/confirm_login', {
token: this.token
}).then(response => {
if (response.data.success) {
this.handleLoginSuccess(response.data);
} else {
this.status = 'expired';
}
}).catch(error => {
console.error('登录确认失败:', error);
this.status = 'error';
});
} catch (error) {
console.error('登录确认失败:', error);
this.status = 'error';
}
},
//
handleLoginSuccess(data) {
this.status = 'confirmed';
this.userInfo = data.user_info;
this.loginTime = new Date().toLocaleString();
//
localStorage.setItem('authToken', data.auth_token);
localStorage.setItem('nick', JSON.stringify(data.nick));
localStorage.setItem('userInfo', JSON.stringify(data.user_info));
setTimeout(() => {
this.isLoggedIn = true;
this.$emit('login-success', data);
}, 1000);
},
//
setExpireTimer() {
this.expireTimer = setTimeout(() => {
if (this.status !== 'confirmed') {
this.status = 'expired';
this.clearTimers();
}
}, 5 * 60 * 1000); // 5
},
//
clearTimers() {
if (this.pollInterval) {
clearInterval(this.pollInterval);
this.pollInterval = null;
}
if (this.expireTimer) {
clearTimeout(this.expireTimer);
this.expireTimer = null;
}
},
}
}
</script>
@ -140,9 +284,34 @@ export default {
margin-bottom: 12px;
}
.refreshCode {
width: 172px;
height: 172px;
background: rgba(255, 255, 255, 0.3);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
border-radius: 12px;
border: 1px solid rgba(255, 255, 255, 0.2);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
display: flex;
flex-direction: column;
gap: 10px;
justify-content: center;
align-items: center;
color: #626573;
font-family: Arial, sans-serif;
font-weight: bold;
cursor: pointer;
margin: 20px auto;
i{
font-size: 28px;
}
}
@media(max-width: 1420px) {
.index_rootContainer {
margin-right: 102px
margin-right: 102px;
}
}

Loading…
Cancel
Save