diff --git a/code/allapp/allapp-go/biz/handler/auth/register_service.go b/code/allapp/allapp-go/biz/handler/auth/register_service.go index ddb3ad72..e8983e4c 100644 --- a/code/allapp/allapp-go/biz/handler/auth/register_service.go +++ b/code/allapp/allapp-go/biz/handler/auth/register_service.go @@ -87,7 +87,7 @@ func RegisterDefault(ctx context.Context, c *app.RequestContext) { } // 初始化用户分类 - err = initMoneyCategoryTx(ctx, tx, params.ID) + err = InitMoneyCategoryTx(ctx, tx, params.ID) if err != nil { errorx.AddError(c, err) return @@ -97,8 +97,15 @@ func RegisterDefault(ctx context.Context, c *app.RequestContext) { response.Success(c).Message("注册成功").Send() } -func initMoneyCategoryTx(ctx context.Context, tx pgx.Tx, userId int64) error { - sysCategories, err := db.Queries.ListMoneySysCategory(ctx) +func InitMoneyCategoryTx( + ctx context.Context, + tx pgx.Tx, + userId int64, +) error { + + q := db.Queries.WithTx(tx) + + sysCategories, err := q.ListMoneySysCategory(ctx) if err != nil { return err } @@ -118,9 +125,12 @@ func initMoneyCategoryTx(ctx context.Context, tx pgx.Tx, userId int64) error { }) } - _, err = db.Queries.WithTx(tx).BatchInsertMoneyUserCategories(ctx, userCategories) + // ⚠️ 注意:这里是 DeleteMoneyCategoryByUserId,不是 ById(你代码里疑似写错) + if err := q.DeleteMoneyCategoryByUserId(ctx, userId); err != nil { + return err + } - if err != nil { + if _, err := q.BatchInsertMoneyUserCategories(ctx, userCategories); err != nil { return err } diff --git a/code/allapp/allapp-go/biz/handler/money/money_category_service.go b/code/allapp/allapp-go/biz/handler/money/money_category_service.go index 19309f63..50beff11 100644 --- a/code/allapp/allapp-go/biz/handler/money/money_category_service.go +++ b/code/allapp/allapp-go/biz/handler/money/money_category_service.go @@ -67,7 +67,7 @@ func DeleteUserMoneyCategory(ctx context.Context, c *app.RequestContext) { return } - err = db.Queries.DeleteUserMoneyCategoryById(ctx, req.Id) + err = db.Queries.DeleteMoneyCategoryById(ctx, req.Id) if err != nil { errorx.AddError(c, err) diff --git a/code/allapp/allapp-go/db/queries/money_user_category.sql b/code/allapp/allapp-go/db/queries/money_user_category.sql index d1e078db..831d6117 100644 --- a/code/allapp/allapp-go/db/queries/money_user_category.sql +++ b/code/allapp/allapp-go/db/queries/money_user_category.sql @@ -7,7 +7,7 @@ SELECT * FROM money_user_category WHERE user_id = $1; --- name: DeleteUserMoneyCategoryById :exec +-- name: DeleteMoneyCategoryById :exec DELETE FROM money_user_category WHERE id = $1; @@ -15,3 +15,7 @@ WHERE id = $1; UPDATE money_user_category SET sort_number = $2 WHERE id = $1; + +-- name: DeleteMoneyCategoryByUserId :exec +DELETE FROM money_user_category +WHERE user_id = $1; \ No newline at end of file diff --git a/code/allapp/allapp-go/db/repo/money_user_category.sql.go b/code/allapp/allapp-go/db/repo/money_user_category.sql.go index 160a265b..48e750ad 100644 --- a/code/allapp/allapp-go/db/repo/money_user_category.sql.go +++ b/code/allapp/allapp-go/db/repo/money_user_category.sql.go @@ -18,13 +18,23 @@ type BatchInsertMoneyUserCategoriesParams struct { SortNumber int32 } -const deleteUserMoneyCategoryById = `-- name: DeleteUserMoneyCategoryById :exec +const deleteMoneyCategoryById = `-- name: DeleteMoneyCategoryById :exec DELETE FROM money_user_category WHERE id = $1 ` -func (q *Queries) DeleteUserMoneyCategoryById(ctx context.Context, id int64) error { - _, err := q.db.Exec(ctx, deleteUserMoneyCategoryById, id) +func (q *Queries) DeleteMoneyCategoryById(ctx context.Context, id int64) error { + _, err := q.db.Exec(ctx, deleteMoneyCategoryById, id) + return err +} + +const deleteMoneyCategoryByUserId = `-- name: DeleteMoneyCategoryByUserId :exec +DELETE FROM money_user_category +WHERE user_id = $1 +` + +func (q *Queries) DeleteMoneyCategoryByUserId(ctx context.Context, userID int64) error { + _, err := q.db.Exec(ctx, deleteMoneyCategoryByUserId, userID) return err } diff --git a/code/allapp/allapp-rn/package.json b/code/allapp/allapp-rn/package.json index cdf969fe..214efb1b 100644 --- a/code/allapp/allapp-rn/package.json +++ b/code/allapp/allapp-rn/package.json @@ -63,6 +63,7 @@ "@types/big.js": "^6.2.2", "@types/react": "~19.1.0", "babel-plugin-module-resolver": "^5.0.2", + "baseline-browser-mapping": "^2.9.14", "eslint": "^9.38.0", "react-native-iconfont-cli": "^2.2.4", "react-native-svg-transformer": "^1.5.2", diff --git a/code/allapp/allapp-rn/pnpm-lock.yaml b/code/allapp/allapp-rn/pnpm-lock.yaml index e90704e9..52547133 100644 --- a/code/allapp/allapp-rn/pnpm-lock.yaml +++ b/code/allapp/allapp-rn/pnpm-lock.yaml @@ -162,6 +162,9 @@ importers: babel-plugin-module-resolver: specifier: ^5.0.2 version: 5.0.2 + baseline-browser-mapping: + specifier: ^2.9.14 + version: 2.9.14 eslint: specifier: ^9.38.0 version: 9.39.1(jiti@1.21.7) @@ -2509,8 +2512,8 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - baseline-browser-mapping@2.8.28: - resolution: {integrity: sha512-gYjt7OIqdM0PcttNYP2aVrr2G0bMALkBaoehD4BuRGjAOtipg0b6wHg1yNL+s5zSnLZZrGHOw4IrND8CD+3oIQ==} + baseline-browser-mapping@2.9.14: + resolution: {integrity: sha512-B0xUquLkiGLgHhpPBqvl7GWegWBUNuujQ6kXd/r1U38ElPT6Ok8KZ8e+FpUGEc2ZoRQUzq/aUnaKFc/svWUGSg==} hasBin: true better-opn@3.0.2: @@ -9105,7 +9108,7 @@ snapshots: base64-js@1.5.1: {} - baseline-browser-mapping@2.8.28: {} + baseline-browser-mapping@2.9.14: {} better-opn@3.0.2: dependencies: @@ -9146,7 +9149,7 @@ snapshots: browserslist@4.28.0: dependencies: - baseline-browser-mapping: 2.8.28 + baseline-browser-mapping: 2.9.14 caniuse-lite: 1.0.30001754 electron-to-chromium: 1.5.252 node-releases: 2.0.27 diff --git a/code/allapp/allapp-rn/src/app/money/category/setting/components/CreateCategory.tsx b/code/allapp/allapp-rn/src/app/money/category/setting/components/CreateCategory.tsx index 59b1cacb..07bffe15 100644 --- a/code/allapp/allapp-rn/src/app/money/category/setting/components/CreateCategory.tsx +++ b/code/allapp/allapp-rn/src/app/money/category/setting/components/CreateCategory.tsx @@ -1,37 +1,67 @@ import { useEffect, useState } from 'react' -import { Pressable, ScrollView, Text, View } from 'react-native' +import { Pressable, Text, View } from 'react-native' +import { AButton } from '@/components/common/ao' import MoneyCategoryIcon from '@/components/common/MoneyCategoryIcon' import { Drawer, DrawerBackdrop, DrawerBody, DrawerContent, + DrawerFooter, DrawerHeader, } from '@/components/ui/drawer' import { Input, InputField } from '@/components/ui/input' - import { useMoneyCategoryStore } from '@/store/moneyCategory' +import { MoneyCategoryEnum } from '@/types/money/category' interface CreateCategoryProps { open: boolean onClose?: () => void + type: MoneyCategoryEnum +} + +interface CreateCategoryForm { + icon: string + name: string } export default function CreateCategory({ open, onClose, + type, }: CreateCategoryProps) { const moneyCategoryStore = useMoneyCategoryStore() const [isOpen, setIsOpen] = useState(open) + const [form, setForm] = useState({ + icon: '', + name: '', + }) + const [confirmDisabled, setConfirmDisabled] = useState(true) + const [confirmLoading, setConfirmLoading] = useState(false) + useEffect(() => { setIsOpen(open) }, [open]) + useEffect(() => { + if (form.name && form.name.length < 6) { + setConfirmDisabled(false) + } + else { + setConfirmDisabled(true) + } + }, [form.name]) + function handleClose() { setIsOpen(false) onClose && onClose() + + setForm({ + icon: '', + name: '', + }) } return ( @@ -45,60 +75,65 @@ export default function CreateCategory({ > - - 取消 - + 取消 - 类别 + {type === MoneyCategoryEnum.Expense ? '添加支出分类' : '添加收入分类'} - - 确认 - + 确认 - + - - - {Object.entries(moneyCategoryStore.ICON_GROUPS).map(([groupName, icons]) => ( - - - {groupName} - + + {Object.entries(moneyCategoryStore.ICON_GROUPS).map(([groupName, icons]) => ( + + + {groupName} + - - {icons.map(icon => ( - { - console.log('select icon:', icon) + + {icons.map(icon => ( + { + setForm(val => ({ + ...val, + icon, + })) + }} + > + - - - - - ))} - + + + + ))} - ))} - + + ))} + + ) 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 768f9f68..e880851d 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 @@ -9,10 +9,11 @@ import { AButton, ATab, LucideIcon } from '@/components/common/ao' import MoneyCategoryIcon from '@/components/common/MoneyCategoryIcon' import CustomHeader from '@/components/custom/Header' import { useMoneyCategoryStore } from '@/store/moneyCategory' +import { MoneyCategoryEnum } from '@/types/money/category' import CreateCategory from './components/CreateCategory' export default function MoneyCategorySetting() { - const [selectedTab, setSelectedTab] = useState(0) + const [selectedTab, setSelectedTab] = useState(MoneyCategoryEnum.Expense) const moneyCategoryStore = useMoneyCategoryStore() const scrollableRef = useAnimatedRef() @@ -25,7 +26,7 @@ export default function MoneyCategorySetting() { const [openCreateCategory, setOpenCreateCategory] = useState(false) useEffect(() => { - setCategories(selectedTab === 0 ? moneyCategoryStore.getExpenseCategories() : moneyCategoryStore.getIncomeCategories()) + setCategories(selectedTab === MoneyCategoryEnum.Expense ? moneyCategoryStore.getExpenseCategories() : moneyCategoryStore.getIncomeCategories()) }, [selectedTab]) const renderItem = useCallback>( @@ -69,18 +70,18 @@ export default function MoneyCategorySetting() { { - setSelectedTab(index) + defaultKey={selectedTab} + onChange={(key) => { + setSelectedTab(key as MoneyCategoryEnum) }} data={[ { - key: 'income', - label: '收入', + key: MoneyCategoryEnum.Expense, + label: '支出', }, { - key: 'expense', - label: '支出', + key: MoneyCategoryEnum.Income, + label: '收入', }, ]} /> @@ -189,6 +190,7 @@ export default function MoneyCategorySetting() { setOpenCreateCategory(false)} /> diff --git a/code/allapp/allapp-rn/src/components/common/ao/Tab.tsx b/code/allapp/allapp-rn/src/components/common/ao/Tab.tsx index 2db6b0ff..4016eefa 100644 --- a/code/allapp/allapp-rn/src/components/common/ao/Tab.tsx +++ b/code/allapp/allapp-rn/src/components/common/ao/Tab.tsx @@ -4,14 +4,14 @@ import PagerView from 'react-native-pager-view' interface TabItem { label: string - key: string + key: string | number content?: React.ReactNode } interface TabProps { data?: TabItem[] - defaultIndex?: number - onChange?: (index: number) => void + defaultKey?: TabItem['key'] + onChange?: (key: TabItem['key']) => void tabBarClass?: string tabItemClass?: string activeTabItemClass?: string @@ -19,47 +19,66 @@ interface TabProps { export default function Tab({ data, - defaultIndex = 0, + defaultKey, onChange, tabBarClass = 'flex flex-row gap-2 overflow-hidden', tabItemClass = 'items-center justify-center rounded-md px-4 py-2 bg-gray-200', activeTabItemClass = 'items-center justify-center rounded-md px-4 py-2 bg-gray-800', }: TabProps) { - const [selectedIndex, setSelectedIndex] = useState(defaultIndex) - const pagerRef = useRef(null) - if (!data || data.length === 0) return null - // 判断是否至少有一个 tab 含 content + // 默认选中 key(没传就用第一个) + const initialKey = defaultKey ?? data[0].key + const [selectedKey, setSelectedKey] = useState(initialKey) + + const pagerRef = useRef(null) + + // 是否有 content const hasContent = useMemo( () => data.some(item => item.content), [data], ) - const handlePress = (index: number) => { - setSelectedIndex(index) - onChange?.(index) - if (hasContent) - pagerRef.current?.setPage(index) + // key -> index + const getIndexByKey = (key: TabItem['key']) => + data.findIndex(item => item.key === key) + + // index -> key + const getKeyByIndex = (index: number) => + data[index]?.key + + const handlePress = (key: TabItem['key']) => { + setSelectedKey(key) + onChange?.(key) + + if (hasContent) { + const index = getIndexByKey(key) + if (index !== -1) + pagerRef.current?.setPage(index) + } } const onPageSelected = (e: any) => { const index = e.nativeEvent.position - setSelectedIndex(index) - onChange?.(index) + const key = getKeyByIndex(index) + + if (key !== undefined) { + setSelectedKey(key) + onChange?.(key) + } } return ( {/* tab bar */} - {data.map((item, index) => { - const isActive = index === selectedIndex + {data.map((item) => { + const isActive = item.key === selectedKey return ( handlePress(index)} + onPress={() => handlePress(item.key)} className={isActive ? activeTabItemClass : tabItemClass} > @@ -74,7 +93,7 @@ export default function Tab({ {data.map(item => ( diff --git a/code/allapp/allapp-rn/src/request/index.ts b/code/allapp/allapp-rn/src/request/index.ts index 476eb11d..de7e4c95 100644 --- a/code/allapp/allapp-rn/src/request/index.ts +++ b/code/allapp/allapp-rn/src/request/index.ts @@ -32,8 +32,8 @@ function isWhiteListed(url: string) { } const alovaInstance = createAlova({ - // baseURL: 'http://192.168.5.6:8086/app', - baseURL: 'http://192.168.1.137:8086/app', + baseURL: 'http://192.168.5.6:8086/app', + // baseURL: 'http://192.168.1.137:8086/app', requestAdapter: axiosRequestAdapter(), timeout: 5000, cacheFor: null, diff --git a/code/allapp/allapp-rn/src/types/money/category.ts b/code/allapp/allapp-rn/src/types/money/category.ts index a0d37e75..11e14803 100644 --- a/code/allapp/allapp-rn/src/types/money/category.ts +++ b/code/allapp/allapp-rn/src/types/money/category.ts @@ -28,3 +28,8 @@ export interface UpdateMoneyCategorySortItem { export interface UpdateMoneyCategorySortParams { data: UpdateMoneyCategorySortItem[] } + +export enum MoneyCategoryEnum { + Expense = 0, // 支出 + Income = 1, // 收入 +}