mi
This commit is contained in:
110
miniprogram/src/pages/index/index.tsx
Normal file
110
miniprogram/src/pages/index/index.tsx
Normal file
@@ -0,0 +1,110 @@
|
||||
import { View, Text, Image, ScrollView, Button } from '@tarojs/components'
|
||||
import Taro, { useLoad } from '@tarojs/taro'
|
||||
import { useState, useEffect } from 'react'
|
||||
import { getConfigs } from '../../api'
|
||||
import './index.scss'
|
||||
|
||||
export default function Index() {
|
||||
const [products, setProducts] = useState<any[]>([])
|
||||
const [typedText, setTypedText] = useState('')
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [error, setError] = useState('')
|
||||
const fullText = "未来已来 AI 核心驱动"
|
||||
|
||||
useLoad(() => {
|
||||
fetchProducts()
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
let i = 0
|
||||
const interval = setInterval(() => {
|
||||
i++
|
||||
setTypedText(fullText.slice(0, i))
|
||||
if (i >= fullText.length) clearInterval(interval)
|
||||
}, 150)
|
||||
return () => clearInterval(interval)
|
||||
}, [])
|
||||
|
||||
const fetchProducts = async () => {
|
||||
setLoading(true)
|
||||
setError('')
|
||||
try {
|
||||
const res: any = await getConfigs()
|
||||
console.log('Configs fetched:', res)
|
||||
// Adapt to different API response structures
|
||||
const list = Array.isArray(res) ? res : (res.results || res.data || [])
|
||||
setProducts(list)
|
||||
} catch (err: any) {
|
||||
console.error('Fetch error:', err)
|
||||
setError(err.errMsg || '加载失败,请检查网络')
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
const goToDetail = (id: number) => {
|
||||
Taro.navigateTo({ url: `/pages/goods/detail?id=${id}` })
|
||||
}
|
||||
|
||||
return (
|
||||
<View className='page-container'>
|
||||
<View className='header'>
|
||||
<View className='logo-box'>
|
||||
<Text className='logo-text'>QUANT SPEED</Text>
|
||||
</View>
|
||||
|
||||
<View className='title-container'>
|
||||
<Text className='title-text'>{typedText}</Text>
|
||||
<Text className='cursor'>|</Text>
|
||||
</View>
|
||||
<Text className='subtitle'>量迹 AI 硬件为您提供最强大的边缘计算能力</Text>
|
||||
</View>
|
||||
|
||||
{loading ? (
|
||||
<View className='status-box'>
|
||||
<Text className='loading-text'>正在加载硬件配置...</Text>
|
||||
</View>
|
||||
) : error ? (
|
||||
<View className='status-box'>
|
||||
<Text className='error-text'>{error}</Text>
|
||||
<Button className='btn-retry' onClick={fetchProducts}>重试</Button>
|
||||
</View>
|
||||
) : products.length === 0 ? (
|
||||
<View className='status-box'>
|
||||
<Text className='empty-text'>暂无硬件产品</Text>
|
||||
</View>
|
||||
) : (
|
||||
<ScrollView scrollX className='product-scroll' enableFlex>
|
||||
<View className='product-list'>
|
||||
{products.map((item) => (
|
||||
<View key={item.id} className='card' onClick={() => goToDetail(item.id)}>
|
||||
<View className='card-cover'>
|
||||
{item.static_image_url ? (
|
||||
<Image src={item.static_image_url} mode='aspectFill' className='card-img' />
|
||||
) : (
|
||||
<View className='placeholder-img'>
|
||||
<Text className='icon-rocket'>🚀</Text>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
<View className='card-body'>
|
||||
<Text className='card-title'>{item.name}</Text>
|
||||
<Text className='card-desc'>{item.description}</Text>
|
||||
<View className='tags'>
|
||||
<View className='tag cyan'><Text>{item.chip_type}</Text></View>
|
||||
{item.has_camera && <View className='tag blue'><Text>Camera</Text></View>}
|
||||
{item.has_microphone && <View className='tag purple'><Text>Mic</Text></View>}
|
||||
</View>
|
||||
<View className='card-footer'>
|
||||
<Text className='price'>¥{item.price}</Text>
|
||||
<View className='btn-arrow'><Text>→</Text></View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
</ScrollView>
|
||||
)}
|
||||
</View>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user