feat : 新增一体机支付宝扫码登录页

This commit is contained in:
2025-12-16 16:51:56 +08:00
parent 77dfab84f1
commit 4a03b4d4cb
3 changed files with 787 additions and 246 deletions

View File

@@ -1,6 +1,6 @@
export default {
baseUrl: 'https://fw.rc.qingdao.gov.cn/rgpp-api/api', // 内网
// baseUrl: 'https://qd.zhaopinzao8dian.com/api', // 测试
// baseUrl: 'https://fw.rc.qingdao.gov.cn/rgpp-api/api', // 内网
baseUrl: 'https://qd.zhaopinzao8dian.com/api', // 测试
// baseUrl: 'http://192.168.3.29:8081',
// baseUrl: 'http://10.213.6.207:19010/api',
// 语音转文字

View File

@@ -1,6 +1,53 @@
<template>
<AppLayout title="就业服务程序">
<tabcontrolVue :current="tabCurrent">
<!-- 扫码登录-->
<view class="alipay-login-container" v-if="isMachineEnv">
<view class="login-scan-area">
<view class="login-title">支付宝扫码登录</view>
<view class="qrcode-container">
<view class="qrcode-wrapper" @click="refreshQrcode">
<view class="qrcode-border">
<view class="qrcode-content">
<view class="qrcode-pattern">
<image class="qrcode-img" src="@/static/icon/qrcode-example.png" mode="scaleToFill" />
<view class="qrcode-corner top-left"></view>
<view class="qrcode-corner top-right"></view>
<view class="qrcode-corner bottom-left"></view>
<view class="scan-line" :style="{ top: scanLineTop + 'rpx' }"></view>
</view>
<!-- 二维码过期提示 -->
<view v-if="qrcodeExpired" class="expired-overlay">
<text class="expired-text">二维码已过期</text>
<view class="refresh-btn" @click.stop="refreshQrcode">
<text class="refresh-text">点击刷新</text>
</view>
</view>
</view>
</view>
<view class="qrcode-tips">
<text class="tips-text">使用支付宝扫一扫登录</text>
<text class="tips-subtext">扫一扫后点击确认完成登录</text>
</view>
</view>
</view>
<!-- 刷新提示 -->
<view class="refresh-tips" v-if="countdown > 0">
<view class="countdown-text"><span class="countdown-num">{{ countdown }}</span> 秒后二维码过期</view>
</view>
</view>
<!-- 扫码成功提示 -->
<view v-if="showSuccessTip" class="success-tip">
<view class="success-content">
<view class="success-icon"></view>
<text class="success-text">登录成功</text>
</view>
</view>
</view>
<!-- 正常登录-->
<tabcontrolVue v-else :current="tabCurrent">
<template v-slot:tab0>
<view class="login-content">
<image class="logo" src="@/static/logo.png"></image>
@@ -75,12 +122,7 @@
</view>
<view class="content-input" @click="changeArea">
<view class="input-titile">求职区域</view>
<input
class="input-con"
v-model="state.areaText"
disabled
placeholder="请选择您的求职区域"
/>
<input class="input-con" v-model="state.areaText" disabled placeholder="请选择您的求职区域" />
</view>
<view class="content-input" @click="changeJobs">
<view class="input-titile">求职岗位</view>
@@ -96,12 +138,7 @@
</view>
<view class="content-input" @click="changeSalay">
<view class="input-titile">期望薪资</view>
<input
class="input-con"
v-model="state.salayText"
disabled
placeholder="请选择您的期望薪资"
/>
<input class="input-con" v-model="state.salayText" disabled placeholder="请选择您的期望薪资" />
</view>
</view>
<view class="next-btn" @tap="complete">开启求职之旅</view>
@@ -117,14 +154,16 @@
</template>
<script setup>
import { storeToRefs } from 'pinia';
import tabcontrolVue from './components/tabcontrol.vue';
import SelectJobs from '@/components/selectJobs/selectJobs.vue';
import { reactive, inject, watch, ref, onMounted } from 'vue';
import { reactive, inject, watch, ref, onMounted, onUnmounted } from 'vue';
import { onLoad, onShow } from '@dcloudio/uni-app';
import useUserStore from '@/stores/useUserStore';
import useDictStore from '@/stores/useDictStore';
const { $api, navTo } = inject('globalFunction');
const { loginSetToken, getUserResume } = useUserStore();
const { isMachineEnv } = storeToRefs(useUserStore());
const { getDictSelectOption, oneDictData } = useDictStore();
const openSelectPopup = inject('openSelectPopup');
// status
@@ -152,12 +191,71 @@ const fromValue = reactive({
experience: '1',
});
// 扫码登录相关状态
const qrcodeExpired = ref(false);
const scanLineTop = ref(0);
const countdown = ref(0);
let scanInterval = null;
let countdownTimer = null;
// 登录成功提示
const showSuccessTip = ref(false);
onLoad((parmas) => {
getTreeselect();
$api.msg('请完善微简历');
if(!isMachineEnv.value) $api.msg('请完善微简历');
});
onMounted(() => {});
onMounted(() => {
startScanAnimation();
resetCountdown();
// 模拟扫码成功
setTimeout(() => {
// showSuccessTip.value=true
}, 5000);
});
onUnmounted(() => {
showSuccessTip.value = false;
stopScanAnimation();
clearInterval(countdownTimer);
});
// 刷新二维码
const refreshQrcode = () => {
qrcodeExpired.value = false;
resetCountdown();
startScanAnimation();
// TODO
};
// 重置倒计时
const resetCountdown = () => {
countdown.value = 60;
clearInterval(countdownTimer);
countdownTimer = setInterval(() => {
if (countdown.value > 0) {
countdown.value--;
} else {
qrcodeExpired.value = true;
clearInterval(countdownTimer);
stopScanAnimation()
}
}, 1000);
};
// 开始扫描动画
const startScanAnimation = () => {
clearInterval(scanInterval);
scanInterval = setInterval(() => {
scanLineTop.value = (scanLineTop.value + 2) % 300;
}, 30);
};
// 停止扫描动画
const stopScanAnimation = () => {
clearInterval(scanInterval);
};
function changeSex(sex) {
fromValue.sex = sex;
@@ -311,6 +409,449 @@ function complete() {
}
</script>
<style lang="scss" scoped>
.alipay-login-container {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
/* 扫码登录区域样式 */
.login-scan-area {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
padding: 0 40rpx;
}
.login-title {
font-size: 36rpx;
font-weight: 600;
color: #1677ff;
margin-bottom: 40rpx;
text-align: center;
}
.qrcode-container {
width: 100%;
display: flex;
justify-content: center;
margin-bottom: 40rpx;
}
.qrcode-wrapper {
display: flex;
flex-direction: column;
align-items: center;
}
.qrcode-border {
width: 400rpx;
height: 400rpx;
background-color: #fff;
border-radius: 20rpx;
padding: 20rpx;
box-shadow: 0 8rpx 30rpx rgba(22, 119, 255, 0.1);
margin-bottom: 30rpx;
position: relative;
}
.qrcode-content {
width: 100%;
height: 100%;
background-color: #f8f8f8;
border-radius: 10rpx;
display: flex;
align-items: center;
justify-content: center;
position: relative;
overflow: hidden;
}
.qrcode-pattern {
width: 300rpx;
height: 300rpx;
background-color: #fff;
position: relative;
}
.qrcode-img{
width: 100%;
height:100%;
}
.qrcode-corner {
position: absolute;
width: 60rpx;
height: 60rpx;
border: 6rpx solid #1677ff;
&.top-left {
top: 0;
left: 0;
border-right: none;
border-bottom: none;
border-radius: 10rpx 0 0 0;
}
&.top-right {
top: 0;
right: 0;
border-left: none;
border-bottom: none;
border-radius: 0 10rpx 0 0;
}
&.bottom-left {
bottom: 0;
left: 0;
border-right: none;
border-top: none;
border-radius: 0 0 0 10rpx;
}
}
.scan-line {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 6rpx;
background: linear-gradient(90deg, transparent, #1677ff, transparent);
z-index: 10;
}
.expired-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.7);
border-radius: 10rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
z-index: 20;
}
.expired-text {
font-size: 32rpx;
color: #fff;
margin-bottom: 30rpx;
}
.refresh-btn {
padding: 16rpx 40rpx;
background-color: #1677ff;
border-radius: 50rpx;
}
.refresh-text {
font-size: 28rpx;
color: #fff;
}
.qrcode-tips {
display: flex;
flex-direction: column;
align-items: center;
}
.tips-text {
font-size: 28rpx;
color: #333;
margin-bottom: 10rpx;
}
.tips-subtext {
font-size: 24rpx;
color: #666;
}
.refresh-tips {
margin-bottom: 40rpx;
}
.countdown-text {
font-size: 24rpx;
color: #999;
display: flex;
align-items: center;
}
.countdown-num{
margin-right: 5rpx;
color: #1677ff;
font-size: 30rpx;
}
.switch-method {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
padding: 30rpx 0;
border-top: 1rpx solid #f0f0f0;
}
.switch-text {
font-size: 28rpx;
color: #666;
}
.switch-btn {
display: flex;
align-items: center;
}
.btn-text {
font-size: 28rpx;
color: #1677ff;
margin-right: 10rpx;
}
.icon-arrow {
font-size: 28rpx;
color: #1677ff;
}
/* 账号密码登录区域样式 */
.login-password-area {
width: 100%;
display: flex;
flex-direction: column;
padding: 0 40rpx;
}
.password-header {
display: flex;
align-items: center;
margin-bottom: 60rpx;
}
.back-btn {
width: 60rpx;
height: 60rpx;
display: flex;
align-items: center;
justify-content: center;
margin-right: 20rpx;
}
.icon-back {
font-size: 36rpx;
color: #333;
}
.login-form {
width: 100%;
}
.form-item {
margin-bottom: 40rpx;
position: relative;
}
.item-label {
font-size: 28rpx;
color: #333;
margin-bottom: 20rpx;
}
.item-input {
width: 100%;
height: 80rpx;
background-color: #f8f8f8;
border-radius: 10rpx;
padding: 0 24rpx;
font-size: 28rpx;
color: #333;
}
.input-placeholder {
color: #999;
font-size: 28rpx;
}
.forget-password {
position: absolute;
right: 0;
top: 0;
font-size: 26rpx;
color: #1677ff;
}
.login-btn {
width: 100%;
height: 90rpx;
background-color: #1677ff;
border-radius: 50rpx;
display: flex;
align-items: center;
justify-content: center;
margin-top: 60rpx;
&.disabled {
background-color: #a0cfff;
}
}
.login-btn-text {
font-size: 32rpx;
color: #fff;
font-weight: 500;
}
.agreement {
display: flex;
align-items: center;
justify-content: center;
margin-top: 40rpx;
flex-wrap: wrap;
}
.agreement-checkbox {
margin-right: 10rpx;
}
.checkbox-icon {
width: 32rpx;
height: 32rpx;
border-radius: 6rpx;
border: 2rpx solid #ddd;
display: flex;
align-items: center;
justify-content: center;
&.checked {
background-color: #1677ff;
border-color: #1677ff;
}
}
.checkmark {
font-size: 24rpx;
color: #fff;
}
.agreement-text {
font-size: 24rpx;
color: #666;
margin-right: 6rpx;
}
.agreement-link {
font-size: 24rpx;
color: #1677ff;
margin-right: 6rpx;
}
.other-login {
margin-top: 80rpx;
}
.other-title {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 50rpx;
}
.title-line {
flex: 1;
height: 1rpx;
background-color: #eee;
}
.title-text {
font-size: 24rpx;
color: #999;
margin: 0 20rpx;
}
.login-methods {
display: flex;
justify-content: center;
gap: 100rpx;
}
.method-item {
display: flex;
flex-direction: column;
align-items: center;
}
.method-icon {
width: 100rpx;
height: 100rpx;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 40rpx;
color: #fff;
margin-bottom: 20rpx;
&.scan-icon {
background-color: #1677ff;
}
&.sms-icon {
background-color: #52c41a;
}
}
.method-text {
font-size: 24rpx;
color: #666;
}
/* 登录成功提示 */
.success-tip {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
}
.success-content {
background-color: #fff;
border-radius: 20rpx;
padding: 60rpx 80rpx;
display: flex;
flex-direction: column;
align-items: center;
}
.success-icon {
width: 120rpx;
height: 120rpx;
border-radius: 50%;
background-color: #52c41a;
display: flex;
align-items: center;
justify-content: center;
font-size: 60rpx;
color: #fff;
margin-bottom: 30rpx;
}
.success-text {
font-size: 32rpx;
color: #333;
}
</style>
<style lang="stylus" scoped>
.backdoor{
position: fixed;

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB