| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- <template>
- <view class="login-container">
- <view class="login-header">
- <view class="logo-box">
- <text class="logo-text1">审计</text>
- <text class="logo-text2">之家</text>
- </view>
- <view class="login-title">登录审计之家</view>
- <view class="login-subtitle">找岗位, XXXXXXXX</view>
- </view>
- <view class="login-body">
- <!-- 动态替换:同意则原样使用获取手机号功能;不同意则纯点击弹窗 -->
- <button v-if="isAgree" class="btn-primary" open-type="getPhoneNumber" @getphonenumber="handleDirectLogin">一键快捷登录</button>
- <button v-else class="btn-primary" @tap="showAgreementModal = true">一键快捷登录</button>
-
- <view class="agreement-box">
- <checkbox-group @change="onAgreeChange">
- <label class="checkbox-label">
- <checkbox value="agree" :checked="isAgree" color="#007AFF" style="transform:scale(0.7)" />
- <text class="agreement-text">我已经阅读并同意</text>
- <text class="link-text" @tap.stop="openDocModal('service')">审计之家服务协议</text>
- <text class="agreement-text"> 及 </text>
- <text class="link-text" @tap.stop="openDocModal('privacy')">隐私政策</text>
- </label>
- </checkbox-group>
- </view>
- </view>
- <view class="login-footer">
- <view class="divider-text">-登录后权益更多-</view>
- <view class="icon-grid">
- <view class="icon-item">
- <view class="icon-circle">
- <image src="/static/icons/icon-info.svg" mode="aspectFit" class="icon-img"></image>
- </view>
- <text class="icon-text">优质信息</text>
- </view>
- <view class="icon-item">
- <view class="icon-circle">
- <image src="/static/icons/icon-service.svg" mode="aspectFit" class="icon-img"></image>
- </view>
- <text class="icon-text">专属客服</text>
- </view>
- <view class="icon-item">
- <view class="icon-circle">
- <image src="/static/icons/icon-recommend.svg" mode="aspectFit" class="icon-img"></image>
- </view>
- <text class="icon-text">曝光推荐</text>
- </view>
- <view class="icon-item">
- <view class="icon-circle">
- <image src="/static/icons/icon-contact.svg" mode="aspectFit" class="icon-img"></image>
- </view>
- <text class="icon-text">快速联系</text>
- </view>
- </view>
- </view>
- <!-- 未同意协议时的提示弹窗 -->
- <view class="custom-modal" :class="{ 'is-show': showAgreementModal }">
- <view class="modal-mask" @tap="closeAgreementModal"></view>
- <view class="modal-content">
- <view class="modal-header">
- <text class="modal-title">提示</text>
- </view>
- <view class="modal-body">
- <view class="modal-text-wrapper">
- <text class="modal-text">请先阅读并同意</text>
- <text class="link-text" @tap.stop="openDocModal('service')">服务协议</text>
- <text class="modal-text"> 及 </text>
- <text class="link-text" @tap.stop="openDocModal('privacy')">隐私政策</text>
- </view>
- </view>
- <view class="modal-footer">
- <view class="btn-cancel" @tap="closeAgreementModal">不同意</view>
- <view class="btn-confirm" style="position: relative;">
- 同意
- <button open-type="getPhoneNumber" @getphonenumber="handleDirectLoginFromModal" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; opacity: 0; z-index: 10; padding: 0; margin: 0;"></button>
- </view>
- </view>
- </view>
- </view>
- <!-- 协议正文弹窗 -->
- <view class="custom-modal doc-modal" :class="{ 'is-show': showDocModal }">
- <view class="modal-mask" @tap="closeDocModal"></view>
- <view class="modal-content doc-modal-content">
- <view class="modal-header">
- <text class="modal-title">{{ docTitle }}</text>
- </view>
- <scroll-view class="modal-body doc-modal-body" scroll-y>
- <rich-text :nodes="docContent"></rich-text>
- </scroll-view>
- <view class="modal-footer">
- <view class="btn-confirm full-width" @tap="closeDocModal">我知道了</view>
- </view>
- </view>
- </view>
- </view>
- </template>
- <script setup lang="js">
- import { ref, onMounted } from 'vue';
- import { wechatLogin, getAgreement } from '../../api/auth';
- const isAgree = ref(false);
- const showAgreementModal = ref(false);
- const showDocModal = ref(false);
- const docTitle = ref('');
- const docContent = ref('');
- // 保存 wx.login 获取的 code,用于后端校验 openid
- const loginCode = ref('');
- // 预获取微信登录 code(在页面加载时就获取,避免授权回调时 code 失效)
- const getLoginCode = () => {
- uni.login({
- provider: 'weixin',
- success: (res) => {
- loginCode.value = res.code;
- }
- });
- };
- onMounted(() => {
- // 检查是否已有有效 token,如果有则直接跳转首页
- const token = uni.getStorageSync('token');
- const userInfo = uni.getStorageSync('userInfo');
- if (token && userInfo && userInfo.studentId) {
- // 已登录,直接跳转
- if (userInfo.isNewUser && !userInfo.name) {
- uni.redirectTo({ url: '/pages/profile/profile' });
- } else {
- uni.switchTab({ url: '/pages/jobs/jobs' });
- }
- return;
- }
- getLoginCode();
- });
- // 打开协议正文弹窗(从后端拉取内容)
- const openDocModal = async (type) => {
- try {
- const res = await getAgreement(type);
- if (res.code === 200) {
- docTitle.value = res.data.title;
- docContent.value = res.data.content;
- showDocModal.value = true;
- return;
- }
- } catch (err) {
- console.error('获取协议失败', err);
- uni.showToast({
- title: '获取协议失败,请稍后重试',
- icon: 'none'
- });
- }
- };
- const closeDocModal = () => {
- showDocModal.value = false;
- };
- const onAgreeChange = (e) => {
- isAgree.value = e.detail.value.length > 0;
- };
- const closeAgreementModal = () => {
- showAgreementModal.value = false;
- };
- /**
- * 微信授权手机号回调(由于使用了v-if控制按钮,此时必然是同意了)
- */
- const handleDirectLogin = async (e) => {
- if (e.detail.errMsg !== 'getPhoneNumber:ok') {
- uni.showToast({
- title: '授权失败',
- icon: 'none'
- });
- return;
- }
- await onAllowLogin(e.detail.code);
- };
- /**
- * 弹窗中的同意并获取手机号回调
- */
- const handleDirectLoginFromModal = async (e) => {
- isAgree.value = true;
- showAgreementModal.value = false;
- if (e.detail.errMsg !== 'getPhoneNumber:ok') {
- uni.showToast({
- title: '授权失败',
- icon: 'none'
- });
- return;
- }
- await onAllowLogin(e.detail.code);
- };
- /**
- * 发起真实登录请求
- */
- const onAllowLogin = async (phoneCode) => {
- uni.showLoading({ title: '登录中...' });
- try {
- const res = await wechatLogin({
- code: loginCode.value,
- phoneCode: phoneCode
- });
- uni.hideLoading();
- if (res.code === 200) {
- uni.setStorageSync('token', res.data.token);
- uni.setStorageSync('userInfo', res.data);
- uni.showToast({
- title: '登录成功',
- icon: 'success'
- });
- setTimeout(() => {
- if (res.data.isNewUser) {
- uni.navigateTo({ url: '/pages/profile/profile' });
- } else {
- uni.switchTab({ url: '/pages/jobs/jobs' });
- }
- }, 1000);
- }
- } catch (err) {
- console.error('登录异常', err);
- uni.hideLoading();
- getLoginCode();
- }
- };
- </script>
- <style lang="scss" scoped>
- @import './login.scss';
- // 仅去除 button 默认边框,不覆盖原本 btn-confirm 的高亮背景与字号
- .btn-confirm::after {
- border: none !important;
- }
- </style>
|