封版手机一键登录

This commit is contained in:
2025-07-31 09:56:28 +08:00
parent 286215ced0
commit 024e04041c
6 changed files with 198 additions and 177 deletions

View File

@@ -7,6 +7,7 @@ import type {
SmsCaptchaResult
} from './model';
import {saveStorageByLoginUser, SERVER_API_URL} from "@/utils/server";
import Taro from '@tarojs/taro';
/**
* 登录
@@ -138,3 +139,131 @@ export async function loginMpWxMobile(data: {
}
return Promise.reject(new Error(res.message));
}
/**
* 微信小程序手机号登录
* @param phoneDetail 微信授权手机号的详细信息
* @param options 登录选项配置
*/
export async function wxPhoneLogin(
phoneDetail: { code: string; encryptedData: string; iv: string },
options?: {
onSuccess?: (user: any) => void;
onError?: (error: string) => void;
showToast?: boolean;
navigateBack?: boolean;
tenantId?: number;
}
) {
const { code, encryptedData, iv } = phoneDetail;
const {
onSuccess,
onError,
showToast = true,
navigateBack = true,
tenantId
} = options || {};
return new Promise((resolve, reject) => {
Taro.login({
success: function () {
if (code) {
Taro.request({
url: 'https://server.websoft.top/api/wx-login/loginByMpWxPhone',
method: 'POST',
data: {
code,
encryptedData,
iv,
notVerifyPhone: true,
refereeId: 0,
sceneType: 'save_referee',
tenantId: tenantId || require('@/utils/config').TenantId
},
header: {
'content-type': 'application/json',
TenantId: tenantId || require('@/utils/config').TenantId
},
success: function (res) {
if (res.data?.code === 0 && res.data?.data) {
// 保存登录信息
saveStorageByLoginUser(res.data.data.access_token, res.data.data.user);
if (showToast) {
Taro.showToast({
title: '登录成功',
icon: 'success'
});
}
// 执行成功回调
if (onSuccess) {
onSuccess(res.data.data.user);
}
// 导航返回
if (navigateBack) {
setTimeout(() => {
Taro.navigateBack();
}, 1500);
}
resolve(res.data.data.user);
} else {
const errorMsg = res.data?.message || '登录失败';
if (onError) {
onError(errorMsg);
}
if (showToast) {
Taro.showToast({
title: errorMsg,
icon: 'error'
});
}
reject(new Error(errorMsg));
}
},
fail: function (_error) {
const errorMsg = '网络请求失败';
if (onError) {
onError(errorMsg);
}
if (showToast) {
Taro.showToast({
title: errorMsg,
icon: 'error'
});
}
reject(new Error(errorMsg));
}
});
} else {
const errorMsg = '获取微信登录凭证失败';
if (onError) {
onError(errorMsg);
}
if (showToast) {
Taro.showToast({
title: errorMsg,
icon: 'error'
});
}
reject(new Error(errorMsg));
}
},
fail: function (_error) {
const errorMsg = '微信登录失败';
if (onError) {
onError(errorMsg);
}
if (showToast) {
Taro.showToast({
title: errorMsg,
icon: 'error'
});
}
reject(new Error(errorMsg));
}
});
});
}

View File

