| | |
| | | <view class="agreement-checkbox"> |
| | | <checkbox-group @change="onAgreementChange"> |
| | | <label class="checkbox-label"> |
| | | <checkbox :checked="agreedToPolicy" value="agreed" color="#007AFF" style="margin-top: 0;" /> |
| | | <checkbox :checked="agreedToPolicy" value="agreed" color="#007AFF" class="round-checkbox" style="margin-top: 0;" /> |
| | | <text class="agreement-text"> |
| | | <text class="text-grey1">同意</text> |
| | | <text @click.stop="handleUserAgrement" class="text-blue agreement-link">《用户协议》</text> |
| | |
| | | |
| | | <view class="action-btn"> |
| | | <button @click="handleLogin" class="login-btn cu-btn block bg-blue lg round">登录</button> |
| | | <!-- 微信一键登录按钮(仅在微信小程序环境显示) --> |
| | | <!-- #ifdef MP-WEIXIN --> |
| | | <button |
| | | v-if="isWechat && wechatOpenId" |
| | | @click="loginByOpenId" |
| | | class="wechat-login-btn cu-btn block bg-green lg round" |
| | | style="margin-top: 20rpx;"> |
| | | <text class="cuIcon-wechat" style="margin-right: 10rpx;"></text> |
| | | 手机号码快捷登录 |
| | | </button> |
| | | <button |
| | | v-else-if="isWechat" |
| | | open-type="getPhoneNumber" |
| | | @getphonenumber="onGetPhoneNumber" |
| | | class="wechat-login-btn cu-btn block bg-green lg round" |
| | | style="margin-top: 20rpx;"> |
| | | <text class="cuIcon-wechat" style="margin-right: 10rpx;"></text> |
| | | 手机号码快捷登录 |
| | | </button> |
| | | <!-- #endif --> |
| | | </view> |
| | | </view> |
| | | </scroll-view> |
| | | </template> |
| | | |
| | | <script> |
| | | import { getCodeImg } from '@/api/login' |
| | | import { getCodeImg, loginByOpenId, loginByWechatPhone } from '@/api/login' |
| | | import { isWxWorkEnvironment,redirectToQyLogin } from '@/utils/wechat' |
| | | |
| | | export default { |
| | | data() { |
| | |
| | | captchaEnabled: true, |
| | | // 用户注册开关 |
| | | register: false, |
| | | // 隐私政策同意状态(默认选中) |
| | | agreedToPolicy: true, |
| | | // 隐私政策同意状态(默认未选中,需要用户主动勾选) |
| | | agreedToPolicy: false, |
| | | globalConfig: getApp().globalData.config, |
| | | loginForm: { |
| | | username: "", |
| | | password: "", |
| | | code: "", |
| | | uuid: '' |
| | | } |
| | | }, |
| | | // 微信一键登录相关 |
| | | isWechat: false, // 是否为微信小程序环境 |
| | | wechatOpenId: '', // 微信OpenID |
| | | wechatUnionId: '', // 微信UnionID |
| | | // 页面参数 |
| | | pageOptions: {} |
| | | } |
| | | }, |
| | | onLoad(options) { |
| | | // 保存页面参数 |
| | | this.pageOptions = options || {} |
| | | isWxWorkEnvironment().then(res=>{ |
| | | if(res){ |
| | | // console.log("企业微信环境 login.vue....") |
| | | redirectToQyLogin(options,this.$tab); |
| | | } |
| | | }); |
| | | |
| | | }, |
| | | created() { |
| | | this.getCode() |
| | | this.checkWechatEnv() |
| | | this.tryAutoLogin() |
| | | }, |
| | | methods: { |
| | | // 用户注册 |
| | |
| | | this.$store.dispatch('GetInfo').then(res => { |
| | | // 触发登录成功事件,启动消息轮询 |
| | | uni.$emit('user-login') |
| | | this.$tab.reLaunch('/pages/index') |
| | | // 处理自动跳转逻辑 |
| | | this.redirectAfterLogin() |
| | | }) |
| | | }, |
| | | |
| | | // ==================== 微信一键登录相关方法 ==================== |
| | | |
| | | // 检查是否在微信小程序环境 |
| | | checkWechatEnv() { |
| | | // #ifdef MP-WEIXIN |
| | | this.isWechat = true |
| | | console.log('当前环境:微信小程序') |
| | | // #endif |
| | | |
| | | // #ifndef MP-WEIXIN |
| | | this.isWechat = false |
| | | console.log('当前环境:非微信小程序') |
| | | // #endif |
| | | |
| | | |
| | | }, |
| | | |
| | | // 尝试自动登录(检查本地是否有保存的OpenID) |
| | | tryAutoLogin() { |
| | | if (!this.isWechat) { |
| | | return |
| | | } |
| | | |
| | | // 从本地存储中获取OpenID和UnionID |
| | | const savedOpenId = uni.getStorageSync('wechat_openid') |
| | | const savedUnionId = uni.getStorageSync('wechat_unionid') |
| | | const autoLogin=true; |
| | | |
| | | if (savedOpenId && autoLogin) { |
| | | console.log('检测到已保存的OpenID,尝试自动登录') |
| | | this.wechatOpenId = savedOpenId |
| | | this.wechatUnionId = savedUnionId // 可能为null |
| | | this.loginByOpenId() |
| | | } |
| | | }, |
| | | |
| | | // 处理获取手机号的回调 |
| | | onGetPhoneNumber(e) { |
| | | console.log('获取手机号回调:', e) |
| | | |
| | | if (!this.agreedToPolicy) { |
| | | this.$modal.msgError("请先阅读并同意用户协议和隐私政策") |
| | | return |
| | | } |
| | | |
| | | if (e.detail.errMsg === 'getPhoneNumber:ok') { |
| | | // 用户同意授权 |
| | | const { code } = e.detail |
| | | |
| | | this.$modal.loading("正在获取手机号...") |
| | | |
| | | // 先获取微信登录code |
| | | uni.login({ |
| | | provider: 'weixin', |
| | | success: (loginRes) => { |
| | | console.log('微信登录code:', loginRes.code) |
| | | console.log('手机号code:', code) |
| | | |
| | | // 调用后端接口,传入loginCode和phoneCode |
| | | loginByWechatPhone(loginRes.code, code).then(response => { |
| | | this.$modal.closeLoading() |
| | | |
| | | if (response.code === 200) { |
| | | // 登录成功,保存OpenID和UnionID |
| | | const openId = response.openId |
| | | const unionId = response.unionId |
| | | |
| | | uni.setStorageSync('wechat_openid', openId) |
| | | this.wechatOpenId = openId |
| | | |
| | | if (unionId) { |
| | | uni.setStorageSync('wechat_unionid', unionId) |
| | | this.wechatUnionId = unionId |
| | | } |
| | | |
| | | // 保存token到本地存储和Vuex |
| | | const token = response.token |
| | | this.$store.commit('SET_TOKEN', token) |
| | | // 必须调用setToken保存到本地存储 |
| | | const { setToken } = require('@/utils/auth') |
| | | setToken(token) |
| | | |
| | | // 获取用户信息并处理自动跳转逻辑 |
| | | this.$store.dispatch('GetInfo').then(() => { |
| | | this.redirectAfterLogin() |
| | | }); |
| | | } else { |
| | | this.$modal.msgError(response.msg || '登录失败') |
| | | } |
| | | }).catch(error => { |
| | | this.$modal.closeLoading() |
| | | console.error('登录失败:', error) |
| | | this.$modal.msgError('登录失败,请重试') |
| | | }) |
| | | }, |
| | | fail: (err) => { |
| | | this.$modal.closeLoading() |
| | | console.error('获取微信登录code失败:', err) |
| | | this.$modal.msgError('获取微信信息失败') |
| | | } |
| | | }) |
| | | } else { |
| | | // 用户拒绝授权 |
| | | this.$modal.msgError('需要您的手机号才能登录') |
| | | } |
| | | }, |
| | | |
| | | // 通过OpenID和UnionID登录 |
| | | loginByOpenId() { |
| | | this.$modal.loading("正在登录...") |
| | | |
| | | // 同时传入openId和unionId进行双重验证 |
| | | loginByOpenId(this.wechatOpenId, this.wechatUnionId).then(response => { |
| | | this.$modal.closeLoading() |
| | | |
| | | if (response.code === 200) { |
| | | // 登录成功,保存token到本地存储和Vuex |
| | | const token = response.token |
| | | this.$store.commit('SET_TOKEN', token) |
| | | // 必须调用setToken保存到本地存储 |
| | | const { setToken } = require('@/utils/auth') |
| | | setToken(token) |
| | | |
| | | // 获取用户信息并处理自动跳转逻辑 |
| | | this.$store.dispatch('GetInfo').then(() => { |
| | | this.redirectAfterLogin() |
| | | }); |
| | | } else { |
| | | // OpenID未绑定或验证失败,需要获取手机号绑定 |
| | | console.log('该OpenID尚未绑定或验证失败,需要获取手机号') |
| | | this.$modal.closeLoading() |
| | | this.$modal.msgError(response.msg || '该微信账号尚未绑定,请点击微信一键登录按钮获取手机号授权') |
| | | } |
| | | }).catch(error => { |
| | | this.$modal.closeLoading() |
| | | console.error('登录失败:', error) |
| | | this.$modal.msgError('登录失败,请重试') |
| | | }) |
| | | }, |
| | | |
| | | /** |
| | | * 获取URL参数 |
| | | */ |
| | | getUrlParam(name) { |
| | | // #ifdef H5 |
| | | const reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); |
| | | const r = window.location.search.substr(1).match(reg); |
| | | if (r != null) return decodeURIComponent(r[2]); |
| | | // #endif |
| | | |
| | | // #ifdef MP-WEIXIN |
| | | // 在小程序中,参数通过onLoad的options传递 |
| | | if (this.pageOptions && this.pageOptions[name]) { |
| | | return decodeURIComponent(this.pageOptions[name]); |
| | | } |
| | | // #endif |
| | | |
| | | return null; |
| | | }, |
| | | |
| | | /** |
| | | * 登录成功后的跳转处理 |
| | | */ |
| | | redirectAfterLogin() { |
| | | try { |
| | | // 检查是否有redirect参数指定跳转页面 |
| | | let redirectUrl = this.getUrlParam("redirect"); |
| | | |
| | | // 如果没有redirect参数,检查是否有保存的目标页面 |
| | | if (!redirectUrl) { |
| | | const { getTargetUrl } = require('@/utils/auth') |
| | | redirectUrl = getTargetUrl() |
| | | } |
| | | |
| | | if (redirectUrl) { |
| | | // 解码redirect参数 |
| | | redirectUrl = decodeURIComponent(redirectUrl); |
| | | console.log("自动跳转到指定页面:", redirectUrl); |
| | | this.$tab.reLaunch(redirectUrl); |
| | | } else { |
| | | // 默认跳转到首页 |
| | | console.log("跳转到首页"); |
| | | this.$tab.reLaunch('/pages/index'); |
| | | } |
| | | } catch (e) { |
| | | console.error("跳转失败,使用默认跳转:", e); |
| | | // 出现异常时,默认跳转到首页 |
| | | this.$tab.reLaunch('/pages/index'); |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | height: 90rpx; |
| | | font-size: 32rpx; |
| | | } |
| | | |
| | | .wechat-login-btn { |
| | | height: 90rpx; |
| | | font-size: 32rpx; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | } |
| | | } |
| | | |
| | | .reg { |
| | |
| | | vertical-align: middle; |
| | | } |
| | | |
| | | // 圆形复选框样式 |
| | | .round-checkbox { |
| | | border-radius: 50% !important; |
| | | } |
| | | |
| | | // 针对微信小程序的圆形样式 |
| | | ::v-deep .uni-checkbox-input, |
| | | ::v-deep .wx-checkbox-input { |
| | | border-radius: 50% !important; |
| | | } |
| | | |
| | | // 针对H5的圆形样式 |
| | | ::v-deep input[type="checkbox"] { |
| | | border-radius: 50% !important; |
| | | -webkit-appearance: none; |
| | | appearance: none; |
| | | width: 36rpx; |
| | | height: 36rpx; |
| | | border: 2rpx solid #d1d1d1; |
| | | background-color: #fff; |
| | | position: relative; |
| | | |
| | | &:checked { |
| | | background-color: #007AFF; |
| | | border-color: #007AFF; |
| | | |
| | | &::after { |
| | | content: ''; |
| | | position: absolute; |
| | | top: 50%; |
| | | left: 50%; |
| | | transform: translate(-50%, -50%); |
| | | width: 12rpx; |
| | | height: 12rpx; |
| | | background-color: #fff; |
| | | border-radius: 50%; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .agreement-text { |
| | | display: inline-flex; |
| | | align-items: center; |