2025-10-20 11:43:44 +08:00
|
|
|
|
<template>
|
|
|
|
|
<uni-popup ref="popup" type="center" :mask-click="false">
|
|
|
|
|
<view class="auth-modal">
|
|
|
|
|
<view class="modal-content">
|
|
|
|
|
<!-- 关闭按钮 -->
|
|
|
|
|
<view class="close-btn" @click="close">
|
|
|
|
|
<uni-icons type="closeempty" size="24" color="#999"></uni-icons>
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
<!-- Logo和标题 -->
|
|
|
|
|
<view class="auth-header">
|
|
|
|
|
<image class="auth-logo" src="@/static/logo.png" mode="aspectFit"></image>
|
|
|
|
|
<view class="auth-title">欢迎使用就业服务</view>
|
|
|
|
|
<view class="auth-subtitle">需要您授权手机号登录</view>
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
<!-- 授权说明 -->
|
|
|
|
|
<view class="auth-tips">
|
|
|
|
|
<view class="tip-item">
|
2025-10-20 16:15:29 +08:00
|
|
|
|
<uni-icons type="checkmarkempty" size="16" color="#256BFA"></uni-icons>
|
2025-10-20 11:43:44 +08:00
|
|
|
|
<text>保护您的个人信息安全</text>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="tip-item">
|
2025-10-20 16:15:29 +08:00
|
|
|
|
<uni-icons type="checkmarkempty" size="16" color="#256BFA"></uni-icons>
|
2025-10-20 11:43:44 +08:00
|
|
|
|
<text>为您推荐更合适的岗位</text>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="tip-item">
|
2025-10-20 16:15:29 +08:00
|
|
|
|
<uni-icons type="checkmarkempty" size="16" color="#256BFA"></uni-icons>
|
2025-10-20 11:43:44 +08:00
|
|
|
|
<text>享受完整的就业服务</text>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
<!-- 授权按钮 -->
|
|
|
|
|
<view class="auth-actions">
|
|
|
|
|
<!-- 微信小程序使用 open-type="getPhoneNumber" -->
|
|
|
|
|
<!-- #ifdef MP-WEIXIN -->
|
|
|
|
|
<button
|
|
|
|
|
class="auth-btn primary"
|
|
|
|
|
open-type="getPhoneNumber"
|
|
|
|
|
@getphonenumber="getPhoneNumber"
|
|
|
|
|
>
|
|
|
|
|
<uni-icons type="phone" size="20" color="#FFFFFF"></uni-icons>
|
|
|
|
|
<text>微信授权登录</text>
|
|
|
|
|
</button>
|
|
|
|
|
<!-- #endif -->
|
|
|
|
|
|
|
|
|
|
<!-- H5和App使用普通按钮 -->
|
|
|
|
|
<!-- #ifndef MP-WEIXIN -->
|
|
|
|
|
<button class="auth-btn primary" @click="wxLogin">
|
|
|
|
|
<uni-icons type="phone" size="20" color="#FFFFFF"></uni-icons>
|
|
|
|
|
<text>微信授权登录</text>
|
|
|
|
|
</button>
|
|
|
|
|
<!-- #endif -->
|
|
|
|
|
|
|
|
|
|
<!-- 测试登录按钮(仅开发环境) -->
|
|
|
|
|
<!-- #ifdef APP-PLUS || H5 -->
|
|
|
|
|
<button class="auth-btn secondary" @click="testLogin">
|
|
|
|
|
<text>测试账号登录</text>
|
|
|
|
|
</button>
|
|
|
|
|
<!-- #endif -->
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
<!-- 用户协议 -->
|
|
|
|
|
<view class="auth-agreement">
|
|
|
|
|
<text>登录即表示同意</text>
|
|
|
|
|
<text class="link" @click="openAgreement('user')">《用户协议》</text>
|
|
|
|
|
<text>和</text>
|
|
|
|
|
<text class="link" @click="openAgreement('privacy')">《隐私政策》</text>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</uni-popup>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup>
|
|
|
|
|
import { ref, inject } from 'vue';
|
|
|
|
|
import useUserStore from '@/stores/useUserStore';
|
|
|
|
|
|
|
|
|
|
const { $api } = inject('globalFunction');
|
|
|
|
|
const { loginSetToken } = useUserStore();
|
|
|
|
|
|
|
|
|
|
const popup = ref(null);
|
|
|
|
|
const emit = defineEmits(['success', 'cancel']);
|
|
|
|
|
|
|
|
|
|
// 打开弹窗
|
|
|
|
|
const open = () => {
|
|
|
|
|
popup.value?.open();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 关闭弹窗
|
|
|
|
|
const close = () => {
|
|
|
|
|
popup.value?.close();
|
|
|
|
|
emit('cancel');
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 微信小程序获取手机号
|
|
|
|
|
const getPhoneNumber = (e) => {
|
|
|
|
|
console.log('获取手机号:', e);
|
|
|
|
|
|
|
|
|
|
if (e.detail.errMsg === 'getPhoneNumber:ok') {
|
|
|
|
|
const { code, encryptedData, iv } = e.detail;
|
|
|
|
|
|
|
|
|
|
// 调用后端接口进行登录
|
|
|
|
|
uni.showLoading({ title: '登录中...' });
|
|
|
|
|
|
|
|
|
|
$api.createRequest('/app/appLogin', {
|
|
|
|
|
code,
|
|
|
|
|
encryptedData,
|
|
|
|
|
iv
|
|
|
|
|
}, 'post').then((resData) => {
|
|
|
|
|
uni.hideLoading();
|
|
|
|
|
|
|
|
|
|
if (resData.token) {
|
|
|
|
|
// 登录成功,存储token
|
|
|
|
|
loginSetToken(resData.token).then((resume) => {
|
|
|
|
|
$api.msg('登录成功');
|
|
|
|
|
close();
|
|
|
|
|
emit('success');
|
|
|
|
|
|
|
|
|
|
// 如果用户信息不完整,跳转到完善信息页面
|
|
|
|
|
if (!resume.data.jobTitleId) {
|
|
|
|
|
uni.navigateTo({
|
|
|
|
|
url: '/pages/login/login?step=1'
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}).catch(() => {
|
|
|
|
|
$api.msg('获取用户信息失败');
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
$api.msg('登录失败,请重试');
|
|
|
|
|
}
|
|
|
|
|
}).catch((err) => {
|
|
|
|
|
uni.hideLoading();
|
|
|
|
|
$api.msg(err.msg || '登录失败,请重试');
|
|
|
|
|
});
|
|
|
|
|
} else if (e.detail.errMsg === 'getPhoneNumber:fail user deny') {
|
|
|
|
|
$api.msg('您取消了授权');
|
|
|
|
|
} else {
|
|
|
|
|
$api.msg('获取手机号失败');
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// H5/App 微信登录
|
|
|
|
|
const wxLogin = () => {
|
|
|
|
|
// #ifdef H5
|
|
|
|
|
// H5网页微信登录逻辑
|
|
|
|
|
uni.showLoading({ title: '登录中...' });
|
|
|
|
|
|
|
|
|
|
// 获取微信授权code
|
|
|
|
|
uni.login({
|
|
|
|
|
provider: 'weixin',
|
|
|
|
|
success: (loginRes) => {
|
|
|
|
|
console.log('微信登录成功:', loginRes);
|
|
|
|
|
|
|
|
|
|
// 调用后端接口进行登录
|
|
|
|
|
$api.createRequest('/app/appLogin', {
|
|
|
|
|
code: loginRes.code
|
|
|
|
|
}, 'post').then((resData) => {
|
|
|
|
|
uni.hideLoading();
|
|
|
|
|
|
|
|
|
|
if (resData.token) {
|
|
|
|
|
loginSetToken(resData.token).then((resume) => {
|
|
|
|
|
$api.msg('登录成功');
|
|
|
|
|
close();
|
|
|
|
|
emit('success');
|
|
|
|
|
|
|
|
|
|
if (!resume.data.jobTitleId) {
|
|
|
|
|
uni.navigateTo({
|
|
|
|
|
url: '/pages/login/login?step=1'
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
$api.msg('登录失败,请重试');
|
|
|
|
|
}
|
|
|
|
|
}).catch((err) => {
|
|
|
|
|
uni.hideLoading();
|
|
|
|
|
$api.msg(err.msg || '登录失败,请重试');
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
fail: (err) => {
|
|
|
|
|
uni.hideLoading();
|
|
|
|
|
console.error('微信登录失败:', err);
|
|
|
|
|
$api.msg('微信登录失败');
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
// #endif
|
|
|
|
|
|
|
|
|
|
// #ifdef APP-PLUS
|
|
|
|
|
// App微信登录逻辑
|
|
|
|
|
uni.getProvider({
|
|
|
|
|
service: 'oauth',
|
|
|
|
|
success: (res) => {
|
|
|
|
|
if (~res.provider.indexOf('weixin')) {
|
|
|
|
|
uni.login({
|
|
|
|
|
provider: 'weixin',
|
|
|
|
|
success: (loginRes) => {
|
|
|
|
|
console.log('微信登录成功:', loginRes);
|
|
|
|
|
|
|
|
|
|
// 调用后端接口进行登录
|
|
|
|
|
$api.createRequest('/app/appLogin', {
|
|
|
|
|
code: loginRes.code
|
|
|
|
|
}, 'post').then((resData) => {
|
|
|
|
|
if (resData.token) {
|
|
|
|
|
loginSetToken(resData.token).then((resume) => {
|
|
|
|
|
$api.msg('登录成功');
|
|
|
|
|
close();
|
|
|
|
|
emit('success');
|
|
|
|
|
|
|
|
|
|
if (!resume.data.jobTitleId) {
|
|
|
|
|
uni.navigateTo({
|
|
|
|
|
url: '/pages/login/login?step=1'
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
fail: (err) => {
|
|
|
|
|
console.error('微信登录失败:', err);
|
|
|
|
|
$api.msg('微信登录失败');
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
// #endif
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 测试账号登录(仅开发环境)
|
|
|
|
|
const testLogin = () => {
|
|
|
|
|
uni.showLoading({ title: '登录中...' });
|
|
|
|
|
|
|
|
|
|
const params = {
|
|
|
|
|
username: 'test',
|
|
|
|
|
password: 'test',
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
$api.createRequest('/app/login', params, 'post').then((resData) => {
|
|
|
|
|
uni.hideLoading();
|
|
|
|
|
|
|
|
|
|
loginSetToken(resData.token).then((resume) => {
|
|
|
|
|
$api.msg('测试登录成功');
|
|
|
|
|
close();
|
|
|
|
|
emit('success');
|
|
|
|
|
|
|
|
|
|
if (!resume.data.jobTitleId) {
|
|
|
|
|
uni.navigateTo({
|
|
|
|
|
url: '/pages/login/login?step=1'
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}).catch(() => {
|
|
|
|
|
$api.msg('获取用户信息失败');
|
|
|
|
|
});
|
|
|
|
|
}).catch((err) => {
|
|
|
|
|
uni.hideLoading();
|
|
|
|
|
$api.msg(err.msg || '登录失败');
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 打开用户协议
|
|
|
|
|
const openAgreement = (type) => {
|
|
|
|
|
const urls = {
|
|
|
|
|
user: '/pages/agreement/user',
|
|
|
|
|
privacy: '/pages/agreement/privacy'
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (urls[type]) {
|
|
|
|
|
uni.navigateTo({
|
|
|
|
|
url: urls[type]
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 暴露方法供父组件调用
|
|
|
|
|
defineExpose({
|
|
|
|
|
open,
|
|
|
|
|
close
|
|
|
|
|
});
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style lang="stylus" scoped>
|
|
|
|
|
.auth-modal
|
|
|
|
|
width: 620rpx
|
|
|
|
|
background: #FFFFFF
|
|
|
|
|
border-radius: 24rpx
|
|
|
|
|
overflow: hidden
|
|
|
|
|
|
|
|
|
|
.modal-content
|
|
|
|
|
padding: 60rpx 40rpx 40rpx
|
|
|
|
|
position: relative
|
|
|
|
|
|
|
|
|
|
.close-btn
|
|
|
|
|
position: absolute
|
|
|
|
|
right: 20rpx
|
|
|
|
|
top: 20rpx
|
|
|
|
|
width: 60rpx
|
|
|
|
|
height: 60rpx
|
|
|
|
|
display: flex
|
|
|
|
|
align-items: center
|
|
|
|
|
justify-content: center
|
|
|
|
|
z-index: 10
|
|
|
|
|
|
|
|
|
|
.auth-header
|
|
|
|
|
text-align: center
|
|
|
|
|
margin-bottom: 40rpx
|
|
|
|
|
|
|
|
|
|
.auth-logo
|
|
|
|
|
width: 120rpx
|
|
|
|
|
height: 120rpx
|
|
|
|
|
margin: 0 auto 24rpx
|
|
|
|
|
|
|
|
|
|
.auth-title
|
|
|
|
|
font-size: 36rpx
|
|
|
|
|
font-weight: 600
|
|
|
|
|
color: #333333
|
|
|
|
|
margin-bottom: 12rpx
|
|
|
|
|
|
|
|
|
|
.auth-subtitle
|
|
|
|
|
font-size: 28rpx
|
|
|
|
|
color: #666666
|
|
|
|
|
|
|
|
|
|
.auth-tips
|
|
|
|
|
background: #F7F8FA
|
|
|
|
|
border-radius: 16rpx
|
|
|
|
|
padding: 24rpx
|
|
|
|
|
margin-bottom: 40rpx
|
|
|
|
|
|
|
|
|
|
.tip-item
|
|
|
|
|
display: flex
|
|
|
|
|
align-items: center
|
|
|
|
|
margin-bottom: 16rpx
|
|
|
|
|
font-size: 26rpx
|
|
|
|
|
color: #666666
|
|
|
|
|
|
|
|
|
|
&:last-child
|
|
|
|
|
margin-bottom: 0
|
|
|
|
|
|
|
|
|
|
text
|
|
|
|
|
margin-left: 12rpx
|
|
|
|
|
|
|
|
|
|
.auth-actions
|
|
|
|
|
margin-bottom: 32rpx
|
|
|
|
|
|
|
|
|
|
.auth-btn
|
|
|
|
|
width: 100%
|
|
|
|
|
height: 88rpx
|
|
|
|
|
border-radius: 44rpx
|
|
|
|
|
display: flex
|
|
|
|
|
align-items: center
|
|
|
|
|
justify-content: center
|
|
|
|
|
font-size: 32rpx
|
|
|
|
|
font-weight: 500
|
|
|
|
|
border: none
|
|
|
|
|
margin-bottom: 20rpx
|
|
|
|
|
|
|
|
|
|
&:last-child
|
|
|
|
|
margin-bottom: 0
|
|
|
|
|
|
|
|
|
|
&.primary
|
2025-10-20 16:15:29 +08:00
|
|
|
|
background: linear-gradient(135deg, #256BFA 0%, #1E5BFF 100%)
|
2025-10-20 11:43:44 +08:00
|
|
|
|
color: #FFFFFF
|
2025-10-20 16:15:29 +08:00
|
|
|
|
box-shadow: 0 8rpx 20rpx rgba(37, 107, 250, 0.3)
|
2025-10-20 11:43:44 +08:00
|
|
|
|
|
|
|
|
|
&.secondary
|
|
|
|
|
background: #F7F8FA
|
|
|
|
|
color: #666666
|
|
|
|
|
|
|
|
|
|
text
|
|
|
|
|
margin-left: 12rpx
|
|
|
|
|
|
|
|
|
|
.auth-agreement
|
|
|
|
|
text-align: center
|
|
|
|
|
font-size: 24rpx
|
|
|
|
|
color: #999999
|
|
|
|
|
line-height: 1.6
|
|
|
|
|
|
|
|
|
|
.link
|
|
|
|
|
color: #256BFA
|
|
|
|
|
text-decoration: underline
|
|
|
|
|
|
|
|
|
|
// 按钮重置样式
|
|
|
|
|
button::after
|
|
|
|
|
border: none
|
|
|
|
|
</style>
|
|
|
|
|
|