This commit is contained in:
oneao committed 2026-01-18 21:20:51 +08:00
1 parent 78c7a812be
commit 1934225c53
24 files changed
+711 -654

No files matched your search

@@ -1,5 +1,5 @@
import { useRouter } from 'expo-router'
import React, { useEffect, useState } from 'react'
import { useFocusEffect, useRouter } from 'expo-router'
import React, { useCallback, useEffect, useState } from 'react'
import { Image, Text, TouchableOpacity, View } from 'react-native'
import { Drawer } from 'react-native-drawer-layout'
import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context'
@@ -52,6 +52,17 @@ export default function Money() {
getMoneyRecords()
}, [appStore.ready, searchParams])
useFocusEffect(
useCallback(() => {
// 页面显示 / 返回时
console.log('===shohw===')
return () => {
// 页面离开(可选)
}
}, []),
)
return (
<View
className="flex-1"
@@ -1,3 +1,4 @@
import type { MoneyCategoryItem } from '@/types/money/category'
import { useEffect, useState } from 'react'
import { Pressable, Text, View } from 'react-native'
import { AButton, AInput } from '@/components/common/ao'
@@ -23,7 +24,7 @@ interface EditCategoryProps {
open: boolean
onClose?: () => void
type: MoneyCategoryEnum
category: MoneyCategoryItem | null
onConfirm?: (form: EditCategoryForm) => Promise<void>
}
@@ -32,6 +33,7 @@ export default function CreateCategory({
onClose,
type,
onConfirm,
category,
}: EditCategoryProps) {
const moneyCategoryStore = useMoneyCategoryStore()
@@ -58,6 +60,12 @@ export default function CreateCategory({
}
}, [form.name, form.icon])
useEffect(() => {
if (category !== null) {
setForm(category)
}
}, [category])
function handleClose() {
setIsOpen(false)
onClose && onClose()
@@ -116,6 +124,7 @@ export default function CreateCategory({
</View>
<AInput
value={form.name}
placeholder="请输入名称(不超过5个字符)"
onChangeText={(text) => {
setForm((val) => {
@@ -25,7 +25,9 @@ export default function MoneyCategorySetting() {
const [draggingDeleteZone, setDraggingDeleteZone] = useState<boolean>(false)
const [deleteTimer, setDeleteTimer] = useState<number | null>(null)
const [openCreateCategory, setOpenCreateCategory] = useState<boolean>(false)
const [showEditCategory, setshowEditCategory] = useState<boolean>(false)
const [selectedCategory, setSelectedCategory] = useState<MoneyCategoryItem | null>(null)
useEffect(() => {
setCategories(selectedTab === MoneyCategoryEnum.Expense ? moneyCategoryStore.getExpenseCategories() : moneyCategoryStore.getIncomeCategories())
@@ -35,7 +37,8 @@ export default function MoneyCategorySetting() {
({ item }) => (
<Pressable
onPress={() => {
console.log('点击进入编辑')
setSelectedCategory(item)
setshowEditCategory(true)
}}
className="flex flex-col items-center justify-center"
>
@@ -64,33 +67,49 @@ export default function MoneyCategorySetting() {
)
async function handleConfirmEdit(form: EditCategoryForm) {
const isDuplicate = moneyCategoryStore.isDuplicateCategory(form.name, selectedTab)
const isDuplicate = moneyCategoryStore.isDuplicateCategory(
form.name,
selectedTab,
form.id ?? null,
)
if (isDuplicate) {
toast.show({
type: 'warning',
title: '类别不能重复',
})
return
}
try {
await moneyCategoryStore.createCategory({
id: 0,
name: form.name,
icon: form.icon,
sort_number: 0,
type: selectedTab,
})
if (form.id != null) {
await moneyCategoryStore.updateCategory({
id: form.id,
name: form.name,
icon: form.icon,
type: selectedTab,
sort_number: 0,
})
}
else {
await moneyCategoryStore.createCategory({
id: 0,
name: form.name,
icon: form.icon,
sort_number: 0,
type: selectedTab,
})
}
setOpenCreateCategory(false)
setshowEditCategory(false)
}
catch (err) {
const message
= err instanceof Error
? err.message
: '新增失败,请稍后再试'
: form.id != null
? '更新失败,请稍后再试'
: '新增失败,请稍后再试'
toast.show({
type: 'error',
@@ -133,7 +152,7 @@ export default function MoneyCategorySetting() {
clickable: false,
}}
onPress={(() =>
setOpenCreateCategory(true)
setshowEditCategory(true)
)}
>
新增
@@ -228,8 +247,12 @@ export default function MoneyCategorySetting() {
<EditCategory
type={selectedTab}
open={openCreateCategory}
onClose={() => setOpenCreateCategory(false)}
open={showEditCategory}
onClose={() => {
setshowEditCategory(false)
setSelectedCategory(null)
}}
category={selectedCategory}
onConfirm={handleConfirmEdit}
/>
</View>
@@ -1,4 +1,4 @@
import type { CreateMoneyCategoryParams, CreateMoneyCategoryResult, DeleteMoneyCategoryParams, QueryMoneyCategoryResult, UpdateMoneyCategorySortParams } from '@/types/money/category'
import type { CreateMoneyCategoryParams, CreateMoneyCategoryResult, DeleteMoneyCategoryParams, QueryMoneyCategoryResult, UpdateMoneyCategoryParams, UpdateMoneyCategoryResult, UpdateMoneyCategorySortParams } from '@/types/money/category'
import alovaInstance from '../../index'
const API_PREFIX = '/money/category'
@@ -18,3 +18,7 @@ export function updateMoneyCategorySortApi(params: UpdateMoneyCategorySortParams
export function createMoneyCategoryApi(params: CreateMoneyCategoryParams) {
return alovaInstance.Post<ResponseData<CreateMoneyCategoryResult>>(`${API_PREFIX}/create`, params)
}
export function updateMoneyCategoryApi(params: UpdateMoneyCategoryParams) {
return alovaInstance.Post<ResponseData<UpdateMoneyCategoryResult>>(`${API_PREFIX}/update`, params)
}
@@ -1,6 +1,6 @@
import type { MoneyCategoryItem, UpdateMoneyCategorySortItem } from '@/types/money/category'
import type { MoneyCategoryItem } from '@/types/money/category'
import { create } from 'zustand'
import { createMoneyCategoryApi, deleteMoneyCategoryApi, queryMoneyCategoryApi, updateMoneyCategorySortApi } from '@/request/api/money/category'
import { createMoneyCategoryApi, deleteMoneyCategoryApi, queryMoneyCategoryApi, updateMoneyCategoryApi, updateMoneyCategorySortApi } from '@/request/api/money/category'
import { MoneyCategoryEnum } from '@/types/money/category'
interface MoneyCategoryStore {
@@ -16,10 +16,11 @@ interface MoneyCategoryStore {
getCategoryById: (id: number) => MoneyCategoryItem | null
createCategory: (category: MoneyCategoryItem) => Promise<void>
updateCategory: (category: MoneyCategoryItem) => Promise<void>
updateSortNumbers: (data: MoneyCategoryItem[], type: number) => Promise<void>
deleteCategoryById: (id: number) => Promise<void>
isDuplicateCategory: (name: string, type: number) => boolean
isDuplicateCategory: (name: string, type: number, excludeId: number | null) => boolean
clear: () => void
}
@@ -162,6 +163,36 @@ export const useMoneyCategoryStore = create<MoneyCategoryStore>()(
}
},
updateCategory: async (category) => {
try {
const res = await updateMoneyCategoryApi({
id: category.id,
name: category.name,
icon: category.icon,
})
if (!res.isSuccess) {
throw new Error(res.message)
}
// 更新本地 categories
set(state => ({
categories: state.categories.map(c =>
c.id !== category.id
? c
: {
...c,
...category,
},
),
}))
}
catch (err) {
console.error(err)
throw err
}
},
updateSortNumbers: async (data, type) => {
const payload = data.map((item, index) => ({
id: item.id,
@@ -207,9 +238,13 @@ export const useMoneyCategoryStore = create<MoneyCategoryStore>()(
}
},
isDuplicateCategory: (name, type) => {
isDuplicateCategory: (name, type, excludeId) => {
const categories = get().categories || []
return categories.some(c => c.name === name && c.type === type)
return categories.some(c =>
c.name === name
&& c.type === type
&& c.id !== excludeId,
)
},
}),
)
@@ -44,3 +44,11 @@ export interface CreateMoneyCategoryParams {
export interface CreateMoneyCategoryResult {
id: number
}
export interface UpdateMoneyCategoryParams {
id: number
name: string
icon: string
}
export interface UpdateMoneyCategoryResult {
}