@@ -1,48 +1,12 @@
import {useEffect, useState} from "react";
import Taro from '@tarojs/taro'
import {Input, Radio, Button} from '@nutui/nutui-react-taro'
import {TenantId} from "@/utils/config";
import './login.scss';
import {saveStorageByLoginUser} from "@/utils/server";
const Login = (props:any) => {
const Login = () => {
const [isAgree, setIsAgree] = useState(false)
const [env, setEnv] = useState<string>()
/* 获取用户手机号 */
const handleGetPhoneNumber = ({detail}) => {
const {code, encryptedData, iv} = detail
Taro.login({
success: function () {
if (code) {
Taro.request({
url: 'https://server.websoft.top/api/wx-login/loginByMpWxPhone',
method: 'POST',
data: {
code,
encryptedData,
iv,
notVerifyPhone: true,
refereeId: 0,
sceneType: 'save_referee',
tenantId: TenantId
},
header: {
'content-type': 'application/json',
TenantId
},
success: function (res) {
saveStorageByLoginUser(res.data.data.access_token,res.data.data.user)
props.done(res.data.data.user);
}
})
} else {
console.log('登录失败!')
}
}
})
}
const reload = () => {
Taro.hideTabBar()
setEnv(Taro.getEnv())

View File

@@ -1,12 +1,9 @@
import {useEffect, useState} from 'react'
import {navigateTo} from '@tarojs/taro'
import Taro from '@tarojs/taro'
import {Button} from '@tarojs/components';
import {Image} from '@nutui/nutui-react-taro'
import {getUserInfo, getWxOpenId} from "@/api/layout";
import {TenantId} from "@/utils/config";
import {User} from "@/api/system/user/model";
// import News from "./News";
import {myPageBszxBm} from "@/api/bszx/bszxBm";
import {listCmsNavigation} from "@/api/cms/cmsNavigation";
@@ -18,47 +15,6 @@ const Page = () => {
const [bmLogs, setBmLogs] = useState<any>()
const [navItems, setNavItems] = useState<any>([])
/* 获取用户手机号 */
const handleGetPhoneNumber = ({detail}) => {
const {code, encryptedData, iv} = detail
Taro.login({
success: function () {
if (code) {
Taro.request({
url: 'https://server.websoft.top/api/wx-login/loginByMpWxPhone',
method: 'POST',
data: {
code,
encryptedData,
iv,
notVerifyPhone: true,
refereeId: 0,
sceneType: 'save_referee',
tenantId: TenantId
},
header: {
'content-type': 'application/json',
TenantId
},
success: function (res) {
Taro.setStorageSync('access_token', res.data.data.access_token)
Taro.setStorageSync('UserId', res.data.data.user.userId)
setUserInfo(res.data.data.user)
Taro.setStorageSync('Phone', res.data.data.user.phone)
setIsLogin(true)
Taro.showToast({
title: '登录成功',
icon: 'success'
});
}
})
} else {
console.log('登录失败!')
}
}
})
}
const onLogin = (item: any, index: number) => {
if(!isLogin){
return navigateTo({url: `/pages/category/category?id=${item.navigationId}`})
@@ -201,8 +157,6 @@ const Page = () => {
}
</div>
</div>
{/*<image src={'https://oss.wsdns.cn/20250224/18a2f3b807c94aac8a67af34e95534d6.jpeg'} className={'book'}>倡议书</image>*/}
{/*<News id={categoryId}/>*/}
</div>
)
}

View File

@@ -1,12 +1,9 @@
import {useEffect, useState} from 'react'
import {navigateTo} from '@tarojs/taro'
import Taro from '@tarojs/taro'
import {Button} from '@tarojs/components';
import {Image} from '@nutui/nutui-react-taro'
import {getUserInfo, getWxOpenId} from "@/api/layout";
import {TenantId} from "@/utils/config";
import {User} from "@/api/system/user/model";
// import News from "./News";
import {myPageBszxBm} from "@/api/bszx/bszxBm";
import {listCmsNavigation} from "@/api/cms/cmsNavigation";
@@ -18,47 +15,6 @@ const OrderIcon = () => {
const [bmLogs, setBmLogs] = useState<any>()
const [navItems, setNavItems] = useState<any>([])
/* 获取用户手机号 */
const handleGetPhoneNumber = ({detail}) => {
const {code, encryptedData, iv} = detail
Taro.login({
success: function () {
if (code) {
Taro.request({
url: 'https://server.websoft.top/api/wx-login/loginByMpWxPhone',
method: 'POST',
data: {
code,
encryptedData,
iv,
notVerifyPhone: true,
refereeId: 0,
sceneType: 'save_referee',
tenantId: TenantId
},
header: {
'content-type': 'application/json',
TenantId
},
success: function (res) {
Taro.setStorageSync('access_token', res.data.data.access_token)
Taro.setStorageSync('UserId', res.data.data.user.userId)
setUserInfo(res.data.data.user)
Taro.setStorageSync('Phone', res.data.data.user.phone)
setIsLogin(true)
Taro.showToast({
title: '登录成功',
icon: 'success'
});
}
})
} else {
console.log('登录失败!')
}
}
})
}
const onLogin = (item: any, index: number) => {
if(!isLogin){
return navigateTo({url: `/pages/category/category?id=${item.navigationId}`})
@@ -201,8 +157,6 @@ const OrderIcon = () => {
}
</div>
</div>
{/*<image src={'https://oss.wsdns.cn/20250224/18a2f3b807c94aac8a67af34e95534d6.jpeg'} className={'book'}>倡议书</image>*/}
{/*<News id={categoryId}/>*/}
</div>
)
}

View File

@@ -1,11 +1,9 @@
import {Button} from '@nutui/nutui-react-taro'
import {Avatar, Tag, Space} from '@nutui/nutui-react-taro'
import {getUserInfo, getWxOpenId} from '@/api/layout';
import Taro from '@tarojs/taro';
import {useEffect, useState} from "react";
import {User} from "@/api/system/user/model";
import navTo from "@/utils/common";
import {TenantId} from "@/utils/config";
function UserCard() {
const [IsLogin, setIsLogin] = useState<boolean>(false)
@@ -100,42 +98,6 @@ function UserCard() {
});
};
/* 获取用户手机号 */
const handleGetPhoneNumber = ({detail}) => {
const {code, encryptedData, iv} = detail
Taro.login({
success: function () {
if (code) {
Taro.request({
url: 'https://server.websoft.top/api/wx-login/loginByMpWxPhone',
method: 'POST',
data: {
code,
encryptedData,
iv,
notVerifyPhone: true,
refereeId: 0,
sceneType: 'save_referee',
tenantId: TenantId
},
header: {
'content-type': 'application/json',
TenantId
},
success: function (res) {
Taro.setStorageSync('access_token', res.data.data.access_token)
Taro.setStorageSync('UserId', res.data.data.user.userId)
setUserInfo(res.data.data.user)
setIsLogin(true)
}
})
} else {
console.log('登录失败!')
}
}
})
}
return (
<>
<div className={'p-4'}>

View File

@@ -1,16 +1,81 @@
import {useEffect, useState} from "react";
import Taro from '@tarojs/taro'
import {Radio, Button} from '@nutui/nutui-react-taro'
import { createWxLoginHandler } from '@/utils/wxLogin'
import {TenantId} from "@/utils/config";
const Login = () => {
const [isAgree, setIsAgree] = useState(false)
const reload = () => {
Taro.hideTabBar()
}
};
const showAuthModal = () => {
Taro.showModal({
title: '授权提示',
content: '需要获取您的用户信息',
confirmText: '去授权',
cancelText: '取消',
success: (res) => {
if (res.confirm) {
// 用户点击确认,打开授权设置页面
openSetting();
}
}
});
};
const openSetting = () => {
// Taro.openSetting调起客户端小程序设置界面返回用户设置的操作结果。设置界面只会出现小程序已经向用户请求过的权限。
Taro.openSetting({
success: (res) => {
if (res.authSetting['scope.userInfo']) {
// 用户授权成功,可以获取用户信息
reload();
} else {
// 用户拒绝授权,提示授权失败
Taro.showToast({
title: '授权失败',
icon: 'none'
});
}
}
});
};
// 创建微信登录处理函数
const handleGetPhoneNumber = createWxLoginHandler({
onSuccess: (user) => {
console.log('登录成功:', user);
// 可以在这里添加额外的成功处理逻辑
},
onError: (error) => {
console.error('登录失败:', error);
},
showToast: true,
navigateBack: true,
tenantId: TenantId
});
useEffect(() => {
reload()
}, [])
// Taro.getSetting获取用户的当前设置。返回值中只会出现小程序已经向用户请求过的权限。
Taro.getSetting({
success: (res) => {
if (res.authSetting['scope.userInfo']) {
// 用户已经授权过,可以直接获取用户信息
console.log('用户已经授权过,可以直接获取用户信息')
reload();
} else {
// 用户未授权,需要弹出授权窗口
console.log('用户未授权,需要弹出授权窗口')
showAuthModal();
}
}
});
}, []);
return (
<>
@@ -20,15 +85,8 @@ const Login = () => {
<>
<div className={'flex justify-center my-5'}>
<Button type="info" size={'large'} className={'w-full rounded-lg p-2'}
disabled={!isAgree}></Button>
disabled={!isAgree} open-type="getPhoneNumber" onGetPhoneNumber={handleGetPhoneNumber}></Button>
</div>
{/*<div className={'my-2 flex fixed justify-center bottom-20 left-0 text-sm items-center text-center w-full'}>*/}
{/* <Button onClick={() => Taro.navigateTo({url: '/passport/setting'})}>服务配置</Button>*/}
{/*</div>*/}
{/*<div className={'w-full fixed bottom-20 my-2 flex justify-center text-sm items-center text-center'}>*/}
{/* 没有账号?<a href={''} onClick={() => Taro.navigateTo({url: '/passport/register'})}*/}
{/* className={'text-blue-600'}>立即注册</a>*/}
{/*</div>*/}
</>
<div className={'my-2 flex text-sm items-center px-1'}>