From 52a20dfa2230411c661b9bb237ce4809842e15a1 Mon Sep 17 00:00:00 2001 From: ZhangAo Date: Wed, 21 Jan 2026 17:19:36 +0800 Subject: [PATCH] u --- code/allapp/allapp-rn/package.json | 1 + code/allapp/allapp-rn/pnpm-lock.yaml | 11 + .../allapp-rn/src/app/(tabs)/money/index.tsx | 2 +- code/allapp/allapp-rn/src/app/auth/index.tsx | 5 - .../setting/components/EditCategory.tsx | 241 ++++++++---------- .../src/app/money/category/setting/index.tsx | 9 +- .../editor/components/CategoryGrid copy.tsx | 111 -------- .../record/editor/components/CategoryGrid.tsx | 33 +-- code/allapp/allapp-rn/src/request/index.ts | 4 +- 9 files changed, 131 insertions(+), 286 deletions(-) delete mode 100644 code/allapp/allapp-rn/src/app/money/record/editor/components/CategoryGrid copy.tsx diff --git a/code/allapp/allapp-rn/package.json b/code/allapp/allapp-rn/package.json index 4d9f94bb..d7736a5e 100644 --- a/code/allapp/allapp-rn/package.json +++ b/code/allapp/allapp-rn/package.json @@ -55,6 +55,7 @@ "react-native-sortables": "^1.9.3", "react-native-svg": "15.12.1", "react-native-web": "^0.21.0", + "react-native-worklets": "0.5.1", "tailwind-merge": "^3.4.0", "zustand": "^5.0.8" }, diff --git a/code/allapp/allapp-rn/pnpm-lock.yaml b/code/allapp/allapp-rn/pnpm-lock.yaml index 50e09a4b..5015a112 100644 --- a/code/allapp/allapp-rn/pnpm-lock.yaml +++ b/code/allapp/allapp-rn/pnpm-lock.yaml @@ -143,6 +143,9 @@ importers: react-native-web: specifier: ^0.21.0 version: 0.21.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react-native-worklets: + specifier: 0.5.1 + version: 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) tailwind-merge: specifier: ^3.4.0 version: 3.4.0 @@ -3964,48 +3967,56 @@ packages: engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [glibc] lightningcss-linux-arm64-gnu@1.30.2: resolution: {integrity: sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [glibc] lightningcss-linux-arm64-musl@1.27.0: resolution: {integrity: sha512-rCGBm2ax7kQ9pBSeITfCW9XSVF69VX+fm5DIpvDZQl4NnQoMQyRwhZQm9pd59m8leZ1IesRqWk2v/DntMo26lg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [musl] lightningcss-linux-arm64-musl@1.30.2: resolution: {integrity: sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [musl] lightningcss-linux-x64-gnu@1.27.0: resolution: {integrity: sha512-Dk/jovSI7qqhJDiUibvaikNKI2x6kWPN79AQiD/E/KeQWMjdGe9kw51RAgoWFDi0coP4jinaH14Nrt/J8z3U4A==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [glibc] lightningcss-linux-x64-gnu@1.30.2: resolution: {integrity: sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [glibc] lightningcss-linux-x64-musl@1.27.0: resolution: {integrity: sha512-QKjTxXm8A9s6v9Tg3Fk0gscCQA1t/HMoF7Woy1u68wCk5kS4fR+q3vXa1p3++REW784cRAtkYKrPy6JKibrEZA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [musl] lightningcss-linux-x64-musl@1.30.2: resolution: {integrity: sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [musl] lightningcss-win32-arm64-msvc@1.27.0: resolution: {integrity: sha512-/wXegPS1hnhkeG4OXQKEMQeJd48RDC3qdh+OA8pCuOPCyvnm/yEayrJdJVqzBsqpy1aJklRCVxscpFur80o6iQ==} 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 c0ff5a37..8c6cb1ec 100644 --- a/code/allapp/allapp-rn/src/app/(tabs)/money/index.tsx +++ b/code/allapp/allapp-rn/src/app/(tabs)/money/index.tsx @@ -56,7 +56,7 @@ export default function Money() { useFocusEffect( useCallback(() => { // 页面显示 / 返回时 - console.log('===shohw===') + console.log('===show===') return () => { // 页面离开(可选) diff --git a/code/allapp/allapp-rn/src/app/auth/index.tsx b/code/allapp/allapp-rn/src/app/auth/index.tsx index a6e99cef..0832300a 100644 --- a/code/allapp/allapp-rn/src/app/auth/index.tsx +++ b/code/allapp/allapp-rn/src/app/auth/index.tsx @@ -1,7 +1,6 @@ import { useRouter } from 'expo-router' import { useEffect } from 'react' import { Image, Text, View } from 'react-native' -import * as QQAPI from 'react-native-qq-lib' import CustomHeader from '@/components/custom/Header' import { Button, ButtonText } from '@/components/ui/button' @@ -12,10 +11,6 @@ export default function AuthIndex() { router.push(url) } - useEffect(() => { - QQAPI.login() - }, []) - return ( ({ - icon: '', - name: '', - }) - + const [form, setForm] = useState({ icon: '', name: '' }) const [confirmDisabled, setConfirmDisabled] = useState(true) const [confirmLoading, setConfirmLoading] = useState(false) + const scrollRef = useRef(null) + const iconPositions = useRef>({}) // 记录每个 icon 的 y 坐标 + + // Drawer 打开/关闭控制 useEffect(() => { setIsOpen(open) - if (!open) { - setForm({ - icon: '', - name: '', - }) - } + if (!open) + setForm({ icon: '', name: '' }) }, [open]) + // 确认按钮状态 useEffect(() => { - if (form.name && form.name.length <= 5 && form.icon) { - setConfirmDisabled(false) - } - else { - setConfirmDisabled(true) - } + setConfirmDisabled(!(form.name && form.name.length <= 5 && form.icon)) }, [form.name, form.icon]) + // 编辑已有分类时填充数据 useEffect(() => { - if (category !== null) { + if (category) setForm(category) - } }, [category]) function handleClose() { - setForm({ - icon: '', - name: '', - }) + setForm({ icon: '', name: '' }) setIsOpen(false) - onClose && onClose() + onClose?.() } return ( - - - - - - 取消 - - {type === MoneyCategoryEnum.Expense ? '添加支出分类' : '添加收入分类'} - - { - if (!onConfirm) { - return - } - - try { - setConfirmLoading(true) - - const trimmedForm = { - ...form, - name: form.name.trim(), - } - - await onConfirm(trimmedForm) - } - catch (err) { - console.error(err) - // 外部报错时,保持弹窗打开,loading 结束 - } - finally { - setConfirmLoading(false) - } - }} - > - 确认 - - - - { - setForm((val) => { - return { - ...val, - name: text, - } - }) - }} - /> - - - {Object.entries(moneyCategoryStore.ICON_GROUPS).map(([groupName, icons]) => ( - - - {groupName} - - - - {icons.map(icon => ( - { - setForm(val => ({ - ...val, - icon, - })) - }} - > - - - - - ))} - - - ))} - - - - + ) } + +// +// +// +// +// +// +// 取消 +// +// +// {type === MoneyCategoryEnum.Expense ? '添加支出分类' : '添加收入分类'} +// +// { +// if (!onConfirm) +// return +// try { +// setConfirmLoading(true) +// await onConfirm({ ...form, name: form.name.trim() }) +// } +// finally { +// setConfirmLoading(false) +// } +// }} +// > +// 确认 +// +// +// setForm(val => ({ ...val, name: text }))} +// /> +// + +// +// {Object.entries(moneyCategoryStore.ICON_GROUPS).map(([groupName, icons]) => ( +// +// {groupName} +// +// {icons.map(icon => ( +// setForm(val => ({ ...val, icon }))} +// > +// { +// console.log(e.nativeEvent.layout) +// iconPositions.current[icon] = e.nativeEvent.layout.y +// }} +// style={{ +// width: 46, +// height: 46, +// borderRadius: 28, +// justifyContent: 'center', +// alignItems: 'center', +// backgroundColor: icon === form.icon ? '#333' : '#F3F4F6', +// }} +// > +// +// +// +// ))} +// +// +// ))} +// + +// +// +// 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 bbca4451..d55a2537 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 @@ -54,10 +54,11 @@ export default function MoneyCategorySetting() { > - {item.name} diff --git a/code/allapp/allapp-rn/src/app/money/record/editor/components/CategoryGrid copy.tsx b/code/allapp/allapp-rn/src/app/money/record/editor/components/CategoryGrid copy.tsx deleted file mode 100644 index 4b646707..00000000 --- a/code/allapp/allapp-rn/src/app/money/record/editor/components/CategoryGrid copy.tsx +++ /dev/null @@ -1,111 +0,0 @@ -import type { ViewStyle } from 'react-native' -import type { MoneyCategoryItem } from '@/types/money/category' -import React, { useEffect, useMemo, useRef } from 'react' -import { FlatList, Pressable, Text, View } from 'react-native' -import MoneyCategoryIcon from '@/components/common/MoneyCategoryIcon' - -interface CategoryGridProps { - data: MoneyCategoryItem[] - selectedCategory?: MoneyCategoryItem | null - onSelectCategory?: (item: MoneyCategoryItem | null) => void - - className?: string - style?: ViewStyle -} - -export default function CategoryGrid({ - data, - selectedCategory, - onSelectCategory, - className, - style, -}: CategoryGridProps) { - const flatListRef = useRef>(null) - - // 每行 4 个,补齐空项 - const memoItems = useMemo(() => { - const items = [...data] - const remainder = items.length % 4 - if (remainder > 0) { - const emptyCount = 4 - remainder - for (let i = 0; i < emptyCount; i++) { - items.push({ id: `empty-${i}` } as any) - } - } - return items - }, [data]) - - // 自动滚动到选中行 - useEffect(() => { - if (!selectedCategory || !flatListRef.current) - return - - // 找到选中项下标 - const itemIndex = data.findIndex(item => item.id === selectedCategory.id) - if (itemIndex === -1 || !flatListRef.current) - return - - setTimeout(() => { - if (flatListRef.current) { - flatListRef.current.scrollToIndex({ - index: Math.floor(itemIndex / 4), - animated: true, - viewPosition: 0.5, - }) - } - }, 0) - }, [selectedCategory]) - - return ( - item.id.toString()} - showsVerticalScrollIndicator={false} - className={`${className}`} - style={[style]} - getItemLayout={(data, index) => { - return { length: 80, offset: 80 * index, index } - }} - renderItem={({ item }) => { - if (!('name' in item)) - return - - const isSelected = selectedCategory?.id === item.id - - return ( - onSelectCategory?.(item)} - onLayout={(event) => { - const { height } = event.nativeEvent.layout - console.log('Pressable 高度:', height) - }} - > - - - - - {item.name} - - - ) - }} - /> - ) -} diff --git a/code/allapp/allapp-rn/src/app/money/record/editor/components/CategoryGrid.tsx b/code/allapp/allapp-rn/src/app/money/record/editor/components/CategoryGrid.tsx index 76a4a5ae..cffd9076 100644 --- a/code/allapp/allapp-rn/src/app/money/record/editor/components/CategoryGrid.tsx +++ b/code/allapp/allapp-rn/src/app/money/record/editor/components/CategoryGrid.tsx @@ -1,6 +1,6 @@ import type { ViewStyle } from 'react-native' import type { MoneyCategoryItem } from '@/types/money/category' -import React, { useEffect, useMemo, useRef } from 'react' +import React, { useEffect, useRef } from 'react' import { FlatList, Pressable, Text, View } from 'react-native' import MoneyCategoryIcon from '@/components/common/MoneyCategoryIcon' @@ -20,27 +20,15 @@ export default function CategoryGrid({ className, style, }: CategoryGridProps) { - const flatListRef = useRef>(null) + const NUM_COLUMNS = 4 - // 每行 4 个,补齐空项 - const memoItems = useMemo(() => { - const items = [...data] - const remainder = items.length % 4 - if (remainder > 0) { - const emptyCount = 4 - remainder - for (let i = 0; i < emptyCount; i++) { - items.push({ id: `empty-${i}` } as any) - } - } - return items - }, [data]) + const flatListRef = useRef>(null) // 自动滚动到选中行 useEffect(() => { if (!selectedCategory || !flatListRef.current) return - // 找到选中项下标 const itemIndex = data.findIndex(item => item.id === selectedCategory.id) if (itemIndex === -1 || !flatListRef.current) return @@ -59,8 +47,8 @@ export default function CategoryGrid({ return ( item.id.toString()} showsVerticalScrollIndicator={false} className={`${className}`} @@ -69,14 +57,15 @@ export default function CategoryGrid({ return { length: 80, offset: 80 * index, index } }} renderItem={({ item }) => { - if (!('name' in item)) - return - const isSelected = selectedCategory?.id === item.id return ( onSelectCategory?.(item)} > - + {item.name} diff --git a/code/allapp/allapp-rn/src/request/index.ts b/code/allapp/allapp-rn/src/request/index.ts index de7e4c95..476eb11d 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,