提交
This commit is contained in:
248
pxdj-merch-uni/src/pages/login/login.vue
Normal file
248
pxdj-merch-uni/src/pages/login/login.vue
Normal file
@@ -0,0 +1,248 @@
|
||||
<!-- pages/login/login.vue -->
|
||||
<template>
|
||||
<view class="container">
|
||||
<!-- 微信登录 -->
|
||||
<template v-if="loginType === 'wxLogin'">
|
||||
<view class="login-title">手机号快捷登录</view>
|
||||
<view class="wx-login-container">
|
||||
<template>
|
||||
<view class="login-status">
|
||||
<text>请授权您的手机号码完成登录</text>
|
||||
</view>
|
||||
<button
|
||||
v-if="autoWxLoginFlag"
|
||||
class="wx-login-btn"
|
||||
open-type="getPhoneNumber"
|
||||
@getphonenumber="getPhoneNumber"
|
||||
:disabled="!isAgree"
|
||||
:class="{'btn-disabled': !isAgree}"
|
||||
>
|
||||
<text class="btn-text">授权手机号</text>
|
||||
</button>
|
||||
|
||||
<!-- 用户协议 -->
|
||||
<view class="agreement-container">
|
||||
<checkbox-group @change="handleAgreeChange">
|
||||
<label class="agreement-item">
|
||||
<checkbox :checked="isAgree" color="#07c160" style="transform:scale(0.7)" />
|
||||
<text class="agreement-text">我已阅读并同意</text>
|
||||
<text class="agreement-link" @tap.stop="openUserAgreement">《用户协议》</text>
|
||||
<text class="agreement-text">和</text>
|
||||
<text class="agreement-link" @tap.stop="openPrivacyPolicy">《隐私政策》</text>
|
||||
</label>
|
||||
</checkbox-group>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getWeChatOpenId } from '@/api/user/user.ts'
|
||||
import useUserStore from "@/stores/user/useUserStore"
|
||||
import { doWxLogin } from "./hooks/login.ts"
|
||||
|
||||
const userStore = useUserStore();
|
||||
const isRegister = ref(false);
|
||||
const inviteCode = ref("");
|
||||
const userInfo = ref({});
|
||||
const isAgree = ref(false);
|
||||
const phoneParams = ref({});
|
||||
const loginType = ref("wxLogin");
|
||||
const autoWxLoginFlag = ref(false);
|
||||
|
||||
|
||||
// 生命周期
|
||||
onLoad((options) => {
|
||||
isRegister.value = options.isRegister == 0;
|
||||
loginType.value = options.loginType || "wxLogin";
|
||||
if (options.inviteCode) {
|
||||
inviteCode.value = options.inviteCode;
|
||||
}
|
||||
autoWxLogin();
|
||||
});
|
||||
|
||||
const getAppId = () => {
|
||||
const appId = uni.getAccountInfoSync().miniProgram.appId;
|
||||
return appId;
|
||||
};
|
||||
|
||||
const autoWxLogin = () => {
|
||||
uni.login({
|
||||
provider: 'weixin',
|
||||
success: function (loginRes) {
|
||||
// 登录成功后显示提示用户需要点击授权
|
||||
uni.showModal({
|
||||
title: '登录提示',
|
||||
content: '请点击下方按钮授权手机号来完成登录',
|
||||
showCancel: false,
|
||||
success: () => {
|
||||
autoWxLoginFlag.value = true;
|
||||
}
|
||||
});
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('微信登录失败:', err)
|
||||
uni.showToast({
|
||||
title: '微信登录失败,请重试',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const getOpenID = async (code) => {
|
||||
try {
|
||||
const { data } = await getWeChatOpenId({ code });
|
||||
phoneParams.value = {
|
||||
sessionKey: data.session_key,
|
||||
openid: data.openid,
|
||||
unionid: data?.unionid ?? "",
|
||||
};
|
||||
uni.showToast({ title: "请授权手机号", icon: "none" });
|
||||
} catch (error) {
|
||||
console.error("获取OpenID失败:", error);
|
||||
}
|
||||
};
|
||||
|
||||
const getPhoneNumber = async (e) => {
|
||||
if (e.detail.errMsg !== 'getPhoneNumber:ok') {
|
||||
uni.showToast({ title: "需要授权手机号才能登录", icon: "none" });
|
||||
return
|
||||
}
|
||||
|
||||
if (!isAgree.value) {
|
||||
uni.showToast({ title: "请先同意用户协议和隐私政策", icon: "none" });
|
||||
return
|
||||
}
|
||||
|
||||
uni.login({
|
||||
provider: 'weixin',
|
||||
success: function (loginRes) {
|
||||
const params = {
|
||||
openIdCode: loginRes.code,
|
||||
phoneCode: e.detail.code,
|
||||
appId: getAppId()
|
||||
}
|
||||
uni.showLoading({
|
||||
title: '登录中...',
|
||||
mask: true
|
||||
})
|
||||
doWxLogin(params).then((res) => {
|
||||
uni.hideLoading()
|
||||
/* uni.reLaunch({
|
||||
url: '/pages/index/index'
|
||||
}) */
|
||||
}).catch(err => {
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
title: err.msg || '登录失败,请重试',
|
||||
icon: 'none'
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 同意协议变更
|
||||
const handleAgreeChange = (e) => {
|
||||
isAgree.value = e.detail.value.length > 0;
|
||||
}
|
||||
|
||||
// 打开用户协议
|
||||
const openUserAgreement = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/agreement/user-agreement'
|
||||
})
|
||||
}
|
||||
|
||||
// 打开隐私政策
|
||||
const openPrivacyPolicy = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/agreement/privacy-policy'
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "./login.scss";
|
||||
|
||||
.login-status {
|
||||
margin: 80rpx 0 40rpx;
|
||||
color: #333;
|
||||
font-size: 30rpx;
|
||||
text-align: center;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.agreement-container {
|
||||
margin-top: 40rpx;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.agreement-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.agreement-text {
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.agreement-link {
|
||||
font-size: 26rpx;
|
||||
color: #07c160;
|
||||
}
|
||||
|
||||
.wx-login-btn {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -50%;
|
||||
left: -50%;
|
||||
width: 200%;
|
||||
height: 200%;
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
transform: rotate(45deg);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
&:active::after {
|
||||
animation: btnRipple 0.6s ease-out;
|
||||
}
|
||||
|
||||
.btn-text {
|
||||
font-weight: 500;
|
||||
letter-spacing: 4rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-disabled {
|
||||
opacity: 0.6;
|
||||
background: linear-gradient(135deg, #cccccc, #aaaaaa) !important;
|
||||
box-shadow: 0 8rpx 20rpx rgba(0, 0, 0, 0.1) !important;
|
||||
}
|
||||
|
||||
@keyframes btnRipple {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translate(-50%, -50%) rotate(45deg) scale(0);
|
||||
}
|
||||
50% {
|
||||
opacity: 0.5;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform: translate(-50%, -50%) rotate(45deg) scale(2);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user