feat: ✨ 登录功能
This commit is contained in:
parent
f137109b12
commit
78d1978943
@ -1,7 +1,218 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="login">login</view>
|
<view class="viewport">
|
||||||
|
<view class="logo">
|
||||||
|
<view class="logo-text">金佰川微商城</view>
|
||||||
|
</view>
|
||||||
|
<view class="login">
|
||||||
|
<!-- 网页端表单登录 -->
|
||||||
|
<!-- <input class="input" type="text" placeholder="请输入用户名/手机号码" />
|
||||||
|
<input class="input" type="text" password placeholder="请输入密码" />
|
||||||
|
<button class="button phone">登录</button> -->
|
||||||
|
|
||||||
|
<!-- 小程序端授权登录 -->
|
||||||
|
<button class="button phone" @getphonenumber="onGetPhoneNumber">
|
||||||
|
<text class="icon icon-phone"></text>
|
||||||
|
手机号快捷登录
|
||||||
|
</button>
|
||||||
|
<view class="extra">
|
||||||
|
<view class="caption">
|
||||||
|
<text>其他登录方式</text>
|
||||||
|
</view>
|
||||||
|
<view class="options">
|
||||||
|
<!-- 通用模拟登录 -->
|
||||||
|
<button @tap="handlePhoneLogin">
|
||||||
|
<text class="icon icon-phone">模拟快捷登录</text>
|
||||||
|
</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="tips">登录/注册即视为你同意《服务条款》和《隐私协议》</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup></script>
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
|
import { postPhoneNumberAPI, postPhoneNumberLoginMockAPI } from '@/services/login'
|
||||||
|
import { useMemberStore } from '@/stores/modules/member'
|
||||||
|
import type { LoginResult } from '@/types/member'
|
||||||
|
|
||||||
<style lang="scss"></style>
|
// 会员信息
|
||||||
|
const memberStore = useMemberStore()
|
||||||
|
|
||||||
|
const code = ref('')
|
||||||
|
onLoad(async () => {
|
||||||
|
const res = await wx.login()
|
||||||
|
code.value = res.code
|
||||||
|
})
|
||||||
|
|
||||||
|
// 获取手机号, 需要认证的小程序才可以调用
|
||||||
|
const onGetPhoneNumber: UniHelper.ButtonOnGetphonenumber = async (e) => {
|
||||||
|
if (e.detail.errMsg === 'getPhoneNumber:ok') {
|
||||||
|
const encryptedData = e.detail.encryptedData!
|
||||||
|
const iv = e.detail.iv!
|
||||||
|
const res = await postPhoneNumberAPI({
|
||||||
|
code: code.value,
|
||||||
|
encryptedData,
|
||||||
|
iv,
|
||||||
|
})
|
||||||
|
res.result && loginSucess(res.result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 模拟快捷登录
|
||||||
|
const handlePhoneLogin = async () => {
|
||||||
|
if (!code.value) {
|
||||||
|
uni.showToast({
|
||||||
|
title: '请先授权登录',
|
||||||
|
icon: 'none',
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const res = await postPhoneNumberLoginMockAPI({
|
||||||
|
phoneNumber: '13800138000',
|
||||||
|
})
|
||||||
|
res.result && loginSucess(res.result)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 登录存储信息
|
||||||
|
const loginSucess = (profile: LoginResult) => {
|
||||||
|
memberStore.clearProfile()
|
||||||
|
memberStore.setProfile(profile)
|
||||||
|
uni.showToast({
|
||||||
|
title: '登录成功',
|
||||||
|
icon: 'none',
|
||||||
|
})
|
||||||
|
setTimeout(() => {
|
||||||
|
uni.switchTab({
|
||||||
|
url: '/pages/my/my',
|
||||||
|
})
|
||||||
|
}, 500)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
page {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.viewport {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
padding: 20rpx 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
flex: 1;
|
||||||
|
text-align: center;
|
||||||
|
.logo-text {
|
||||||
|
margin-top: 25vh;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.login {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 60vh;
|
||||||
|
padding: 40rpx 20rpx 20rpx;
|
||||||
|
|
||||||
|
.input {
|
||||||
|
width: 100%;
|
||||||
|
height: 80rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
border-radius: 72rpx;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
padding-left: 30rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 80rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
border-radius: 72rpx;
|
||||||
|
color: #fff;
|
||||||
|
.icon {
|
||||||
|
font-size: 40rpx;
|
||||||
|
margin-right: 6rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.phone {
|
||||||
|
background-color: #28bb9c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wechat {
|
||||||
|
background-color: #06c05f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.extra {
|
||||||
|
flex: 1;
|
||||||
|
padding: 70rpx 70rpx 0;
|
||||||
|
.caption {
|
||||||
|
width: 440rpx;
|
||||||
|
line-height: 1;
|
||||||
|
border-top: 1rpx solid #ddd;
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #999;
|
||||||
|
position: relative;
|
||||||
|
text {
|
||||||
|
transform: translate(-40%);
|
||||||
|
background-color: #fff;
|
||||||
|
position: absolute;
|
||||||
|
top: -12rpx;
|
||||||
|
left: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.options {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 70rpx;
|
||||||
|
button {
|
||||||
|
padding: 0;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #444;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 80rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
margin-bottom: 6rpx;
|
||||||
|
font-size: 40rpx;
|
||||||
|
border: 1rpx solid #444;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.icon-weixin::before {
|
||||||
|
border-color: #06c05f;
|
||||||
|
color: #06c05f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tips {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 80rpx;
|
||||||
|
left: 20rpx;
|
||||||
|
right: 20rpx;
|
||||||
|
font-size: 22rpx;
|
||||||
|
color: #999;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
29
src/services/login.ts
Normal file
29
src/services/login.ts
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import { http } from '@/utils/http'
|
||||||
|
import type { LoginResult } from '@/types/member'
|
||||||
|
|
||||||
|
type LoginParams = {
|
||||||
|
code: string
|
||||||
|
encryptedData: string
|
||||||
|
iv: string
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取手机号
|
||||||
|
export const postPhoneNumberAPI = (data: LoginParams) => {
|
||||||
|
return http<LoginResult>({
|
||||||
|
url: '/login/wxMin',
|
||||||
|
method: 'POST',
|
||||||
|
data,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 模拟快捷登录
|
||||||
|
type PhoneNumberLoginMockParams = {
|
||||||
|
phoneNumber: string
|
||||||
|
}
|
||||||
|
export const postPhoneNumberLoginMockAPI = (data: PhoneNumberLoginMockParams) => {
|
||||||
|
return http<LoginResult>({
|
||||||
|
url: '/login/wxMin/simple',
|
||||||
|
method: 'POST',
|
||||||
|
data,
|
||||||
|
})
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user