From f59d5c4f59f5067b45d231dc330c9248f423fb2c Mon Sep 17 00:00:00 2001 From: oneao Date: Mon, 20 Apr 2026 22:03:40 +0800 Subject: [PATCH] u --- .../allapp-go-v3/internal/handle/auth.go | 7 +- .../app/app-rn4/src/app/(tabs)/home/index.tsx | 169 +++++++- code/app/app-rn4/src/app/auth/login.tsx | 317 +++++++-------- code/app/app-rn4/src/app/auth/login2.tsx | 280 +++++++++++++ code/app/app-rn4/src/app/family/entry.tsx | 373 ++++++++++-------- code/app/app-rn4/src/types/auth.ts | 17 +- 6 files changed, 791 insertions(+), 372 deletions(-) create mode 100644 code/app/app-rn4/src/app/auth/login2.tsx diff --git a/code/allapp/allapp-go-v3/internal/handle/auth.go b/code/allapp/allapp-go-v3/internal/handle/auth.go index 2ec49ab7..d76ddf7f 100644 --- a/code/allapp/allapp-go-v3/internal/handle/auth.go +++ b/code/allapp/allapp-go-v3/internal/handle/auth.go @@ -73,16 +73,11 @@ func handleThirdLogin( // ========= 校验状态 ========= id := toInt64(user["id"]) - status := toInt64(user["status"]) - - if status == 0 { - return httpx.Fail(c, "账号已被禁用") - } // ========= 更新登录时间 ========= if err := dbClient.Update( c.Context(), - "user", + "b_user", "id", map[string]any{ "id": id, diff --git a/code/app/app-rn4/src/app/(tabs)/home/index.tsx b/code/app/app-rn4/src/app/(tabs)/home/index.tsx index f583c0b3..b8aca6e1 100644 --- a/code/app/app-rn4/src/app/(tabs)/home/index.tsx +++ b/code/app/app-rn4/src/app/(tabs)/home/index.tsx @@ -1,32 +1,165 @@ -import React, { useEffect } from "react"; +import React, { useEffect, useState } from "react"; import LayoutView from "@/components/layout/view"; -import EmptyState from "@/components/EmptyStatus"; -import { s3ListBucketsApi } from "@/request/api"; +import { loadDataApi } from "@/request/api"; +import { View, Text, TouchableOpacity } from "react-native"; +import { useFamilyStore } from "@/store"; export default function Home() { - // const [dailyData, setDailyData] = useState(null); + const familyStore = useFamilyStore(); + const [family, setFamily] = useState({}); + const [duration, setDuration] = useState({ + days: 0, + hours: 0, + minutes: 0, + seconds: 0, + }); - // useEffect(() => { - // fetchDailyInfo() - // .then((res: any) => { - // if (res?.code === "1") { - // console.log(res); - // setDailyData(res); - // } - // }) - // .catch(() => {}); - // }, []); + const mockMembers = [ + { name: "张三", online: true }, + { name: "李四", online: false }, + { name: "王五", online: true }, + ]; + + async function loadFamilyData() { + const res = await loadDataApi({ + view_name: "b_family", + search_condition: "id = ?", + search_columns: [], + order_by: "", + args: [familyStore.currentFamily?.family_id], + }); + + if (res.isSuccess && res.data.length > 0) { + setFamily(res.data[0]); + } + } + + function calcDuration(startTime: string) { + const start = new Date(startTime).getTime(); + const now = Date.now(); + let diff = Math.floor((now - start) / 1000); + + const days = Math.floor(diff / (3600 * 24)); + diff %= 3600 * 24; + + const hours = Math.floor(diff / 3600); + diff %= 3600; + + const minutes = Math.floor(diff / 60); + const seconds = diff % 60; + + return { days, hours, minutes, seconds }; + } useEffect(() => { - s3ListBucketsApi().then((res) => { - console.log(res); - }); + loadFamilyData(); }, []); + useEffect(() => { + if (!family.create_time) return; + + const timer = setInterval(() => { + setDuration(calcDuration(family.create_time)); + }, 1000); + + return () => clearInterval(timer); + }, [family.create_time]); + return ( - + {/* 🌸 顶部情绪背景区 */} + + + {family.name || "我们的家庭"} + + + 在一起的第 + + {/* 💖 超大核心数字(恋爱记风格) */} + + {duration.days} + + + 天 + + + {/* ⏱ 小时间补充 */} + + + {duration.hours}时 {duration.minutes}分 {duration.seconds}秒 + + + + {/* 💕 情侣/家庭状态区 */} + + 我们的状态 + + + 家庭成员 + {mockMembers.length} 人 + + + + 在线人数 + + {mockMembers.filter((m) => m.online).length} 人 + + + + + {/* 💌 邀请区(恋爱记风格按钮) */} + + + 邀请家人加入 + + + + {/* 🔑 邀请码(弱化但温柔) */} + + 邀请码 + AB12CD + + + {/* 🕊 底部情绪提示 */} + + 💖 一起走过的每一天都值得记录 + ); diff --git a/code/app/app-rn4/src/app/auth/login.tsx b/code/app/app-rn4/src/app/auth/login.tsx index d4b7d13f..d69ebe6b 100644 --- a/code/app/app-rn4/src/app/auth/login.tsx +++ b/code/app/app-rn4/src/app/auth/login.tsx @@ -5,10 +5,10 @@ import { Button, LinkButton, ControlField, Checkbox, Spinner } from "heroui-nati import { IconQq, IconWeixin } from "@/components/iconfont"; import { useState } from "react"; import { FadeIn } from "react-native-reanimated"; -import { useUserStore } from "@/store"; +import { useUserStore, useFamilyStore } from "@/store"; import { useRouter } from "expo-router"; -// import ExpoQQ from "expo-qq"; -// import ExpoWeChat from "expo-wechat"; +import ExpoQQ from "expo-qq"; +import ExpoWeChat from "expo-wechat"; import { useEvent } from "expo"; import { toast } from "sonner-native"; import { loginQqApi, loginWxApi } from "@/request/api"; @@ -16,6 +16,7 @@ import { loginQqApi, loginWxApi } from "@/request/api"; export default function Login() { const router = useRouter(); const userStore = useUserStore(); + const familyStore = useFamilyStore(); const [loading, setLoading] = useState(false); const [isAgreed, setIsAgreed] = useState(true); @@ -26,195 +27,182 @@ export default function Login() { }); // 登录 - // const onLoginFinished = useEvent(ExpoQQ, "onLoginFinished"); - // const onGetUserInfo = useEvent(ExpoQQ, "onGetUserInfo"); - // const authResult = useEvent(ExpoWeChat, "onAuthResult"); + const onLoginFinished = useEvent(ExpoQQ, "onLoginFinished"); + const onGetUserInfo = useEvent(ExpoQQ, "onGetUserInfo"); + const authResult = useEvent(ExpoWeChat, "onAuthResult"); - // useEffect(() => { - // ExpoQQ.init("102826474", ""); - // ExpoWeChat.registerApp("wxdab3e21a1f7e392f", ""); - // }, []); + useEffect(() => { + ExpoQQ.init("102826474", ""); + ExpoWeChat.registerApp("wxdab3e21a1f7e392f", ""); + }, []); - // // 微信登录 - // async function handleLoginWechat() { - // if (loading) { - // return; - // } - // setLoading(true); + // 微信登录 + async function handleLoginWechat() { + if (loading) { + return; + } + setLoading(true); - // // 检查微信是否安装 - // const isInstalled = await ExpoWeChat.isWXAppInstalled(); - // if (!isInstalled) { - // toast.warning(onLoginFinished?.errorMessage || "请先安装微信"); - // setLoading(false); - // return; - // } + // 检查微信是否安装 + const isInstalled = await ExpoWeChat.isWXAppInstalled(); + if (!isInstalled) { + toast.warning(onLoginFinished?.errorMessage || "请先安装微信"); + setLoading(false); + return; + } - // setForm((val) => ({ - // ...val, - // type: 0, - // })); + setForm((val) => ({ + ...val, + type: 0, + })); - // ExpoWeChat.sendAuthRequest("snsapi_userinfo", "state123"); - // } + ExpoWeChat.sendAuthRequest("snsapi_userinfo", "state123"); + } - // // QQ 登录 - // async function handleLoginQQ() { - // if (loading) { - // return; - // } - - // setLoading(true); - - // setForm((val) => ({ - // ...val, - // type: 1, - // })); - // await ExpoQQ.login(["get_user_info"]); - // } - - /** - * {"code": 1000, "data": {"avatar": "http://thirdqq.qlogo.cn/ek_qqapp/AQHVialeUibE42oV8RvTTVZ4tyRlPYeJrUibWTwtCPfV68E4rSzn9cw00GkXQ3QDTiawwhjoqQb7/100", - * "nickname": "Zhang", "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7ImlkIjo3OTY0NTY3MTI3ODU5ODl9LCJpYXQiOjE3NzY1ODU2MDR9.ZwmN5_0MGrP9dYpn3quK94HXMG3QYKmAq7wnP5X68dY", "userId": 796456712785989}, "isSuccess": true, "message": "success", "track_id": "djIRo23SZlA160zBTH2DX-kxeuLApKTNyZdxqqauSMk"} - */ - - function handleTest() { + // QQ 登录 + async function handleLoginQQ() { if (loading) { return; } setLoading(true); - setTimeout(() => { - requestAnimationFrame(() => { - userStore.setUserInfo({ - id: 779895419121733, - token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7ImlkIjo3OTY0NTY3MTI3ODU5ODl9LCJpYXQiOjE3NzY1ODU2MDR9.ZwmN5_0MGrP9dYpn3quK94HXMG3QYKmAq7wnP5X68dY", - nickname: "Zhang", - avatar: - "http://thirdqq.qlogo.cn/ek_qqapp/AQHVialeUibE42oV8RvTTVZ4tyRlPYeJrUibWTwtCPfV68E4rSzn9cw00GkXQ3QDTiawwhjoqQb7/100", - }); - userStore.setAuthExpired(false); - // router.replace("/(tabs)/home"); - router.replace("/family/entry"); - }); - setLoading(false); - }, 2000); + setForm((val) => ({ + ...val, + type: 1, + })); + await ExpoQQ.login(["get_user_info"]); } - // useEffect(() => { - // if (!onLoginFinished) { - // return; - // } + useEffect(() => { + if (!onLoginFinished) { + return; + } - // if (!onLoginFinished.success) { - // toast.warning(onLoginFinished?.errorMessage || "授权失败,请检查手机是否安装 QQ 或确认授权"); - // setLoading(false); - // return; - // } + if (!onLoginFinished.success) { + toast.warning(onLoginFinished?.errorMessage || "授权失败,请检查手机是否安装 QQ 或确认授权"); + setLoading(false); + return; + } - // const fetchUserInfo = async () => { - // try { - // const tokenInfo = await ExpoQQ.getLoginTokenInfo(); - // if (!tokenInfo.openId) { - // toast.warning(tokenInfo?.errorMessage || "授权失败,请检查手机是否安装 QQ 或确认授权"); - // setLoading(false); - // return; - // } + const fetchUserInfo = async () => { + try { + const tokenInfo = await ExpoQQ.getLoginTokenInfo(); + if (!tokenInfo.openId) { + toast.warning(tokenInfo?.errorMessage || "授权失败,请检查手机是否安装 QQ 或确认授权"); + setLoading(false); + return; + } - // setForm((val) => ({ - // ...val, - // openid: String(tokenInfo.openId), - // })); + setForm((val) => ({ + ...val, + openid: String(tokenInfo.openId), + })); - // await ExpoQQ.sendGetUserInfoReq(); - // } catch (e) { - // console.log(e); + await ExpoQQ.sendGetUserInfoReq(); + } catch (e) { + console.log(e); - // setLoading(false); - // } - // }; + setLoading(false); + } + }; - // fetchUserInfo(); - // }, [onLoginFinished]); + fetchUserInfo(); + }, [onLoginFinished]); - // // QQ登录 - // useEffect(() => { - // const handleLogin = async () => { - // if (!onGetUserInfo) { - // setLoading(false); - // return; - // } + // QQ登录 + useEffect(() => { + const handleLogin = async () => { + if (!onGetUserInfo) { + setLoading(false); + return; + } - // try { - // const loginRes = await loginQqApi({ - // openid: form.openid, - // nickname: onGetUserInfo.nickname || "", - // avatar: onGetUserInfo.figureurlQq_2 || onGetUserInfo.figureurl_2, - // }); + try { + const loginRes = await loginQqApi({ + openid: form.openid, + nickname: onGetUserInfo.nickname || "", + avatar: onGetUserInfo.figureurlQq_2 || onGetUserInfo.figureurl_2, + }); - // console.log(loginRes); + if (loginRes.isSuccess) { + requestAnimationFrame(() => { + userStore.setUserInfo({ + token: loginRes.data.token, + id: loginRes.data.userId, + nickname: loginRes.data.nickname, + avatar: loginRes.data.avatar, + }); - // if (loginRes.isSuccess) { - // requestAnimationFrame(() => { - // userStore.setUserInfo({ - // token: loginRes.data.token, - // id: loginRes.data.userId, - // nickname: loginRes.data.nickname, - // avatar: loginRes.data.avatar, - // }); + userStore.setAuthExpired(false); - // userStore.setAuthExpired(false); - // router.replace("/(tabs)/home"); - // }); - // } - // } catch (err) { - // console.error("登录接口出错", err); - // } finally { - // setLoading(false); - // } - // }; + if (loginRes.data.family_id === 0) { + router.replace("/family/entry"); + } else { + familyStore.setCurrentFamily({ + family_id: loginRes.data.family_id, + }); - // handleLogin(); - // }, [onGetUserInfo]); + router.replace("/(tabs)/home"); + } + }); + } + } catch (err) { + console.error("登录接口出错", err); + } finally { + setLoading(false); + } + }; - // // 微信登录 - // useEffect(() => { - // if (!authResult) return; + handleLogin(); + }, [onGetUserInfo]); - // const handleLogin = async () => { - // if (authResult.errorCode === 0) { - // try { - // const loginRes = await loginWxApi({ - // code: authResult.code, - // }); + // 微信登录 + useEffect(() => { + if (!authResult) return; - // if (loginRes.isSuccess) { - // requestAnimationFrame(() => { - // userStore.setUserInfo({ - // token: loginRes.data.token, - // id: loginRes.data.userId, - // nickname: loginRes.data.nickname, - // avatar: loginRes.data.avatar, - // }); + const handleLogin = async () => { + if (authResult.errorCode === 0) { + try { + const loginRes = await loginWxApi({ + code: authResult.code, + }); - // userStore.setAuthExpired(false); - // router.replace("/(tabs)/home"); - // }); - // } - // } catch (err) { - // console.error("登录接口出错", err); - // } finally { - // setLoading(false); - // } - // } else { - // console.log("授权失败:", authResult.errorMessage); - // setLoading(false); - // } - // }; + if (loginRes.isSuccess) { + requestAnimationFrame(() => { + userStore.setUserInfo({ + token: loginRes.data.token, + id: loginRes.data.userId, + nickname: loginRes.data.nickname, + avatar: loginRes.data.avatar, + }); - // handleLogin(); - // }, [authResult]); + userStore.setAuthExpired(false); + + if (loginRes.data.family_id === 0) { + router.replace("/family/entry"); + } else { + familyStore.setCurrentFamily({ + family_id: loginRes.data.family_id, + }); + + router.replace("/(tabs)/home"); + } + }); + } + } catch (err) { + console.error("登录接口出错", err); + } finally { + setLoading(false); + } + } else { + console.log("授权失败:", authResult.errorMessage); + setLoading(false); + } + }; + + handleLogin(); + }, [authResult]); return ( <> @@ -234,7 +222,7 @@ export default function Login() { - {/* */} - - diff --git a/code/app/app-rn4/src/app/auth/login2.tsx b/code/app/app-rn4/src/app/auth/login2.tsx new file mode 100644 index 00000000..20c38fd2 --- /dev/null +++ b/code/app/app-rn4/src/app/auth/login2.tsx @@ -0,0 +1,280 @@ +import { useEffect } from "react"; +import { Stack } from "expo-router"; +import { Image, Text, View } from "react-native"; +import { Button, LinkButton, ControlField, Checkbox, Spinner } from "heroui-native"; +import { IconQq, IconWeixin } from "@/components/iconfont"; +import { useState } from "react"; +import { FadeIn } from "react-native-reanimated"; +import { useUserStore } from "@/store"; +import { useRouter } from "expo-router"; +import ExpoQQ from "expo-qq"; +import ExpoWeChat from "expo-wechat"; +import { useEvent } from "expo"; +import { toast } from "sonner-native"; +import { loginQqApi, loginWxApi } from "@/request/api"; + +export default function Login() { + const router = useRouter(); + const userStore = useUserStore(); + + const [loading, setLoading] = useState(false); + const [isAgreed, setIsAgreed] = useState(true); + const [form, setForm] = useState({ + type: 0, + openid: "", + code: "", + }); + + // 登录 + // const onLoginFinished = useEvent(ExpoQQ, "onLoginFinished"); + // const onGetUserInfo = useEvent(ExpoQQ, "onGetUserInfo"); + // const authResult = useEvent(ExpoWeChat, "onAuthResult"); + + // useEffect(() => { + // ExpoQQ.init("102826474", ""); + // ExpoWeChat.registerApp("wxdab3e21a1f7e392f", ""); + // }, []); + + // // 微信登录 + // async function handleLoginWechat() { + // if (loading) { + // return; + // } + // setLoading(true); + + // // 检查微信是否安装 + // const isInstalled = await ExpoWeChat.isWXAppInstalled(); + // if (!isInstalled) { + // toast.warning(onLoginFinished?.errorMessage || "请先安装微信"); + // setLoading(false); + // return; + // } + + // setForm((val) => ({ + // ...val, + // type: 0, + // })); + + // ExpoWeChat.sendAuthRequest("snsapi_userinfo", "state123"); + // } + + // // QQ 登录 + // async function handleLoginQQ() { + // if (loading) { + // return; + // } + + // setLoading(true); + + // setForm((val) => ({ + // ...val, + // type: 1, + // })); + // await ExpoQQ.login(["get_user_info"]); + // } + + /** + * {"code": 1000, "data": {"avatar": "http://thirdqq.qlogo.cn/ek_qqapp/AQHVialeUibE42oV8RvTTVZ4tyRlPYeJrUibWTwtCPfV68E4rSzn9cw00GkXQ3QDTiawwhjoqQb7/100", + * "nickname": "Zhang", "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7ImlkIjo3OTY0NTY3MTI3ODU5ODl9LCJpYXQiOjE3NzY1ODU2MDR9.ZwmN5_0MGrP9dYpn3quK94HXMG3QYKmAq7wnP5X68dY", "userId": 796456712785989}, "isSuccess": true, "message": "success", "track_id": "djIRo23SZlA160zBTH2DX-kxeuLApKTNyZdxqqauSMk"} + */ + + function handleTest() { + if (loading) { + return; + } + + setLoading(true); + + setTimeout(() => { + requestAnimationFrame(() => { + userStore.setUserInfo({ + id: 779895419121733, + token: + "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7ImlkIjo3OTY0NTY3MTI3ODU5ODl9LCJpYXQiOjE3NzY1ODU2MDR9.ZwmN5_0MGrP9dYpn3quK94HXMG3QYKmAq7wnP5X68dY", + nickname: "Zhang", + avatar: + "http://thirdqq.qlogo.cn/ek_qqapp/AQHVialeUibE42oV8RvTTVZ4tyRlPYeJrUibWTwtCPfV68E4rSzn9cw00GkXQ3QDTiawwhjoqQb7/100", + }); + userStore.setAuthExpired(false); + // router.replace("/(tabs)/home"); + router.replace("/family/entry"); + }); + setLoading(false); + }, 2000); + } + + // useEffect(() => { + // if (!onLoginFinished) { + // return; + // } + + // if (!onLoginFinished.success) { + // toast.warning(onLoginFinished?.errorMessage || "授权失败,请检查手机是否安装 QQ 或确认授权"); + // setLoading(false); + // return; + // } + + // const fetchUserInfo = async () => { + // try { + // const tokenInfo = await ExpoQQ.getLoginTokenInfo(); + // if (!tokenInfo.openId) { + // toast.warning(tokenInfo?.errorMessage || "授权失败,请检查手机是否安装 QQ 或确认授权"); + // setLoading(false); + // return; + // } + + // setForm((val) => ({ + // ...val, + // openid: String(tokenInfo.openId), + // })); + + // await ExpoQQ.sendGetUserInfoReq(); + // } catch (e) { + // console.log(e); + + // setLoading(false); + // } + // }; + + // fetchUserInfo(); + // }, [onLoginFinished]); + + // // QQ登录 + // useEffect(() => { + // const handleLogin = async () => { + // if (!onGetUserInfo) { + // setLoading(false); + // return; + // } + + // try { + // const loginRes = await loginQqApi({ + // openid: form.openid, + // nickname: onGetUserInfo.nickname || "", + // avatar: onGetUserInfo.figureurlQq_2 || onGetUserInfo.figureurl_2, + // }); + + // console.log(loginRes); + + // if (loginRes.isSuccess) { + // requestAnimationFrame(() => { + // userStore.setUserInfo({ + // token: loginRes.data.token, + // id: loginRes.data.userId, + // nickname: loginRes.data.nickname, + // avatar: loginRes.data.avatar, + // }); + + // userStore.setAuthExpired(false); + // router.replace("/(tabs)/home"); + // }); + // } + // } catch (err) { + // console.error("登录接口出错", err); + // } finally { + // setLoading(false); + // } + // }; + + // handleLogin(); + // }, [onGetUserInfo]); + + // // 微信登录 + // useEffect(() => { + // if (!authResult) return; + + // const handleLogin = async () => { + // if (authResult.errorCode === 0) { + // try { + // const loginRes = await loginWxApi({ + // code: authResult.code, + // }); + + // if (loginRes.isSuccess) { + // requestAnimationFrame(() => { + // userStore.setUserInfo({ + // token: loginRes.data.token, + // id: loginRes.data.userId, + // nickname: loginRes.data.nickname, + // avatar: loginRes.data.avatar, + // }); + + // userStore.setAuthExpired(false); + // router.replace("/(tabs)/home"); + // }); + // } + // } catch (err) { + // console.error("登录接口出错", err); + // } finally { + // setLoading(false); + // } + // } else { + // console.log("授权失败:", authResult.errorMessage); + // setLoading(false); + // } + // }; + + // handleLogin(); + // }, [authResult]); + + return ( + <> + + + + + Welcome to Allapp + + + + {/* + + */} + + + + + + + + + + 登录即表示你同意我们的 + + 用户协议 + + 和 + + 隐私政策 + + + + + + ); +} diff --git a/code/app/app-rn4/src/app/family/entry.tsx b/code/app/app-rn4/src/app/family/entry.tsx index eb5890aa..6f445381 100644 --- a/code/app/app-rn4/src/app/family/entry.tsx +++ b/code/app/app-rn4/src/app/family/entry.tsx @@ -4,20 +4,17 @@ import { Stack } from "expo-router"; import EmptyState from "@/components/EmptyStatus"; import { Button, - Separator, Spinner, - Chip, BottomSheet, Label, TextField, Input, InputOTP, type InputOTPRef, - PressableFeedback, useBottomSheetAwareHandlers, } from "heroui-native"; import { PlusIcon, HousePlusIcon } from "lucide-react-native"; -import { getUniqueIdApi, loadDataApi, loadDataBySqlApi, saveDataApi } from "@/request/api"; +import { getUniqueIdApi, loadDataApi, saveDataApi } from "@/request/api"; import { useUserStore, useFamilyStore } from "@/store"; import { toast } from "sonner-native"; import { generateCode } from "@/utils/common"; @@ -86,6 +83,14 @@ export default function EntryFamily() { const [createLoading, setCreateLoading] = useState(false); const createInputRef = useRef(null); + useEffect(() => { + if (familyStore.inFamily()) { + toast.warning("你已经有家庭了"); + + router.replace("/home"); + } + }, []); + useEffect(() => { if (showCreate) { requestAnimationFrame(() => { @@ -114,10 +119,56 @@ export default function EntryFamily() { } }, [showJoin]); + // 是否已有家庭 + async function getUserFamily() { + const res = await loadDataApi({ + view_name: "b_family_member", + search_condition: "user_id = ?", + order_by: "", + search_columns: ["family_id"], + args: [userStore.userInfo.id], + }); + + if (!res.isSuccess) return null; + + return res.data?.[0]?.family_id || null; + } + + // 跳转封装 + function enterFamily(familyId: number) { + familyStore.setCurrentFamily({ family_id: familyId }); + + requestAnimationFrame(() => { + router.replace("/home"); + }); + } + + async function generateInviteCode() { + for (let i = 0; i < 5; i++) { + const code = generateCode(6); + + const res = await loadDataApi({ + view_name: "b_family", + search_condition: "invite_code = ?", + order_by: "", + search_columns: ["id"], + args: [code], + }); + + if (!res.isSuccess) throw new Error("邀请码校验失败"); + + if (res.data.length === 0) { + return code; + } + } + + throw new Error("邀请码生成失败"); + } + async function handleCreate() { if (createLoading) return; - if (createForm.name === "") { + if (!createForm.name.trim()) { toast.warning("空间名称不能为空"); return; } @@ -125,116 +176,61 @@ export default function EntryFamily() { setCreateLoading(true); try { - // 检查是否存在该家庭 - const memberRes = await loadDataApi({ - view_name: "b_family_member", - search_condition: "user_id = ?", - search_columns: ["family_id"], - order_by: "", - args: [userStore.userInfo.id], - }); - - if (!memberRes.isSuccess) { - return; - } - - if (memberRes.data.length > 0) { + const existFamilyId = await getUserFamily(); + if (existFamilyId) { toast.warning("你已经有家庭了"); - - familyStore.setCurrentFamily({ - family_id: memberRes.data[0].family_id, - }); - - requestAnimationFrame(() => { - router.replace("/home"); - }); - + enterFamily(existFamilyId); return; } - let inviteCode = ""; - let isExist = true; + const inviteCode = await generateInviteCode(); - // 循环生成直到不存在 - while (isExist) { - inviteCode = generateCode(6); - - const res = await loadDataBySqlApi({ - sql: `SELECT 1 FROM b_family WHERE invite_code = ? LIMIT 1`, - args: [inviteCode], - }); - - if (!res.isSuccess) { - throw new Error("校验邀请码失败"); - } - - isExist = res.data.length > 0; - } - - // 创建 const autoRes = await getUniqueIdApi(2); - if (!autoRes.isSuccess) { - return; - } + if (!autoRes.isSuccess) return; - const familyId = autoRes.data[0]; - const familyMemberId = autoRes.data[1]; + const [familyId, memberId] = autoRes.data; - // 插入空间 - const requestData = []; - - requestData.push({ - table_name: "b_family", - key_field: "id", - inserts: [ - { - id: familyId, - name: createForm.name, - invite_code: inviteCode, - owner_id: userStore.userInfo.id, - }, - ], - updates: [], - deletes: [], - }); - - // 插入空间用户 - requestData.push({ - table_name: "b_family_member", - key_field: "id", - inserts: [ - { - id: familyMemberId, - family_id: familyId, - user_id: userStore.userInfo.id, - role: 0, - nickname: userStore.userInfo.nickname, - }, - ], - updates: [], - deletes: [], - }); - - const saveRes = await saveDataApi(requestData); + const saveRes = await saveDataApi([ + { + table_name: "b_family", + key_field: "id", + inserts: [ + { + id: familyId, + name: createForm.name, + invite_code: inviteCode, + owner_id: userStore.userInfo.id, + }, + ], + updates: [], + deletes: [], + }, + { + table_name: "b_family_member", + key_field: "id", + inserts: [ + { + id: memberId, + family_id: familyId, + user_id: userStore.userInfo.id, + role: 0, + nickname: userStore.userInfo.nickname, + }, + ], + updates: [], + deletes: [], + }, + ]); if (saveRes.isSuccess) { toast.success("创建成功"); setShowCreate(false); + setCreateForm({ name: "" }); - setCreateForm({ - name: "", - }); - - familyStore.setCurrentFamily({ - family_id: familyId, - }); - - requestAnimationFrame(() => { - router.replace("/home"); - }); + enterFamily(familyId); } } catch (e) { - console.log(e); + console.error(e); } finally { setCreateLoading(false); } @@ -258,91 +254,56 @@ export default function EntryFamily() { setJoinLoading(true); try { - const res = await loadDataBySqlApi({ - sql: ` SELECT - s.id, - s.name, - EXISTS ( - SELECT 1 - FROM space_member sm - WHERE sm.space_id = s.id - AND sm.user_id = ? - ) AS is_joined - FROM space s - WHERE s.invite_code = ? - LIMIT 1; - `, - args: [userStore.userInfo.id, code], + const existFamilyId = await getUserFamily(); + if (existFamilyId) { + toast.warning("你已经有家庭了"); + enterFamily(existFamilyId); + return; + } + + const res = await loadDataApi({ + view_name: "b_family", + search_condition: "invite_code = ?", + order_by: "", + search_columns: ["id"], + args: [code], }); if (!res.isSuccess) return; - const row = res.data?.[0]; + const family = res.data?.[0]; - if (!row) { + if (!family) { toast.warning("邀请码无效"); return; } - - if (row.is_joined) { - toast.warning("你已经在该空间了"); - return; - } - const autoRes = await getUniqueIdApi(1); - if (!autoRes.isSuccess) { - return; - } + if (!autoRes.isSuccess) return; - // 设置是否是默认空间 - let isDefault = false; - - const defaultRes = await loadDataApi({ - view_name: "v_user_spaces", - search_condition: `v_user_id = ?`, - search_columns: ["v_is_default"], - order_by: "", - args: [userStore.userInfo.id], - }); - - if (!defaultRes.isSuccess) { - return; - } - - if (defaultRes.data.length == 0) { - isDefault = true; - } - - // 加入 - const requestData = []; - - requestData.push({ - table_name: "space_member", - key_field: "id", - inserts: [ - { - id: autoRes.data[0], - space_id: row.id, - user_id: userStore.userInfo.id, - role: 1, - is_default: isDefault ? 1 : 0, - sort_number: defaultRes.data.length, - member_name: userStore.userInfo.nickname, - }, - ], - updates: [], - deletes: [], - }); - - const saveRes = await saveDataApi(requestData); + const saveRes = await saveDataApi([ + { + table_name: "b_family_member", + key_field: "id", + inserts: [ + { + id: autoRes.data[0], + family_id: family.id, + user_id: userStore.userInfo.id, + role: 1, + nickname: userStore.userInfo.nickname, + }, + ], + updates: [], + deletes: [], + }, + ]); if (saveRes.isSuccess) { - toast.success("加入成功"); + toast.success("加入家庭成功"); setShowJoin(false); + setJoinForm({ invite_code: "" }); - setJoinForm({ - invite_code: "", - }); + enterFamily(family.id); } } catch (e) { console.error(e); @@ -352,6 +313,12 @@ export default function EntryFamily() { } } + function handleToLogin() { + requestAnimationFrame(() => { + router.replace("/auth/login"); + }); + } + return ( <> 创建家庭 - @@ -384,7 +356,12 @@ export default function EntryFamily() { - {}} className="items-center py-2"> + { + handleToLogin(); + }} + className="items-center py-2" + > 重新登录 @@ -426,6 +403,56 @@ export default function EntryFamily() { + + { + setShowJoin(val); + }} + > + + + + + + + + { + setJoinForm({ + invite_code: val, + }); + }} + > + + + + + + + + + + + + + + + + + + + ); } diff --git a/code/app/app-rn4/src/types/auth.ts b/code/app/app-rn4/src/types/auth.ts index 844731a9..4a95220a 100644 --- a/code/app/app-rn4/src/types/auth.ts +++ b/code/app/app-rn4/src/types/auth.ts @@ -1,16 +1,17 @@ export interface LoginQqParams { - openid: string - nickname: string - avatar: string + openid: string; + nickname: string; + avatar: string; } export interface LoginWxParams { - code: string + code: string; } export interface LoginResult { - token: string - userId: number - nickname: string - avatar: string + token: string; + userId: number; + nickname: string; + avatar: string; + family_id: number; }