From e51f4948d426dd546af4fc704b4a140dd6e8401e Mon Sep 17 00:00:00 2001 From: oneao Date: Mon, 19 Jan 2026 22:12:28 +0800 Subject: [PATCH] u --- .../allapp/allapp-go/utils/pgtypex/pgtypex.go | 7 ++- .../money/components/TransactionsList.tsx | 14 +++--- .../allapp-rn/src/app/(tabs)/money/index.tsx | 3 +- .../setting/components/EditCategory.tsx | 11 +++-- .../src/app/money/category/setting/index.tsx | 2 + .../src/app/money/record/detail/index.tsx | 12 +++-- .../src/app/money/record/editor/index.tsx | 22 +++------- .../allapp-rn/src/store/moneyCategory.ts | 15 ++++--- .../allapp/allapp-rn/src/store/moneyRecord.ts | 44 ++++++++++++++----- .../allapp-rn/src/types/money/record.ts | 25 +++-------- 10 files changed, 89 insertions(+), 66 deletions(-) diff --git a/code/allapp/allapp-go/utils/pgtypex/pgtypex.go b/code/allapp/allapp-go/utils/pgtypex/pgtypex.go index 92c1aa1c..d981dbb6 100644 --- a/code/allapp/allapp-go/utils/pgtypex/pgtypex.go +++ b/code/allapp/allapp-go/utils/pgtypex/pgtypex.go @@ -129,6 +129,9 @@ func TimestampToMillis(ts pgtype.Timestamp) int64 { return ts.Time.UnixMilli() } -func DateToString(s pgtype.Date) string { - return s.Time.String() +func DateToString(d pgtype.Date) string { + if !d.Valid { + return "" + } + return d.Time.Format("2006-01-02") } diff --git a/code/allapp/allapp-rn/src/app/(tabs)/money/components/TransactionsList.tsx b/code/allapp/allapp-rn/src/app/(tabs)/money/components/TransactionsList.tsx index 6baed1fe..6225ea08 100644 --- a/code/allapp/allapp-rn/src/app/(tabs)/money/components/TransactionsList.tsx +++ b/code/allapp/allapp-rn/src/app/(tabs)/money/components/TransactionsList.tsx @@ -1,4 +1,4 @@ -import type { MoneyRecordGroup, MoneyRecordItem } from '@/types/money/record' +import type { MoneyRecord, MoneyRecordGroup } from '@/types/money/record' import React, { useCallback, useState } from 'react' import { RefreshControl, SectionList, Text, TouchableHighlight, Vibration, View } from 'react-native' import { @@ -11,11 +11,13 @@ import { import { LucideIcon } from '@/components/common/ao' import EmptyState from '@/components/common/EmptyStatus' import MoneyCategoryIcon from '@/components/common/MoneyCategoryIcon' +import { useMoneyCategoryStore } from '@/store/moneyCategory' import { useUserStore } from '@/store/user' +import { MoneyCategoryEnum } from '@/types/money/category' interface StaticTransactionsProps { records: MoneyRecordGroup[] - onUpdate?: (data: MoneyRecordItem) => void + onUpdate?: (data: MoneyRecord) => void onDelete?: (id: number) => void onDetail?: (id: number) => void onRefreshData?: () => void @@ -30,6 +32,7 @@ export default function StaticTransactions({ onLoadMore, onRefreshData, }: StaticTransactionsProps) { + const moneyCategoryStore = useMoneyCategoryStore() const userID = useUserStore().userInfo?.id const [refreshing, setRefreshing] = useState(false) const [loadingMore, setLoadingMore] = useState(false) @@ -119,6 +122,7 @@ export default function StaticTransactions({ )} renderItem={({ item }) => { + const category = moneyCategoryStore.getCategoryById(item.category_id) return ( - + - {item.remark ? item.remark : item.category_name} + {item.remark ? item.remark : category?.name} { item.user_id !== userID && ( @@ -166,7 +170,7 @@ export default function StaticTransactions({ - {item.category_type === 1 ? '+' : '-'} + {category?.type === MoneyCategoryEnum.Income ? '+' : '-'} {' '} {item.amount} diff --git a/code/allapp/allapp-rn/src/app/(tabs)/money/index.tsx b/code/allapp/allapp-rn/src/app/(tabs)/money/index.tsx index 44e9c131..cc7949d5 100644 --- a/code/allapp/allapp-rn/src/app/(tabs)/money/index.tsx +++ b/code/allapp/allapp-rn/src/app/(tabs)/money/index.tsx @@ -34,6 +34,7 @@ export default function Money() { record_time: searchParams.record_time, }).then((res) => { if (res.isSuccess) { + console.log(res.data.records) moneyRecordStore.setRecords(res.data.records, searchParams.record_time) } else { @@ -62,7 +63,7 @@ export default function Money() { } }, []), ) - + return ( { setIsOpen(open) + if (!open) { + setForm({ + icon: '', + name: '', + }) + } }, [open]) useEffect(() => { @@ -67,13 +73,12 @@ export default function CreateCategory({ }, [category]) function handleClose() { - setIsOpen(false) - onClose && onClose() - setForm({ icon: '', name: '', }) + setIsOpen(false) + onClose && onClose() } return ( diff --git a/code/allapp/allapp-rn/src/app/money/category/setting/index.tsx b/code/allapp/allapp-rn/src/app/money/category/setting/index.tsx index e36a21e6..70a80e21 100644 --- a/code/allapp/allapp-rn/src/app/money/category/setting/index.tsx +++ b/code/allapp/allapp-rn/src/app/money/category/setting/index.tsx @@ -99,6 +99,8 @@ export default function MoneyCategorySetting() { sort_number: 0, type: selectedTab, }) + + scrollableRef.current?.scrollToEnd({ animated: true }) } setshowEditCategory(false) diff --git a/code/allapp/allapp-rn/src/app/money/record/detail/index.tsx b/code/allapp/allapp-rn/src/app/money/record/detail/index.tsx index 4c35c6de..bcc27995 100644 --- a/code/allapp/allapp-rn/src/app/money/record/detail/index.tsx +++ b/code/allapp/allapp-rn/src/app/money/record/detail/index.tsx @@ -4,14 +4,18 @@ import { Text, View } from 'react-native' import { AButton, ACell, ACellGroup, AModal } from '@/components/common/ao' import MoneyCategoryIcon from '@/components/common/MoneyCategoryIcon' import CustomHeader from '@/components/custom/Header' +import { useMoneyCategoryStore } from '@/store/moneyCategory' import { useMoneyRecordStore } from '@/store/moneyRecord' import { useUserStore } from '@/store/user' +import { MoneyCategoryEnum } from '@/types/money/category' import { toDateString, toDateTimeString } from '@/utils/time' export default function MoneyRecordDetail() { const router = useRouter() const moneyRecordStore = useMoneyRecordStore() + const moneyCategoryStore = useMoneyCategoryStore() const userStore = useUserStore() + const { id: detailId } = useLocalSearchParams<{ id: string }>() const moneryRecord = moneyRecordStore.getMoneyRecordById(Number(detailId)) @@ -22,18 +26,20 @@ export default function MoneyRecordDetail() { return null } + const moneyCategory = moneyCategoryStore.getCategoryById(moneryRecord.category_id) + return ( <> - - {moneryRecord.category_name} + + {moneyCategory?.name} - + diff --git a/code/allapp/allapp-rn/src/app/money/record/editor/index.tsx b/code/allapp/allapp-rn/src/app/money/record/editor/index.tsx index ce358ff6..a8f91f96 100644 --- a/code/allapp/allapp-rn/src/app/money/record/editor/index.tsx +++ b/code/allapp/allapp-rn/src/app/money/record/editor/index.tsx @@ -1,5 +1,5 @@ import type { MoneyCategoryItem } from '@/types/money/category' -import type { MoneyRecordBase, MoneyRecordItem } from '@/types/money/record' +import type { MoneyRecord } from '@/types/money/record' import { useLocalSearchParams, useRouter } from 'expo-router' import { useEffect, useState } from 'react' import { Text, TouchableOpacity, View } from 'react-native' @@ -28,21 +28,19 @@ export default function MoenyRecordEditor() { // 选中分类 const [selectedCategory, setSelectedCategory] = useState(null) // 记账记录 - const defaultMoneyRecord: MoneyRecordBase = { + const defaultMoneyRecord: MoneyRecord = { id: -1, category_id: -1, username: '', - category_icon: '', - category_name: '', - category_type: 0, user_id: -1, amount: '0.00', remark: '', record_time: getCurrentDate(), - create_time: '', + create_time: 0, + update_time: 0, } - const [moneyRecord, setMoneyRecord] = useState(defaultMoneyRecord) + const [moneyRecord, setMoneyRecord] = useState(defaultMoneyRecord) useEffect(() => { if (updateId) { @@ -90,12 +88,9 @@ export default function MoenyRecordEditor() { record_time: moneyRecord.record_time, }).then((res) => { if (res.isSuccess) { - const result: MoneyRecordItem = { + const result: MoneyRecord = { ...moneyRecord, category_id: selectedCategory.id, - category_type: selectedCategory.type, - category_name: selectedCategory.name, - category_icon: selectedCategory.icon, } moneyRecordStore.updateMoneyRecord(result) @@ -115,12 +110,9 @@ export default function MoenyRecordEditor() { }) .then((res) => { if (res.isSuccess) { - const result: MoneyRecordItem = { + const result: MoneyRecord = { ...res.data, category_id: selectedCategory.id, - category_type: selectedCategory.type, - category_name: selectedCategory.name, - category_icon: selectedCategory.icon, } moneyRecordStore.addMoneyRecord(result) diff --git a/code/allapp/allapp-rn/src/store/moneyCategory.ts b/code/allapp/allapp-rn/src/store/moneyCategory.ts index f6f479bc..1770c072 100644 --- a/code/allapp/allapp-rn/src/store/moneyCategory.ts +++ b/code/allapp/allapp-rn/src/store/moneyCategory.ts @@ -96,7 +96,12 @@ export const useMoneyCategoryStore = create()( categories: [], - setCategories: categories => set({ categories }), + setCategories: categories => + set({ + categories: [...categories].sort( + (a, b) => (a.sort_number ?? 0) - (b.sort_number ?? 0), + ), + }), init: async () => { try { @@ -120,14 +125,10 @@ export const useMoneyCategoryStore = create()( }, getExpenseCategories: () => - (get().categories || []) - .filter(c => c.type === MoneyCategoryEnum.Expense) - .sort((a, b) => (a.sort_number ?? 0) - (b.sort_number ?? 0)), + get().categories.filter(c => c.type === MoneyCategoryEnum.Expense), getIncomeCategories: () => - (get().categories || []) - .filter(c => c.type === MoneyCategoryEnum.Income) - .sort((a, b) => (a.sort_number ?? 0) - (b.sort_number ?? 0)), + get().categories.filter(c => c.type === MoneyCategoryEnum.Income), getCategoryById: (id: number) => { return get().categories.find(c => c.id === id) || null diff --git a/code/allapp/allapp-rn/src/store/moneyRecord.ts b/code/allapp/allapp-rn/src/store/moneyRecord.ts index c0edfa1a..a6de6ca3 100644 --- a/code/allapp/allapp-rn/src/store/moneyRecord.ts +++ b/code/allapp/allapp-rn/src/store/moneyRecord.ts @@ -1,9 +1,10 @@ -import type { MoneyRecordGroup, MoneyRecordItem } from '@/types/money/record' +import type { MoneyRecord, MoneyRecordGroup } from '@/types/money/record' import { create } from 'zustand' import { deleteMoneyRecordApi } from '@/request/api/money/record' import { MoneyCategoryEnum } from '@/types/money/category' import { add, sub } from '@/utils/math' import { isInMonth } from '@/utils/time' +import { useMoneyCategoryStore } from './moneyCategory' interface MoneyRecordStore { records: MoneyRecordGroup[] @@ -14,30 +15,47 @@ interface MoneyRecordStore { getTotalExpense: () => string getTotalBalance: () => string - setRecords: (records: MoneyRecordGroup[], month: string) => void + setRecords: (records: MoneyRecord[], month: string) => void setCurrentMonth: (month: string) => void - addMoneyRecord: (data: MoneyRecordItem) => void - updateMoneyRecord: (updated: MoneyRecordItem) => void + addMoneyRecord: (data: MoneyRecord) => void + updateMoneyRecord: (updated: MoneyRecord) => void deleteMoneyRecord: (id: number) => void - getMoneyRecordById: (id: number) => MoneyRecordItem | null + getMoneyRecordById: (id: number) => MoneyRecord | null } -function recomputeGroups(records: MoneyRecordItem[]) { +function recomputeGroups(records: MoneyRecord[]) { + const { getCategoryById } = useMoneyCategoryStore.getState() + const groupsMap: Record = {} records.forEach((r) => { - const group = groupsMap[r.record_time] ?? { record_time: r.record_time, records: [], income: '0.00', expense: '0.00' } + const category = getCategoryById(r.category_id) + if (!category) + return + + const group = groupsMap[r.record_time] ?? { + record_time: r.record_time, + records: [], + income: '0.00', + expense: '0.00', + } + group.records.push(r) - if (r.category_type === MoneyCategoryEnum.Expense) + + if (category.type === MoneyCategoryEnum.Expense) group.expense = add(group.expense, r.amount) - if (r.category_type === MoneyCategoryEnum.Income) + + if (category.type === MoneyCategoryEnum.Income) group.income = add(group.income, r.amount) + groupsMap[r.record_time] = group }) - return Object.values(groupsMap).sort((a, b) => b.record_time.localeCompare(a.record_time)) + return Object.values(groupsMap).sort((a, b) => + b.record_time.localeCompare(a.record_time), + ) } export const useMoneyRecordStore = create((set, get) => ({ @@ -59,8 +77,10 @@ export const useMoneyRecordStore = create((set, get) => ({ /* ---------------- base ---------------- */ setRecords: (records, month) => { - const flatRecords = records.flatMap(g => g.records) - const newGroups = recomputeGroups(flatRecords) + const filtered = records.filter(r => + isInMonth(r.record_time, month), + ) + const newGroups = recomputeGroups(filtered) set({ records: newGroups, currentMonth: month }) }, diff --git a/code/allapp/allapp-rn/src/types/money/record.ts b/code/allapp/allapp-rn/src/types/money/record.ts index 1c3ec725..a9fab3aa 100644 --- a/code/allapp/allapp-rn/src/types/money/record.ts +++ b/code/allapp/allapp-rn/src/types/money/record.ts @@ -1,19 +1,16 @@ // types/money/record.ts // 基础记录 -export interface MoneyRecordBase { +export interface MoneyRecord { id: number - category_id: number - category_type: number - category_name: string - category_icon: string user_id: number username: string + category_id: number amount: string remark: string record_time: string - create_time: string - update_time?: string + create_time: number + update_time: number } // 查询条件(请求参数) @@ -21,24 +18,16 @@ export interface QueryMoneyRecordsParams { record_time: string } -// 查询结果的记录 -export interface MoneyRecordItem extends MoneyRecordBase { - -} - // 分组 & 查询结果 export interface MoneyRecordGroup { record_time: string expense: string income: string - records: MoneyRecordItem[] + records: MoneyRecord[] } export interface QueryMoneyRecordsResult { - records: MoneyRecordGroup[] - total_income: string - total_expense: string - total_balance: string + records: MoneyRecord[] } // 新增请求参数 @@ -49,7 +38,7 @@ export interface InsertMoneyRecordParams { record_time: string } -export interface InsertMoneyRecordResult extends MoneyRecordBase {} +export interface InsertMoneyRecordResult extends MoneyRecord {} // 更新 export interface UpdateMoneyRecordParams {