|
|
|
@ -10,7 +10,7 @@ import {
|
|
|
|
|
Image, |
|
|
|
|
Modal, |
|
|
|
|
SafeAreaView, |
|
|
|
|
Alert |
|
|
|
|
Alert, |
|
|
|
|
} from "react-native"; |
|
|
|
|
import { useTranslation } from "react-i18next"; |
|
|
|
|
import { useNavigation } from "@react-navigation/native"; |
|
|
|
@ -21,31 +21,32 @@ import PhoneLoginModal from "./PhoneLoginModal";
|
|
|
|
|
import { loginApi } from "../../services/api/login"; |
|
|
|
|
import { userApi } from "../../services"; |
|
|
|
|
import useUserStore from "../../store/user"; |
|
|
|
|
import AsyncStorage from "@react-native-async-storage/async-storage"; |
|
|
|
|
|
|
|
|
|
// 使用标准的ES6模块导入
|
|
|
|
|
// import {
|
|
|
|
|
// GoogleSignin,
|
|
|
|
|
// statusCodes,
|
|
|
|
|
// } from "@react-native-google-signin/google-signin";
|
|
|
|
|
import { |
|
|
|
|
GoogleSignin, |
|
|
|
|
statusCodes, |
|
|
|
|
} from "@react-native-google-signin/google-signin"; |
|
|
|
|
|
|
|
|
|
// import { LoginManager, AccessToken, Settings } from "react-native-fbsdk-next";
|
|
|
|
|
import { LoginManager, AccessToken, Settings } from "react-native-fbsdk-next"; |
|
|
|
|
|
|
|
|
|
const isDevelopment = __DEV__; // 开发模式检测
|
|
|
|
|
|
|
|
|
|
// 移出条件块,始终尝试配置 Google 登录
|
|
|
|
|
// try {
|
|
|
|
|
// // 配置 Google 登录
|
|
|
|
|
// GoogleSignin.configure({
|
|
|
|
|
// iosClientId: "YOUR_IOS_CLIENT_ID_HERE.apps.googleusercontent.com", // iOS CLIENT_ID
|
|
|
|
|
// webClientId:
|
|
|
|
|
// "449517618313-av37nffa7rqkefu0ajh5auou3pb0mt51.apps.googleusercontent.com", // <-- 更新为此 Web Client ID
|
|
|
|
|
// scopes: ["profile", "email"],
|
|
|
|
|
// offlineAccess: false, // <-- 确保为 false 或移除
|
|
|
|
|
// forceCodeForRefreshToken: false, // <-- 确保为 false 或移除
|
|
|
|
|
// });
|
|
|
|
|
// } catch (error) {
|
|
|
|
|
// console.log("Google Sign-in模块配置错误:", error); // 稍微修改了日志信息
|
|
|
|
|
// }
|
|
|
|
|
try { |
|
|
|
|
// 配置 Google 登录
|
|
|
|
|
GoogleSignin.configure({ |
|
|
|
|
iosClientId: "YOUR_IOS_CLIENT_ID_HERE.apps.googleusercontent.com", // iOS CLIENT_ID
|
|
|
|
|
webClientId: |
|
|
|
|
"449517618313-av37nffa7rqkefu0ajh5auou3pb0mt51.apps.googleusercontent.com", // <-- 更新为此 Web Client ID
|
|
|
|
|
scopes: ["profile", "email"], |
|
|
|
|
offlineAccess: false, // <-- 确保为 false 或移除
|
|
|
|
|
forceCodeForRefreshToken: false, // <-- 确保为 false 或移除
|
|
|
|
|
}); |
|
|
|
|
} catch (error) { |
|
|
|
|
console.log("Google Sign-in模块配置错误:", error); // 稍微修改了日志信息
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
type RootStackParamList = { |
|
|
|
|
Login: undefined; |
|
|
|
@ -108,122 +109,154 @@ export const LoginScreen = ({ onClose, isModal }: LoginScreenProps) => {
|
|
|
|
|
|
|
|
|
|
// 处理谷歌登录
|
|
|
|
|
const handleGoogleLogin = async () => { |
|
|
|
|
// try {
|
|
|
|
|
// if (!GoogleSignin || typeof GoogleSignin.signIn !== "function") {
|
|
|
|
|
// console.log("Google Sign-in模块未正确初始化或配置失败");
|
|
|
|
|
// return;
|
|
|
|
|
// }
|
|
|
|
|
// await GoogleSignin.hasPlayServices();
|
|
|
|
|
// const userInfo = await GoogleSignin.signIn();
|
|
|
|
|
// console.log("Google 登录成功:", userInfo);
|
|
|
|
|
// try {
|
|
|
|
|
// const res = await loginApi.googleLogin(userInfo);
|
|
|
|
|
// const user = await userApi.getProfile();
|
|
|
|
|
// setUser(user);
|
|
|
|
|
try { |
|
|
|
|
if (!GoogleSignin || typeof GoogleSignin.signIn !== "function") { |
|
|
|
|
console.log("Google Sign-in模块未正确初始化或配置失败"); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
await GoogleSignin.hasPlayServices(); |
|
|
|
|
const userInfo = await GoogleSignin.signIn(); |
|
|
|
|
console.log("Google 登录成功:", userInfo); |
|
|
|
|
try { |
|
|
|
|
const res = await loginApi.googleLogin(userInfo); |
|
|
|
|
const token = res.token_type + " " + res.access_token; |
|
|
|
|
await AsyncStorage.setItem("token", token); |
|
|
|
|
const user = await userApi.getProfile(); |
|
|
|
|
setUser(user); |
|
|
|
|
navigation.navigate("MainTabs", { screen: "Home" }); |
|
|
|
|
} catch (err) { |
|
|
|
|
console.log("Google 登录失败:", err); |
|
|
|
|
navigation.navigate("Login"); |
|
|
|
|
} |
|
|
|
|
// 这里可以处理登录成功后的逻辑
|
|
|
|
|
// 比如导航到主页面或保存用户信息
|
|
|
|
|
// navigation.navigate("MainTabs", { screen: "Home" });
|
|
|
|
|
// } catch (err) {
|
|
|
|
|
// console.log("Google 登录失败:", err);
|
|
|
|
|
// navigation.navigate("Login");
|
|
|
|
|
// }
|
|
|
|
|
// // 这里可以处理登录成功后的逻辑
|
|
|
|
|
// // 比如导航到主页面或保存用户信息
|
|
|
|
|
// // navigation.navigate("MainTabs", { screen: "Home" });
|
|
|
|
|
// } catch (error: any) {
|
|
|
|
|
// console.log("Google 登录错误:", error);
|
|
|
|
|
// // 开发模式下的错误处理
|
|
|
|
|
// if (isDevelopment) {
|
|
|
|
|
// console.log("开发模式:忽略Google登录错误,但已尝试真实登录"); // 修改日志,表明已尝试真实登录
|
|
|
|
|
// return;
|
|
|
|
|
// }
|
|
|
|
|
// if (statusCodes && error.code === statusCodes.SIGN_IN_CANCELLED) {
|
|
|
|
|
// console.log("用户取消登录");
|
|
|
|
|
// } else if (statusCodes && error.code === statusCodes.IN_PROGRESS) {
|
|
|
|
|
// console.log("登录正在进行中");
|
|
|
|
|
// } else if (
|
|
|
|
|
// statusCodes &&
|
|
|
|
|
// error.code === statusCodes.PLAY_SERVICES_NOT_AVAILABLE
|
|
|
|
|
// ) {
|
|
|
|
|
// console.log("Play Services 不可用");
|
|
|
|
|
// } else {
|
|
|
|
|
// console.log("其他错误:", error.message);
|
|
|
|
|
// navigation.navigate("Login");
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
} catch (error: any) { |
|
|
|
|
console.log("Google 登录错误:", error); |
|
|
|
|
// 开发模式下的错误处理
|
|
|
|
|
if (isDevelopment) { |
|
|
|
|
console.log("开发模式:忽略Google登录错误,但已尝试真实登录"); // 修改日志,表明已尝试真实登录
|
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
if (statusCodes && error.code === statusCodes.SIGN_IN_CANCELLED) { |
|
|
|
|
console.log("用户取消登录"); |
|
|
|
|
} else if (statusCodes && error.code === statusCodes.IN_PROGRESS) { |
|
|
|
|
console.log("登录正在进行中"); |
|
|
|
|
} else if ( |
|
|
|
|
statusCodes && |
|
|
|
|
error.code === statusCodes.PLAY_SERVICES_NOT_AVAILABLE |
|
|
|
|
) { |
|
|
|
|
console.log("Play Services 不可用"); |
|
|
|
|
} else { |
|
|
|
|
console.log("其他错误:", error.message); |
|
|
|
|
navigation.navigate("Login"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
const [userInfo, setUserInfo] = useState<any>(null); |
|
|
|
|
|
|
|
|
|
// useEffect(() => {
|
|
|
|
|
// // 确保在 App 启动时初始化 SDK。这通常在您的 App.js 的顶层完成。
|
|
|
|
|
// // 如果您在 app.json 中配置了 Facebook App ID,这里可以省略 Settings.setAppID 和 Settings.setDisplayName
|
|
|
|
|
// Settings.initializeSDK();
|
|
|
|
|
|
|
|
|
|
// // 在应用程序启动时检查是否已经登录(可选)
|
|
|
|
|
// AccessToken.getCurrentAccessToken().then(data => {
|
|
|
|
|
// if (data) {
|
|
|
|
|
// console.log("已登录 Facebook,Token:", data.accessToken);
|
|
|
|
|
// // 可以尝试获取用户信息
|
|
|
|
|
// // fetchFacebookProfile(data.accessToken);
|
|
|
|
|
// }
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
|
// }, []);
|
|
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
|
// 确保在 App 启动时初始化 SDK。这通常在您的 App.js 的顶层完成。
|
|
|
|
|
// 如果您在 app.json 中配置了 Facebook App ID,这里可以省略 Settings.setAppID 和 Settings.setDisplayName
|
|
|
|
|
Settings.initializeSDK(); |
|
|
|
|
|
|
|
|
|
// 在应用程序启动时检查是否已经登录(可选)
|
|
|
|
|
AccessToken.getCurrentAccessToken().then((data) => { |
|
|
|
|
if (data) { |
|
|
|
|
console.log("已登录 Facebook,Token:", data.accessToken); |
|
|
|
|
// 可以尝试获取用户信息
|
|
|
|
|
// fetchFacebookProfile(data.accessToken);
|
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
}, []); |
|
|
|
|
|
|
|
|
|
// 辅助函数:获取 Facebook 用户资料 (可选,需要 'public_profile' 权限)
|
|
|
|
|
// const fetchFacebookProfile = async (token:string) => {
|
|
|
|
|
// try {
|
|
|
|
|
// const response = await fetch(`https://graph.facebook.com/me?fields=id,name,email&access_token=${token}`);
|
|
|
|
|
// const profile = await response.json();
|
|
|
|
|
// setUserInfo(profile);
|
|
|
|
|
// console.log('Facebook User Info:', profile);
|
|
|
|
|
// } catch (error) {
|
|
|
|
|
// console.error('获取 Facebook 用户资料错误:', error);
|
|
|
|
|
// Alert.alert("获取资料失败", "无法从 Facebook 获取用户详细资料,请检查网络或权限设置。");
|
|
|
|
|
// }
|
|
|
|
|
// };
|
|
|
|
|
const fetchFacebookProfile = async (token: string) => { |
|
|
|
|
try { |
|
|
|
|
const response = await fetch( |
|
|
|
|
`https://graph.facebook.com/me?fields=id,name,email&access_token=${token}` |
|
|
|
|
); |
|
|
|
|
const profile = await response.json(); |
|
|
|
|
setUserInfo(profile); |
|
|
|
|
console.log("Facebook User Info:", profile); |
|
|
|
|
return profile; |
|
|
|
|
} catch (error) { |
|
|
|
|
console.error("获取 Facebook 用户资料错误:", error); |
|
|
|
|
Alert.alert( |
|
|
|
|
"获取资料失败", |
|
|
|
|
"无法从 Facebook 获取用户详细资料,请检查网络或权限设置。" |
|
|
|
|
); |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// 处理Facebook登录
|
|
|
|
|
const handleFacebookLogin = async () => { |
|
|
|
|
// try {
|
|
|
|
|
// // 可选: 先退出登录,确保每次都是全新登录 (主要用于测试)
|
|
|
|
|
// // await LoginManager.logOut();
|
|
|
|
|
|
|
|
|
|
// const result = await LoginManager.logInWithPermissions([
|
|
|
|
|
// "public_profile",
|
|
|
|
|
// "email",
|
|
|
|
|
// ]);
|
|
|
|
|
|
|
|
|
|
// if (result.isCancelled) {
|
|
|
|
|
// Alert.alert("登录取消", "用户取消了 Facebook 登录。");
|
|
|
|
|
// return;
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// const data = await AccessToken.getCurrentAccessToken();
|
|
|
|
|
// // 确保 accessToken 存在且为字符串
|
|
|
|
|
// if (!data || !data.accessToken) {
|
|
|
|
|
// Alert.alert("登录失败", "无法获取有效的 Facebook AccessToken。");
|
|
|
|
|
// return;
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// const tokenString = data.accessToken.toString();
|
|
|
|
|
// console.log("Facebook Access Token:", tokenString);
|
|
|
|
|
|
|
|
|
|
// // 直接获取 Facebook 用户信息并打印
|
|
|
|
|
// await fetchFacebookProfile(tokenString);
|
|
|
|
|
|
|
|
|
|
// // 移除之前的 Alert, 因为 fetchFacebookProfile 内部会处理打印和可能的错误提示
|
|
|
|
|
// // 如果 fetchFacebookProfile 成功,信息已在控制台,如果失败,它会 Alert
|
|
|
|
|
// // 可以选择在这里加一个通用成功提示,表明流程已执行
|
|
|
|
|
// Alert.alert("操作完成", "已尝试 Facebook 登录并获取用户信息,请查看控制台输出。");
|
|
|
|
|
|
|
|
|
|
// } catch (error: any) {
|
|
|
|
|
// console.error("Facebook 登录或获取资料时发生错误:", error);
|
|
|
|
|
// let errorMessage = "发生未知错误";
|
|
|
|
|
// if (error && typeof error.message === 'string') {
|
|
|
|
|
// errorMessage = error.message;
|
|
|
|
|
// }
|
|
|
|
|
// Alert.alert("登录错误", `Facebook 操作失败:${errorMessage}`);
|
|
|
|
|
// }
|
|
|
|
|
try { |
|
|
|
|
// 可选: 先退出登录,确保每次都是全新登录 (主要用于测试)
|
|
|
|
|
// await LoginManager.logOut();
|
|
|
|
|
|
|
|
|
|
const result = await LoginManager.logInWithPermissions([ |
|
|
|
|
"public_profile", |
|
|
|
|
"email", |
|
|
|
|
]); |
|
|
|
|
|
|
|
|
|
if (result.isCancelled) { |
|
|
|
|
Alert.alert("登录取消", "用户取消了 Facebook 登录。"); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const data = await AccessToken.getCurrentAccessToken(); |
|
|
|
|
// 确保 accessToken 存在且为字符串
|
|
|
|
|
if (!data || !data.accessToken) { |
|
|
|
|
Alert.alert("登录失败", "无法获取有效的 Facebook AccessToken。"); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const tokenString = data.accessToken.toString(); |
|
|
|
|
console.log("Facebook Access Token:", tokenString); |
|
|
|
|
|
|
|
|
|
// 获取 Facebook 用户信息
|
|
|
|
|
const profile = await fetchFacebookProfile(tokenString); |
|
|
|
|
|
|
|
|
|
if (profile) { |
|
|
|
|
try { |
|
|
|
|
// 准备发送给后端的数据 - 扁平化格式
|
|
|
|
|
const facebookData = { |
|
|
|
|
id: profile.id, |
|
|
|
|
name: profile.name, |
|
|
|
|
email: profile.email, |
|
|
|
|
access_token: tokenString, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
console.log("发送给后端的Facebook数据:", facebookData); |
|
|
|
|
|
|
|
|
|
// 调用后端Facebook登录API
|
|
|
|
|
const res = await loginApi.facebookLogin(facebookData); |
|
|
|
|
console.log("Facebook 后端登录响应:", res); |
|
|
|
|
const token = res.token_type + " " + res.access_token; |
|
|
|
|
await AsyncStorage.setItem("token", token); |
|
|
|
|
// 获取用户信息并更新状态
|
|
|
|
|
const user = await userApi.getProfile(); |
|
|
|
|
setUser(user); |
|
|
|
|
|
|
|
|
|
// 导航到主页面
|
|
|
|
|
navigation.navigate("MainTabs", { screen: "Home" }); |
|
|
|
|
} catch (err) { |
|
|
|
|
console.log("Facebook 后端登录失败:", err); |
|
|
|
|
Alert.alert("登录失败", "Facebook 登录验证失败,请重试。"); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
Alert.alert("登录失败", "无法获取 Facebook 用户信息,请重试。"); |
|
|
|
|
} |
|
|
|
|
} catch (error: any) { |
|
|
|
|
console.error("Facebook 登录或获取资料时发生错误:", error); |
|
|
|
|
let errorMessage = "发生未知错误"; |
|
|
|
|
if (error && typeof error.message === "string") { |
|
|
|
|
errorMessage = error.message; |
|
|
|
|
} |
|
|
|
|
Alert.alert("登录错误", `Facebook 操作失败:${errorMessage}`); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// 处理Apple登录
|
|
|
|
|