This commit is contained in:
oneao committed 2025-11-10 17:31:45 +08:00
1 parent 7ed98a04c1
commit dee2eab404
25 files changed
+1037 -518

No files matched your search

+1 -1
View File
@@ -1,5 +1,5 @@
{
"symbol_url": "//at.alicdn.com/t/c/font_5056764_6s6rld1vyq.js",
"symbol_url": "//at.alicdn.com/t/c/font_5056764_07da4x030572.js",
"use_typescript": true,
"save_dir": "./src/components/iconfont",
"trim_icon_prefix": "icon",
@@ -3,7 +3,7 @@ import CustomTabbar from '@/components/custom/Tabbar'
import { toast } from '@/utils/toast'
export const unstable_settings = {
initialRouteName: 'money',
initialRouteName: 'money/index',
}
export default function TabsLayout() {
@@ -1,159 +0,0 @@
import type { SegmentedTabItem } from '@/components/common/ao/SegmentedTabs'
import React, { useEffect, useState } from 'react'
import { Pressable, Text, View } from 'react-native'
import Animated, { useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated'
import { SafeAreaView } from 'react-native-safe-area-context'
import { LucideIcon } from '@/components/common/ao'
import SegmentedTabs from '@/components/common/ao/SegmentedTabs'
import { Button, ButtonText } from '@/components/ui/button'
import {
Drawer,
DrawerBackdrop,
DrawerBody,
DrawerCloseButton,
DrawerContent,
DrawerFooter,
DrawerHeader,
} from '@/components/ui/drawer'
import { CloseIcon, Icon } from '@/components/ui/icon'
function Detail() {
const [dateSelected, setDateSelected] = useState(false)
const [filterOpen, setFilterOpen] = useState(false)
useEffect(() => {
console.log('Detail加载了')
}, [])
// 动画角度
const dateRotation = useSharedValue(0)
const filterRotation = useSharedValue(0)
const toggleDate = () => {
setDateSelected(prev => !prev)
dateRotation.value = withTiming(dateRotation.value === 0 ? 180 : 0, { duration: 200 })
}
const toggleFilter = () => {
setFilterOpen(prev => !prev)
filterRotation.value = withTiming(filterRotation.value === 0 ? 180 : 0, { duration: 200 })
}
const dateAnimatedStyle = useAnimatedStyle(() => ({
transform: [{ rotate: `${dateRotation.value}deg` }],
}))
const filterAnimatedStyle = useAnimatedStyle(() => ({
transform: [{ rotate: `${filterRotation.value}deg` }],
}))
return (
<View>
<View className="flex-row justify-between">
<Pressable
className="flex-row items-center gap-1"
onPress={toggleDate}
>
<Text style={{ fontSize: 16 }}>今天</Text>
<Animated.View style={dateAnimatedStyle}>
<LucideIcon icon="ChevronDown" size={18} />
</Animated.View>
</Pressable>
<Pressable
className="flex-row items-center gap-1"
onPress={toggleFilter}
>
<Text style={{ fontSize: 16 }}>筛选</Text>
<Animated.View style={filterAnimatedStyle}>
<LucideIcon icon="ChevronDown" size={18} />
</Animated.View>
</Pressable>
</View>
<Drawer
isOpen={dateSelected}
anchor="bottom"
onClose={() => {
setDateSelected(false)
}}
size="md"
>
<DrawerBackdrop />
<DrawerContent style={{ padding: 12 }}>
<DrawerBody style={{ padding: 0, marginTop: 0, marginBottom: 0 }}>
<Text>This is the basic drawer component.</Text>
<Text>This is the basic drawer component.</Text>
<Text>This is the basic drawer component.</Text>
<Text>This is the basic drawer component.</Text>
<Text>This is the basic drawer component.</Text>
<Text>This is the basic drawer component.</Text>
<Text>This is the basic drawer component.</Text>
<Text>This is the basic drawer component.</Text>
<Text>This is the basic drawer component.</Text>
<Text>This is the basic drawer component.</Text>
<Text>This is the basic drawer component.</Text>
<Text>This is the basic drawer component.</Text>
<Text>This is the basic drawer component.</Text>
<Text>This is the basic drawer component.</Text>
<Text>This is the basic drawer component.</Text>
<Text>This is the basic drawer component.</Text>
<Text>This is the basic drawer component.</Text>
<Text>This is the basic drawer component.</Text>
<Text>This is the basic drawer component.</Text>
</DrawerBody>
</DrawerContent>
</Drawer>
</View>
)
}
function Chart() {
useEffect(() => {
console.log('Chart记载了')
}, [])
return (
<View>
<Text>这里是视图内这里是视图内容这里是视图内容这里是视图内容这里是视图内容这里是视图内容这里是视图内容这里是视图内容这里是视图内容这里是视图内容容</Text>
</View>
)
}
export default function MoneyTest() {
const [selectedIndex, setSelectedIndex] = useState(0)
const tabs: SegmentedTabItem[] = [
{
label: '明细',
icon: 'ScrollText',
content: <Detail />, // ✅ 注意这里不要调用 Detail()
},
{
label: '视图',
icon: 'ChartPie',
content: <Chart />, // ✅ 注意这里不要调用 Chart()
},
{
label: '视图2',
icon: 'ChartPie',
content: (
<View>
<Text>这里是视图内容2</Text>
</View>
),
},
]
return (
<SafeAreaView style={{ flex: 1, paddingTop: 4, paddingLeft: 8, paddingRight: 8 }}>
<SegmentedTabs
headerWidth={220}
tabs={tabs}
value={selectedIndex}
onChange={setSelectedIndex}
cacheContent={true}
/>
</SafeAreaView>
)
}
@@ -0,0 +1,53 @@
import React from 'react'
import { Text, View } from 'react-native'
function BalanceCard() {
return (
<View className="mt-6 rounded-lg overflow-hidden shadow-lg shadow-gray-300 bg-white">
<View className="p-4 relative">
<View className="absolute top-2 left-2 bg-green-50 rounded-md px-3 py-1.5 flex-row items-center z-10 border border-green-100">
<View className="w-2 h-2 bg-green-500 rounded-full mr-2" />
<Text className="text-green-700 text-xs font-semibold">账单已出</Text>
</View>
{/* 总余额 */}
<View className="items-center mb-4 mt-3">
<Text className="text-gray-500 text-sm font-medium mb-2">总余额 (CNY)</Text>
<Text className="text-4xl font-black text-gray-800 text-center tracking-tight">
¥ 12,322.67
</Text>
</View>
{/* 收入 / 支出 */}
<View className="flex-row justify-between rounded-lg pt-4">
{/* 收入 */}
<View className="flex-1 items-center pr-3">
<View className="flex-row justify-center w-full mb-2">
<Text className="text-gray-600 text-sm font-medium">收入</Text>
<Text className="text-green-500 text-xs font-semibold ml-1">↑ +10%</Text>
</View>
<Text className="text-2xl font-bold text-gray-800 text-center">
¥ 12,232.00
</Text>
</View>
{/* 分隔线 */}
<View className="w-px bg-gray-200 mx-1" />
{/* 支出 */}
<View className="flex-1 items-center pl-3">
<View className="flex-row justify-center w-full mb-2">
<Text className="text-gray-600 text-sm font-medium">支出</Text>
<Text className="text-red-500 text-xs font-semibold ml-1">↓ -20%</Text>
</View>
<Text className="text-2xl font-bold text-gray-800 text-center">
¥ 1,980.00
</Text>
</View>
</View>
</View>
</View>
)
}
export default BalanceCard
@@ -0,0 +1,20 @@
import React from 'react'
import { IconJiaotong, IconLingshi, IconRiyongpin, IconShouru, IconShucai, IconYule, IconZhichu } from '@/components/iconfont'
// 图标映射表
const iconMap: Record<string, React.ElementType> = {
jiaotong: IconJiaotong,
lingshi: IconLingshi,
riyongpin: IconRiyongpin,
shucai: IconShucai,
yule: IconYule,
}
// 默认图标
const DefaultIcon = IconLingshi
// 根据类别 name 返回图标组件
export function getCategoryIcon(name: string, size = 24,type: , color?: string) {
const IconComponent = iconMap[name] || DefaultIcon
return <IconComponent size={size} color={color} />
}
@@ -0,0 +1,56 @@
import { Pressable, Text, View } from 'react-native'
import Animated, { useAnimatedStyle, withSpring, withTiming } from 'react-native-reanimated'
import { IconQuxian1 } from '@/components/iconfont'
interface TabSelectorProps {
options: string[]
selected: number
onSelect: (tab: number) => void
}
const TabSelector: React.FC<TabSelectorProps> = ({ options, selected, onSelect }) => {
return (
<View className="flex-row gap-4 items-center h-10 mt-2">
{options.map((tab, index) => {
const isActive = selected === index
const animatedStyle = useAnimatedStyle(() => ({
transform: [
{ rotate: '50deg' },
{ scale: withSpring(isActive ? 1 : 0.8, { damping: 12, stiffness: 120 }) },
],
opacity: withTiming(isActive ? 1 : 0, { duration: 200 }),
}))
return (
<View key={tab} className="relative h-full items-center">
<Pressable
onPress={() => onSelect(index)}
className="h-full items-center justify-center"
>
<Text
className={`${isActive ? 'font-bold text-xl text-black' : 'font-normal text-base text-gray-600 '}`}
>
{tab}
</Text>
<Animated.View
style={[
{
position: 'absolute',
bottom: -2,
},
animatedStyle,
]}
>
<IconQuxian1 size={22} color="#7566f3" />
</Animated.View>
</Pressable>
</View>
)
})}
</View>
)
}
export default TabSelector
@@ -0,0 +1,103 @@
import React from 'react'
import { Text, View } from 'react-native'
import { LucideIcon } from '@/components/common/ao'
import IconFont from '@/components/iconfont'
interface Transaction {
id: string
description: string
title: string
amount: number
type: 'income' | 'expense'
}
interface DaySection {
title: string
totalIncome: number
totalExpense: number
data: Transaction[]
}
// 模拟数据
const sections: DaySection[] = [
{
title: '2024/11/10',
totalIncome: 3200,
totalExpense: 1980,
data: [
{ id: '1', title: '午餐', description: '公司食堂', amount: 25, type: 'expense' },
{ id: '2', title: '打车', description: '回家', amount: 40, type: 'expense' },
{ id: '3', title: '工资', description: '11月工资', amount: 3200, type: 'income' },
],
},
{
title: '2024/11/09',
totalIncome: 1200,
totalExpense: 560,
data: [
{ id: '4', title: '早餐', description: '面包牛奶', amount: 15, type: 'expense' },
{ id: '5', title: '电影票', description: '周末电影', amount: 45, type: 'expense' },
{ id: '6', title: '兼职收入', description: '家教', amount: 1200, type: 'income' },
],
},
]
export default function StaticTransactions() {
return (
<View className="mt-4 space-y-6 px-2">
{sections.map(section => (
<View key={section.title} className="space-y-4">
<View className="py-2">
<View className="flex-row items-center justify-between">
<View className="flex-row items-center gap-2">
<Text className="text-gray-700 font-semibold text-base">{section.title}</Text>
<Text className="text-gray-400 text-sm">星期日</Text>
</View>
<View className="flex-row items-center gap-4">
<Text className="text-gray-500 text-sm">
收入 ¥
{section.totalIncome}
</Text>
<Text className="text-gray-500 text-sm">
支出 ¥
{section.totalExpense}
</Text>
</View>
</View>
</View>
{/* 交易列表 */}
{section.data.map(item => (
<View
key={item.id}
className="flex-row items-center bg-white rounded-md p-4 shadow-md mb-4"
>
{/* 图标 */}
<View className="w-12 h-12 rounded-full bg-white shadow-md items-center justify-center mr-4">
{/* <IconFont name="shucai" size={28} /> */}
<IconFont name='jiaotong' size={28} />
</View>
{/* 标题 + 描述 */}
<View className="flex-1">
<Text className="text-gray-800 font-medium text-base">{item.title}</Text>
<Text className="text-gray-400 text-sm mt-0.5">{item.description}</Text>
</View>
{/* 金额 */}
<Text
className={`font-semibold text-base ${
item.type === 'income' ? 'text-green-600' : 'text-red-600'
}`}
>
{item.type === 'income' ? '+' : '-'}
¥
{item.amount}
</Text>
</View>
))}
</View>
))}
</View>
)
}
@@ -0,0 +1,59 @@
import { LinearGradient } from 'expo-linear-gradient'
import React, { useState } from 'react'
import { ScrollView, Text, View } from 'react-native'
import { useSafeAreaInsets } from 'react-native-safe-area-context'
import { LucideIcon } from '@/components/common/ao'
import BalanceCard from './components/BalanceCard'
import TabSelector from './components/TabSelector'
import TransactionsList from './components/TransactionsList'
export default function Money() {
const insets = useSafeAreaInsets()
const [selected, setSelected] = useState(0)
return (
<LinearGradient
colors={['#f2f6ff', '#ffffff']}
start={{ x: 0, y: 0 }}
end={{ x: 0, y: 1 }}
className="flex-1"
style={{
paddingTop: insets.top,
paddingBottom: insets.bottom,
paddingLeft: 8,
paddingRight: 8,
}}
>
{/* 顶部固定栏 */}
<View style={{ zIndex: 10 }}>
<View className="flex flex-row justify-between items-center py-2">
<View className="flex flex-row items-center gap-2">
<Text className="font-bold text-lg">2025/11/10</Text>
<LucideIcon icon="CircleChevronDown" size={16} />
</View>
<View className="flex flex-row items-center gap-2">
<LucideIcon icon="SlidersHorizontal" />
<Text>筛选</Text>
</View>
</View>
<TabSelector
options={['明细', '视图']}
selected={selected}
onSelect={tab => setSelected(tab)}
/>
</View>
{/* 可滚动内容 */}
<ScrollView
showsVerticalScrollIndicator={false}
contentContainerStyle={{ paddingBottom: 20 }}
style={{ marginTop: 0 }}
>
<BalanceCard />
<TransactionsList />
</ScrollView>
</LinearGradient>
)
}
@@ -1,14 +1,13 @@
import type { icons } from 'lucide-react-native'
import type { LayoutChangeEvent, StyleProp, TextStyle, ViewStyle } from 'react-native'
import type { StyleProp, TextStyle, ViewStyle } from 'react-native'
import React, { useEffect, useRef, useState } from 'react'
import { Platform, Pressable, Text, View } from 'react-native'
import Animated, { useAnimatedStyle, useSharedValue, withSpring, withTiming } from 'react-native-reanimated'
import Animated, { useAnimatedStyle, useSharedValue, withSpring } from 'react-native-reanimated'
import LucideIcon from './LucideIcon'
export interface SegmentedTabItem {
label: string
icon?: keyof typeof icons
content?: React.ReactNode
}
interface SegmentedTabsProps {
@@ -34,12 +33,7 @@ interface SegmentedTabsProps {
fontSize?: number
iconSize?: number
contentContainerStyle?: StyleProp<ViewStyle>
animateContent?: boolean
cacheContent?: boolean
headerWidth?: number
contentWidth?: number
width?: number
}
export default function SegmentedTabs({
@@ -60,188 +54,123 @@ export default function SegmentedTabs({
unselectedColor = '#666',
fontSize = 14,
iconSize = 14,
contentContainerStyle,
animateContent = true,
cacheContent = true,
headerWidth,
contentWidth,
width,
}: SegmentedTabsProps) {
const [selectedIndex, setSelectedIndex] = useState(value ?? defaultIndex)
const [headerMeasuredWidth, setHeaderMeasuredWidth] = useState(0)
const [contentMeasuredWidth, setContentMeasuredWidth] = useState(0)
const [ready, setReady] = useState(false)
const sliderX = useSharedValue(0)
const contentX = useSharedValue(0)
const initialized = useRef(false)
const actualHeaderWidth = headerWidth ?? headerMeasuredWidth
const actualContentWidth = contentWidth ?? contentMeasuredWidth
const actualHeaderWidth = width ?? headerMeasuredWidth
const tabWidth = actualHeaderWidth ? actualHeaderWidth / tabs.length : 0
const sliderWidth = tabWidth - spacing * 2
const sliderHeight = tabHeight - spacing * 2
// 外部 value 改变
useEffect(() => {
if (value !== undefined)
setSelectedIndex(value)
}, [value])
// 滑块和内容动画
useEffect(() => {
if (!ready || tabWidth === 0 || actualContentWidth === 0)
if (!ready || tabWidth === 0)
return
const target = selectedIndex * tabWidth + spacing
if (!initialized.current) {
sliderX.value = target
contentX.value = -selectedIndex * actualContentWidth
initialized.current = true
}
else {
sliderX.value = withSpring(target, { damping: 18, stiffness: 150, mass: 1 })
contentX.value = animateContent
? withTiming(-selectedIndex * actualContentWidth, { duration: 250 })
: -selectedIndex * actualContentWidth
}
}, [selectedIndex, tabWidth, actualContentWidth, ready])
}, [selectedIndex, tabWidth, ready])
const animatedSliderStyle = useAnimatedStyle(() => ({
transform: [{ translateX: sliderX.value }],
}))
const animatedContentStyle = useAnimatedStyle(() => ({
transform: [{ translateX: contentX.value }],
}))
const handlePress = (index: number) => {
if (value === undefined)
setSelectedIndex(index)
onChange?.(index)
}
const handleHeaderLayout = (event: LayoutChangeEvent) => {
const handleHeaderLayout = (event: any) => {
const { width } = event.nativeEvent.layout
setHeaderMeasuredWidth(width)
if (width > 0 && actualContentWidth > 0 && !ready)
setReady(true)
}
const handleContentLayout = (event: LayoutChangeEvent) => {
const { width } = event.nativeEvent.layout
setContentMeasuredWidth(width)
if (width > 0 && actualHeaderWidth > 0 && !ready)
if (width > 0 && !ready)
setReady(true)
}
return (
<View className="w-full h-full">
{/* Header */}
<View
className={className}
style={[
{
width: headerWidth,
flexDirection: 'row',
backgroundColor: '#f2f2f2',
borderRadius,
height: tabHeight,
overflow: 'hidden',
},
style,
]}
onLayout={handleHeaderLayout}
>
{/* 滑块 */}
{ready && (
<Animated.View
style={[
{
position: 'absolute',
top: spacing,
left: 0,
width: sliderWidth,
height: sliderHeight,
borderRadius,
backgroundColor: sliderColor,
...Platform.select({ android: { elevation: 6 } }),
},
sliderStyle,
animatedSliderStyle,
]}
/>
)}
{tabs.map((tab, i) => {
const isActive = i === selectedIndex
return (
<Pressable
key={i}
onPress={() => handlePress(i)}
style={{
width: tabWidth,
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'row',
gap: spacing,
}}
>
{tab.icon && (
<LucideIcon
icon={tab.icon}
size={iconSize}
color={isActive ? selectedColor : unselectedColor}
/>
)}
<Text
style={[
{ color: isActive ? selectedColor : unselectedColor, fontSize, fontWeight: 'bold' },
isActive ? selectedTextStyle : unselectedTextStyle,
]}
>
{tab.label}
</Text>
</Pressable>
)
})}
</View>
{/* Content */}
<View
style={[
{ width: contentWidth ?? '100%', flex: 1, overflow: 'hidden', marginTop: 16 },
contentContainerStyle,
]}
onLayout={handleContentLayout}
>
<View
className={className}
style={[
{
width,
flexDirection: 'row',
backgroundColor: '#f2f2f2',
borderRadius,
height: tabHeight,
overflow: 'hidden',
},
style,
]}
onLayout={handleHeaderLayout}
>
{ready && (
<Animated.View
style={[
{ flexDirection: 'row', width: actualContentWidth * tabs.length },
animatedContentStyle,
{
position: 'absolute',
top: spacing,
left: 0,
width: sliderWidth,
height: sliderHeight,
borderRadius,
backgroundColor: sliderColor,
...Platform.select({ android: { elevation: 6 } }),
},
sliderStyle,
animatedSliderStyle,
]}
>
{tabs.map((tab, i) => {
const isActive = i === selectedIndex
const shouldRender = cacheContent || isActive
/>
)}
if (!shouldRender) {
// 占位保持宽度
return <View key={`placeholder-${i}`} style={{ width: actualContentWidth }} />
}
return (
<View
key={isActive ? `tab-${i}-${selectedIndex}` : i} // ✅ 动态 key,确保重新挂载
style={{ width: actualContentWidth }}
>
{tab.content}
</View>
)
})}
</Animated.View>
</View>
{tabs.map((tab, i) => {
const isActive = i === selectedIndex
return (
<Pressable
key={i}
onPress={() => handlePress(i)}
style={{
width: tabWidth,
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'row',
gap: spacing,
}}
>
{tab.icon && (
<LucideIcon
icon={tab.icon}
size={iconSize}
color={isActive ? selectedColor : unselectedColor}
/>
)}
<Text
style={[
{ color: isActive ? selectedColor : unselectedColor, fontSize, fontWeight: 'bold' },
isActive ? selectedTextStyle : unselectedTextStyle,
]}
>
{tab.label}
</Text>
</Pressable>
)
})}
</View>
)
}
@@ -0,0 +1,124 @@
/* 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<GProps, 'color'>, ViewProps {
size?: number;
color?: string | string[];
}
const IconJiaotong: FunctionComponent<Props> = ({
size = 18,
color,
...rest
}) => {
return (
<Svg viewBox="0 0 1024 1024" width={size} height={size} {...rest}>
<Path
d="M32.698182 259.258182h953.832727v194.909091H32.698182z"
fill={getIconColor(color, 0, '#FFFFFF')}
/>
<Path
d="M46.778182 468.363636h937.076363V705.163636H46.778182z"
fill={getIconColor(color, 1, '#F9B332')}
/>
<Path
d="M46.545455 439.854545h953.94909v28.625455H46.545455zM40.96 688.407273h959.534545v28.625454H40.96z"
fill={getIconColor(color, 2, '#1D1D1B')}
/>
<Path
d="M112.407273 331.869091h228.887272v171.636364H112.407273z"
fill={getIconColor(color, 3, '#87CCEC')}
/>
<Path
d="M355.607273 517.934545H98.094545V317.672727h257.512728v200.261818z m-228.887273-28.625454H326.981818v-143.127273H126.72v143.127273z"
fill={getIconColor(color, 4, '#1D1C1A')}
/>
<Path
d="M467.665455 331.869091h228.887272v171.636364H467.665455z"
fill={getIconColor(color, 5, '#87CCEC')}
/>
<Path
d="M710.865455 517.934545H453.352727V317.672727h257.512728v200.261818z m-228.887273-28.625454h200.261818v-143.127273H481.978182v143.127273z"
fill={getIconColor(color, 6, '#1D1C1A')}
/>
<Path
d="M822.923636 331.869091h171.636364v171.636364H822.923636z"
fill={getIconColor(color, 7, '#87CCEC')}
/>
<Path
d="M1008.872727 517.934545H808.610909V317.672727H1008.872727v200.261818z m-171.636363-28.625454h143.010909v-143.127273H837.236364v143.127273z"
fill={getIconColor(color, 8, '#1D1C1A')}
/>
<Path
d="M908.683636 554.356364h85.876364v65.28h-85.876364z"
fill={getIconColor(color, 9, '#E31E26')}
/>
<Path
d="M1008.872727 633.949091h-114.501818v-93.905455H1008.872727v93.905455z m-85.876363-28.625455h57.250909v-36.654545h-57.250909v36.654545z"
fill={getIconColor(color, 10, '#1D1C1A')}
/>
<Path
d="M862.254545 175.010909h28.625455v84.247273H862.254545zM498.618182 184.087273H98.094545v28.625454h71.447273v46.545455h28.625455v-46.545455h200.378182v46.545455H427.054545v-46.545455h71.563637zM862.254545 126.370909h28.625455v28.625455H862.254545zM819.432727 541.090909H862.254545v28.625455h-42.821818z"
fill={getIconColor(color, 11, '#1D1D1B')}
/>
<Path
d="M126.254545 541.090909h28.625455v28.625455h-28.625455zM170.24 541.090909h28.625455v28.625455h-28.625455z"
fill={getIconColor(color, 12, '#FDFEFF')}
/>
<Path
d="M32.698182 717.032727h953.832727v28.625455H32.698182z"
fill={getIconColor(color, 13, '#CBBBA1')}
/>
<Path
d="M214.341818 541.090909h28.625455v28.625455h-28.625455zM202.518109 450.661236l80.963491-80.964654 15.140073 15.138909-80.964655 80.965818zM192.197818 400.646982l29.128146-29.126982 15.138909 15.138909-29.126982 29.128146zM555.630545 450.661236l80.963491-80.964654 15.140073 15.138909-80.964654 80.965818zM550.355782 400.646982l29.126982-29.126982 15.138909 15.138909-29.125818 29.128146zM875.322182 450.661236l80.964654-80.964654 15.138909 15.138909-80.96349 80.965818zM868.724364 400.646982l29.128145-29.128146 15.138909 15.140073-29.125818 29.126982z"
fill={getIconColor(color, 14, '#FDFEFF')}
/>
<Path
d="M1008.872727 774.167273H18.385455v-532.945455H1008.872727v532.945455zM46.894545 745.541818h933.352728V269.963636H46.894545v475.578182z"
fill={getIconColor(color, 15, '#1D1C1A')}
/>
<Path
d="M291.258182 764.392727m-96 0a96 96 0 1 0 192 0 96 96 0 1 0-192 0Z"
fill={getIconColor(color, 16, '#373736')}
/>
<Path
d="M291.258182 874.589091c-60.741818 0-110.196364-49.454545-110.196364-110.312727 0-60.741818 49.454545-110.196364 110.196364-110.196364s110.196364 49.454545 110.196363 110.196364c0 60.858182-49.454545 110.312727-110.196363 110.312727z m0-191.883636c-45.032727 0-81.687273 36.654545-81.687273 81.687272s36.654545 81.687273 81.687273 81.687273 81.687273-36.654545 81.687273-81.687273-36.770909-81.687273-81.687273-81.687272z"
fill={getIconColor(color, 17, '#1D1C1A')}
/>
<Path
d="M291.258182 764.392727m-40.494546 0a40.494545 40.494545 0 1 0 80.989091 0 40.494545 40.494545 0 1 0-80.989091 0Z"
fill={getIconColor(color, 18, '#FFFFFF')}
/>
<Path
d="M291.258182 819.2c-30.254545 0-54.807273-24.552727-54.807273-54.807273s24.552727-54.807273 54.807273-54.807272 54.807273 24.552727 54.807273 54.807272-24.552727 54.807273-54.807273 54.807273z m0-81.105455c-14.429091 0-26.181818 11.752727-26.181818 26.181819s11.752727 26.181818 26.181818 26.181818 26.181818-11.752727 26.181818-26.181818-11.752727-26.181818-26.181818-26.181819z"
fill={getIconColor(color, 19, '#1D1C1A')}
/>
<Path
d="M750.778182 764.392727m-96 0a96 96 0 1 0 192 0 96 96 0 1 0-192 0Z"
fill={getIconColor(color, 20, '#373736')}
/>
<Path
d="M750.778182 874.589091c-60.741818 0-110.196364-49.454545-110.196364-110.312727 0-60.741818 49.454545-110.196364 110.196364-110.196364s110.312727 49.454545 110.312727 110.196364c0 60.858182-49.454545 110.312727-110.312727 110.312727z m0-191.883636c-45.032727 0-81.687273 36.654545-81.687273 81.687272s36.654545 81.687273 81.687273 81.687273 81.687273-36.654545 81.687273-81.687273-36.654545-81.687273-81.687273-81.687272z"
fill={getIconColor(color, 21, '#1D1C1A')}
/>
<Path
d="M750.778182 764.392727m-40.494546 0a40.494545 40.494545 0 1 0 80.989091 0 40.494545 40.494545 0 1 0-80.989091 0Z"
fill={getIconColor(color, 22, '#FFFFFF')}
/>
<Path
d="M750.778182 819.2c-30.254545 0-54.807273-24.552727-54.807273-54.807273s24.552727-54.807273 54.807273-54.807272 54.807273 24.552727 54.807273 54.807272-24.552727 54.807273-54.807273 54.807273z m0-81.105455c-14.429091 0-26.181818 11.752727-26.181818 26.181819s11.752727 26.181818 26.181818 26.181818 26.181818-11.752727 26.181818-26.181818-11.752727-26.181818-26.181818-26.181819z"
fill={getIconColor(color, 23, '#1D1C1A')}
/>
</Svg>
);
};
export default React.memo(IconJiaotong);
@@ -0,0 +1,76 @@
/* 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<GProps, 'color'>, ViewProps {
size?: number;
color?: string | string[];
}
const IconLingshi: FunctionComponent<Props> = ({
size = 18,
color,
...rest
}) => {
return (
<Svg viewBox="0 0 1024 1024" width={size} height={size} {...rest}>
<Path
d="M676.73 604.6925c0 21.9-17.925 39.825-39.8325 39.825H501.4625c-21.9075 0-39.8325-17.925-39.8325-39.825V86.855c0-21.9075 17.925-39.825 39.8325-39.825h135.435c21.9075 0 39.825 17.925 39.825 39.825v517.83z"
fill={getIconColor(color, 0, '#FFD553')}
/>
<Path
d="M852.29 625.055c-3.0375 21.6975-23.265 36.9675-44.9625 33.9375l-134.13-18.75c-21.6975-3.0375-36.975-23.2725-33.9375-44.97l71.7-512.8425c3.0375-21.6975 23.265-36.9675 44.9625-33.93l134.13 18.75c21.6975 3.03 36.9675 23.265 33.9375 44.9625l-71.7 512.8425z"
fill={getIconColor(color, 1, '#FFD553')}
/>
<Path
d="M538.145 654.08c1.785 21.825-14.625 41.1525-36.4575 42.9375L366.7025 708.05c-21.8325 1.785-41.16-14.625-42.945-36.45l-42.18-516.12c-1.785-21.8325 14.625-41.16 36.4575-42.9375l134.985-11.025c21.8325-1.7925 41.16 14.61 42.945 36.45l42.18 516.105zM792.2375 706.805c-1.335 21.87-20.325 38.6625-42.1875 37.3275l-135.18-8.2725c-21.8625-1.335-38.6625-20.325-37.3275-42.195l31.62-516.8625c1.335-21.8625 20.325-38.6625 42.195-37.3275l135.18 8.2725c21.87 1.335 38.6625 20.325 37.3275 42.1875l-31.6275 516.87z"
fill={getIconColor(color, 2, '#FDBA55')}
/>
<Path
d="M414.0725 592.685c4.5225 21.4425-9.315 42.675-30.75 47.1975l-132.525 27.9525c-21.435 4.515-42.675-9.3225-47.1975-30.765L96.74 130.4c-4.5225-21.4425 9.3225-42.675 30.7575-47.1975l132.5175-27.9525c21.435-4.5225 42.675 9.315 47.1975 30.7575l106.86 506.685z"
fill={getIconColor(color, 3, '#FFD553')}
/>
<Path
d="M703.025 361.535c-21.915 0-43.575 17.5275-48.15 38.955l-19.6725 92.22c-4.5675 21.42-26.235 38.955-48.1425 38.955H454.1975c-21.915 0-43.575-17.535-48.15-38.955l-19.665-92.2125c-4.575-21.4275-26.235-38.9625-48.15-38.9625H154.19c-21.9075 0-37.0125 17.7-33.57 39.3375l85.4775 536.7675c3.45 21.6375 24.195 39.3375 46.095 39.3375h536.88c21.915 0 42.6525-17.7 46.1025-39.3375l85.4775-536.7675c3.45-21.63-11.6625-39.3375-33.57-39.3375H703.025z"
fill={getIconColor(color, 4, '#FF6376')}
/>
<Path
d="M190.3025 838.5125L200.75 904.1h639.7575l10.4475-65.5725z"
fill={getIconColor(color, 5, '#FFD553')}
/>
<Path
d="M310.6925 646.8725m-27.2025 0a27.2025 27.2025 0 1 0 54.405 0 27.2025 27.2025 0 1 0-54.405 0Z"
fill={getIconColor(color, 6, '#3F4963')}
/>
<Path
d="M730.5575 646.8725m-27.2025 0a27.2025 27.2025 0 1 0 54.405 0 27.2025 27.2025 0 1 0-54.405 0Z"
fill={getIconColor(color, 7, '#3F4963')}
/>
<Path
d="M339.8 741.9425h-58.2a15.0225 15.0225 0 0 1 0-30.0525h58.2a15.0225 15.0225 0 0 1 0 30.0525zM759.6575 741.9425h-58.2a15.0225 15.0225 0 1 1 0-30.0525h58.2a15.0225 15.0225 0 0 1 0 30.0525z"
fill={getIconColor(color, 8, '#FF9596')}
/>
<Path
d="M486.5675 723.14a49.14 49.14 0 0 1-49.08-49.08 15.0225 15.0225 0 0 1 30.045 0 19.05 19.05 0 0 0 19.035 19.035c10.5 0 19.0425-8.5425 19.0425-19.035a15.0225 15.0225 0 1 1 30.045 0 49.14 49.14 0 0 1-49.0875 49.08z"
fill={getIconColor(color, 9, '#3F4963')}
/>
<Path
d="M554.69 723.14a49.14 49.14 0 0 1-49.08-49.08 15.0225 15.0225 0 1 1 30.045 0 19.05 19.05 0 0 0 19.035 19.035c10.5 0 19.035-8.5425 19.035-19.035a15.0225 15.0225 0 1 1 30.0525 0 49.14 49.14 0 0 1-49.0875 49.08z"
fill={getIconColor(color, 10, '#3F4963')}
/>
<Path
d="M892.13 52.3625L758.0075 33.6125c-29.9475-4.1925-57.735 16.7775-61.9275 46.74l-4.3275 30.945V86.855C691.7525 56.6075 667.145 32 636.8975 32H501.4625c-30.2475 0-54.855 24.6075-54.855 54.855v0.105L324.8675 96.905l-2.955-14.01a54.465 54.465 0 0 0-23.7525-34.5975 54.4575 54.4575 0 0 0-41.2425-7.755L124.3925 68.4875a54.4875 54.4875 0 0 0-34.5975 23.76 54.465 54.465 0 0 0-7.755 41.2425l46.3725 219.8775c-4.5 2.6325-8.55 5.985-11.955 9.975-9.12 10.6875-13.02 25.23-10.6875 39.9l85.4775 536.76c4.65 29.16 31.4175 51.9975 60.9375 51.9975h536.88c29.52 0 56.2875-22.845 60.9375-51.9975l85.47-536.7675c2.34-14.655-1.5525-29.1975-10.68-39.8925a47.3775 47.3775 0 0 0-18.8925-13.3275l32.9625-235.725c4.1925-29.955-16.7775-57.735-46.725-61.9275zM785.6225 162.7475c6.57 0.3975 12.6225 3.3675 17.025 8.355 4.4175 4.9875 6.6225 11.3475 6.225 17.925l-9.6375 157.485H703.0175c-29.1525 0-56.7525 22.335-62.8275 50.85L620.51 489.575c-1.89 8.8575-8.5275 17.0325-16.7775 22.035l20.4225-333.885a24.615 24.615 0 0 1 8.355-17.025 24.645 24.645 0 0 1 17.925-6.225l135.18 8.2725zM476.6525 86.855a24.84 24.84 0 0 1 24.8175-24.81h135.4275a24.84 24.84 0 0 1 24.81 24.81v38.205l-9.4275-0.5775a54.435 54.435 0 0 0-39.675 13.7025 54.4725 54.4725 0 0 0-18.435 37.7025l-20.8425 340.7475h-31.335l-31.05-379.89A54.4725 54.4725 0 0 0 491.75 99.425a55.2 55.2 0 0 0-15.0825-9.12v-3.45z m-22.4025 29.625a24.63 24.63 0 0 1 18.045 5.85 24.63 24.63 0 0 1 8.7 16.86l30.8475 377.445h-57.6525c-14.7375 0-30.3675-12.645-33.45-27.06l-19.6575-92.2125c-2.7825-13.0425-10.0725-24.78-19.95-33.69l-50.0175-237.1275L454.25 116.48zM111.4475 127.2875a24.615 24.615 0 0 1 3.525-18.6375 24.6225 24.6225 0 0 1 15.63-10.755l132.5175-27.9525a24.6225 24.6225 0 0 1 18.6375 3.525 24.615 24.615 0 0 1 10.755 15.63l54.435 258.075a58.4025 58.4025 0 0 0-8.7-0.66H157.6775l-46.2375-219.225z m794.3625 271.2225L820.325 935.285c-2.31 14.46-16.62 26.67-31.2675 26.67H252.2c-14.6475 0-28.9575-12.21-31.26-26.67L135.455 398.51c-0.9675-6.045 0.405-11.61 3.87-15.6675 3.45-4.05 8.7375-6.285 14.8575-6.285h184.0575c14.7375 0 30.375 12.6525 33.45 27.075l19.665 92.205c6.0825 28.515 33.6825 50.85 62.835 50.85h132.87c29.16 0 56.76-22.335 62.835-50.85L669.575 403.625c3.075-14.415 18.705-27.0675 33.45-27.0675h184.05c6.1275 0 11.4075 2.235 14.865 6.285 3.465 4.05 4.8375 9.6225 3.8775 15.675z m3.3-288.375l-33.0525 236.3775h-46.7175l9.525-155.655a54.4875 54.4875 0 0 0-13.7025-39.6675 54.48 54.48 0 0 0-37.7025-18.435l-67.785-4.1475 6.165-44.1a24.825 24.825 0 0 1 28.005-21.135l134.1225 18.75a24.84 24.84 0 0 1 21.1425 28.005zM310.7 619.655a27.2025 27.2025 0 1 0 0 54.405 27.2025 27.2025 0 0 0 0-54.405z m419.8575 0a27.2025 27.2025 0 1 0 0 54.405 27.2025 27.2025 0 0 0 0-54.405z m-141.81 39.375a15.0225 15.0225 0 0 0-15.0225 15.0225c0 10.5-8.5425 19.035-19.035 19.035a19.0575 19.0575 0 0 1-19.035-19.035 15.0225 15.0225 0 1 0-30.0525 0c0 10.5-8.5425 19.035-19.035 19.035a19.0575 19.0575 0 0 1-19.035-19.035 15.0225 15.0225 0 1 0-30.0525 0 49.14 49.14 0 0 0 49.08 49.08 48.9 48.9 0 0 0 34.065-13.785 48.9 48.9 0 0 0 34.0575 13.7925 49.14 49.14 0 0 0 49.08-49.0875 15.0075 15.0075 0 0 0-15.015-15.0225z"
fill={getIconColor(color, 11, '#000000')}
/>
</Svg>
);
};
export default React.memo(IconLingshi);
@@ -7,7 +7,6 @@ import type { ViewProps } from 'react-native';
import { Svg, GProps, Path } from 'react-native-svg';
import { getIconColor } from './helper';
// ✅ 关键改动:排除 GProps.color
interface Props extends Omit<GProps, 'color'>, ViewProps {
size?: number;
color?: string | string[];
@@ -66,4 +65,4 @@ const IconQq: FunctionComponent<Props> = ({
);
};
export default React.memo(IconQq);
export default React.memo(IconQq);
@@ -0,0 +1,32 @@
/* 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<GProps, 'color'>, ViewProps {
size?: number;
color?: string | string[];
}
const IconQuxian1: FunctionComponent<Props> = ({
size = 18,
color,
...rest
}) => {
return (
<Svg viewBox="0 0 1377 1024" width={size} height={size} {...rest}>
<Path
d="M1108.943077 682.832417c0-86.82715-84.780144-178.17477-385.178201-274.042861-98.426848-28.146326-41.281278-95.015172 129.302514-152.416617a1050.11382 1050.11382 0 0 1 426.459479-85.291896s85.291896-7.420395 85.291895-85.291896a78.383252 78.383252 0 0 0-85.291895-85.291895 1658.756787 1658.756787 0 0 0-682.335166 170.583791c-101.326772 74.630409-226.535275 221.247177-85.291896 341.167583 60.557246 68.233517 565.058809 111.902967 335.794194 245.2142-242.570151 93.224042-410.509894 95.953383-762.253672 95.953383a82.136096 82.136096 0 0 0-85.291896 85.291895c0 78.127376 85.291896 85.291896 85.291896 85.291896 326.241501 0 646.768445-21.322974 767.627061-85.291896 87.594777-46.398791 255.875687-145.76385 255.875687-255.875687z"
fill={getIconColor(color, 0, '#898E95')}
/>
</Svg>
);
};
export default React.memo(IconQuxian1);
@@ -0,0 +1,60 @@
/* 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<GProps, 'color'>, ViewProps {
size?: number;
color?: string | string[];
}
const IconRiyongpin: FunctionComponent<Props> = ({
size = 18,
color,
...rest
}) => {
return (
<Svg viewBox="0 0 1024 1024" width={size} height={size} {...rest}>
<Path
d="M133.12 1024c-16.896 0-30.72-13.824-30.72-30.72V30.72C102.4 13.824 116.224 0 133.12 0c16.896 0 30.72 13.824 30.72 30.72v962.56c0 16.896-13.824 30.72-30.72 30.72z"
fill={getIconColor(color, 0, '#474A54')}
/>
<Path
d="M338.432 464.896H141.824c-2.56 0-4.096-2.048-4.096-4.096V59.392c0-2.56 2.048-4.096 4.096-4.096h196.096c2.56 0 4.096 2.048 4.096 4.096v400.896c0.512 2.56-1.536 4.608-3.584 4.608z"
fill={getIconColor(color, 1, '#F9D582')}
/>
<Path
d="M338.432 490.496H141.824c-16.384 0-29.696-13.312-29.696-29.696V59.392c0-16.384 13.312-29.696 29.696-29.696h196.096c16.384 0 29.696 13.312 29.696 29.696v400.896c0.512 16.384-12.8 30.208-29.184 30.208z m-175.104-51.2h153.6v-358.4h-153.6v358.4z"
fill={getIconColor(color, 2, '#474A54')}
/>
<Path
d="M205.824 126.976h111.104v51.2H205.824v-51.2z m0 112.64h111.104v51.2H205.824v-51.2z m0 100.352h111.104v51.2H205.824v-51.2z"
fill={getIconColor(color, 3, '#474A54')}
/>
<Path
d="M487.424 881.664l43.008-600.576c0-2.56 2.56-4.608 5.12-4.608h323.072c2.56 0 5.12 2.048 5.12 4.608l43.008 600.576H487.424z"
fill={getIconColor(color, 4, '#92CA9C')}
/>
<Path
d="M460.288 907.264l45.056-627.712c1.024-15.872 14.848-28.672 30.72-28.672h323.072c15.872 0 29.696 12.288 30.72 28.672l45.056 627.712H460.288z m94.208-605.184l-39.424 553.984h364.032L839.68 302.08H554.496z"
fill={getIconColor(color, 5, '#474A54')}
/>
<Path
d="M539.136 302.08c-10.752 0-20.48-5.632-26.112-14.336-5.632-9.216-6.144-19.968-1.536-29.696l54.784-111.616c5.12-10.752 15.872-17.408 27.648-17.408h206.336c11.776 0 22.528 6.656 27.648 17.408l54.784 111.616c4.608 9.728 4.096 20.48-1.536 29.696-5.632 9.216-15.36 14.336-26.112 14.336H539.136z m67.584-121.856L571.904 250.88h250.368l-34.816-70.656H606.72zM909.312 1018.88H484.864c-8.704 0-16.896-3.584-22.528-9.728a32 32 0 0 1-8.192-23.04l9.216-130.048h466.944l9.216 130.048c0.512 8.704-2.56 16.896-8.192 23.04s-13.824 9.728-22.016 9.728z m-402.432-51.2h380.416l-4.096-60.416H511.488l-4.608 60.416z"
fill={getIconColor(color, 6, '#474A54')}
/>
<Path
d="M742.4 179.712h-92.16c-16.896 0-30.72-13.824-30.72-30.72v-117.76c0-16.896 13.824-30.72 30.72-30.72H742.4c16.896 0 30.72 13.824 30.72 30.72v117.76c0 16.896-13.824 30.72-30.72 30.72z m-71.68-51.2h51.2v-76.8h-51.2v76.8z m-95.5392 319.0272l83.3024-83.2512 36.1984 36.1984-83.2768 83.2768-36.224-36.224z m17.2544 113.3824l136.8576-136.8576 36.1984 36.224-136.832 136.832-36.224-36.1984z"
fill={getIconColor(color, 7, '#474A54')}
/>
</Svg>
);
};
export default React.memo(IconRiyongpin);
@@ -0,0 +1,32 @@
/* 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<GProps, 'color'>, ViewProps {
size?: number;
color?: string | string[];
}
const IconShouru: FunctionComponent<Props> = ({
size = 18,
color,
...rest
}) => {
return (
<Svg viewBox="0 0 1024 1024" width={size} height={size} {...rest}>
<Path
d="M430.417902 1023.906918C223.867952 1023.906918 51.339636 917.234433 51.339636 694.767385A313.315517 313.315517 0 0 1 151.12402 479.374602a520.423961 520.423961 0 0 1 65.80929-56.733751 50.404145 50.404145 0 0 0 11.402599-6.795019 91.732752 91.732752 0 0 1-54.499772-79.538951 107.417144 107.417144 0 0 1 115.980729-95.362967 104.62467 104.62467 0 0 1 38.582674 6.84156 35.324789 35.324789 0 0 1 13.590037 6.795019c2.233979 2.187438 6.795019 0 6.795019 2.187437a115.329152 115.329152 0 0 1 22.758658-24.946096 82.564131 82.564131 0 0 1 122.729207 0 106.020907 106.020907 0 0 1 22.758658 24.946096 13.590037 13.590037 0 0 0 8.982456 2.233979 74.791746 74.791746 0 0 1 13.590037-6.795019 104.671212 104.671212 0 0 1 38.582675-6.84156 106.020907 106.020907 0 0 1 115.608399 95.269885 91.593128 91.593128 0 0 1-54.499773 79.49241c4.654122 2.28052 6.795019 4.654122 11.309517 6.84156a372.329788 372.329788 0 0 1 65.855832 56.733751 315.921825 315.921825 0 0 1 102.390692 211.064449c0 222.467048-172.481774 329.139533-379.031725 329.139533z m-133.945641-288.555586a21.502045 21.502045 0 0 0 22.712117 22.758658h90.755386v88.428325a22.712117 22.712117 0 1 0 45.424234 0v-88.428325h90.848468a22.712117 22.712117 0 1 0 0-45.424234H455.363998v-54.453232h93.082447a22.712117 22.712117 0 1 0 0-45.424234H480.635882l74.93137-74.884828a22.479411 22.479411 0 0 0-31.787656-31.787656l-90.848468 90.848468-91.034633-90.615762a22.479411 22.479411 0 0 0-31.694573 31.787656l74.838287 74.465957H316.950399a22.758658 22.758658 0 0 0 0 45.517317h93.082447v54.453231H319.184378a21.362422 21.362422 0 0 0-22.712117 22.712117z m419.708753-532.431597h85.58931V0h85.449687v202.919735h85.356604l-129.943096 215.439323z"
fill={getIconColor(color, 0, '#DFA46E')}
/>
</Svg>
);
};
export default React.memo(IconShouru);
@@ -0,0 +1,48 @@
/* 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<GProps, 'color'>, ViewProps {
size?: number;
color?: string | string[];
}
const IconShucai: FunctionComponent<Props> = ({
size = 18,
color,
...rest
}) => {
return (
<Svg viewBox="0 0 1024 1024" width={size} height={size} {...rest}>
<Path
d="M988.86528 307.2s185.6 651.2-299.2 688S96.06528 859.2 25.66528 696l963.2-388.8z"
fill={getIconColor(color, 0, '#036029')}
/>
<Path
d="M432.06528 70.4s54.4-72 211.2-36.8 376 227.2 366.4 363.2-27.2 153.6 0 200-27.2 81.6-73.6 99.2c-46.4 17.6-17.6 126.4-73.6 126.4-54.4 0-73.6-9.6-118.4 0-46.4 9.6-118.4-108.8-118.4-108.8l-164.8-336L432.06528 80"
fill={getIconColor(color, 1, '#3B8234')}
/>
<Path
d="M48.06528 760s-147.2-336 73.6-571.2c17.6-27.2 46.4-54.4 147.2-54.4S368.06528 16 432.06528 33.6s54.4 81.6 128 81.6 83.2-44.8 118.4 0c36.8 44.8 36.8 108.8 91.2 145.6 54.4 36.8 91.2 27.2 100.8 72 9.6 44.8-46.4 118.4-27.2 145.6S928.06528 560 864.06528 624s-100.8 64-100.8 108.8 27.2 91.2-36.8 118.4-128 27.2-137.6 64-36.8 54.4-73.6 64c-36.8 9.6-110.4-54.4-147.2-44.8-36.8 6.4-182.4 60.8-320-174.4z"
fill={getIconColor(color, 2, '#86C958')}
/>
<Path
d="M65.66528 777.6S212.86528 352 670.46528 360c0 0-366.4 0-550.4 489.6 1.6 0-44.8-35.2-54.4-72z"
fill={getIconColor(color, 3, '#FFFFFF')}
/>
<Path
d="M139.26528 668.8s-110.4-153.6 9.6-344c0 0-73.6 244.8 9.6 308.8l-19.2 35.2zM350.46528 451.2s-17.6-180.8 137.6-254.4c0 0-128 99.2-100.8 235.2l-36.8 19.2zM276.86528 550.4s137.6 153.6 393.6 81.6c0 0-192 118.4-412.8-44.8l19.2-36.8zM148.86528 750.4c73.6 91.2 284.8 91.2 284.8 91.2-201.6-9.6-265.6-126.4-265.6-126.4l-19.2 35.2z"
fill={getIconColor(color, 4, '#FFFFFF')}
/>
</Svg>
);
};
export default React.memo(IconShucai);
@@ -7,7 +7,6 @@ import type { ViewProps } from 'react-native';
import { Svg, GProps, Path } from 'react-native-svg';
import { getIconColor } from './helper';
// ✅ 关键改动:排除 GProps.color
interface Props extends Omit<GProps, 'color'>, ViewProps {
size?: number;
color?: string | string[];
@@ -34,4 +33,4 @@ const IconWeixin: FunctionComponent<Props> = ({
);
};
export default React.memo(IconWeixin);
export default React.memo(IconWeixin);
@@ -0,0 +1,72 @@
/* 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<GProps, 'color'>, ViewProps {
size?: number;
color?: string | string[];
}
const IconYule: FunctionComponent<Props> = ({
size = 18,
color,
...rest
}) => {
return (
<Svg viewBox="0 0 1024 1024" width={size} height={size} {...rest}>
<Path
d="M455.7312 262.0928V147.3536c0-31.1296 25.1904-56.32 56.32-56.32s56.32 25.1904 56.32 56.32v114.7392c0 31.1296-25.1904 56.32-56.32 56.32s-56.32-25.1904-56.32-56.32z"
fill={getIconColor(color, 0, '#F7BC00')}
/>
<Path
d="M478.7712 262.0928V147.3536a33.28 33.28 0 1 1 66.56 0v114.7392a33.28 33.28 0 1 1-66.56 0z"
fill={getIconColor(color, 1, '#FFD029')}
/>
<Path
d="M496.6912 262.0928V147.3536c0-8.4992 6.8608-15.36 15.36-15.36s15.36 6.8608 15.36 15.36v114.7392c0 8.4992-6.8608 15.36-15.36 15.36s-15.36-6.8608-15.36-15.36z"
fill={getIconColor(color, 2, '#FFE576')}
/>
<Path
d="M44.8512 788.1728L117.7088 295.936c8.0896-54.6816 53.76-95.1296 107.52-95.1296h580.4544c54.272 0 100.2496 41.2672 107.7248 96.6656l66.1504 492.2368c9.0624 67.328-41.728 127.3344-107.7248 127.3344h-86.8352c-26.3168 0-51.712-9.8304-71.5264-27.648l-43.1616-38.8096c-19.8144-17.8176-45.2096-27.648-71.5264-27.648H449.9968c-27.0848 0-53.1456 10.3936-73.1648 29.1328l-38.1952 35.7888c-20.0192 18.7392-46.1312 29.1328-73.1648 29.1328h-113.152c-66.56 0.0512-117.504-61.0304-107.4688-128.8192z"
fill={getIconColor(color, 3, '#025FFC')}
/>
<Path
d="M78.848 751.104l67.5328-439.296c7.5264-48.8448 49.8688-84.8896 99.6864-84.8896h538.1632c50.3296 0 92.9792 36.8128 99.8912 86.272l61.3376 439.296c8.3968 60.1088-38.7072 113.664-99.8912 113.664h-80.5376c-24.3712 0-47.9744-8.7552-66.304-24.6784l-40.0384-34.6624a101.25824 101.25824 0 0 0-66.304-24.6784H454.5536c-25.088 0-49.3056 9.2672-67.84 26.0096l-35.4304 31.9488a101.33504 101.33504 0 0 1-67.84 26.0096H178.5344c-61.7472 0.0512-109.0048-54.4768-99.6864-114.9952z"
fill={getIconColor(color, 4, '#0C7AF2')}
/>
<Path
d="M116.0704 711.0144l61.7472-382.72c6.8608-42.5472 45.568-73.984 91.136-73.984h491.9808c46.0288 0 84.992 32.0512 91.2896 75.1616l56.064 382.72c7.68 52.3264-35.3792 99.0208-91.2896 99.0208h-73.6256c-22.272 0-43.8272-7.6288-60.6208-21.504l-36.5568-30.208c-16.7936-13.8752-38.3488-21.504-60.6208-21.504H459.4688c-22.9376 0-45.056 8.0896-62.0032 22.6816l-32.3584 27.8528c-16.9472 14.592-39.0656 22.6816-62.0032 22.6816H207.1552c-56.4224 0.0512-99.584-47.4624-91.0848-100.1984z"
fill={getIconColor(color, 5, '#3489FA')}
/>
<Path
d="M166.0928 659.712l53.9648-307.9168c5.9904-34.2016 39.8336-59.4944 79.616-59.4944h429.824c40.192 0 74.24 25.8048 79.7696 60.4672l48.9984 307.9168c6.7072 42.1376-30.9248 79.6672-79.7696 79.6672h-64.3072c-19.456 0-38.2976-6.144-52.992-17.3056l-31.9488-24.2688c-14.6944-11.1616-33.4848-17.3056-52.992-17.3056H466.1248c-20.0192 0-39.3728 6.5024-54.1696 18.2272l-28.3136 22.3744c-14.848 11.7248-34.1504 18.2272-54.1696 18.2272H245.6576c-49.3056 0.0512-86.9888-38.1952-79.5648-80.5888z"
fill={getIconColor(color, 6, '#3F91FC')}
/>
<Path
d="M691.5072 341.9648c-93.8496 0-171.3664 71.0144-181.8112 162.1504-9.4208-40.3968-45.312-70.656-88.3712-71.2704-0.6656-50.2272-41.7792-90.88-92.16-90.88s-91.4432 40.6528-92.16 90.88c-50.2272 0.7168-90.88 41.7792-90.88 92.16s40.6528 91.4432 90.88 92.16c0.7168 50.2272 41.7792 90.88 92.16 90.88s91.4432-40.6528 92.16-90.88c43.0592-0.6144 79.0016-30.8736 88.3712-71.2704 10.3936 91.0848 87.9616 162.1504 181.8112 162.1504 100.9152 0 183.04-82.1248 183.04-182.9888 0-101.0176-82.1248-183.0912-183.04-183.0912z m0 181.7088c0.768 0 1.28 0.5632 1.28 1.3312 0 1.4848-2.6112 1.4848-2.6112 0 0.0512-0.768 0.6144-1.3312 1.3312-1.3312z"
fill={getIconColor(color, 7, '#025FFC')}
/>
<Path
d="M420.0448 468.6336H385.536v-34.56c0-31.1296-25.1904-56.32-56.32-56.32s-56.32 25.1904-56.32 56.32v34.56h-34.56c-31.1296 0-56.32 25.1904-56.32 56.32s25.1904 56.32 56.32 56.32h34.56v34.5088c0 31.1296 25.1904 56.32 56.32 56.32s56.32-25.1904 56.32-56.32v-34.5088h34.5088c31.1296 0 56.32-25.1904 56.32-56.32s-25.1904-56.32-56.32-56.32zM691.5072 672.1536c-81.152 0-147.2-65.9968-147.2-147.1488 0-81.152 65.9968-147.2 147.2-147.2s147.2 65.9968 147.2 147.2c0 81.1008-66.048 147.1488-147.2 147.1488z m0-181.7088c-19.0464 0-34.56 15.5136-34.56 34.56s15.5136 34.5088 34.56 34.5088 34.56-15.5136 34.56-34.5088c0-19.0976-15.5136-34.56-34.56-34.56z"
fill={getIconColor(color, 8, '#F7BC00')}
/>
<Path
d="M420.0448 491.6736H362.496V434.1248a33.28 33.28 0 1 0-66.56 0v57.6H238.336a33.28 33.28 0 1 0 0 66.56H295.936v57.5488a33.28 33.28 0 1 0 66.56 0v-57.5488h57.5488c18.3808 0 33.28-14.8992 33.28-33.28s-14.8992-33.3312-33.28-33.3312zM691.5072 649.1136c-68.4544 0-124.16-55.7056-124.16-124.1088 0-68.4544 55.7056-124.16 124.16-124.16s124.16 55.7056 124.16 124.16c0 68.4032-55.7056 124.1088-124.16 124.1088z m0-181.7088c-31.744 0-57.6 25.8048-57.6 57.6s25.8048 57.5488 57.6 57.5488 57.6-25.8048 57.6-57.5488-25.856-57.6-57.6-57.6z"
fill={getIconColor(color, 9, '#FFD029')}
/>
<Path
d="M420.0448 509.5936H344.576V434.1248c0-8.4992-6.8608-15.36-15.36-15.36s-15.36 6.8608-15.36 15.36v75.52H238.336c-8.4992 0-15.36 6.8608-15.36 15.36s6.8608 15.36 15.36 15.36H313.856v75.4688c0 8.4992 6.8608 15.36 15.36 15.36s15.36-6.8608 15.36-15.36v-75.4688h75.4688c8.4992 0 15.36-6.8608 15.36-15.36s-6.8608-15.4112-15.36-15.4112zM691.5072 631.1936c-58.5728 0-106.24-47.6672-106.24-106.1888s47.6672-106.24 106.24-106.24 106.24 47.6672 106.24 106.24-47.6672 106.1888-106.24 106.1888z m0-181.7088c-41.6256 0-75.52 33.8432-75.52 75.52 0 41.6256 33.8432 75.4688 75.52 75.4688s75.52-33.8432 75.52-75.4688c0-41.6768-33.8944-75.52-75.52-75.52z"
fill={getIconColor(color, 10, '#FFE576')}
/>
</Svg>
);
};
export default React.memo(IconYule);
@@ -0,0 +1,32 @@
/* 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<GProps, 'color'>, ViewProps {
size?: number;
color?: string | string[];
}
const IconZhichu: FunctionComponent<Props> = ({
size = 18,
color,
...rest
}) => {
return (
<Svg viewBox="0 0 1024 1024" width={size} height={size} {...rest}>
<Path
d="M430.344938 1024C223.816193 1024 51.299735 917.308826 51.299735 694.822436A313.424504 313.424504 0 0 1 151.08616 479.240797 515.861545 515.861545 0 0 1 217.013736 422.570701a50.327956 50.327956 0 0 0 11.303331-6.853604 91.705309 91.705309 0 0 1-54.521952-79.481345A107.407222 107.407222 0 0 1 289.59033 240.899056a104.696469 104.696469 0 0 1 38.564308 6.853604 36.416163 36.416163 0 0 1 13.604914 6.802457c2.250437 2.199291 6.802457 0 6.802458 2.199291a114.925728 114.925728 0 0 1 22.708955-24.959393 99.735278 99.735278 0 0 1 145.357775 24.959393 13.604915 13.604915 0 0 0 9.001748 2.250437 73.088058 73.088058 0 0 1 13.604915-6.751311 117.125019 117.125019 0 0 1 154.359522 88.431946 91.705309 91.705309 0 0 1-54.521952 79.481345c4.55202 2.250437 6.802457 4.603167 11.303332 6.802457a375.20923 375.20923 0 0 1 65.87643 56.721243 316.288697 316.288697 0 0 1 102.292592 211.131911c0 222.486389-172.567604 329.177564-379.045202 329.177564z m-133.901004-288.362819a21.430298 21.430298 0 0 0 22.708955 22.708956h90.73353v88.534239a22.760102 22.760102 0 0 0 45.520204 0v-88.534239h90.784676a22.708956 22.708956 0 1 0 0-45.366765H455.355477v-54.41966h93.137405a22.760102 22.760102 0 0 0 0-45.469057H480.366016l74.929324-74.929324a22.50437 22.50437 0 0 0-31.812996-31.76185l-90.784677 90.784676-90.835822-90.784676a22.50437 22.50437 0 0 0-31.812996 31.76185l74.929324 74.775885H316.902452a22.708956 22.708956 0 1 0 0 45.417911h93.035114v54.521952H319.152889a21.379152 21.379152 0 0 0-22.708955 22.708956z m505.223116-317.107038V215.581639H716.201588L842.737526 0.204585l129.962739 215.377054h-85.516608v202.948504z"
fill={getIconColor(color, 0, '#10B213')}
/>
</Svg>
);
};
export default React.memo(IconZhichu);
@@ -7,7 +7,6 @@ import type { ViewProps } from 'react-native';
import { Svg, GProps, Path } from 'react-native-svg';
import { getIconColor } from './helper';
// ✅ 关键改动:排除 GProps.color
interface Props extends Omit<GProps, 'color'>, ViewProps {
size?: number;
color?: string | string[];
@@ -42,4 +41,4 @@ const IconZhiwen: FunctionComponent<Props> = ({
);
};
export default React.memo(IconZhiwen);
export default React.memo(IconZhiwen);
@@ -4,14 +4,30 @@
import React, { FunctionComponent } from 'react';
import { ViewProps } from 'react-native';
import { GProps } from 'react-native-svg';
import IconZhichu from './IconZhichu';
import IconShouru from './IconShouru';
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 IconZhichu } from './IconZhichu';
export { default as IconShouru } from './IconShouru';
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 = 'weixin' | 'zhiwen' | 'QQ';
export type IconNames = 'zhichu' | 'shouru' | 'jiaotong' | 'shucai' | 'riyongpin' | 'yule' | 'lingshi' | 'quxian1' | 'weixin' | 'zhiwen' | 'QQ';
interface Props extends GProps, ViewProps {
name: IconNames;
@@ -21,12 +37,28 @@ interface Props extends GProps, ViewProps {
let IconFont: FunctionComponent<Props> = ({ name, ...rest }) => {
switch (name) {
case 'zhichu':
return <IconZhichu key="1" {...rest} />;
case 'shouru':
return <IconShouru key="2" {...rest} />;
case 'jiaotong':
return <IconJiaotong key="3" {...rest} />;
case 'shucai':
return <IconShucai key="4" {...rest} />;
case 'riyongpin':
return <IconRiyongpin key="5" {...rest} />;
case 'yule':
return <IconYule key="6" {...rest} />;
case 'lingshi':
return <IconLingshi key="7" {...rest} />;
case 'quxian1':
return <IconQuxian1 key="8" {...rest} />;
case 'weixin':
return <IconWeixin key="1" {...rest} />;
return <IconWeixin key="9" {...rest} />;
case 'zhiwen':
return <IconZhiwen key="2" {...rest} />;
return <IconZhiwen key="10" {...rest} />;
case 'QQ':
return <IconQq key="3" {...rest} />;
return <IconQq key="11" {...rest} />;
}
return null;
@@ -30,7 +30,7 @@ function isWhiteListed(url: string) {
}
const alovaInstance = createAlova({
baseURL: 'http://192.168.5.6:8085/app',
baseURL: 'http://192.168.1.136:8085/app',
requestAdapter: axiosRequestAdapter(),
timeout: 5000,
responded: {
+33 -204
View File
@@ -1,205 +1,34 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>账单卡片 + 日期筛选</title>
<style>
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
background: #f7f8fa;
padding: 12px;
}
<!-- <Drawer
isOpen={dateSelected}
anchor="bottom"
onClose={() => {
setDateSelected(false)
}}
size="md"
>
<DrawerBackdrop />
<DrawerContent style={{ padding: 12 }}>
<DrawerBody style={{ padding: 0, marginTop: 0, marginBottom: 0 }}>
<Text>This is the basic drawer component.</Text>
<Text>This is the basic drawer component.</Text>
<Text>This is the basic drawer component.</Text>
<Text>This is the basic drawer component.</Text>
<Text>This is the basic drawer component.</Text>
<Text>This is the basic drawer component.</Text>
<Text>This is the basic drawer component.</Text>
<Text>This is the basic drawer component.</Text>
<Text>This is the basic drawer component.</Text>
<Text>This is the basic drawer component.</Text>
<Text>This is the basic drawer component.</Text>
<Text>This is the basic drawer component.</Text>
<Text>This is the basic drawer component.</Text>
<Text>This is the basic drawer component.</Text>
<Text>This is the basic drawer component.</Text>
<Text>This is the basic drawer component.</Text>
<Text>This is the basic drawer component.</Text>
<Text>This is the basic drawer component.</Text>
<Text>This is the basic drawer component.</Text>
</DrawerBody>
</DrawerContent>
</Drawer> -->
/* 顶部搜索 + 筛选 */
.filter-bar {
display: flex;
align-items: center;
background: #fff;
border-radius: 12px;
box-shadow: 0 2px 6px rgba(0,0,0,0.05);
padding: 8px 10px;
margin-bottom: 12px;
}
.search-box {
flex: 1;
display: flex;
align-items: center;
background: #f2f3f7;
border-radius: 8px;
padding: 6px 10px;
}
.search-box svg {
width: 16px;
height: 16px;
fill: #999;
}
.search-box input {
flex: 1;
border: none;
outline: none;
background: transparent;
margin-left: 6px;
font-size: 14px;
}
.filter-btn {
background: #007aff;
color: #fff;
padding: 7px 14px;
border-radius: 8px;
margin-left: 8px;
font-size: 13px;
}
/* 卡片 */
.card {
background: #fff;
border-radius: 16px;
padding: 16px;
box-shadow: 0 3px 8px rgba(0,0,0,0.08);
margin-bottom: 12px;
}
.card-date {
font-size: 12px;
color: #888;
margin-bottom: 10px;
}
.card-amount {
font-size: 24px;
font-weight: bold;
color: #222;
margin-bottom: 12px;
}
.card-summary {
display: flex;
justify-content: space-between;
font-size: 14px;
color: #555;
}
/* 折叠日期筛选面板 */
.filter-panel {
background: #fff;
border-radius: 12px;
padding: 12px 16px;
box-shadow: 0 3px 8px rgba(0,0,0,0.08);
max-height: 0;
overflow: hidden;
transition: max-height 0.35s ease;
margin-bottom: 12px;
}
.filter-panel.show {
max-height: 220px;
}
.filter-panel .panel-title {
font-size: 13px;
color: #666;
margin-bottom: 6px;
margin-top: 6px;
}
.filter-panel .date-input {
width: 100%;
padding: 8px 12px;
font-size: 14px;
border-radius: 8px;
border: 1px solid #ddd;
}
.filter-panel .panel-actions {
display: flex;
gap: 8px;
margin-top: 12px;
}
.filter-panel .btn {
flex: 1;
text-align: center;
padding: 10px 0;
border-radius: 10px;
font-size: 14px;
}
.btn.reset {
background-color: #f2f3f7;
color: #333;
}
.btn.confirm {
background-color: #007aff;
color: #fff;
}
</style>
</head>
<body>
<!-- 搜索 + 筛选 -->
<div class="filter-bar">
<div class="search-box">
<svg viewBox="0 0 24 24"><path d="M10,2A8,8 0 0,1 18,10C18,11.85 17.37,13.55 16.28,14.86L22,20.59L20.59,22L14.86,16.28C13.55,17.37 11.85,18 10,18A8,8 0 0,1 2,10A8,8 0 0,1 10,2Z"/></svg>
<input type="text" placeholder="搜索备注、分类...">
</div>
<div class="filter-btn" onclick="togglePanel()">筛选</div>
</div>
<!-- 日期筛选面板 -->
<div id="filterPanel" class="filter-panel">
<div class="panel-title">选择日期</div>
<input type="date" id="dateInput" class="date-input">
<div class="panel-actions">
<div class="btn reset" onclick="resetDate()">重置</div>
<div class="btn confirm" onclick="applyDate()">确定</div>
</div>
</div>
<!-- 卡片 -->
<div class="card">
<div id="cardDate" class="card-date">当前周期:本月</div>
<div id="cardRemaining" class="card-amount">剩余:¥2500</div>
<div class="card-summary">
<div>收入:¥5000</div>
<div>支出:¥2500</div>
</div>
</div>
<script>
const panel = document.getElementById('filterPanel');
const cardDate = document.getElementById('cardDate');
const cardRemaining = document.getElementById('cardRemaining');
function togglePanel() {
panel.classList.toggle('show');
}
function resetDate() {
document.getElementById('dateInput').value = '';
cardDate.innerText = "当前周期:本月";
cardRemaining.innerText = "剩余:¥2500";
panel.classList.remove('show');
}
function applyDate() {
const dateVal = document.getElementById('dateInput').value;
if(dateVal) {
// 模拟根据日期计算的金额,这里可替换为真实数据逻辑
cardDate.innerText = `当前周期:${dateVal}`;
cardRemaining.innerText = `剩余:¥${Math.floor(Math.random()*5000)}`;
}
panel.classList.remove('show');
}
</script>
</body>
</html>
+118
View File
@@ -0,0 +1,118 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>记账卡片优化版</title>
<style>
body {
margin: 0;
font-family: "PingFang SC", "Helvetica", "Arial", sans-serif;
background-color: #f0f2f5;
display: flex;
justify-content: center;
padding: 16px;
}
.card {
width: 100%;
max-width: 420px;
border-radius: 24px;
padding: 24px;
background: linear-gradient(135deg, #667eea, #764ba2);
color: #fff;
box-shadow: 0 10px 20px rgba(0,0,0,0.15);
display: flex;
flex-direction: column;
gap: 20px;
}
.card-header {
font-size: 14px;
opacity: 0.85;
}
.balance {
font-size: 32px;
font-weight: 700;
letter-spacing: 1px;
}
.summary {
display: flex;
justify-content: space-between;
gap: 16px;
}
.summary-item {
flex: 1;
background-color: rgba(255,255,255,0.1);
border-radius: 16px;
padding: 14px;
display: flex;
flex-direction: column;
align-items: center;
transition: transform 0.2s;
}
.summary-item:hover {
transform: translateY(-3px);
}
.summary-item .title {
font-size: 13px;
opacity: 0.8;
margin-bottom: 6px;
}
.summary-item .amount {
font-size: 20px;
font-weight: 600;
margin-bottom: 4px;
}
.summary-item .percent {
font-size: 12px;
font-weight: bold;
}
.percent.up {
color: #16c784; /* 上升绿色 */
}
.percent.down {
color: #ff6b6b; /* 下降红色 */
}
@media (max-width: 360px) {
.balance {
font-size: 28px;
}
.summary-item .amount {
font-size: 18px;
}
}
</style>
</head>
<body>
<div class="card">
<div class="card-header">账户余额</div>
<div class="balance">¥ 8,520.00</div>
<div class="summary">
<div class="summary-item">
<div class="title">收入</div>
<div class="amount">¥ 12,000.00</div>
<div class="percent up">+15% ↑</div>
</div>
<div class="summary-item">
<div class="title">支出</div>
<div class="amount">¥ 3,480.00</div>
<div class="percent down">-5% ↓</div>
</div>
</div>
</div>
</body>
</html>
+6
View File
@@ -856,6 +856,12 @@ const #componentName#: FunctionComponent<Props> = ({
export default React.memo(#componentName#);
```
生成图标命令:
```bash
npx iconfont-rn
```
## 配置深度链接