Files
workspace/code/base-project/base-app/src/app/(tabs)/money/index.tsx
T
2025-11-19 22:55:09 +08:00

169 lines
5.1 KiB
TypeScript

import type { MoneyRecordGroup, MoneyRecordItem, QueryMoneyRecordsResult } from '@/types/money/record'
import { useRouter } from 'expo-router'
import React, { useEffect, useState } from 'react'
import { Text, TouchableOpacity, View } from 'react-native'
import { useSafeAreaInsets } from 'react-native-safe-area-context'
import { ADatePicker, LucideIcon } from '@/components/common/ao'
import { Fab, FabIcon } from '@/components/ui/fab'
import { AddIcon } from '@/components/ui/icon'
import { Progress, ProgressFilledTrack } from '@/components/ui/progress'
import { deleteMoneyRecordApi, queryMoneyRecordsApi } from '@/request/api/money/record'
import { useMoneyRecordStore } from '@/store/moneyRecord'
import { getCurrentYearMonth } from '@/utils/time'
import { toast } from '@/utils/toast'
import TransactionsList from './components/TransactionsList'
export default function Money() {
const moneyRecordStore = useMoneyRecordStore()
const router = useRouter()
// 安全高度
const insets = useSafeAreaInsets()
// 日期筛选
const [showDatePicker, setShowDatePicker] = useState(false)
const [searchParams, setSearchParams] = useState({
record_time: getCurrentYearMonth(),
})
useEffect(() => {
queryMoneyRecordsApi({
record_time: searchParams.record_time,
}).then((res) => {
if (res.isSuccess) {
moneyRecordStore.setRecords(res.data.records, res.data.total_expense, res.data.total_income, searchParams.record_time)
}
else {
toast.show({
title: res.message || '查询错误,请稍后再试',
})
}
}).catch((err) => {
console.log(err)
})
}, [searchParams])
return (
<View
className="flex-1"
>
<View
style={{
paddingTop: insets.top,
backgroundColor: '#fff',
elevation: 3,
}}
>
<View className="flex flex-row justify-between items-center px-3">
<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>
<TouchableOpacity
className="flex flex-row items-center gap-2"
>
<LucideIcon icon="Menu" size={24} clickable={false} />
</TouchableOpacity>
</View>
<View className="mt-3 m-4 ">
<View className="flex flex-row gap-4">
<View className="flex-1">
<Text className="text-gray-500 text-sm">收入</Text>
<Text
className="text-lg font-semibold mt-0.5"
numberOfLines={1}
ellipsizeMode="tail"
>
{moneyRecordStore.total_income}
</Text>
</View>
<View className="flex-1">
<Text className="text-gray-500 text-sm">支出</Text>
<Text
className="text-lg font-semibold mt-0.5"
numberOfLines={1}
ellipsizeMode="tail"
>
{moneyRecordStore.total_expense}
</Text>
</View>
<View className="flex-1">
<Text className="text-gray-500 text-sm">结余</Text>
<Text
className="text-lg font-semibold mt-0.5"
numberOfLines={1}
ellipsizeMode="tail"
>
0.00
</Text>
</View>
</View>
<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 />
</Progress>
</View>
<Text className="text-xs text-blue-500">点击设置</Text>
</View>
</View>
</View>
<View className="flex-1 mt-2">
<TransactionsList
records={moneyRecordStore.records}
onUpdate={(data) => {
router.navigate({
pathname: '/money/record/editor',
params: { id: data.id },
})
}}
onDelete={(id) => {
moneyRecordStore.deleteMoneyRecord(id)
}}
/>
</View>
<Fab
size="lg"
onPress={() => {
router.navigate('/money/record/editor')
}}
>
<FabIcon as={AddIcon} size="xl" />
</Fab>
<ADatePicker
show={showDatePicker}
mode="month"
date={searchParams.record_time}
onConfirm={(val) => {
setSearchParams({
...searchParams,
record_time: val,
})
setShowDatePicker(false)
}}
onClose={() => {
setShowDatePicker(false)
}}
/>
</View>
)
}