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 (
-
-
-
- )
- }
+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 {