344 lines
9.3 KiB
Vue
Raw Normal View History

2024-08-07 10:31:42 +08:00
<template>
2025-06-09 11:33:50 +08:00
<!-- 规格弹窗 -->
<su-popup :show="authType !== ''" round="10" :showClose="true" @close="closeAuthModal">
<view class="login-wrap">
<!-- 1. 账号密码登录 accountLogin -->
<account-login v-if="authType === 'accountLogin'" :agreeStatus="state.protocol" @onConfirm="onConfirm" />
<!-- 2. 短信登录 smsLogin -->
<sms-login v-if="authType === 'smsLogin'" :agreeStatus="state.protocol" @onConfirm="onConfirm" />
<!-- 3. 忘记密码 resetPassword-->
<reset-password v-if="authType === 'resetPassword'" />
<!-- 4. 绑定手机号 changeMobile -->
<change-mobile v-if="authType === 'changeMobile'" />
<!-- 5. 修改密码 changePassword-->
<changePassword v-if="authType === 'changePassword'" />
<!-- 6. 微信小程序授权 -->
<mp-authorization v-if="authType === 'mpAuthorization'" />
<!-- 7. 第三方登录 -->
<view v-if="['accountLogin', 'smsLogin'].includes(authType)"
class="auto-login-box ss-flex ss-flex-col ss-row-center ss-col-center">
<!-- 7.1 微信小程序的快捷登录 -->
<view v-if="sheep.$platform.name === 'WechatMiniProgram'" class="ss-flex register-box">
<view class="register-title">还没有账号?</view>
<button v-if="openCode" class="ss-reset-button login-btn" @tap="weixinLogin">
快捷登录
</button>
<button v-else-if="!openCode" class="ss-reset-button login-btn" open-type="getPhoneNumber"
@getphonenumber="getPhoneNumber">
快捷登录
</button>
<view class="circle" />
</view>
<!-- 7.2 微信的公众号App小程序的登录基于 openid + code -->
<button v-if="
2024-08-07 10:31:42 +08:00
['WechatOfficialAccount', 'WechatMiniProgram', 'App'].includes(sheep.$platform.name) &&
sheep.$platform.isWechatInstalled
2025-06-09 11:33:50 +08:00
" @tap="thirdLogin('wechat')" class="ss-reset-button auto-login-btn">
<image class="auto-login-img" :src="sheep.$url.static('/static/img/shop/platform/wechat.png')" />
</button>
<!-- 7.3 iOS 登录 TODO 芋艿等后面搞 App 再弄 -->
<button v-if="sheep.$platform.os === 'ios' && sheep.$platform.name === 'App'" @tap="thirdLogin('apple')"
class="ss-reset-button auto-login-btn">
<image class="auto-login-img" :src="sheep.$url.static('/static/img/shop/platform/apple.png')" />
</button>
</view>
<!-- 用户协议的勾选 -->
<view v-if="['accountLogin', 'smsLogin'].includes(authType)" class="agreement-box ss-flex ss-row-center"
:class="{ shake: currentProtocol }">
<label class="radio ss-flex ss-col-center" @tap="onChange">
<radio :checked="state.protocol" color="var(--ui-BG-Main)" style="transform: scale(0.8)"
@tap.stop="onChange" />
<view class="agreement-text ss-flex ss-col-center ss-m-l-8">
我已阅读并遵守
<view class="tcp-text" @tap.stop="onProtocol('用户协议')"> 用户协议 </view>
<view class="agreement-text"></view>
<view class="tcp-text" @tap.stop="onProtocol('隐私协议')"> 隐私协议 </view>
</view>
</label>
</view>
<view class="safe-box" />
</view>
</su-popup>
2024-08-07 10:31:42 +08:00
</template>
<script setup>
2025-06-09 11:33:50 +08:00
import {
onMounted,
computed,
reactive,
ref,
watchEffect,
watch
} from 'vue';
import sheep from '@/sheep';
import accountLogin from './components/account-login.vue';
import smsLogin from './components/sms-login.vue';
import resetPassword from './components/reset-password.vue';
import changeMobile from './components/change-mobile.vue';
import changePassword from './components/change-password.vue';
import mpAuthorization from './components/mp-authorization.vue';
import {
closeAuthModal,
showAuthModal
} from '@/sheep/hooks/useModal';
import AuthUtil from '@/sheep/api/member/auth';
const appInfo = computed(() => sheep.$store('app').info);
const modalStore = sheep.$store('modal');
// 授权弹窗类型
const authType = computed(() => modalStore.auth);
const openCode = ref(false)
const showModal = ref(false)
onMounted(async () => {
const codeResult = await uni.login();
console.log('codeResult', codeResult)
if (codeResult.errMsg !== 'login:ok') {
return resolve(false);
}
const socialType = 34
const checkLogin = await AuthUtil.checkLogin(socialType, codeResult.code, 'default')
console.log('查询到的', checkLogin.data)
if (checkLogin.data === -1) {
openCode.value = false
} else {
openCode.value = true
}
});
watch(openCode, (newVal) => {
console.log('openCode changed:', newVal);
});
watch(showModal, (newVal) => {
console.log('showModal changed:', newVal);
});
watchEffect(() => {
if (authType.value === 'mpAuthorization') {
state.canClose = false
} else {
state.canClose = true
}
});
const state = reactive({
protocol: false,
});
const currentProtocol = ref(false);
// 勾选协议
function onChange() {
state.protocol = !state.protocol;
}
// 查看协议
function onProtocol(title) {
2025-05-08 16:52:29 +08:00
closeAuthModal();
2025-06-09 11:33:50 +08:00
sheep.$router.go('/pages/public/richtext', {
title,
});
}
// 点击登录 / 注册事件
function onConfirm(e) {
currentProtocol.value = e;
setTimeout(() => {
currentProtocol.value = false;
}, 1000);
}
const weixinLogin = async (e) => {
console.log('11111')
if (!state.protocol) {
currentProtocol.value = true;
setTimeout(() => {
currentProtocol.value = false;
}, 1000);
sheep.$helper.toast('请勾选同意');
return;
}
return new Promise(async (resolve, reject) => {
// 1. 获得微信 code
const codeResult = await uni.login();
console.log('codeResult', codeResult)
if (codeResult.errMsg !== 'login:ok') {
return resolve(false);
}
const loginRes = await sheep.$platform.useProvider().login();
console.log('免授权的login()', loginRes)
closeAuthModal();
const userInfo = await sheep.$store('user').getInfo();
console.log("用户数据1", userInfo)
if (codeResult.code) {
closeAuthModal();
const socialType = 34;
const loginResult = await AuthUtil.socialLogin(socialType, codeResult.code, 'default');
console.log('e', e.detail)
console.log('loginResult', loginResult)
loginResult.data.openid.uni.setStorageSync('oppenid')
if (loginResult.code === 0) {
// setOpenid(loginResult.data.openid);
console.log('跑到这?')
sheep.$store('user').setToken(
loginResult.data.token,
loginResult.data.refreshToken
);
// closeAuthModal();
return resolve(true);
} else {
openCode.value = false
return resolve(false);
}
} else {
openCode.value = false
return resolve(false);
}
});
}
// 第三方授权登陆微信小程序、Apple
const thirdLogin = async (provider) => {
if (!state.protocol) {
currentProtocol.value = true;
setTimeout(() => {
currentProtocol.value = false;
}, 1000);
sheep.$helper.toast('请勾选同意');
return;
}
const loginRes = await sheep.$platform.useProvider(provider).login();
if (loginRes) {
const userInfo = await sheep.$store('user').getInfo();
closeAuthModal();
console.log("用户数据", userInfo)
// #ifdef MP-WEIXIN
const regex = /^用户/;
if (regex.test(userInfo.nickname) || !userInfo.avatar) {
showAuthModal('mpAuthorization');
return
}
// #endif
if (userInfo.avatar && userInfo.nickname) {
return;
}
// 触发小程序授权信息弹框
// #ifdef MP-WEIXIN
showAuthModal('mpAuthorization');
// #endif
2025-05-08 16:52:29 +08:00
}
2025-06-09 11:33:50 +08:00
};
// 微信小程序的“手机号快速验证”https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/getPhoneNumber.html
const getPhoneNumber = async (e) => {
if (e.detail.errMsg !== 'getPhoneNumber:ok') {
sheep.$helper.toast('快捷登录失败');
return;
}
if (!state.protocol) {
currentProtocol.value = true;
setTimeout(() => {
currentProtocol.value = false;
}, 1000);
sheep.$helper.toast('请勾选同意');
return;
}
let result = await sheep.$platform.useProvider().mobileLogin(e.detail);
if (result) {
openCode.value = true;
const userInfo = await sheep.$store('user').getInfo();
closeAuthModal();
if (userInfo.avatar && (userInfo.nickname && !userInfo.nickname.startsWith("用户"))) {
return;
}
console.log("用户数据", userInfo)
// #ifdef MP-WEIXIN
showAuthModal('mpAuthorization');
// #endif
}
};
2024-08-07 10:31:42 +08:00
</script>
<style lang="scss" scoped>
2025-06-09 11:33:50 +08:00
@import './index.scss';
.shake {
animation: shake 0.05s linear 4 alternate;
}
@keyframes shake {
from {
transform: translateX(-10rpx);
}
to {
transform: translateX(10rpx);
}
}
.register-box {
position: relative;
justify-content: center;
.register-btn {
color: #999999;
font-size: 30rpx;
font-weight: 500;
}
.register-title {
color: #999999;
font-size: 30rpx;
font-weight: 400;
margin-right: 24rpx;
}
.or-title {
margin: 0 16rpx;
color: #999999;
font-size: 30rpx;
font-weight: 400;
}
.login-btn {
color: var(--ui-BG-Main);
font-size: 30rpx;
font-weight: 500;
}
.circle {
position: absolute;
right: 0rpx;
top: 18rpx;
width: 8rpx;
height: 8rpx;
border-radius: 8rpx;
background: var(--ui-BG-Main);
}
}
.safe-box {
height: calc(constant(safe-area-inset-bottom) / 5 * 3);
height: calc(env(safe-area-inset-bottom) / 5 * 3);
}
.tcp-text {
color: var(--ui-BG-Main);
}
.agreement-text {
color: $dark-9;
}
</style>