From 74190219270f444ac02e5843385b99dfecb8b925 Mon Sep 17 00:00:00 2001 From: oneao Date: Tue, 18 Nov 2025 22:35:18 +0800 Subject: [PATCH] u --- code/base-project/base-app/package.json | 2 + code/base-project/base-app/pnpm-lock.yaml | 31 ++++ .../base-app/src/app/(tabs)/chat.tsx | 156 ++++++++++++++---- .../base-app/src/app/(tabs)/love.tsx | 86 ++-------- .../app/(tabs)/money/components/AddDrawer.tsx | 29 ++-- .../money/components/TransactionsList.tsx | 3 +- .../app/(tabs)/user/components/ListItem.tsx | 2 +- .../base-app/src/app/auth/_layout.tsx | 29 ---- .../base-app/src/app/auth/index.tsx | 49 +++--- .../base-app/src/app/auth/login.tsx | 97 +++++------ .../base-app/src/app/auth/register.tsx | 121 +++++++------- .../src/app/system/settings/index.tsx | 11 +- .../base-app/src/app/system/share/index.tsx | 14 +- .../base-app/src/components/custom/Header.tsx | 93 ++++++++++- .../base-app/src/request/index.ts | 9 +- .../base-app/src/store/moneyCategory.ts | 44 +++++ .../base-app/src/store/moneyRecord.ts | 3 + .../base-app/src/types/money/category.ts | 5 - .../base-go-v2/internal/api/money/index.go | 17 +- 19 files changed, 474 insertions(+), 327 deletions(-) delete mode 100644 code/base-project/base-app/src/app/auth/_layout.tsx create mode 100644 code/base-project/base-app/src/store/moneyCategory.ts create mode 100644 code/base-project/base-app/src/store/moneyRecord.ts diff --git a/code/base-project/base-app/package.json b/code/base-project/base-app/package.json index 5eb9d3c4..9f4fb3c2 100644 --- a/code/base-project/base-app/package.json +++ b/code/base-project/base-app/package.json @@ -42,11 +42,13 @@ "react-native-gesture-handler": "~2.28.0", "react-native-keyboard-controller": "1.18.5", "react-native-modal": "14.0.0-rc.1", + "react-native-pager-view": "6.9.1", "react-native-popup-menu": "^0.18.0", "react-native-reanimated": "~4.1.3", "react-native-safe-area-context": "~5.6.1", "react-native-screens": "~4.16.0", "react-native-svg": "15.12.1", + "react-native-tab-view": "^4.2.0", "react-native-web": "^0.21.0", "react-native-worklets": "0.5.1", "tailwind-merge": "^3.4.0", diff --git a/code/base-project/base-app/pnpm-lock.yaml b/code/base-project/base-app/pnpm-lock.yaml index 9b6d4509..eebf1b95 100644 --- a/code/base-project/base-app/pnpm-lock.yaml +++ b/code/base-project/base-app/pnpm-lock.yaml @@ -104,6 +104,9 @@ importers: react-native-modal: specifier: 14.0.0-rc.1 version: 14.0.0-rc.1(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) + react-native-pager-view: + specifier: 6.9.1 + version: 6.9.1(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) react-native-popup-menu: specifier: ^0.18.0 version: 0.18.0 @@ -119,6 +122,9 @@ importers: react-native-svg: specifier: 15.12.1 version: 15.12.1(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) + react-native-tab-view: + specifier: ^4.2.0 + version: 4.2.0(react-native-pager-view@6.9.1(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) react-native-web: specifier: ^0.21.0 version: 0.21.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0) @@ -4857,6 +4863,12 @@ packages: react: '*' react-native: '>=0.70.0' + react-native-pager-view@6.9.1: + resolution: {integrity: sha512-uUT0MMMbNtoSbxe9pRvdJJKEi9snjuJ3fXlZhG8F2vVMOBJVt/AFtqMPUHu9yMflmqOr08PewKzj9EPl/Yj+Gw==} + peerDependencies: + react: '*' + react-native: '*' + react-native-popup-menu@0.18.0: resolution: {integrity: sha512-XD3gyp/hwL5YWw2J034DerfvbJ6S2YHqAzvqAFRU+UGnFD4JyTqggfm4UyynBD26O1PDoRb45Loil+NZCGfCnA==} @@ -4892,6 +4904,13 @@ packages: react: '*' react-native: '*' + react-native-tab-view@4.2.0: + resolution: {integrity: sha512-TUbh7Yr0tE/99t1pJQLbQ+4/Px67xkT7/r3AhfV+93Q3WoUira0Lx7yuKUP2C118doqxub8NCLERwcqsHr29nQ==} + peerDependencies: + react: '>= 18.2.0' + react-native: '*' + react-native-pager-view: '>= 6.0.0' + react-native-web@0.21.2: resolution: {integrity: sha512-SO2t9/17zM4iEnFvlu2DA9jqNbzNhoUP+AItkoCOyFmDMOhUnBBznBDCYN92fGdfAkfQlWzPoez6+zLxFNsZEg==} peerDependencies: @@ -11796,6 +11815,11 @@ snapshots: react-native: 0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0) react-native-animatable: 1.4.0 + react-native-pager-view@6.9.1(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0): + dependencies: + react: 19.1.0 + react-native: 0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0) + react-native-popup-menu@0.18.0: {} react-native-reanimated@4.1.5(@babel/core@7.28.5)(react-native-worklets@0.5.1(@babel/core@7.28.5)(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0): @@ -11840,6 +11864,13 @@ snapshots: react-native: 0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0) warn-once: 0.1.1 + react-native-tab-view@4.2.0(react-native-pager-view@6.9.1(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0): + dependencies: + react: 19.1.0 + react-native: 0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0) + react-native-pager-view: 6.9.1(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) + use-latest-callback: 0.2.6(react@19.1.0) + react-native-web@0.21.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0): dependencies: '@babel/runtime': 7.28.4 diff --git a/code/base-project/base-app/src/app/(tabs)/chat.tsx b/code/base-project/base-app/src/app/(tabs)/chat.tsx index bc7b3503..2919c633 100644 --- a/code/base-project/base-app/src/app/(tabs)/chat.tsx +++ b/code/base-project/base-app/src/app/(tabs)/chat.tsx @@ -1,39 +1,125 @@ -import { DatePicker } from '@yz1311/react-native-wheel-picker' -import { useState } from 'react' -import { Button, Text, View } from 'react-native' -import { ADatePicker } from '@/components/common/ao' +import * as React from 'react' +import { Pressable, StyleSheet, Text, useWindowDimensions, View } from 'react-native' +import { SafeAreaView } from 'react-native-safe-area-context' +import { TabView } from 'react-native-tab-view' -export default function Chat() { - const [show, setShow] = useState(false) +// 两个示例页面 +function PageOne() { return ( - <> - - - {/* { - setShow(false) - }} - /> */} - - { - setShow(false) - }} - onClose={() => { - setShow(false) - }} - /> - - - + + 第一页内容 + ) } + +function PageTwo() { + return ( + + 第二页内容 + + ) +} + +export default function SimpleTabView() { + const layout = useWindowDimensions() + const [index, setIndex] = React.useState(0) + + const routes = [ + { key: 'one', title: 'Tab 1' }, + { key: 'two', title: 'Tab 2' }, + ] + + const renderScene = ({ route }: { route: { key: string } }) => { + switch (route.key) { + case 'one': + return + case 'two': + return + default: + return null + } + } + + return ( + + {/* Header + Tab */} + + console.log('Left button clicked')}> + 返回 + + + + {routes.map((r, i) => { + const focused = i === index + return ( + setIndex(i)} style={styles.tabButton}> + {r.title} + {focused && } + + ) + })} + + + console.log('Right button clicked')}> + 添加 + + + + {/* TabView */} + null} // 不使用默认 TabBar + /> + + 123 + + ) +} + +const styles = StyleSheet.create({ + header: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + paddingHorizontal: 16, + paddingVertical: 8, + borderBottomWidth: 0.5, + borderColor: '#ddd', + }, + headerButton: { + fontSize: 16, + color: '#007AFF', + }, + tabContainer: { + flexDirection: 'row', + justifyContent: 'center', + flex: 1, + }, + tabButton: { + marginHorizontal: 12, + alignItems: 'center', + paddingVertical: 4, + }, + tabText: { + fontSize: 16, + color: '#666', + }, + tabTextActive: { + color: '#007AFF', + fontWeight: 'bold', + }, + underline: { + height: 2, + backgroundColor: '#007AFF', + width: '100%', + marginTop: 2, + }, + page: { + flex: 1, + alignItems: 'center', + justifyContent: 'center', + }, +}) diff --git a/code/base-project/base-app/src/app/(tabs)/love.tsx b/code/base-project/base-app/src/app/(tabs)/love.tsx index 881cfb6e..4d8aa2b2 100644 --- a/code/base-project/base-app/src/app/(tabs)/love.tsx +++ b/code/base-project/base-app/src/app/(tabs)/love.tsx @@ -1,78 +1,18 @@ -import React, { useState } from 'react' -import { FlatList, Text, View } from 'react-native' -import { - Menu, - MenuOption, - MenuOptions, - MenuProvider, - MenuTrigger, -} from 'react-native-popup-menu' -import { Button, ButtonText } from '@/components/ui/button' +import { useRouter } from 'expo-router' +import { Text, View } from 'react-native' +import { AButton } from '@/components/common/ao' -export default function Example() { - const data = Array.from({ length: 10 }, (_, i) => i + 1) - const [activeIndex, setActiveIndex] = useState(null) - - const renderItem = ({ item: index }: { item: number }) => { - const isActive = activeIndex === index - - return ( - - setActiveIndex(index)} - onClose={() => setActiveIndex(null)} - > - {/* MenuTrigger 应该包装一个可触摸的组件 */} - - {/* 触发区域的内容 */} - - Item - {' '} - {index} - {' '} - {isActive ? '(active)' : ''} - - - - - alert(`Clicked Option A for ${index}`)}> - - Option A - - {index} - - - alert(`Clicked Option B for ${index}`)}> - - Option B - - {index} - - - setActiveIndex(null)}> - Close Menu - - - - - ) - } +export default function Love() { + const router = useRouter() return ( - item.toString()} - /> + + { + router.navigate('/auth') + }} + > + 跳转到登录页面 + + ) } diff --git a/code/base-project/base-app/src/app/(tabs)/money/components/AddDrawer.tsx b/code/base-project/base-app/src/app/(tabs)/money/components/AddDrawer.tsx index d072428c..30ecf0e0 100644 --- a/code/base-project/base-app/src/app/(tabs)/money/components/AddDrawer.tsx +++ b/code/base-project/base-app/src/app/(tabs)/money/components/AddDrawer.tsx @@ -1,4 +1,4 @@ -import type { MoneyCategoryItem, QueryMoneyCategoryResult } from '@/types/money/category' +import type { MoneyCategoryItem } from '@/types/money/category' import type { MoneyRecordBase, MoneyRecordItem } from '@/types/money/record' import Big from 'big.js' import { useEffect, useMemo, useState } from 'react' @@ -16,6 +16,7 @@ import { import { useKeyboardHeight } from '@/hooks/useKeyboardHeight' import { queryMoneyCategoryApi } from '@/request/api/money/category' import { insertMoneyRecordApi, updateMoneyRecordApi } from '@/request/api/money/record' +import { useMoneyCategoryStore } from '@/store/moneyCategory' import { getCurrentDate, toDateString } from '@/utils/time' import { toast } from '@/utils/toast' import MoneyCategoryIcon from './MoneyCategoryIcon' @@ -65,6 +66,8 @@ export default function AddMoneyDrawer({ onConfirm, updateData, }: AddMoneyDrawerProps) { + const moneyCategoryStore = useMoneyCategoryStore() + const insets = useSafeAreaInsets() // 选择顺序:0 支出 1收入 const [selectedIndex, setSelectedIndex] = useState(0) @@ -76,11 +79,6 @@ export default function AddMoneyDrawer({ const [showDatePicker, setShowDatePicker] = useState(false) // 备注聚焦 const [remarkIsFocused, setRemarkIsFocused] = useState(false) - // 分类 - const [categories, setCategories] = useState({ - income: [], - expense: [], - }) // 选中分类 const [selectedCategory, setSelectedCategory] = useState(null) @@ -106,10 +104,13 @@ export default function AddMoneyDrawer({ const fetchCategories = async () => { try { - const res = await queryMoneyCategoryApi() - if (res.isSuccess) { - setCategories(res.data) + if (moneyCategoryStore.categories.length === 0) { + const res = await queryMoneyCategoryApi() + if (res.isSuccess) { + moneyCategoryStore.setCategories(res.data) + } } + console.log(moneyCategoryStore.categories) } catch (err) { console.error('获取分类失败', err) @@ -128,7 +129,7 @@ export default function AddMoneyDrawer({ if (type === 0) { // 支出 - categories.expense.forEach((item) => { + moneyCategoryStore.expense.forEach((item) => { if (item.id === updateData.category_id) { setSelectedCategory(item) } @@ -136,14 +137,14 @@ export default function AddMoneyDrawer({ } else if (type === 1) { // 收入 - categories.income.forEach((item) => { + moneyCategoryStore.income.forEach((item) => { if (item.id === updateData.category_id) { setSelectedCategory(item) } }) } } - }, [categories]) + }, [isOpen]) function resetData() { // 清空键盘记录 @@ -399,7 +400,6 @@ export default function AddMoneyDrawer({ }) .then((res) => { if (res.isSuccess) { - const result: MoneyRecordItem = { ...res.data, category_name: selectedCategory.name, @@ -466,9 +466,8 @@ export default function AddMoneyDrawer({ }} > {(() => { - const list = selectedIndex === 1 ? categories.income : categories.expense + const list = selectedIndex === 1 ? moneyCategoryStore.income : moneyCategoryStore.expense - // useMemo 生成补全后的列表 const memoItems = useMemo(() => { const items = [...list] const remainder = items.length % 4 diff --git a/code/base-project/base-app/src/app/(tabs)/money/components/TransactionsList.tsx b/code/base-project/base-app/src/app/(tabs)/money/components/TransactionsList.tsx index eeb42561..a6d6822a 100644 --- a/code/base-project/base-app/src/app/(tabs)/money/components/TransactionsList.tsx +++ b/code/base-project/base-app/src/app/(tabs)/money/components/TransactionsList.tsx @@ -10,7 +10,6 @@ import { } from 'react-native-popup-menu' import { LucideIcon } from '@/components/common/ao' import EmptyState from '@/components/common/EmptyStatus' -import { Badge, BadgeText } from '@/components/ui/badge' import MoneyCategoryIcon from './MoneyCategoryIcon' interface StaticTransactionsProps { @@ -112,7 +111,7 @@ export default function StaticTransactions({ { index === 1 && ( - 操作人:张三 + 张三 ) } diff --git a/code/base-project/base-app/src/app/(tabs)/user/components/ListItem.tsx b/code/base-project/base-app/src/app/(tabs)/user/components/ListItem.tsx index 1c11f6de..812f355a 100644 --- a/code/base-project/base-app/src/app/(tabs)/user/components/ListItem.tsx +++ b/code/base-project/base-app/src/app/(tabs)/user/components/ListItem.tsx @@ -29,7 +29,7 @@ export default function ListItem({ icon, text, href, onPress }: ListItemProps) { className="flex flex-row items-center py-3" onPress={handlePress} > - + {text} diff --git a/code/base-project/base-app/src/app/auth/_layout.tsx b/code/base-project/base-app/src/app/auth/_layout.tsx deleted file mode 100644 index 9fd52344..00000000 --- a/code/base-project/base-app/src/app/auth/_layout.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import type { StepLayoutItem } from '@/components/custom/StepLayout' -import { Slot, Stack, useRouter } from 'expo-router' -import { Image, Text, View } from 'react-native' -import { SafeAreaView } from 'react-native-safe-area-context' -import StepLayout from '@/components/custom/StepLayout' -import CustomTabbar from '@/components/custom/Tabbar' - -const steps: StepLayoutItem[] = [ - { - path: '/auth/index', - showHearder: false, - }, - { - title: '登录', - path: '/auth/login', - }, - { - title: '注册', - path: '/auth/register', - }, -] - -export default function AuthLayout() { - return ( - - - - ) -} diff --git a/code/base-project/base-app/src/app/auth/index.tsx b/code/base-project/base-app/src/app/auth/index.tsx index b63cf3e8..8ab1d909 100644 --- a/code/base-project/base-app/src/app/auth/index.tsx +++ b/code/base-project/base-app/src/app/auth/index.tsx @@ -1,5 +1,6 @@ import { useRouter } from 'expo-router' import { Image, Text, View } from 'react-native' +import CustomHeader from '@/components/custom/Header' import { Button, ButtonText } from '@/components/ui/button' export default function AuthIndex() { @@ -10,33 +11,39 @@ export default function AuthIndex() { } return ( - - + + + - + - - ONEAO - + + ONEAO + - - + + - + + + ) } diff --git a/code/base-project/base-app/src/app/auth/login.tsx b/code/base-project/base-app/src/app/auth/login.tsx index d3c476fc..6f9a90fc 100644 --- a/code/base-project/base-app/src/app/auth/login.tsx +++ b/code/base-project/base-app/src/app/auth/login.tsx @@ -2,6 +2,7 @@ import { useRouter } from 'expo-router' import { useState } from 'react' import { Image, Text, View } from 'react-native' import { AButton, ACheckbox, AForm, AFormItem, AInput } from '@/components/common/ao' +import CustomHeader from '@/components/custom/Header' import { IconQq, IconWeixin, IconZhiwen } from '@/components/iconfont' import { Divider } from '@/components/ui/divider' import useFormValidation from '@/hooks/useFormValidation' @@ -85,59 +86,63 @@ export default function AuthLogin() { } return ( - - - - - - handleInputChange('account', text)} - /> - - - - handleInputChange('password', text)} - /> - - - - - setForm(prev => ({ ...prev, rememberMe: checked }))} - label="记住我" + + + + - 忘记密码? - + + + handleInputChange('account', text)} + /> + - - 登录 - + + handleInputChange('password', text)} + /> + + - - - + + setForm(prev => ({ ...prev, rememberMe: checked }))} + label="记住我" + /> + + 忘记密码? - 社交账号 - - - - - - - - + + 登录 + + + + + + + 社交账号 + + + + + + + + + + + ) } diff --git a/code/base-project/base-app/src/app/auth/register.tsx b/code/base-project/base-app/src/app/auth/register.tsx index 38d4c20d..b1ccc8d8 100644 --- a/code/base-project/base-app/src/app/auth/register.tsx +++ b/code/base-project/base-app/src/app/auth/register.tsx @@ -5,6 +5,7 @@ import { useRef, useState } from 'react' import { Image, ScrollView, View } from 'react-native' import { AButton, AForm, AFormItem, AInput } from '@/components/common/ao' +import CustomHeader from '@/components/custom/Header' import { registerDefaultApi } from '@/request/api/auth' import { toast } from '@/utils/toast' @@ -57,68 +58,72 @@ export default function AuthRegister() { } return ( - - - + + + + + - - - handleInputChange('username', text)} - /> - + + + handleInputChange('username', text)} + /> + - - handleInputChange('password', text)} - /> - + + handleInputChange('password', text)} + /> + - val === form.password, - message: '两次密码不一致', - }, - ]} - > - handleInputChange('confirmPassword', text)} - /> - - + val === form.password, + message: '两次密码不一致', + }, + ]} + > + handleInputChange('confirmPassword', text)} + /> + + - + + + 注册 + + + + - 注册 - - - ) } diff --git a/code/base-project/base-app/src/app/system/settings/index.tsx b/code/base-project/base-app/src/app/system/settings/index.tsx index ee07b7d2..f4c30e43 100644 --- a/code/base-project/base-app/src/app/system/settings/index.tsx +++ b/code/base-project/base-app/src/app/system/settings/index.tsx @@ -1,9 +1,14 @@ import { Text, View } from 'react-native' +import CustomHeader from '@/components/custom/Header' -export default function Settings() { +export default function Share() { return ( - - Settings + + + + + 123 + ) } diff --git a/code/base-project/base-app/src/app/system/share/index.tsx b/code/base-project/base-app/src/app/system/share/index.tsx index e2909c7b..a61be67d 100644 --- a/code/base-project/base-app/src/app/system/share/index.tsx +++ b/code/base-project/base-app/src/app/system/share/index.tsx @@ -1,17 +1,13 @@ import { Stack } from 'expo-router' import { Text, View } from 'react-native' +import CustomHeader from '@/components/custom/Header' export default function Share() { return ( - <> - - - Share - - + + + + ) } diff --git a/code/base-project/base-app/src/components/custom/Header.tsx b/code/base-project/base-app/src/components/custom/Header.tsx index 5d599bfb..08e6fd00 100644 --- a/code/base-project/base-app/src/components/custom/Header.tsx +++ b/code/base-project/base-app/src/components/custom/Header.tsx @@ -1,17 +1,92 @@ -import { Stack } from 'expo-router' -import { SafeAreaView } from 'react-native-safe-area-context' +import type { ViewStyle } from 'react-native' +import { Stack, useRouter } from 'expo-router' +import React from 'react' +import { Image, Text, TouchableOpacity, View } from 'react-native' +import { useSafeAreaInsets } from 'react-native-safe-area-context' +import { LucideIcon } from '../common/ao' + +export type StackScreenProps = React.ComponentProps + +interface CustomHeaderProps { + showHeader?: boolean + title?: string | React.ReactNode + left?: React.ReactNode + right?: React.ReactNode + safeArea?: boolean + screenProps?: StackScreenProps + className?: string + style?: ViewStyle +} + +export default function CustomHeader({ + showHeader = true, + title, + left, + right, + safeArea = true, + className = '', + style, + screenProps, +}: CustomHeaderProps) { + const safeAreaInsets = useSafeAreaInsets() + const router = useRouter() + + if (!showHeader) { + return ( + + ) + } -export default function CustomHeader() { return ( <> - - - - + + + {left || ( + router.back()}> + + + )} + + + + {typeof title === 'string' + ? ( + {title} + ) + : ( + title + )} + + + + {right || ( + + )} + + ) } diff --git a/code/base-project/base-app/src/request/index.ts b/code/base-project/base-app/src/request/index.ts index 6c068bd8..a70533ab 100644 --- a/code/base-project/base-app/src/request/index.ts +++ b/code/base-project/base-app/src/request/index.ts @@ -30,8 +30,8 @@ function isWhiteListed(url: string) { } const alovaInstance = createAlova({ - // baseURL: 'http://192.168.5.6:8085/app', - baseURL: 'http://192.168.1.136:8085/app', + baseURL: 'http://192.168.5.6:8085/app', + // baseURL: 'http://192.168.1.136:8085/app', requestAdapter: axiosRequestAdapter(), timeout: 5000, cacheFor: null, @@ -76,9 +76,9 @@ const alovaInstance = createAlova({ // 重试原请求 method.config.headers.token = newToken - const retryResult = await method.send() // ✅ 获取结果 + const retryResult = await method.send() - return retryResult // ✅ 一定要 return! + return retryResult } catch (err) { return Promise.reject(err) @@ -88,7 +88,6 @@ const alovaInstance = createAlova({ return result }, onError: (error: AxiosError, _method) => { - console.log('===跳转到error了===') console.log(error.status) switch (error.status) { diff --git a/code/base-project/base-app/src/store/moneyCategory.ts b/code/base-project/base-app/src/store/moneyCategory.ts new file mode 100644 index 00000000..b4db0008 --- /dev/null +++ b/code/base-project/base-app/src/store/moneyCategory.ts @@ -0,0 +1,44 @@ +import type { MoneyCategoryItem } from '@/types/money/category' +import { create } from 'zustand' + +interface MoneyCategoryStore { + categories: MoneyCategoryItem[] + expense: MoneyCategoryItem[] + income: MoneyCategoryItem[] + setCategories: (categories: MoneyCategoryItem[]) => void + addCategory: (category: MoneyCategoryItem) => void + removeCategory: (id: number) => void +} + +export const useMoneyCategoryStore = create()(set => ({ + categories: [], + expense: [], + income: [], + + setCategories: categories => + set({ + categories, + expense: categories.filter(c => c.type === 0), + income: categories.filter(c => c.type === 1), + }), + + addCategory: category => + set((state) => { + const newCategories = [...state.categories, category] + return { + categories: newCategories, + expense: newCategories.filter(c => c.type === 0), + income: newCategories.filter(c => c.type === 1), + } + }), + + removeCategory: id => + set((state) => { + const newCategories = state.categories.filter(c => c.id !== id) + return { + categories: newCategories, + expense: newCategories.filter(c => c.type === 0), + income: newCategories.filter(c => c.type === 1), + } + }), +})) diff --git a/code/base-project/base-app/src/store/moneyRecord.ts b/code/base-project/base-app/src/store/moneyRecord.ts new file mode 100644 index 00000000..0488bcee --- /dev/null +++ b/code/base-project/base-app/src/store/moneyRecord.ts @@ -0,0 +1,3 @@ +import { create } from 'zustand' +import { MoneyCategoryItem } from '@/types/money/category' +import { MoneyRecordGroup, MoneyRecordItem } from '@/types/money/record' diff --git a/code/base-project/base-app/src/types/money/category.ts b/code/base-project/base-app/src/types/money/category.ts index de80bbd3..b55f421e 100644 --- a/code/base-project/base-app/src/types/money/category.ts +++ b/code/base-project/base-app/src/types/money/category.ts @@ -11,8 +11,3 @@ export interface MoneyCategoryBase { export interface MoneyCategoryItem extends MoneyCategoryBase { } - -export interface QueryMoneyCategoryResult { - income: MoneyCategoryItem[] - expense: MoneyCategoryItem[] -} diff --git a/code/base-project/base-go-v2/internal/api/money/index.go b/code/base-project/base-go-v2/internal/api/money/index.go index f55847d4..b6c4ff96 100644 --- a/code/base-project/base-go-v2/internal/api/money/index.go +++ b/code/base-project/base-go-v2/internal/api/money/index.go @@ -189,22 +189,7 @@ func getUserCategory(c *router.Context) error { return c.AddError(err) } - // 按 type 分组并保持顺序 - result := map[string][]mapx.M{ - "income": {}, - "expense": {}, - } - - for _, cat := range userCategories { - t := cat.GetInt("type") - if t == 1 { - result["income"] = append(result["income"], cat) - } else if t == 0 { - result["expense"] = append(result["expense"], cat) - } - } - - return response.Success(c).Data(result).Send() + return response.Success(c).Data(userCategories).Send() } func insertMoneyRecord(c *router.Context) error {