This commit is contained in:
oneao committed 2025-11-16 20:48:56 +08:00
1 parent c2c5cc92af
commit caed43a011
60 files changed
+1710 -1272

No files matched your search

@@ -1,129 +1,126 @@
import type { LayoutChangeEvent } from 'react-native'
import { BlurView } from 'expo-blur'
import { LinearGradient } from 'expo-linear-gradient'
import React, { useEffect, useRef, useState } from 'react'
import type { QueryMoneyRecordsResult } from '@/types/money/record'
import React, { useEffect, useState } from 'react'
import { ScrollView, Text, TouchableOpacity, View } from 'react-native'
import { useSafeAreaInsets } from 'react-native-safe-area-context'
import { ADateTimeDrawer, LucideIcon } from '@/components/common/ao'
import { IconJiaotong } from '@/components/iconfont'
import { ADatePicker, LucideIcon } from '@/components/common/ao'
import { Fab, FabIcon } from '@/components/ui/fab'
import { Grid, GridItem } from '@/components/ui/grid'
import { AddIcon } from '@/components/ui/icon'
import { Progress, ProgressFilledTrack } from '@/components/ui/progress'
import { queryMoneyRecordsApi } from '@/request/api/money'
import { queryMoneyRecordsApi } from '@/request/api/money/record'
import { getCurrentYearMonth } from '@/utils/time'
import { toast } from '@/utils/toast'
import AddMoneyDrawer from './components/AddDrawer'
import TransactionsList from './components/TransactionsList'
export default function Money() {
const [showAddDrawer, setShowAddDrawer] = useState(false)
// 安全高度
const insets = useSafeAreaInsets()
const [gradientHeight, setGradientHeight] = useState(200)
const gridLayout = useRef<{ y: number, height: number } | null>(null)
const onGridLayout = (e: LayoutChangeEvent) => {
if (!gridLayout.current) {
const { y, height } = e.nativeEvent.layout
gridLayout.current = { y, height }
setGradientHeight(y + height / 2 + 16 + insets.top)
}
}
// 日期筛选
const [showDatePicker, setShowDatePicker] = useState(false)
const [searchParams, setSearchParams] = useState({
record_time: getCurrentYearMonth(),
})
// 数据
const [moneyRecords, setMoneyRecords] = useState<QueryMoneyRecordsResult>({
total_expense: '0',
total_income: '0',
records: [],
})
useEffect(() => {
queryMoneyRecordsApi({
record_time: searchParams.record_time,
}).then((res) => {
console.log(res.data)
if (res.isSuccess) {
console.log(res.data.records)
setMoneyRecords(res.data)
}
else {
toast.show({
title: res.message || '查询错误,请稍后再试',
})
}
}).catch((err) => {
console.log(err)
})
}, [searchParams])
return (
<View
className="flex-1 relative bg-white"
className="flex-1"
style={{
paddingTop: insets.top,
}}
>
<LinearGradient
colors={['#fef6e4', '#fff8e1', '#ffffff']}
locations={[0, 0.95, 1]}
start={{ x: 0, y: 0 }}
end={{ x: 0, y: 1 }}
style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
height: gradientHeight,
zIndex: 0,
}}
/>
<View>
<View className="flex flex-row justify-between items-center px-4">
<TouchableOpacity
onPress={() => setShowDatePicker(true)}
className="flex flex-row items-center gap-1"
>
<Text className="font-bold text-lg">{searchParams.record_time}</Text>
<LucideIcon icon="ChevronDown" size={16} color="#666" clickable={false} />
</TouchableOpacity>
<View style={{ zIndex: 10, paddingLeft: 12, paddingRight: 12 }}>
<View className="flex flex-row justify-between items-center py-2">
<BlurView intensity={80} className="px-2 py-1">
<TouchableOpacity
onPress={() => setShowDatePicker(true)}
className="flex flex-row items-center gap-2"
>
<Text className="font-bold text-base">{searchParams.record_time}</Text>
<LucideIcon icon="ArrowBigDownDash" size={16} />
</TouchableOpacity>
</BlurView>
<View className="flex flex-row items-center gap-2">
<LucideIcon icon="SlidersHorizontal" />
</View>
<TouchableOpacity
className="flex flex-row items-center gap-2"
>
<LucideIcon icon="Menu" size={24} clickable={false} />
</TouchableOpacity>
</View>
<View className="mt-2">
{/* 余额区域 */}
<View className="items-center mb-3">
<Text className="text-gray-500 text-xs">
余额
<Text className="text-red-500">↓20%</Text>
</Text>
<Text className="font-bold text-2xl mt-0.5">22,313.00</Text>
</View>
{/* 收入/支出/结余 */}
<View className="flex-row justify-around py-2">
<View className="items-center">
<Text className="text-gray-500 text-xs">
收入
<Text className="text-green-500">↑20%</Text>
<View className="mt-3 border border-gray-200 rounded-lg m-4 p-4 shadow-sm bg-white">
<View
style={{
borderTopLeftRadius: 8,
borderTopRightRadius: 8,
}}
>
<View className="mb-4">
<Text className="text-gray-500 text-sm">
余额
{/* <Text className="text-red-500">↓20%</Text> */}
</Text>
<Text className="text-lg font-semibold mt-0.5">11.0</Text>
<Text className="font-bold text-2xl mt-0.5">22,313.00</Text>
</View>
<View className="items-center">
<Text className="text-gray-500 text-xs">
支出
<Text className="text-green-500">↑20%</Text>
</Text>
<Text className="text-lg font-semibold mt-0.5">11.0</Text>
</View>
<View className="flex-row flex gap-8">
<View>
<Text className="text-gray-500 text-sm">
收入
{/* <Text className="text-green-500">↑20%</Text> */}
</Text>
<Text className="text-lg font-semibold mt-0.5">{moneyRecords.total_income}</Text>
</View>
<View className="items-center">
<Text className="text-gray-500 text-xs">
结余
<Text className="text-green-500">↑20%</Text>
</Text>
<Text className="text-lg font-semibold mt-0.5">11.0</Text>
<View>
<Text className="text-gray-500 text-sm">
支出
{/* <Text className="text-green-500">↑20%</Text> */}
</Text>
<Text className="text-lg font-semibold mt-0.5">{moneyRecords.total_expense}</Text>
</View>
{/*
<View>
<Text className="text-gray-500 text-sm">
结余
<Text className="text-green-500">↑20%</Text>
</Text>
<Text className="text-lg font-semibold mt-0.5">11.0</Text>
</View> */}
</View>
</View>
{/* 预算进度 */}
<View className="flex-row items-center gap-3 mt-3">
<Text className="text-xs text-gray-600 w-8 text-right">预算</Text>
<View
className="flex-row items-center gap-3 mt-2"
style={{
borderBottomLeftRadius: 8,
borderBottomRightRadius: 8,
}}
>
<Text className="text-sm text-gray-600 text-right">预算</Text>
<View className="flex-1">
<Progress size="sm">
<ProgressFilledTrack />
@@ -132,36 +129,10 @@ export default function Money() {
<Text className="text-xs text-blue-500">点击设置</Text>
</View>
</View>
<View
onLayout={onGridLayout}
className="mt-4 pt-2 pb-2 bg-white rounded-md"
>
<Grid
_extra={{ className: 'grid-cols-5' }}
>
{[...Array.from({ length: 5 })].map((_, i) => (
<GridItem
key={i}
className="flex flex-col items-center"
_extra={{ className: 'col-span-1' }}
>
<IconJiaotong size={28} />
<Text className="text-xs mt-1 text-gray-500">账单</Text>
</GridItem>
))}
</Grid>
</View>
</View>
<View style={{ flex: 1, paddingHorizontal: 12 }}>
<ScrollView
contentContainerStyle={{ paddingBottom: 16 }}
showsVerticalScrollIndicator={false}
>
<TransactionsList />
</ScrollView>
<View className="flex-1 px-4 mt-2">
<TransactionsList records={moneyRecords.records} />
</View>
<Fab
@@ -178,11 +149,14 @@ export default function Money() {
onClose={() => {
setShowAddDrawer(false)
}}
onConfirm={(res) => {
setShowAddDrawer(false)
}}
/>
<ADateTimeDrawer
isOpen={showDatePicker}
modeType="year-month"
<ADatePicker
show={showDatePicker}
mode="month"
onConfirm={(val) => {
setSearchParams({
...searchParams,