This commit is contained in:
oneao committed 2026-01-25 22:18:27 +08:00
1 parent 500fab7a80
commit 8f3f6982db
54 files changed
+2076 -1877

No files matched your search

@@ -1,47 +1,27 @@
import type { TabbarItem } from '@/components/custom/Tabbar'
import CustomTabbar from '@/components/custom/Tabbar'
import { toast } from '@/utils/toast'
export const unstable_settings = {
initialRouteName: 'money/index',
}
import { TabSlot } from 'expo-router/ui'
import { Text, View } from 'react-native'
export default function TabsLayout() {
const tabbarOptions: TabbarItem[] = [
{
name: 'money',
href: '/money',
icon: 'CircleDollarSign',
},
{
name: 'love',
href: '/love',
icon: 'Heart',
},
{
name: 'app',
icon: 'LayoutGrid',
activeIcon: 'Smile',
iconSize: 26,
onPress: () => {
toast.show({
title: '该功能尚未开发,请尽情期待!',
})
},
},
{
name: 'chat',
href: '/chat',
icon: 'MessageCircle',
},
{
name: 'user',
href: '/user',
icon: 'CircleUserRound',
},
]
return (
<CustomTabbar data={tabbarOptions} />
<View className="flex-1 bg-gray-100">
<View className="flex-1 px-4 pt-4 pb-24">
<TabSlot />
</View>
<View
className="
absolute
left-3 right-3 bottom-8
h-14
flex-row items-center
px-2
gap-4
"
>
<View className="bg-white rounded-md shadow-lg h-12 w-12"></View>
<View className="flex-1 bg-white rounded-md shadow-lg h-12"></View>
<View className="bg-white rounded-md shadow-lg h-12 w-12"></View>
</View>
</View>
)
}
Whitespace-only changes.
@@ -13,11 +13,11 @@ export default function User() {
return (
<SafeAreaView className="flex-1 p-4">
<View className="flex flex-row items-center ">
<View className="flex flex-row items-center">
<Avatar size="md" className="border-0">
<AvatarImage
className="bg-white"
source={require('@/static/images/logo.png')}
source={{ uri: userStore.userInfo?.avatar }}
/>
</Avatar>
<Text className="text-xl font-semibold ml-3">{userStore.userInfo?.username}</Text>
+230 -61
View File
@@ -1,94 +1,263 @@
import { useEvent } from 'expo'
import ExpoQQ from 'expo-qq'
import { useRouter } from 'expo-router'
import { useEffect } from 'react'
import ExpoWeChat from 'expo-wechat'
import { useEffect, useState } from 'react'
import { Image, Text, View } from 'react-native'
import { AButton, ACheckbox } from '@/components/common/ao'
import CustomHeader from '@/components/custom/Header'
import { Button, ButtonText } from '@/components/ui/button'
import { IconQq, IconWeixin } from '@/components/iconfont'
import { loginQqApi, loginWxApi } from '@/request/api/auth'
import { useUserStore } from '@/store/user'
import { toast } from '@/utils/toast'
export default function LoginScreen() {
const [loading, setLoading] = useState(false)
const [isAgree, setIsAgree] = useState(true)
const [form, setForm] = useState({
type: 0,
openid: '',
code: '',
})
export default function AuthIndex() {
const router = useRouter()
const userStore = useUserStore()
function toPath(url: string) {
router.push(url)
const onLoginFinished = useEvent(ExpoQQ, 'onLoginFinished')
const onGetUserInfo = useEvent(ExpoQQ, 'onGetUserInfo')
const authResult = useEvent(ExpoWeChat, 'onAuthResult')
async function onQQLogin() {
setLoading(true)
setForm(val => ({
...val,
type: 1,
}))
await ExpoQQ.login(['get_user_info'])
}
// /// 监听登录结果,你也可以使用ExpoQQ.addListener('onLoginFinished', callback)来实现,但请不要忘记移除监听
// const onSendLoginFinished = useEvent(ExpoQQ, 'onGetUserInfo')
// const onLoginFinished = useEvent(ExpoQQ, 'onLoginFinished')
async function onWeChatLogin() {
setLoading(true)
// useEffect(() => {
// console.log(onSendLoginFinished)
// }, [onSendLoginFinished])
// 检查微信是否安装
const isInstalled = await ExpoWeChat.isWXAppInstalled()
if (!isInstalled) {
toast.show({
title: onLoginFinished?.errorMessage || '请先安装微信',
})
setLoading(false)
return
}
// /// 国内应用需要在用户接受隐私协议后再初始化
// useEffect(() => {
// const init = async () => {
// await ExpoQQ.init('102826474', 'universal link')
// }
// init()
// }, [])
setForm(val => ({
...val,
type: 0,
}))
// useEffect(() => {
// if (!onLoginFinished || !onLoginFinished.success)
// return
ExpoWeChat.sendAuthRequest('snsapi_userinfo', 'state123')
}
// const fetchUserInfo = async () => {
// try {
// // 1️⃣ 确认 SDK 已经拿到 token
// const tokenInfo = await ExpoQQ.getLoginTokenInfo()
// console.log('tokenInfo', tokenInfo)
useEffect(() => {
ExpoQQ.init('102826474', '')
ExpoWeChat.registerApp('wxdab3e21a1f7e392f', '')
}, [])
// // 2️⃣ 再请求用户信息
// await ExpoQQ.sendGetUserInfoReq()
// }
// catch (e) {
// console.error('QQ 登录未完成', e)
// }
// }
useEffect(() => {
if (!onLoginFinished) {
return
}
// fetchUserInfo()
// }, [onLoginFinished])
if (!onLoginFinished.success) {
toast.show({
title: onLoginFinished?.errorMessage || '授权失败,请检查手机是否安装 QQ 或确认授权',
})
setLoading(false)
return
}
// /// 调用qq登陆
// const loginByQQ = async () => {
// await ExpoQQ.login(['get_user_info'])
// }
const fetchUserInfo = async () => {
try {
const tokenInfo = await ExpoQQ.getLoginTokenInfo()
if (!tokenInfo.openId) {
toast.show({
title: tokenInfo?.errorMessage || '授权失败,请检查手机是否安装 QQ 或确认授权',
})
setLoading(false)
return
}
setForm(val => ({
...val,
openid: String(tokenInfo.openId),
}))
await ExpoQQ.sendGetUserInfoReq()
}
catch (e) {
console.error('QQ 登录未完成', e)
setLoading(false)
}
}
fetchUserInfo()
}, [onLoginFinished])
// QQ登录
useEffect(() => {
const handleLogin = async () => {
if (!onGetUserInfo)
return
try {
const loginRes = await loginQqApi({
openid: form.openid,
username: onGetUserInfo.nickname || '',
avatar: onGetUserInfo.figureurlQq_2 || onGetUserInfo.figureurl_2,
})
if (loginRes.isSuccess) {
userStore.setUserInfo({
token: loginRes.data.token,
id: loginRes.data.userId,
username: loginRes.data.username,
avatar: loginRes.data.avatar,
})
console.log(loginRes.data.token)
router.push('/')
}
}
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) {
userStore.setUserInfo({
token: loginRes.data.token,
id: loginRes.data.userId,
username: loginRes.data.username,
avatar: loginRes.data.avatar,
})
router.push('/')
}
}
catch (err) {
console.error('登录接口出错', err)
}
finally {
setLoading(false)
}
}
else {
console.log('授权失败:', authResult.errorMessage)
setLoading(false)
}
}
handleLogin()
}, [authResult])
function testLogin() {
// eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjo3NjY3ODU5ODIxNjUwNjEsImlhdCI6MTc2OTM0ODI0Nn0.17ZNaHD3HSLM8dVn_JQK-gvsG9MKj47IRYV9D4xZkzs
userStore.setUserInfo({
token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjo3NjY3ODU5ODIxNjUwNjEsImlhdCI6MTc2OTM0ODI0Nn0.17ZNaHD3HSLM8dVn_JQK-gvsG9MKj47IRYV9D4xZkzs',
id: 766785982165061,
username: 'Zhang',
avatar: 'http://thirdqq.qlogo.cn/ek_qqapp/AQHVialeUibE42oV8RvTTVZ4tyRlPYeJrUibWTwtCPfV68E4rSzn9cw00GkXQ3QDTiawwhjoqQb7/100',
})
router.push('/')
}
return (
<View className="flex-1">
<View className="flex-1 bg-white px-6 justify-center">
<CustomHeader
showHeader={false}
/>
<View className="flex-1 bg-white items-center justify-center">
<Image
source={require('@/static/images/work.png')}
style={{ width: '100%', height: 280 }}
className="mb-6"
/>
<View className="items-center mb-12">
<Image
source={require('@/static/images/logo.png')}
style={{ width: 60, height: 60 }}
className="mb-6"
className="w-20 h-20 mb-4"
resizeMode="contain"
/>
<Text className="font-bold text-3xl text-[#333] tracking-wide">
ONEAO
<Text className="text-xl font-semibold text-gray-900">
Welcome to OneAO
</Text>
</View>
<View className="w-full flex flex-col gap-3 mt-12 px-3">
<Button action="secondary" onPress={() => toPath('/auth/login')}>
<ButtonText>登录</ButtonText>
</Button>
<View className="flex flex-col gap-4">
<AButton
leftIcon={
<IconWeixin color="#fff" />
}
loading={loading}
onPress={onWeChatLogin}
>
WeChat
</AButton>
<Button action="secondary" onPress={() => toPath('/auth/register')}>
<ButtonText>注册</ButtonText>
</Button>
</View>
<AButton
variant="outline"
leftIcon={
<IconQq />
}
loading={loading}
onPress={onQQLogin}
>
QQ
</AButton>
<AButton
variant="outline"
leftIcon={
<IconQq />
}
loading={loading}
onPress={testLogin}
>
模拟登录
</AButton>
</View>
<View className="mt-10 items-center flex flex-row justify-center">
<ACheckbox
checked={isAgree}
size="sm"
label={(
<Text className="text-sm text-gray-400 text-center leading-4">
登录即表示你同意我们的
<Text className="text-gray-600"> 用户协议 </Text>
和
<Text className="text-gray-600"> 隐私政策</Text>
</Text>
)}
onChange={(val) => {
setIsAgree(val)
}}
/>
</View>
</View>
)
}
@@ -157,7 +157,6 @@ export default function CreateCategory({
data={flatListData}
keyExtractor={([groupName]) => groupName}
renderItem={renderGroup}
initialNumToRender={1}
/>
</ADrawer>
)