diff --git a/code/allapp/allapp-rn/package.json b/code/allapp/allapp-rn/package.json index bc72d487..bbb8fdb9 100644 --- a/code/allapp/allapp-rn/package.json +++ b/code/allapp/allapp-rn/package.json @@ -15,6 +15,7 @@ "@gluestack-ui/core": "^3.0.12", "@gluestack-ui/utils": "^3.0.11", "@gluestack/ui-next-adapter": "^3.0.3", + "@legendapp/list": "^2.0.19", "@legendapp/motion": "2.4.0", "@react-native-async-storage/async-storage": "2.2.0", "@react-navigation/drawer": "^7.5.0", diff --git a/code/allapp/allapp-rn/pnpm-lock.yaml b/code/allapp/allapp-rn/pnpm-lock.yaml index 68806833..07e04e30 100644 --- a/code/allapp/allapp-rn/pnpm-lock.yaml +++ b/code/allapp/allapp-rn/pnpm-lock.yaml @@ -23,6 +23,9 @@ importers: '@gluestack/ui-next-adapter': specifier: ^3.0.3 version: 3.0.3 + '@legendapp/list': + specifier: ^2.0.19 + version: 2.0.19(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) '@legendapp/motion': specifier: 2.4.0 version: 2.4.0(nativewind@4.2.1(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))(react-native-safe-area-context@5.6.2(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-svg@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@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)(tailwindcss@3.4.18(yaml@2.8.1)))(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) @@ -1149,6 +1152,12 @@ packages: '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + '@legendapp/list@2.0.19': + resolution: {integrity: sha512-zDWg8yg0smKxxk+M7gwAbZAnf5uczohPA+IjqLSkImz7+e9ytxeT0Mq35RBO9RTKODOXfV/aIgm1uqUHLBEdmg==} + peerDependencies: + react: '*' + react-native: '*' + '@legendapp/motion@2.4.0': resolution: {integrity: sha512-AAYpRLGvxGD5hIGl9sVHyoUufr66zoH82PuxYcKiPSMdCBI3jwZFWh6CuHjV1leRKVIRk2py1rSvIVabG8eqcw==} peerDependencies: @@ -4018,48 +4027,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==} @@ -6098,7 +6115,7 @@ snapshots: '@babel/helpers@7.28.4': dependencies: - '@babel/template': 7.27.2 + '@babel/template': 7.28.6 '@babel/types': 7.28.6 '@babel/highlight@7.25.9': @@ -7181,6 +7198,12 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 + '@legendapp/list@2.0.19(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) + use-sync-external-store: 1.6.0(react@19.1.0) + '@legendapp/motion@2.4.0(nativewind@4.2.1(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))(react-native-safe-area-context@5.6.2(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-svg@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@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)(tailwindcss@3.4.18(yaml@2.8.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: '@legendapp/tools': 2.0.1(react@19.1.0) @@ -8692,7 +8715,7 @@ snapshots: '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.28.5 + '@babel/parser': 7.28.6 '@babel/types': 7.28.6 '@types/babel__traverse@7.28.0': @@ -9038,7 +9061,7 @@ snapshots: babel-plugin-jest-hoist@29.6.3: dependencies: - '@babel/template': 7.27.2 + '@babel/template': 7.28.6 '@babel/types': 7.28.6 '@types/babel__core': 7.20.5 '@types/babel__traverse': 7.28.0 @@ -10494,7 +10517,7 @@ snapshots: istanbul-lib-instrument@5.2.1: dependencies: '@babel/core': 7.28.5 - '@babel/parser': 7.28.5 + '@babel/parser': 7.28.6 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 6.3.1 @@ -10536,7 +10559,7 @@ snapshots: jest-message-util@29.7.0: dependencies: - '@babel/code-frame': 7.27.1 + '@babel/code-frame': 7.28.6 '@jest/types': 29.6.3 '@types/stack-utils': 2.0.3 chalk: 4.1.2 @@ -11541,7 +11564,7 @@ snapshots: parse-json@5.2.0: dependencies: - '@babel/code-frame': 7.27.1 + '@babel/code-frame': 7.28.6 error-ex: 1.3.4 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 diff --git a/code/allapp/allapp-rn/src/app/auth/index.tsx b/code/allapp/allapp-rn/src/app/auth/index.tsx index 51d565cf..ca096122 100644 --- a/code/allapp/allapp-rn/src/app/auth/index.tsx +++ b/code/allapp/allapp-rn/src/app/auth/index.tsx @@ -1,13 +1,14 @@ import { useEvent } from 'expo' -import ExpoQQ from 'expo-qq' +// import ExpoQQ from 'expo-qq' import { useRouter } from 'expo-router' -import ExpoWeChat from 'expo-wechat' +// import ExpoWeChat from 'expo-wechat' import { useEffect, useState } from 'react' import { Image, Text, View } from 'react-native' import { AButton, ACheckbox } from '@/components/common/ao' import CustomHeader from '@/components/custom/Header' import { IconQq, IconWeixin } from '@/components/iconfont' import { loginQqApi, loginWxApi } from '@/request/api/auth' +import { useAppStore } from '@/store/app' import { useUserStore } from '@/store/user' import { toast } from '@/utils/toast' @@ -22,161 +23,162 @@ export default function Auth() { const router = useRouter() const userStore = useUserStore() + const appStore = useAppStore() - const onLoginFinished = useEvent(ExpoQQ, 'onLoginFinished') - const onGetUserInfo = useEvent(ExpoQQ, 'onGetUserInfo') - const authResult = useEvent(ExpoWeChat, 'onAuthResult') + // const onLoginFinished = useEvent(ExpoQQ, 'onLoginFinished') + // const onGetUserInfo = useEvent(ExpoQQ, 'onGetUserInfo') + // const authResult = useEvent(ExpoWeChat, 'onAuthResult') - async function onQQLogin() { - setLoading(true) - setForm(val => ({ - ...val, - type: 1, - })) - await ExpoQQ.login(['get_user_info']) - } + // async function onQQLogin() { + // setLoading(true) + // setForm(val => ({ + // ...val, + // type: 1, + // })) + // await ExpoQQ.login(['get_user_info']) + // } - async function onWeChatLogin() { - setLoading(true) + // async function onWeChatLogin() { + // setLoading(true) - // 检查微信是否安装 - const isInstalled = await ExpoWeChat.isWXAppInstalled() - if (!isInstalled) { - toast.show({ - title: onLoginFinished?.errorMessage || '请先安装微信', - }) - setLoading(false) - return - } + // // 检查微信是否安装 + // const isInstalled = await ExpoWeChat.isWXAppInstalled() + // if (!isInstalled) { + // toast.show({ + // title: onLoginFinished?.errorMessage || '请先安装微信', + // }) + // setLoading(false) + // return + // } - setForm(val => ({ - ...val, - type: 0, - })) + // setForm(val => ({ + // ...val, + // type: 0, + // })) - ExpoWeChat.sendAuthRequest('snsapi_userinfo', 'state123') - } + // ExpoWeChat.sendAuthRequest('snsapi_userinfo', 'state123') + // } - useEffect(() => { - ExpoQQ.init('102826474', '') - ExpoWeChat.registerApp('wxdab3e21a1f7e392f', '') - }, []) + // useEffect(() => { + // ExpoQQ.init('102826474', '') + // ExpoWeChat.registerApp('wxdab3e21a1f7e392f', '') + // }, []) - useEffect(() => { - if (!onLoginFinished) { - return - } + // useEffect(() => { + // if (!onLoginFinished) { + // return + // } - if (!onLoginFinished.success) { - toast.show({ - title: onLoginFinished?.errorMessage || '授权失败,请检查手机是否安装 QQ 或确认授权', - }) - setLoading(false) - return - } + // if (!onLoginFinished.success) { + // toast.show({ + // title: onLoginFinished?.errorMessage || '授权失败,请检查手机是否安装 QQ 或确认授权', + // }) + // setLoading(false) + // return + // } - const fetchUserInfo = async () => { - try { - const tokenInfo = await ExpoQQ.getLoginTokenInfo() - if (!tokenInfo.openId) { - toast.show({ - title: tokenInfo?.errorMessage || '授权失败,请检查手机是否安装 QQ 或确认授权', - }) - setLoading(false) - return - } + // const fetchUserInfo = async () => { + // try { + // const tokenInfo = await ExpoQQ.getLoginTokenInfo() + // if (!tokenInfo.openId) { + // toast.show({ + // title: tokenInfo?.errorMessage || '授权失败,请检查手机是否安装 QQ 或确认授权', + // }) + // setLoading(false) + // return + // } - setForm(val => ({ - ...val, - openid: String(tokenInfo.openId), - })) + // setForm(val => ({ + // ...val, + // openid: String(tokenInfo.openId), + // })) - await ExpoQQ.sendGetUserInfoReq() - } - catch (e) { - console.error('QQ 登录未完成', e) - setLoading(false) - } - } + // await ExpoQQ.sendGetUserInfoReq() + // } + // catch (e) { + // console.error('QQ 登录未完成', e) + // setLoading(false) + // } + // } - fetchUserInfo() - }, [onLoginFinished]) + // fetchUserInfo() + // }, [onLoginFinished]) - // QQ登录 - useEffect(() => { - const handleLogin = async () => { - if (!onGetUserInfo) - return + // // QQ登录 + // useEffect(() => { + // const handleLogin = async () => { + // if (!onGetUserInfo) + // return - try { - const loginRes = await loginQqApi({ - openid: form.openid, - username: onGetUserInfo.nickname || '', - avatar: onGetUserInfo.figureurlQq_2 || onGetUserInfo.figureurl_2, - }) + // try { + // const loginRes = await loginQqApi({ + // openid: form.openid, + // username: onGetUserInfo.nickname || '', + // avatar: onGetUserInfo.figureurlQq_2 || onGetUserInfo.figureurl_2, + // }) - if (loginRes.isSuccess) { - userStore.setUserInfo({ - token: loginRes.data.token, - id: loginRes.data.userId, - username: loginRes.data.username, - avatar: loginRes.data.avatar, - }) + // if (loginRes.isSuccess) { + // userStore.setUserInfo({ + // token: loginRes.data.token, + // id: loginRes.data.userId, + // username: loginRes.data.username, + // avatar: loginRes.data.avatar, + // }) - console.log(loginRes.data.token) + // console.log(loginRes.data.token) - router.push('/') - } - } - catch (err) { - console.error('登录接口出错', err) - } - finally { - setLoading(false) - } - } + // router.push('/') + // } + // } + // catch (err) { + // console.error('登录接口出错', err) + // } + // finally { + // setLoading(false) + // } + // } - handleLogin() - }, [onGetUserInfo]) + // handleLogin() + // }, [onGetUserInfo]) - // 微信登录 - useEffect(() => { - if (!authResult) - return + // // 微信登录 + // useEffect(() => { + // if (!authResult) + // return - const handleLogin = async () => { - if (authResult.errorCode === 0) { - try { - const loginRes = await loginWxApi({ - code: authResult.code, - }) + // const handleLogin = async () => { + // if (authResult.errorCode === 0) { + // try { + // const loginRes = await loginWxApi({ + // code: authResult.code, + // }) - if (loginRes.isSuccess) { - userStore.setUserInfo({ - token: loginRes.data.token, - id: loginRes.data.userId, - username: loginRes.data.username, - avatar: loginRes.data.avatar, - }) + // if (loginRes.isSuccess) { + // userStore.setUserInfo({ + // token: loginRes.data.token, + // id: loginRes.data.userId, + // username: loginRes.data.username, + // avatar: loginRes.data.avatar, + // }) - router.push('/') - } - } - catch (err) { - console.error('登录接口出错', err) - } - finally { - setLoading(false) - } - } - else { - console.log('授权失败:', authResult.errorMessage) - setLoading(false) - } - } + // router.push('/') + // } + // } + // catch (err) { + // console.error('登录接口出错', err) + // } + // finally { + // setLoading(false) + // } + // } + // else { + // console.log('授权失败:', authResult.errorMessage) + // setLoading(false) + // } + // } - handleLogin() - }, [authResult]) + // handleLogin() + // }, [authResult]) function testLogin() { // eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjo3NjY3ODU5ODIxNjUwNjEsImlhdCI6MTc2OTM0ODI0Nn0.17ZNaHD3HSLM8dVn_JQK-gvsG9MKj47IRYV9D4xZkzs @@ -188,6 +190,8 @@ export default function Auth() { avatar: 'http://thirdqq.qlogo.cn/ek_qqapp/AQHVialeUibE42oV8RvTTVZ4tyRlPYeJrUibWTwtCPfV68E4rSzn9cw00GkXQ3QDTiawwhjoqQb7/100', }) + appStore.init() + router.push('/') } @@ -208,7 +212,7 @@ export default function Auth() { - } @@ -227,7 +231,7 @@ export default function Auth() { onPress={onQQLogin} > QQ - + */} ({ icon: '', name: '' }) const [confirmDisabled, setConfirmDisabled] = useState(true) const [confirmLoading, setConfirmLoading] = useState(false) - const flatListData = Object.entries(moneyCategoryStore.ICON_GROUPS) - const flatListData2 = Object.values(moneyCategoryStore.ICON_GROUPS).flat() + const listRef = useRef(null) - const flatListRef = useRef>(null) - // Drawer 打开/关闭控制 useEffect(() => { setIsOpen(open) if (!open) @@ -47,24 +46,24 @@ export default function CreateCategory({ // 确认按钮状态 useEffect(() => { setConfirmDisabled(!(form.name && form.name.length <= 5 && form.icon)) - - const itemIndex = flatListData2.findIndex(item => item === form.icon) - if (itemIndex === -1 || !flatListRef.current) - return - - if (form.icon) { - setTimeout(() => { - if (flatListRef.current) { - flatListRef.current.scrollToIndex({ - index: Math.floor(itemIndex / 5), - animated: true, - viewPosition: 0.5, - }) - } - }, 0) - } }, [form.name, form.icon]) + useEffect(() => { + if (!form.icon || !listRef.current) { + return + } + + const index = moneyCategoryStore.findIconGroupsRow(form.icon) + + if (index !== -1) { + listRef.current.scrollToIndex({ + index, + viewPosition: 0.5, + animated: true, + }) + } + }, [form.icon]) + // 编辑已有分类时填充数据 useEffect(() => { if (category) @@ -77,55 +76,6 @@ export default function CreateCategory({ onClose?.() } - // 渲染每组 Icon - const renderGroup = useCallback( - ({ item }: { item: [string, string[]] }) => { - const [groupName, icons] = item - - return ( - - {groupName} - - - {icons.map((icon) => { - const selected = form.icon === icon - - return ( - - setForm(v => ({ - ...v, - icon, - }))} - > - - - - - ) - })} - - - ) - }, - [form.icon], - ) - return ( )} > - groupName} - renderItem={renderGroup} - getItemLayout={(data, index) => { - return { length: 80, offset: 80 * index, index } - }} - /> + + setForm(prevForm => ({ ...prevForm, name: text }))} + /> + String(item.index)} + recycleItems + initialContainerPoolRatio={20} + style={{ flex: 1 }} + initialScrollIndex={moneyCategoryStore.findIconGroupsRow(category?.icon || '')} + renderItem={({ item }) => ( + + { + item.type === 'title' + ? ( + {item.value} + ) + : ( + + {item.value.map((icon) => { + const selected = form.icon === icon + + return ( + { + setForm(prevForm => ({ + ...prevForm, + icon, + })) + }} + > + + + + + ) + })} + + ) + } + + )} + /> + + ) } diff --git a/code/allapp/allapp-rn/src/request/index.ts b/code/allapp/allapp-rn/src/request/index.ts index 1288fff7..2f5e9787 100644 --- a/code/allapp/allapp-rn/src/request/index.ts +++ b/code/allapp/allapp-rn/src/request/index.ts @@ -28,8 +28,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/store/moneyCategory.ts b/code/allapp/allapp-rn/src/store/moneyCategory.ts index 13b8093b..edcf25f7 100644 --- a/code/allapp/allapp-rn/src/store/moneyCategory.ts +++ b/code/allapp/allapp-rn/src/store/moneyCategory.ts @@ -1,10 +1,10 @@ -import type { MoneyCategoryItem } from '@/types/money/category' +import type { IconGroupType, MoneyCategoryItem } from '@/types/money/category' import { create } from 'zustand' import { createMoneyCategoryApi, deleteMoneyCategoryApi, queryMoneyCategoryApi, updateMoneyCategoryApi, updateMoneyCategorySortApi } from '@/request/api/money/category' import { MoneyCategoryEnum } from '@/types/money/category' interface MoneyCategoryStore { - ICON_GROUPS: Record + IconGroups: IconGroupType[] categories: MoneyCategoryItem[] init: () => Promise @@ -22,77 +22,195 @@ interface MoneyCategoryStore { isDuplicateCategory: (name: string, type: number, excludeId: number | null) => boolean + findIconGroupsRow: (iconName: string) => number clear: () => void } export const useMoneyCategoryStore = create()( (set, get) => ({ - ICON_GROUPS: { - 餐饮: [ - 'money_canyin', - 'money_yinpin', - 'money_lingshi', - 'money_xiaoye', - ], - 娱乐: [ - 'money_yule', - 'money_youxi', - 'money_dianying', - ], - 交通: [ - 'money_jiaotong', - 'money_tingchefei', - 'money_jiayou', - ], - 生活消费: [ - 'money_lijin', - 'money_jiadian', - 'money_riyongpin', - 'money_shucai', - 'money_meifa', - 'money_shuidian', - 'money_wenju', - 'money_zhufang', - 'money_baoxian', - 'money_baojianpin', - 'money_huafei', - 'money_lvyou', - 'money_gouwu', - 'money_shuben', - 'money_chongwu', - 'money_ruanjian', - ], - 健康: [ - 'money_tijian', - 'money_yao', - 'money_jiuyi', - ], - 公益: [ - 'money_gongyi', - ], - 兼职与收入: [ - 'money_gongzi', - 'money_jianzhi', - ], - 鲜花与水果: [ - 'money_shuiguo', - 'money_xianhua', - ], - 转账与转移: [ - 'money_zhuanzhang', - ], - 家庭与家电: [ - 'money_kuaidi', - 'money_weixiu', - 'money_jiaju', - 'money_muying', - 'money_liwu', - ], - 运动与娱乐: [ - 'money_yundong', - 'money_peixun', - ], - }, + IconGroups: [ + { + index: 0, + type: 'title', + value: '餐饮', + }, + { + index: 1, + type: 'icons', + value: [ + 'money_canyin', + 'money_yinpin', + 'money_lingshi', + 'money_xiaoye', + ], + }, + { + index: 2, + type: 'title', + value: '娱乐', + }, + { + index: 3, + type: 'icons', + value: [ + 'money_yule', + 'money_youxi', + 'money_dianying', + ], + }, + { + index: 4, + type: 'title', + value: '交通', + }, + { + index: 5, + type: 'icons', + value: [ + 'money_jiaotong', + 'money_tingchefei', + 'money_jiayou', + ], + }, + { + index: 6, + type: 'title', + value: '生活消费', + }, + { + index: 7, + type: 'icons', + value: [ + 'money_lijin', + 'money_jiadian', + 'money_riyongpin', + 'money_shucai', + 'money_meifa', + ], + }, + { + index: 8, + type: 'icons', + value: [ + 'money_shuidian', + 'money_wenju', + 'money_zhufang', + 'money_baoxian', + 'money_baojianpin', + ], + }, + { + index: 9, + type: 'icons', + value: [ + 'money_huafei', + 'money_lvyou', + 'money_gouwu', + 'money_shuben', + 'money_chongwu', + ], + }, + { + index: 10, + type: 'icons', + value: [ + 'money_ruanjian', + ], + }, + { + index: 11, + type: 'title', + value: '健康', + }, + { + index: 12, + type: 'icons', + value: [ + 'money_tijian', + 'money_yao', + 'money_jiuyi', + ], + }, + { + index: 13, + type: 'title', + value: '公益', + }, + { + index: 14, + type: 'icons', + value: [ + 'money_gongyi', + ], + }, + { + index: 15, + type: 'title', + value: '兼职与收入', + }, + { + index: 16, + type: 'icons', + value: [ + 'money_gongzi', + 'money_jianzhi', + ], + }, + { + index: 17, + type: 'title', + value: '鲜花与水果', + }, + { + index: 18, + type: 'icons', + value: [ + 'money_shuiguo', + 'money_xianhua', + ], + }, + { + index: 19, + type: 'title', + value: '转账与转移', + }, + { + index: 20, + type: 'icons', + value: [ + 'money_zhuanzhang', + ], + }, + { + index: 21, + type: 'title', + value: '家庭与家电', + }, + { + index: 22, + type: 'icons', + value: [ + 'money_kuaidi', + 'money_weixiu', + 'money_jiaju', + 'money_muying', + 'money_liwu', + ], + }, + { + index: 23, + type: 'title', + value: '运动与娱乐', + }, + { + index: 24, + type: 'icons', + value: [ + 'money_yundong', + 'money_peixun', + ], + }, + ], categories: [], @@ -247,5 +365,18 @@ export const useMoneyCategoryStore = create()( && c.id !== excludeId, ) }, + + findIconGroupsRow: (iconName) => { + const iconGroups = get().IconGroups + + for (const group of iconGroups) { + if (group.type === 'icons' && group.value.includes(iconName)) { + return group.index + } + } + + return 0 + }, + }), ) diff --git a/code/allapp/allapp-rn/src/types/money/category.ts b/code/allapp/allapp-rn/src/types/money/category.ts index ee6f222a..0b2f8349 100644 --- a/code/allapp/allapp-rn/src/types/money/category.ts +++ b/code/allapp/allapp-rn/src/types/money/category.ts @@ -52,3 +52,23 @@ export interface UpdateMoneyCategoryParams { } export interface UpdateMoneyCategoryResult { } + +// 图标分组基础接口 +interface BaseIconGroupType { + index: number +} + +// 当 type 为 'title' 时,value 必须是 string +interface TitleIconGroupType extends BaseIconGroupType { + type: 'title' + value: string +} + +// 当 type 为 'icons' 时,value 必须是 string[] +interface IconsIconGroupType extends BaseIconGroupType { + type: 'icons' + value: string[] +} + +// 联合类型 +export type IconGroupType = TitleIconGroupType | IconsIconGroupType