first commit

This commit is contained in:
2026-07-27 14:54:21 +08:00
commit 4d086758e8
161 changed files with 63776 additions and 0 deletions
+4
View File
@@ -0,0 +1,4 @@
{
"navigationBarTitleText": "智绘微刻",
"usingComponents": {}
}
+211
View File
@@ -0,0 +1,211 @@
.index-page {
padding: 0 24px 24px;
}
/* 顶部标题栏 */
.header-bar {
padding: 20px 0 16px;
display: flex;
align-items: center;
}
.header-title {
font-size: 48px;
font-weight: 800;
color: #5c3a3a;
letter-spacing: 4px;
}
/* 搜索框卡片 */
.search-card {
padding: 20px 24px;
}
.search-inner {
display: flex;
align-items: center;
background: #f8f9fa;
border-radius: 40px;
padding: 16px 24px;
}
.search-icon {
font-size: 28px;
margin-right: 16px;
}
.search-input {
flex: 1;
font-size: 28px;
color: #5c3a3a;
background: transparent;
border: none;
outline: none;
}
.search-input::placeholder {
color: #b08d8d;
font-size: 26px;
}
.search-result-hint {
margin-top: 16px;
padding-top: 16px;
border-top: 2px dashed #eee;
}
.hint-text {
font-size: 24px;
color: #b08d8d;
}
/* 成品展示轮播 */
.showcase-section {
margin-top: 20px;
}
.showcase-swiper {
height: 460rpx;
}
.showcase-swiper-item {
display: flex;
align-items: center;
justify-content: center;
padding: 0 10rpx;
box-sizing: border-box;
}
.showcase-swiper-card {
width: 100%;
height: 100%;
padding: 20px;
display: flex;
flex-direction: column;
align-items: center;
position: relative;
box-sizing: border-box;
overflow: hidden;
}
.showcase-image-wrapper {
width: 100%;
height: 240rpx;
border-radius: 16px;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 16px;
}
.showcase-emoji {
font-size: 80px;
}
.showcase-info {
text-align: center;
}
.showcase-info .showcase-title {
font-size: 32px;
font-weight: 700;
color: #5c3a3a;
display: block;
margin-bottom: 8px;
}
.showcase-info .showcase-desc {
font-size: 24px;
color: #b08d8d;
display: block;
}
.showcase-tag {
position: absolute;
top: 16px;
right: 16px;
background: rgba(255, 154, 158, 0.15);
color: #ff6b81;
font-size: 20px;
padding: 4px 16px;
border-radius: 20px;
font-weight: 500;
}
/* 热门品类 */
.category-section {
margin-top: 20px;
}
.category-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
}
.category-item {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
padding: 32px 20px;
transition: transform 0.2s;
}
.category-item:active {
transform: scale(0.96);
}
.category-icon {
font-size: 56px;
margin-bottom: 12px;
}
.category-icon-img {
width: 120px;
height: 120px;
object-fit: contain;
margin-bottom: 12px;
}
.category-name {
font-size: 28px;
font-weight: 700;
color: #5c3a3a;
margin-bottom: 8px;
}
.category-desc {
font-size: 22px;
color: #b08d8d;
}
/* 空状态 */
.empty-category {
display: flex;
flex-direction: column;
align-items: center;
padding: 60px 40px;
text-align: center;
}
.empty-icon {
font-size: 64px;
margin-bottom: 16px;
}
.empty-text {
font-size: 30px;
font-weight: 600;
color: #5c3a3a;
margin-bottom: 8px;
}
.empty-sub {
font-size: 24px;
color: #b08d8d;
}
/* 底部安全区 */
.safe-bottom-placeholder {
height: 160px;
}
+143
View File
@@ -0,0 +1,143 @@
import { View, Text, Swiper, SwiperItem, Input, Image } from '@tarojs/components'
import Taro from '@tarojs/taro'
import { useState } from 'react'
import './index.scss'
import { CATEGORIES } from '../../utils/productConfig'
import ThemeToggle from '../../components/ThemeToggle'
import { useThemeContext } from '../../context/ThemeContext'
// 成品展示数据
const SHOWCASES = [
{ title: '毕业纪念笔记本', desc: '全班名字组成校徽', color: '#FFE4EC' },
{ title: '铜质杯垫', desc: '金属质感桌面艺术', color: '#E8D5C4' },
{ title: '竹制笔盒', desc: '自然竹纹文房雅器', color: '#E0F0D9' },
{ title: '书本型灯', desc: '温暖光影点亮心意', color: '#FFF3CD' },
{ title: '情侣定制礼', desc: '两个人的名字交织', color: '#FCE4EC' },
{ title: '企业年会礼', desc: '员工名字组成Logo', color: '#E3F2FD' }
]
export default function Index() {
const { theme } = useThemeContext()
const [searchKey, setSearchKey] = useState('')
const navigateToProduct = (categoryId: string) => {
Taro.navigateTo({ url: `/pages/product/index?id=${categoryId}` })
}
const filteredCategories = searchKey.trim()
? CATEGORIES.filter(
(c) => c.name.includes(searchKey) || c.desc.includes(searchKey)
)
: CATEGORIES
const handleSearch = (e: any) => {
setSearchKey(e.detail.value)
}
return (
<View className={`theme-${theme}`}>
<View className='index-page'>
<ThemeToggle />
{/* 顶部标题栏 */}
<View className='header-bar'>
<Text className='header-title'></Text>
</View>
{/* 搜索框 */}
<View className='search-card dashed-card'>
<View className='star-badge' />
<View className='search-inner'>
<Text className='search-icon'>🔍</Text>
<Input
className='search-input'
type='text'
placeholder='搜索定制品类:笔记本、杯垫、书灯...'
value={searchKey}
onInput={handleSearch}
confirmType='search'
/>
</View>
{searchKey.trim() && (
<View className='search-result-hint'>
<Text className='hint-text'>
{filteredCategories.length > 0
? `找到 ${filteredCategories.length} 个相关品类`
: '没有找到相关品类,试试看其他关键词'}
</Text>
</View>
)}
</View>
{/* 成品展示轮播 */}
<View className='showcase-section mt-20'>
<Text className='section-title'></Text>
<Swiper
className='showcase-swiper'
indicatorColor='#e0e0e0'
indicatorActiveColor='#ff9a9e'
circular
autoplay
interval={3000}
duration={500}
previousMargin='40rpx'
nextMargin='40rpx'
indicatorDots
>
{SHOWCASES.map((item, idx) => (
<SwiperItem key={idx} className='showcase-swiper-item'>
<View className='showcase-swiper-card dashed-card'>
<View className='star-badge' />
<View
className='showcase-image-wrapper'
style={{ background: item.color }}
>
<Text className='showcase-emoji'>🎁</Text>
</View>
<View className='showcase-info'>
<Text className='showcase-title'>{item.title}</Text>
<Text className='showcase-desc'>{item.desc}</Text>
</View>
<View className='showcase-tag'></View>
</View>
</SwiperItem>
))}
</Swiper>
</View>
{/* 热门品类 */}
<View className='category-section mt-20'>
<Text className='section-title'></Text>
<View className='category-grid'>
{filteredCategories.map((cat) => (
<View
key={cat.id}
className='category-item dashed-card'
onClick={() => navigateToProduct(cat.id)}
>
<View className='star-badge' />
{cat.images && cat.images.length > 0 ? (
<Image className='category-icon-img' src={cat.images[0]} mode='aspectFit' />
) : (
<Text className='category-icon'>{cat.icon}</Text>
)}
<Text className='category-name'>{cat.name}</Text>
<Text className='category-desc'>{cat.desc}</Text>
<Text className='category-price'>¥{cat.price} </Text>
</View>
))}
</View>
{filteredCategories.length === 0 && (
<View className='empty-category dashed-card'>
<Text className='empty-icon'>🔍</Text>
<Text className='empty-text'></Text>
<Text className='empty-sub'></Text>
</View>
)}
</View>
<View className='safe-bottom-placeholder' />
</View>
</View>
)
}