feat(user): 实现扫码登录和推荐人绑定功能- 添加扫码登录相关API接口,包括生成二维码、检查状态、确认登录等
- 在用户注册时支持从邀请参数中获取推荐人ID并绑定 - 修改管理员面板UI,添加统一扫码功能入口- 更新用户管理相关API地址,统一使用SERVER_API_URL - 调整优惠券卡片样式,移除小程序不支持的CSS属性 - 添加聊天会话和消息管理相关API模块 - 新增分销商银行卡管理API接口 - 修改系统用户模型,增加推荐人ID字段 - 更新广告位查询接口,支持根据code获取广告位 - 调整邀请绑定接口参数,将refereeId改为dealerId - 修改环境配置中的应用名称为"时里院子市集" - 移除分享到朋友圈的相关代码 - 添加管理员面板组件,提供统一扫码等管理功能 -修复用户管理API请求参数传递问题 - 添加聊天消息和会话管理的完整CRUD接口 - 更新系统用户相关接口URL,确保正确调用后端服务 - 添加分销商银行卡管理的完整API接口实现 - 修改邀请绑定接口,使用dealerId替代refereeId参数 - 修复扫码登录相关API的URL拼接问题 - 添加二维码内容解析功能,支持多种格式的token提取 - 更新用户信息模型,增加推荐人ID字段 -优化管理员面板样式和交互逻辑- 调整优惠券组件样式,兼容小程序环境限制- 修复用户管理模块的API调用问题 - 添加聊天相关数据模型和接口定义 - 更新环境配置中的应用名称 -修复邀请绑定相关的参数传递问题- 添加扫码登录状态枚举和相关数据结构定义- 优化管理员功能面板的UI展示和交互体验- 修复系统用户管理接口的请求参数问题 - 添加分销商银行卡管理相关接口实现- 调整聊天消息和会话管理接口的数据结构定义 -修复用户管理模块中的API调用路径问题 - 添加扫码登录相关工具函数,如设备信息获取等 - 更新邀请绑定接口的数据模型定义 -优化管理员面板组件的样式和功能实现 -修复系统用户管理接口中的参数传递问题 - 添加聊天相关模块的完整API接口实现 - 调整分销商银行卡管理模块的数据结构定义- 修复扫码登录相关接口的URL拼接问题- 更新用户管理模块中的API调用方式 - 添加聊天消息批量发送等相关接口实现- 修复邀请绑定接口中的参数名称问题- 优化管理员面板组件的功能和交互逻辑 - 调整系统用户管理接口的请求参数传递方式 - 添加分销商银行卡管理模块的完整接口实现 -修复聊天相关接口中的数据结构问题 - 更新扫码登录相关接口的数据模型定义 - 优化管理员功能面板的展示效果和用户体验
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import Taro from '@tarojs/taro';
|
||||
import { User } from '@/api/system/user/model';
|
||||
import { getUserInfo, updateUserInfo } from '@/api/layout';
|
||||
import { getUserInfo, updateUserInfo, loginByOpenId } from '@/api/layout';
|
||||
import { TenantId } from '@/config/app';
|
||||
import {getStoredInviteParams, handleInviteRelation} from '@/utils/invite';
|
||||
|
||||
// 用户Hook
|
||||
export const useUser = () => {
|
||||
@@ -9,8 +11,62 @@ export const useUser = () => {
|
||||
const [isLoggedIn, setIsLoggedIn] = useState(false);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
// 自动登录(通过OpenID)
|
||||
const autoLoginByOpenId = async () => {
|
||||
try {
|
||||
const res = await new Promise<any>((resolve, reject) => {
|
||||
Taro.login({
|
||||
success: (loginRes) => {
|
||||
loginByOpenId({
|
||||
code: loginRes.code,
|
||||
tenantId: TenantId
|
||||
}).then(async (data) => {
|
||||
if (data) {
|
||||
// 保存登录信息
|
||||
saveUserToStorage(data.access_token, data.user);
|
||||
setUser(data.user);
|
||||
setIsLoggedIn(true);
|
||||
|
||||
// 处理邀请关系
|
||||
if (data.user?.userId) {
|
||||
try {
|
||||
const inviteSuccess = await handleInviteRelation(data.user.userId);
|
||||
if (inviteSuccess) {
|
||||
console.log('自动登录时邀请关系建立成功');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('自动登录时处理邀请关系失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
resolve(data.user);
|
||||
} else {
|
||||
reject(new Error('自动登录失败'));
|
||||
}
|
||||
}).catch(_ => {
|
||||
// 首次注册,跳转到邀请注册页面
|
||||
const pages = Taro.getCurrentPages();
|
||||
const currentPage = pages[pages.length - 1];
|
||||
const inviteParams = getStoredInviteParams()
|
||||
if (currentPage?.route !== 'dealer/apply/add' && inviteParams?.inviter) {
|
||||
return Taro.navigateTo({
|
||||
url: '/dealer/apply/add'
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
fail: reject
|
||||
});
|
||||
});
|
||||
return res;
|
||||
} catch (error) {
|
||||
console.error('自动登录失败:', error);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
// 从本地存储加载用户数据
|
||||
const loadUserFromStorage = () => {
|
||||
const loadUserFromStorage = async () => {
|
||||
try {
|
||||
const token = Taro.getStorageSync('access_token');
|
||||
const userData = Taro.getStorageSync('User');
|
||||
@@ -26,8 +82,13 @@ export const useUser = () => {
|
||||
setIsLoggedIn(true);
|
||||
setUser({ userId, tenantId } as User);
|
||||
} else {
|
||||
setUser(null);
|
||||
setIsLoggedIn(false);
|
||||
// 没有本地登录信息,尝试自动登录
|
||||
console.log('没有本地登录信息,尝试自动登录...');
|
||||
const autoLoginResult = await autoLoginByOpenId();
|
||||
if (!autoLoginResult) {
|
||||
setUser(null);
|
||||
setIsLoggedIn(false);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载用户数据失败:', error);
|
||||
@@ -43,9 +104,24 @@ export const useUser = () => {
|
||||
try {
|
||||
Taro.setStorageSync('access_token', token);
|
||||
Taro.setStorageSync('User', userInfo);
|
||||
Taro.setStorageSync('UserId', userInfo.userId);
|
||||
Taro.setStorageSync('TenantId', userInfo.tenantId);
|
||||
Taro.setStorageSync('Phone', userInfo.phone);
|
||||
|
||||
// 确保关键字段不为空时才保存,避免覆盖现有数据
|
||||
if (userInfo.userId) {
|
||||
Taro.setStorageSync('UserId', userInfo.userId);
|
||||
}
|
||||
if (userInfo.tenantId) {
|
||||
Taro.setStorageSync('TenantId', userInfo.tenantId);
|
||||
}
|
||||
if (userInfo.phone) {
|
||||
Taro.setStorageSync('Phone', userInfo.phone);
|
||||
}
|
||||
// 保存头像和昵称信息
|
||||
if (userInfo.avatar) {
|
||||
Taro.setStorageSync('Avatar', userInfo.avatar);
|
||||
}
|
||||
if (userInfo.nickname) {
|
||||
Taro.setStorageSync('Nickname', userInfo.nickname);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('保存用户数据失败:', error);
|
||||
}
|
||||
@@ -114,9 +190,16 @@ export const useUser = () => {
|
||||
}
|
||||
|
||||
try {
|
||||
const updatedUser = { ...user, ...userData };
|
||||
// 先获取最新的用户信息,确保我们有完整的数据
|
||||
const latestUserInfo = await getUserInfo();
|
||||
|
||||
// 合并最新的用户信息和要更新的数据
|
||||
const updatedUser = { ...latestUserInfo, ...userData };
|
||||
|
||||
// 调用API更新用户信息
|
||||
await updateUserInfo(updatedUser);
|
||||
|
||||
// 更新本地状态
|
||||
setUser(updatedUser);
|
||||
|
||||
// 更新本地存储
|
||||
@@ -216,7 +299,10 @@ export const useUser = () => {
|
||||
|
||||
// 初始化时加载用户数据
|
||||
useEffect(() => {
|
||||
loadUserFromStorage();
|
||||
loadUserFromStorage().catch(error => {
|
||||
console.error('初始化用户数据失败:', error);
|
||||
setLoading(false);
|
||||
});
|
||||
}, []);
|
||||
|
||||
return {
|
||||
@@ -231,6 +317,7 @@ export const useUser = () => {
|
||||
fetchUserInfo,
|
||||
updateUser,
|
||||
loadUserFromStorage,
|
||||
autoLoginByOpenId,
|
||||
|
||||
// 工具方法
|
||||
hasPermission,
|
||||
|
||||
Reference in New Issue
Block a user