diff --git a/code/base-project/base-app/iconfont.json b/code/base-project/base-app/iconfont.json index 555face9..38164f1e 100644 --- a/code/base-project/base-app/iconfont.json +++ b/code/base-project/base-app/iconfont.json @@ -1,5 +1,5 @@ { - "symbol_url": "//at.alicdn.com/t/c/font_5056764_xsiwaq3nrni.js", + "symbol_url": "//at.alicdn.com/t/c/font_5056764_h6glhbjob2.js", "use_typescript": true, "save_dir": "./src/components/iconfont", "trim_icon_prefix": "icon", 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 13a93fca..06f9c76d 100644 --- a/code/base-project/base-app/src/app/(tabs)/chat.tsx +++ b/code/base-project/base-app/src/app/(tabs)/chat.tsx @@ -1,15 +1,28 @@ -import { ScrollView, Text, View } from 'react-native' +import { ScrollView, Text } from 'react-native' +import { AButton } from '@/components/common/ao' +import { useUserStore } from '@/store/user' export default function Chat() { + const userStore = useUserStore() + return ( - - {Array.from({ length: 50 }).map((_, i) => ( - - Chat message - {' '} - {i + 1} - - ))} + + { + userStore.setUserInfo({ + ...(userStore.userInfo as any), + token: `test-token-${Date.now()}`, + }) + }} + > + 测试 + + + + 当前 token: + {' '} + {userStore.userInfo?.token ?? '(无)'} + ) } 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 b88639b8..c21c1d2d 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,14 +1,17 @@ import type { MoneyCategoryResult } from '@/request/api/money' import type { MoneyCategory } from '@/types/money' +import { DeleteIcon } from 'lucide-react-native' import { useEffect, useState } from 'react' import { Pressable, Text, View } from 'react-native' import { useSafeAreaInsets } from 'react-native-safe-area-context' +import { AInput } from '@/components/common/ao' import SegmentedTabs from '@/components/common/ao/SegmentedTabs' import { Drawer, DrawerBackdrop, DrawerBody, DrawerContent, + DrawerFooter, DrawerHeader, } from '@/components/ui/drawer' import { Grid, GridItem } from '@/components/ui/grid' @@ -20,6 +23,37 @@ interface AddMoneyDrawerProps { onClose: () => void } +interface KeydownItem { + key: string | number + content: React.ReactNode +} +const keys: KeydownItem[] = [ + { key: '1', content: 1 }, + { key: '2', content: 2 }, + { key: '3', content: 3 }, + { key: 'del', content: }, + { key: '4', content: 4 }, + { key: '5', content: 5 }, + { key: '6', content: 6 }, + { key: '+', content: + }, + { key: '7', content: 7 }, + { key: '8', content: 8 }, + { key: '9', content: 9 }, + { key: '-', content: - }, + { key: 'clear', content: ( + + AC + + ) }, + { key: '0', content: 0 }, + { key: '.', content: . }, + { key: '/', content: ( + + 完成 + + ) }, +] + export default function AddMoneyDrawer({ isOpen, onClose, @@ -27,12 +61,18 @@ export default function AddMoneyDrawer({ const insets = useSafeAreaInsets() const [selectedIndex, setSelectedIndex] = useState(0) const [selectedCategoryId, setSelectedCategoryId] = useState(null) + const [showKeydown, setShowKeydown] = useState(false) const [categories, setCategories] = useState({ income: [], expense: [], }) + function selectCategory(item: MoneyCategory) { + setSelectedCategoryId(item.id) + setShowKeydown(true) + } + useEffect(() => { if (isOpen) { const fetchCategories = async () => { @@ -50,72 +90,139 @@ export default function AddMoneyDrawer({ } }, [isOpen]) + const handlePress = (key: string | number, idx: number) => { + console.log('点击了格子 key:', key, '索引:', idx) + } + return ( - - - - - - - - 取消 - - + <> + + + + + + + + 取消 + + - - - {(() => { - const list = selectedIndex === 0 ? categories.income : categories.expense - const items = list.map((item) => { - const isSelected = selectedCategoryId === item.id - return ( - - setSelectedCategoryId(item.id)} - > - + + {(() => { + const list = selectedIndex === 0 ? categories.income : categories.expense + const items = list.map((item) => { + const isSelected = selectedCategoryId === item.id + return ( + + selectCategory(item)} > - - - - {item.name} - - - - ) - }) + + + + + {item.name} + + + + ) + }) - const remainder = list.length % 4 - if (remainder > 0) { - const emptyCount = 4 - remainder - for (let i = 0; i < emptyCount; i++) { - items.push() + const remainder = list.length % 4 + if (remainder > 0) { + const emptyCount = 4 - remainder + for (let i = 0; i < emptyCount; i++) { + items.push() + } } - } - return items - })()} - - - - + return items + })()} + + + + + + + + + + 0.00 + + + + + + {keys.map((item, idx) => { + const isFirstCol = idx % 4 === 0 + const isFirstRow = idx < 4 + const isLastCol = (idx + 1) % 4 === 0 + const isLastRow = idx >= 12 + + return ( + handlePress(item.key, idx)} + style={{ + width: '25%', + height: '25%', + justifyContent: 'center', + alignItems: 'center', + borderTopWidth: isFirstRow ? 0.3 : 0, + borderLeftWidth: isFirstCol ? 0.3 : 0, + borderRightWidth: !isLastCol ? 0.3 : 0, + borderBottomWidth: !isLastRow ? 0.3 : 0, + borderColor: '#ddd', + }} + > + {item.content} + + ) + })} + + + + + + + ) } diff --git a/code/base-project/base-app/src/app/(tabs)/money/components/MoneyCategoryIcon.tsx b/code/base-project/base-app/src/app/(tabs)/money/components/MoneyCategoryIcon.tsx index eaeb9f12..cc1646af 100644 --- a/code/base-project/base-app/src/app/(tabs)/money/components/MoneyCategoryIcon.tsx +++ b/code/base-project/base-app/src/app/(tabs)/money/components/MoneyCategoryIcon.tsx @@ -1,5 +1,6 @@ import React from 'react' import { + IconGongzi, IconJiaotong, IconLingshi, IconRiyongpin, @@ -13,18 +14,19 @@ const iconMap: Record = { jiaotong: IconJiaotong, lingshi: IconLingshi, riyongpin: IconRiyongpin, - shouru: IconShouru, shucai: IconShucai, yule: IconYule, - zhichu: IconZhichu, + gongzi: IconGongzi, } -const DefaultIcon = IconLingshi +const DefaultIncomeIcon = IconShouru +const DefaultExpenseIcon = IconZhichu interface CategoryIconProps { name?: string size?: number color?: string + type?: 0 | 1 } /** @@ -34,7 +36,10 @@ export default function MoneyCategoryIcon({ name, size = 24, color, + type = 1, }: CategoryIconProps) { - const IconComponent = iconMap[name ?? ''] || DefaultIcon + const IconComponent + = iconMap[name ?? ''] || (type === 0 ? DefaultIncomeIcon : DefaultExpenseIcon) + return } diff --git a/code/base-project/base-app/src/app/(tabs)/money/components/TabSelector.tsx b/code/base-project/base-app/src/app/(tabs)/money/components/TabSelector.tsx index 3f87ebd6..2e202539 100644 --- a/code/base-project/base-app/src/app/(tabs)/money/components/TabSelector.tsx +++ b/code/base-project/base-app/src/app/(tabs)/money/components/TabSelector.tsx @@ -1,6 +1,6 @@ import { Pressable, Text, View } from 'react-native' import Animated, { useAnimatedStyle, withSpring, withTiming } from 'react-native-reanimated' -import { IconQuxian1 } from '@/components/iconfont' +// import { IconQuxian1 } from '@/components/iconfont' interface TabSelectorProps { options: string[] @@ -43,7 +43,7 @@ const TabSelector: React.FC = ({ options, selected, onSelect } animatedStyle, ]} > - + {/* */} diff --git a/code/base-project/base-app/src/components/iconfont/IconGongzi.tsx b/code/base-project/base-app/src/components/iconfont/IconGongzi.tsx new file mode 100644 index 00000000..aa76e4ad --- /dev/null +++ b/code/base-project/base-app/src/components/iconfont/IconGongzi.tsx @@ -0,0 +1,47 @@ +/* tslint:disable */ +/* eslint-disable */ + +import React, { FunctionComponent } from 'react'; +import { ViewProps } from 'react-native'; +import { Svg, GProps, Path } from 'react-native-svg'; +import { getIconColor } from './helper'; + +interface Props extends GProps, ViewProps { + size?: number; + color?: string | string[]; +} + +let IconGongzi: FunctionComponent = ({ size, color, ...rest }) => { + return ( + + + + + + + + ); +}; + +IconGongzi.defaultProps = { + size: 18, +}; + +IconGongzi = React.memo ? React.memo(IconGongzi) : IconGongzi; + +export default IconGongzi; diff --git a/code/base-project/base-app/src/components/iconfont/IconIcon.tsx b/code/base-project/base-app/src/components/iconfont/IconIcon.tsx deleted file mode 100644 index 02b28301..00000000 --- a/code/base-project/base-app/src/components/iconfont/IconIcon.tsx +++ /dev/null @@ -1,64 +0,0 @@ -/* eslint-disable */ -/* tslint:disable */ - -import React from 'react'; -import type { FunctionComponent } from 'react'; -import type { ViewProps } from 'react-native'; -import { Svg, GProps, Path } from 'react-native-svg'; -import { getIconColor } from './helper'; - -interface Props extends Omit, ViewProps { - size?: number; - color?: string | string[]; -} - -const IconIcon: FunctionComponent = ({ - size = 18, - color, - ...rest -}) => { - return ( - - - - - - - - - - - - - - ); -}; - -export default React.memo(IconIcon); \ No newline at end of file diff --git a/code/base-project/base-app/src/components/iconfont/IconJiaotong.tsx b/code/base-project/base-app/src/components/iconfont/IconJiaotong.tsx index 4a4acd8e..f9586f34 100644 --- a/code/base-project/base-app/src/components/iconfont/IconJiaotong.tsx +++ b/code/base-project/base-app/src/components/iconfont/IconJiaotong.tsx @@ -1,24 +1,18 @@ -/* eslint-disable */ /* tslint:disable */ +/* eslint-disable */ -import React from 'react'; -import type { FunctionComponent } from 'react'; -import type { ViewProps } from 'react-native'; +import React, { FunctionComponent } from 'react'; +import { ViewProps } from 'react-native'; import { Svg, GProps, Path } from 'react-native-svg'; import { getIconColor } from './helper'; -interface Props extends Omit, ViewProps { +interface Props extends GProps, ViewProps { size?: number; color?: string | string[]; } -const IconJiaotong: FunctionComponent = ({ - size = 18, - color, - ...rest -}) => { +let IconJiaotong: FunctionComponent = ({ size, color, ...rest }) => { return ( - = ({ fill={getIconColor(color, 23, '#1D1C1A')} /> - ); }; -export default React.memo(IconJiaotong); \ No newline at end of file +IconJiaotong.defaultProps = { + size: 18, +}; + +IconJiaotong = React.memo ? React.memo(IconJiaotong) : IconJiaotong; + +export default IconJiaotong; diff --git a/code/base-project/base-app/src/components/iconfont/IconLingshi.tsx b/code/base-project/base-app/src/components/iconfont/IconLingshi.tsx index 6e738a10..921fd1b2 100644 --- a/code/base-project/base-app/src/components/iconfont/IconLingshi.tsx +++ b/code/base-project/base-app/src/components/iconfont/IconLingshi.tsx @@ -1,24 +1,18 @@ -/* eslint-disable */ /* tslint:disable */ +/* eslint-disable */ -import React from 'react'; -import type { FunctionComponent } from 'react'; -import type { ViewProps } from 'react-native'; +import React, { FunctionComponent } from 'react'; +import { ViewProps } from 'react-native'; import { Svg, GProps, Path } from 'react-native-svg'; import { getIconColor } from './helper'; -interface Props extends Omit, ViewProps { +interface Props extends GProps, ViewProps { size?: number; color?: string | string[]; } -const IconLingshi: FunctionComponent = ({ - size = 18, - color, - ...rest -}) => { +let IconLingshi: FunctionComponent = ({ size, color, ...rest }) => { return ( - = ({ fill={getIconColor(color, 11, '#000000')} /> - ); }; -export default React.memo(IconLingshi); \ No newline at end of file +IconLingshi.defaultProps = { + size: 18, +}; + +IconLingshi = React.memo ? React.memo(IconLingshi) : IconLingshi; + +export default IconLingshi; diff --git a/code/base-project/base-app/src/components/iconfont/IconQq.tsx b/code/base-project/base-app/src/components/iconfont/IconQq.tsx index 49bb0a15..b5a81e3c 100644 --- a/code/base-project/base-app/src/components/iconfont/IconQq.tsx +++ b/code/base-project/base-app/src/components/iconfont/IconQq.tsx @@ -1,24 +1,18 @@ -/* eslint-disable */ /* tslint:disable */ +/* eslint-disable */ -import React from 'react'; -import type { FunctionComponent } from 'react'; -import type { ViewProps } from 'react-native'; +import React, { FunctionComponent } from 'react'; +import { ViewProps } from 'react-native'; import { Svg, GProps, Path } from 'react-native-svg'; import { getIconColor } from './helper'; -interface Props extends Omit, ViewProps { +interface Props extends GProps, ViewProps { size?: number; color?: string | string[]; } -const IconQq: FunctionComponent = ({ - size = 18, - color, - ...rest -}) => { +let IconQq: FunctionComponent = ({ size, color, ...rest }) => { return ( - = ({ fill={getIconColor(color, 9, '#EB1C26')} /> - ); }; -export default React.memo(IconQq); \ No newline at end of file +IconQq.defaultProps = { + size: 18, +}; + +IconQq = React.memo ? React.memo(IconQq) : IconQq; + +export default IconQq; diff --git a/code/base-project/base-app/src/components/iconfont/IconQuxian1.tsx b/code/base-project/base-app/src/components/iconfont/IconQuxian1.tsx deleted file mode 100644 index 24dae233..00000000 --- a/code/base-project/base-app/src/components/iconfont/IconQuxian1.tsx +++ /dev/null @@ -1,32 +0,0 @@ -/* eslint-disable */ -/* tslint:disable */ - -import React from 'react'; -import type { FunctionComponent } from 'react'; -import type { ViewProps } from 'react-native'; -import { Svg, GProps, Path } from 'react-native-svg'; -import { getIconColor } from './helper'; - -interface Props extends Omit, ViewProps { - size?: number; - color?: string | string[]; -} - -const IconQuxian1: FunctionComponent = ({ - size = 18, - color, - ...rest -}) => { - return ( - - - - - - ); -}; - -export default React.memo(IconQuxian1); \ No newline at end of file diff --git a/code/base-project/base-app/src/components/iconfont/IconRiyongpin.tsx b/code/base-project/base-app/src/components/iconfont/IconRiyongpin.tsx index cab3d405..d0de3bc7 100644 --- a/code/base-project/base-app/src/components/iconfont/IconRiyongpin.tsx +++ b/code/base-project/base-app/src/components/iconfont/IconRiyongpin.tsx @@ -1,24 +1,18 @@ -/* eslint-disable */ /* tslint:disable */ +/* eslint-disable */ -import React from 'react'; -import type { FunctionComponent } from 'react'; -import type { ViewProps } from 'react-native'; +import React, { FunctionComponent } from 'react'; +import { ViewProps } from 'react-native'; import { Svg, GProps, Path } from 'react-native-svg'; import { getIconColor } from './helper'; -interface Props extends Omit, ViewProps { +interface Props extends GProps, ViewProps { size?: number; color?: string | string[]; } -const IconRiyongpin: FunctionComponent = ({ - size = 18, - color, - ...rest -}) => { +let IconRiyongpin: FunctionComponent = ({ size, color, ...rest }) => { return ( - = ({ fill={getIconColor(color, 7, '#474A54')} /> - ); }; -export default React.memo(IconRiyongpin); \ No newline at end of file +IconRiyongpin.defaultProps = { + size: 18, +}; + +IconRiyongpin = React.memo ? React.memo(IconRiyongpin) : IconRiyongpin; + +export default IconRiyongpin; diff --git a/code/base-project/base-app/src/components/iconfont/IconShouru.tsx b/code/base-project/base-app/src/components/iconfont/IconShouru.tsx index ea4f5cd6..f894577d 100644 --- a/code/base-project/base-app/src/components/iconfont/IconShouru.tsx +++ b/code/base-project/base-app/src/components/iconfont/IconShouru.tsx @@ -1,32 +1,51 @@ -/* eslint-disable */ /* tslint:disable */ +/* eslint-disable */ -import React from 'react'; -import type { FunctionComponent } from 'react'; -import type { ViewProps } from 'react-native'; +import React, { FunctionComponent } from 'react'; +import { ViewProps } from 'react-native'; import { Svg, GProps, Path } from 'react-native-svg'; import { getIconColor } from './helper'; -interface Props extends Omit, ViewProps { +interface Props extends GProps, ViewProps { size?: number; color?: string | string[]; } -const IconShouru: FunctionComponent = ({ - size = 18, - color, - ...rest -}) => { +let IconShouru: FunctionComponent = ({ size, color, ...rest }) => { return ( - + + + + + - ); }; -export default React.memo(IconShouru); \ No newline at end of file +IconShouru.defaultProps = { + size: 18, +}; + +IconShouru = React.memo ? React.memo(IconShouru) : IconShouru; + +export default IconShouru; diff --git a/code/base-project/base-app/src/components/iconfont/IconShucai.tsx b/code/base-project/base-app/src/components/iconfont/IconShucai.tsx index b93fef35..a118f8ea 100644 --- a/code/base-project/base-app/src/components/iconfont/IconShucai.tsx +++ b/code/base-project/base-app/src/components/iconfont/IconShucai.tsx @@ -1,24 +1,18 @@ -/* eslint-disable */ /* tslint:disable */ +/* eslint-disable */ -import React from 'react'; -import type { FunctionComponent } from 'react'; -import type { ViewProps } from 'react-native'; +import React, { FunctionComponent } from 'react'; +import { ViewProps } from 'react-native'; import { Svg, GProps, Path } from 'react-native-svg'; import { getIconColor } from './helper'; -interface Props extends Omit, ViewProps { +interface Props extends GProps, ViewProps { size?: number; color?: string | string[]; } -const IconShucai: FunctionComponent = ({ - size = 18, - color, - ...rest -}) => { +let IconShucai: FunctionComponent = ({ size, color, ...rest }) => { return ( - = ({ fill={getIconColor(color, 4, '#FFFFFF')} /> - ); }; -export default React.memo(IconShucai); \ No newline at end of file +IconShucai.defaultProps = { + size: 18, +}; + +IconShucai = React.memo ? React.memo(IconShucai) : IconShucai; + +export default IconShucai; diff --git a/code/base-project/base-app/src/components/iconfont/IconWeixin.tsx b/code/base-project/base-app/src/components/iconfont/IconWeixin.tsx index 5eaf4d38..a9fd0fb6 100644 --- a/code/base-project/base-app/src/components/iconfont/IconWeixin.tsx +++ b/code/base-project/base-app/src/components/iconfont/IconWeixin.tsx @@ -1,24 +1,18 @@ -/* eslint-disable */ /* tslint:disable */ +/* eslint-disable */ -import React from 'react'; -import type { FunctionComponent } from 'react'; -import type { ViewProps } from 'react-native'; +import React, { FunctionComponent } from 'react'; +import { ViewProps } from 'react-native'; import { Svg, GProps, Path } from 'react-native-svg'; import { getIconColor } from './helper'; -interface Props extends Omit, ViewProps { +interface Props extends GProps, ViewProps { size?: number; color?: string | string[]; } -const IconWeixin: FunctionComponent = ({ - size = 18, - color, - ...rest -}) => { +let IconWeixin: FunctionComponent = ({ size, color, ...rest }) => { return ( - = ({ fill={getIconColor(color, 1, '#4CBF00')} /> - ); }; -export default React.memo(IconWeixin); \ No newline at end of file +IconWeixin.defaultProps = { + size: 18, +}; + +IconWeixin = React.memo ? React.memo(IconWeixin) : IconWeixin; + +export default IconWeixin; diff --git a/code/base-project/base-app/src/components/iconfont/IconYule.tsx b/code/base-project/base-app/src/components/iconfont/IconYule.tsx index 61e4d720..3ba09f3f 100644 --- a/code/base-project/base-app/src/components/iconfont/IconYule.tsx +++ b/code/base-project/base-app/src/components/iconfont/IconYule.tsx @@ -1,24 +1,18 @@ -/* eslint-disable */ /* tslint:disable */ +/* eslint-disable */ -import React from 'react'; -import type { FunctionComponent } from 'react'; -import type { ViewProps } from 'react-native'; +import React, { FunctionComponent } from 'react'; +import { ViewProps } from 'react-native'; import { Svg, GProps, Path } from 'react-native-svg'; import { getIconColor } from './helper'; -interface Props extends Omit, ViewProps { +interface Props extends GProps, ViewProps { size?: number; color?: string | string[]; } -const IconYule: FunctionComponent = ({ - size = 18, - color, - ...rest -}) => { +let IconYule: FunctionComponent = ({ size, color, ...rest }) => { return ( - = ({ fill={getIconColor(color, 10, '#FFE576')} /> - ); }; -export default React.memo(IconYule); \ No newline at end of file +IconYule.defaultProps = { + size: 18, +}; + +IconYule = React.memo ? React.memo(IconYule) : IconYule; + +export default IconYule; diff --git a/code/base-project/base-app/src/components/iconfont/IconYule1.tsx b/code/base-project/base-app/src/components/iconfont/IconYule1.tsx deleted file mode 100644 index 7b9ad0b3..00000000 --- a/code/base-project/base-app/src/components/iconfont/IconYule1.tsx +++ /dev/null @@ -1,32 +0,0 @@ -/* eslint-disable */ -/* tslint:disable */ - -import React from 'react'; -import type { FunctionComponent } from 'react'; -import type { ViewProps } from 'react-native'; -import { Svg, GProps, Path } from 'react-native-svg'; -import { getIconColor } from './helper'; - -interface Props extends Omit, ViewProps { - size?: number; - color?: string | string[]; -} - -const IconYule1: FunctionComponent = ({ - size = 18, - color, - ...rest -}) => { - return ( - - - - - - ); -}; - -export default React.memo(IconYule1); \ No newline at end of file diff --git a/code/base-project/base-app/src/components/iconfont/IconZhichu.tsx b/code/base-project/base-app/src/components/iconfont/IconZhichu.tsx index 71695d82..fe397bc5 100644 --- a/code/base-project/base-app/src/components/iconfont/IconZhichu.tsx +++ b/code/base-project/base-app/src/components/iconfont/IconZhichu.tsx @@ -1,32 +1,51 @@ -/* eslint-disable */ /* tslint:disable */ +/* eslint-disable */ -import React from 'react'; -import type { FunctionComponent } from 'react'; -import type { ViewProps } from 'react-native'; +import React, { FunctionComponent } from 'react'; +import { ViewProps } from 'react-native'; import { Svg, GProps, Path } from 'react-native-svg'; import { getIconColor } from './helper'; -interface Props extends Omit, ViewProps { +interface Props extends GProps, ViewProps { size?: number; color?: string | string[]; } -const IconZhichu: FunctionComponent = ({ - size = 18, - color, - ...rest -}) => { +let IconZhichu: FunctionComponent = ({ size, color, ...rest }) => { return ( - + + + + + - ); }; -export default React.memo(IconZhichu); \ No newline at end of file +IconZhichu.defaultProps = { + size: 18, +}; + +IconZhichu = React.memo ? React.memo(IconZhichu) : IconZhichu; + +export default IconZhichu; diff --git a/code/base-project/base-app/src/components/iconfont/IconZhiwen.tsx b/code/base-project/base-app/src/components/iconfont/IconZhiwen.tsx index c4b9b46e..f5b3a3fc 100644 --- a/code/base-project/base-app/src/components/iconfont/IconZhiwen.tsx +++ b/code/base-project/base-app/src/components/iconfont/IconZhiwen.tsx @@ -1,24 +1,18 @@ -/* eslint-disable */ /* tslint:disable */ +/* eslint-disable */ -import React from 'react'; -import type { FunctionComponent } from 'react'; -import type { ViewProps } from 'react-native'; +import React, { FunctionComponent } from 'react'; +import { ViewProps } from 'react-native'; import { Svg, GProps, Path } from 'react-native-svg'; import { getIconColor } from './helper'; -interface Props extends Omit, ViewProps { +interface Props extends GProps, ViewProps { size?: number; color?: string | string[]; } -const IconZhiwen: FunctionComponent = ({ - size = 18, - color, - ...rest -}) => { +let IconZhiwen: FunctionComponent = ({ size, color, ...rest }) => { return ( - = ({ fill={getIconColor(color, 3, '#FFBB12')} /> - ); }; -export default React.memo(IconZhiwen); \ No newline at end of file +IconZhiwen.defaultProps = { + size: 18, +}; + +IconZhiwen = React.memo ? React.memo(IconZhiwen) : IconZhiwen; + +export default IconZhiwen; diff --git a/code/base-project/base-app/src/components/iconfont/index.tsx b/code/base-project/base-app/src/components/iconfont/index.tsx index d2810d83..1abb5559 100644 --- a/code/base-project/base-app/src/components/iconfont/index.tsx +++ b/code/base-project/base-app/src/components/iconfont/index.tsx @@ -4,34 +4,30 @@ import React, { FunctionComponent } from 'react'; import { ViewProps } from 'react-native'; import { GProps } from 'react-native-svg'; -import IconIcon from './IconIcon'; -import IconYule1 from './IconYule1'; import IconZhichu from './IconZhichu'; import IconShouru from './IconShouru'; +import IconGongzi from './IconGongzi'; import IconJiaotong from './IconJiaotong'; import IconShucai from './IconShucai'; import IconRiyongpin from './IconRiyongpin'; import IconYule from './IconYule'; import IconLingshi from './IconLingshi'; -import IconQuxian1 from './IconQuxian1'; import IconWeixin from './IconWeixin'; import IconZhiwen from './IconZhiwen'; import IconQq from './IconQq'; -export { default as IconIcon } from './IconIcon'; -export { default as IconYule1 } from './IconYule1'; export { default as IconZhichu } from './IconZhichu'; export { default as IconShouru } from './IconShouru'; +export { default as IconGongzi } from './IconGongzi'; export { default as IconJiaotong } from './IconJiaotong'; export { default as IconShucai } from './IconShucai'; export { default as IconRiyongpin } from './IconRiyongpin'; export { default as IconYule } from './IconYule'; export { default as IconLingshi } from './IconLingshi'; -export { default as IconQuxian1 } from './IconQuxian1'; export { default as IconWeixin } from './IconWeixin'; export { default as IconZhiwen } from './IconZhiwen'; export { default as IconQq } from './IconQq'; -export type IconNames = 'icon' | 'yule1' | 'zhichu' | 'shouru' | 'jiaotong' | 'shucai' | 'riyongpin' | 'yule' | 'lingshi' | 'quxian1' | 'weixin' | 'zhiwen' | 'QQ'; +export type IconNames = 'zhichu' | 'shouru' | 'gongzi' | 'jiaotong' | 'shucai' | 'riyongpin' | 'yule' | 'lingshi' | 'weixin' | 'zhiwen' | 'QQ'; interface Props extends GProps, ViewProps { name: IconNames; @@ -41,32 +37,28 @@ interface Props extends GProps, ViewProps { let IconFont: FunctionComponent = ({ name, ...rest }) => { switch (name) { - case 'icon': - return ; - case 'yule1': - return ; case 'zhichu': - return ; + return ; case 'shouru': - return ; + return ; + case 'gongzi': + return ; case 'jiaotong': - return ; + return ; case 'shucai': - return ; + return ; case 'riyongpin': - return ; + return ; case 'yule': - return ; + return ; case 'lingshi': - return ; - case 'quxian1': - return ; + return ; case 'weixin': - return ; + return ; case 'zhiwen': - return ; + return ; case 'QQ': - return ; + return ; } return null; diff --git a/code/base-project/base-app/src/request/api/auth.ts b/code/base-project/base-app/src/request/api/auth.ts index b4a777c1..30b3f117 100644 --- a/code/base-project/base-app/src/request/api/auth.ts +++ b/code/base-project/base-app/src/request/api/auth.ts @@ -18,7 +18,7 @@ interface LoginDefaultParams { interface LoginDefaultResult { token: string refreshToken: string - userId: string + userId: number username: string seqNo: number gender: number diff --git a/code/base-project/base-app/src/request/index.ts b/code/base-project/base-app/src/request/index.ts index d74320ab..91ba317c 100644 --- a/code/base-project/base-app/src/request/index.ts +++ b/code/base-project/base-app/src/request/index.ts @@ -3,7 +3,7 @@ import type { AxiosError } from 'axios' import { axiosRequestAdapter } from '@alova/adapter-axios' import { createAlova } from 'alova' import { router } from 'expo-router' -import { userStore } from '@/store/user' +import { useUserStore } from '@/store/user' import { toast } from '@/utils/toast' enum HttpCode { @@ -30,9 +30,11 @@ function isWhiteListed(url: string) { } const alovaInstance = createAlova({ - 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, + cacheLogger: false, responded: { onSuccess: async (response, method: Method) => { const resData = response.data as ResponseData @@ -53,7 +55,7 @@ const alovaInstance = createAlova({ // Access Token 过期但 Refresh Token 有效 → 刷新 token 并重试 if (resData.code === HttpCode.RefreshToken) { try { - const refreshToken = userStore.getState().userInfo?.refreshToken + const refreshToken = useUserStore.getState().userInfo?.refreshToken if (!refreshToken) { router.replace('/auth/login') return @@ -61,26 +63,24 @@ const alovaInstance = createAlova({ // 调用刷新接口 const res = await alovaInstance.Get>('/auth/refresh/token', { - headers: { - refreshToken, - }, - }) + headers: { refreshToken }, + }).send() + const newToken = res.data // 更新 store - userStore.getState().setUserInfo({ - ...userStore.getState().userInfo!, + useUserStore.getState().setUserInfo({ + ...useUserStore.getState().userInfo!, token: newToken, }) // 重试原请求 method.config.headers.token = newToken - await method.send() + const retryResult = await method.send() // ✅ 获取结果 - return + return retryResult // ✅ 一定要 return! } catch (err) { - // router.replace('/auth/login') return Promise.reject(err) } } @@ -88,6 +88,9 @@ const alovaInstance = createAlova({ return result }, onError: (error: AxiosError, _method) => { + console.log('===跳转到error了===') + console.log(error.status) + switch (error.status) { case 400: toast.show({ @@ -142,7 +145,7 @@ const alovaInstance = createAlova({ if (isWhiteListed(method.url)) return - if (!userStore.getState().isLoggedIn()) { + if (!useUserStore.getState().isLoggedIn()) { toast.show({ title: '尚未登录,请先登录', }) @@ -151,7 +154,8 @@ const alovaInstance = createAlova({ return Promise.reject(new Error('未登录')) } - method.config.headers.token = userStore.getState().userInfo?.token ?? '' + method.config.cacheFor = 0 + method.config.headers.token = useUserStore.getState().userInfo?.token ?? '' }, }) diff --git a/code/base-project/base-app/src/store/user.ts b/code/base-project/base-app/src/store/user.ts index d5b8e96a..2d070f37 100644 --- a/code/base-project/base-app/src/store/user.ts +++ b/code/base-project/base-app/src/store/user.ts @@ -16,7 +16,6 @@ const useUserStore = create()( userInfo: null, setUserInfo: userInfo => set({ userInfo }), logout: () => { - console.log('当前 token:', get().userInfo?.token) set({ userInfo: null }) }, isLoggedIn: () => !!get().userInfo?.token, @@ -28,6 +27,4 @@ const useUserStore = create()( ), ) -const userStore = useUserStore - -export { userStore, useUserStore } +export { useUserStore } diff --git a/code/base-project/base-go-v2/internal/api/auth/index.go b/code/base-project/base-go-v2/internal/api/auth/index.go index f3625ab9..4ff976f9 100644 --- a/code/base-project/base-go-v2/internal/api/auth/index.go +++ b/code/base-project/base-go-v2/internal/api/auth/index.go @@ -16,7 +16,7 @@ func InitAuthRouter(r *router.Router) { group := r.Group("auth") group.POST("/login/default", loginDefault) group.POST("/register/default", registerDefault) - group.POST("/refresh/token", RefreshAccessToken) + group.GET("/refresh/token", RefreshAccessToken) } func RefreshAccessToken(c *router.Context) error { @@ -48,13 +48,8 @@ func RefreshAccessToken(c *router.Context) error { return err } - // 返回新的 Access Token - respData := map[string]string{ - "accessToken": newAccessToken, - } - return response.Success(c). - Data(respData). + Data(newAccessToken). Send() } diff --git a/code/base-project/base-go-v2/internal/api/middleware/auth.go b/code/base-project/base-go-v2/internal/api/middleware/auth.go index 5c177b88..837bd7ab 100644 --- a/code/base-project/base-go-v2/internal/api/middleware/auth.go +++ b/code/base-project/base-go-v2/internal/api/middleware/auth.go @@ -9,12 +9,8 @@ import ( func AuthMiddleware() router.HandlerFunc { return func(c *router.Context) error { - fmt.Println("===请求进入===") - token := c.Header("token") if token == "" { - fmt.Println("===未提供 Token===") - c.Abort() return response.Fail(c). Code(response.HttpCode.Unauthorized). @@ -41,7 +37,6 @@ func AuthMiddleware() router.HandlerFunc { Send() } - fmt.Println("===请求通过===") return c.Next() } } diff --git a/code/base-project/base-go-v2/internal/router/router.go b/code/base-project/base-go-v2/internal/router/router.go index 9bb326c1..3c8ffb91 100644 --- a/code/base-project/base-go-v2/internal/router/router.go +++ b/code/base-project/base-go-v2/internal/router/router.go @@ -194,8 +194,9 @@ func (r *Router) handle(method, path string, handler HandlerFunc) *Router { func (r *Router) Handler(ctx *fasthttp.RequestCtx) { method := string(ctx.Method()) root := r.roots[method] + if root == nil { - ctx.Error("404 Not Found", fasthttp.StatusNotFound) + ctx.Error("未找到该页面", fasthttp.StatusNotFound) return } diff --git a/code/base-project/base-go-v2/internal/utils/jwtx/jwt.go b/code/base-project/base-go-v2/internal/utils/jwtx/jwt.go index cdd330c2..10b48b9d 100644 --- a/code/base-project/base-go-v2/internal/utils/jwtx/jwt.go +++ b/code/base-project/base-go-v2/internal/utils/jwtx/jwt.go @@ -61,19 +61,42 @@ func createToken(userID int64, expiry time.Duration) (string, error) { // VerifyToken 验证 token 并返回结构化结果 func VerifyToken(tokenString string) TokenResult { - result := TokenResult{IsValid: false, IsExpired: false} + result := TokenResult{ + IsValid: false, + IsExpired: false, + } - token, _ := jwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token *jwt.Token) (interface{}, error) { + // 🧩 1. token 为空 + if tokenString == "" { + return result + } + + // 🧩 2. 解析 token + token, err := jwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token *jwt.Token) (interface{}, error) { return []byte(config.App.JWT.Secret), nil }) - claims, ok := token.Claims.(*CustomClaims) - if !ok || !token.Valid { - return result // token 无效 + // 🧩 3. token 为 nil(解析异常) + if token == nil { + return result } + // 🧩 4. 提取 claims 并验证 + claims, ok := token.Claims.(*CustomClaims) + if !ok { + return result + } + + // 🧩 5. 解析失败或签名无效 + if err != nil || !token.Valid { + return result + } + + // ✅ 6. 填充结果 result.Claims = claims result.IsValid = true + + // 🧩 7. 检查是否过期 if claims.ExpiresAt != nil && time.Now().After(claims.ExpiresAt.Time) { result.IsExpired = true }