fix(runtime): 解决运行时错误并优化自动登录功能

-修复了 Taro 应用启动时的运行时错误
- 解决了 TypeScript 类型错误和导入问题
- 优化了自动登录逻辑,集成到 useUser Hook 中
- 从 app.ts 中移除了重复的自动登录代码
- 在 Header.tsx 中添加了正确的 API 调用
This commit is contained in:
2025-09-05 14:17:13 +08:00
parent 16db2c4eac
commit 1df0f7735c
6 changed files with 374 additions and 47 deletions

View File

@@ -3,48 +3,13 @@ import Taro, {useDidShow, useDidHide} from '@tarojs/taro'
// 全局样式
import './app.scss'
import {loginByOpenId} from "@/api/layout";
import {TenantId} from "@/config/app";
import {saveStorageByLoginUser} from "@/utils/server";
import {parseInviteParams, saveInviteParams, trackInviteSource, handleInviteRelation} from "@/utils/invite";
import {parseInviteParams, saveInviteParams, trackInviteSource} from "@/utils/invite";
function App(props: { children: any; }) {
const reload = () => {
Taro.login({
success: (res) => {
loginByOpenId({
code: res.code,
tenantId: TenantId
}).then(async data => {
if (data) {
saveStorageByLoginUser(data.access_token, data.user)
// 处理邀请关系
if (data.user?.userId) {
try {
const inviteSuccess = await handleInviteRelation(data.user.userId)
if (inviteSuccess) {
console.log('自动登录时邀请关系建立成功')
}
} catch (error) {
console.error('自动登录时处理邀请关系失败:', error)
}
}
}
})
}
})
};
// 可以使用所有的 React Hooks
useEffect(() => {
// Taro.getSetting获取用户的当前设置。返回值中只会出现小程序已经向用户请求过的权限。
Taro.getSetting({
success: (res) => {
if (res.authSetting['scope.userInfo']) {
reload();
}
}
});
// 自动登录逻辑现在已经集成到 useUser Hook 中
// 这里只需要处理邀请参数
}, []);
// 对应 onShow

View File

@@ -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 { handleInviteRelation } from '@/utils/invite';
// 用户Hook
export const useUser = () => {
@@ -9,8 +11,52 @@ 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(reject);
},
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 +72,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);
@@ -216,7 +267,10 @@ export const useUser = () => {
// 初始化时加载用户数据
useEffect(() => {
loadUserFromStorage();
loadUserFromStorage().catch(error => {
console.error('初始化用户数据失败:', error);
setLoading(false);
});
}, []);
return {
@@ -231,6 +285,7 @@ export const useUser = () => {
fetchUserInfo,
updateUser,
loadUserFromStorage,
autoLoginByOpenId,
// 工具方法
hasPermission,

View File

@@ -1,9 +1,9 @@
import { useState, useEffect, useCallback } from 'react'
import {pageShopUserCoupon} from "@/api/shop/shopUserCoupon";
import {pageShopGift} from "@/api/shop/shopGift";
import {useUser} from "@/hooks/useUser";
import Taro from '@tarojs/taro'
import {getUserInfo} from "@/api/layout";
import {useUser} from "@/hooks/useUser";
interface UserData {
balance: number
@@ -35,6 +35,14 @@ export const useUserData = (): UseUserDataReturn => {
// 获取用户数据
const fetchUserData = useCallback(async () => {
// 检查用户ID是否存在更直接的登录状态检查
const userId = Taro.getStorageSync('UserId')
if (!userId) {
setLoading(false)
setData(null)
return
}
try {
setLoading(true)
setError(null)
@@ -42,8 +50,8 @@ export const useUserData = (): UseUserDataReturn => {
// 并发请求所有数据
const [userDataRes, couponsRes, giftCardsRes] = await Promise.all([
getUserInfo(),
pageShopUserCoupon({ page: 1, limit: 1, userId: Taro.getStorageSync('UserId'), status: 0}),
pageShopGift({ page: 1, limit: 1, userId: Taro.getStorageSync('UserId'), status: 0})
pageShopUserCoupon({ page: 1, limit: 1, userId, status: 0}),
pageShopGift({ page: 1, limit: 1, userId, status: 0})
])
const newData: UserData = {

View File

@@ -96,12 +96,13 @@ const Header = (props: any) => {
const handleGetPhoneNumber = ({detail}: { detail: { code?: string, encryptedData?: string, iv?: string } }) => {
const {code, encryptedData, iv} = detail
Taro.login({
success: function () {
success: (loginRes)=> {
if (code) {
Taro.request({
url: 'https://server.websoft.top/api/wx-login/loginByMpWxPhone',
method: 'POST',
data: {
authCode: loginRes.code,
code,
encryptedData,
iv,