001.004.homepage-ui-refactor.md 10 KB

Story 001.004: homepage-ui-refactor

Status

Draft

Story

As a 小程序用户, I want 看到与tcb-shop-demo设计一致的现代化首页UI, so that 我能获得更好的视觉体验和更直观的商品浏览体验

Acceptance Criteria

  1. 首页UI结构与tcb-shop-demo一致,包含搜索栏、轮播图、商品列表区域
  2. 样式遵循tcb-shop-demo的设计规范,包括渐变背景、圆角搜索框等
  3. 商品卡片布局与tcb-shop-demo一致,包含图片、标题、价格、购物车按钮
  4. 使用已集成的tcb-theme.css主题变量和样式系统
  5. 保持与现有TabBarLayout的兼容性

Tasks / Subtasks

  • 创建TDesign组件库 (AC: 1, 5)
    • 创建Taro React版本的TDesign组件
    • 创建 mini/src/components/tdesign/search/index.tsx - Search组件 (对照: mini/tdesign/search/)
    • 创建 mini/src/components/tdesign/swiper/index.tsx - Swiper组件 (对照: mini/tdesign/swiper/)
    • 创建 mini/src/components/tdesign/icon/index.tsx - Icon组件 (对照: mini/tdesign/icon/)
    • 创建 mini/src/components/tdesign/toast/index.tsx - Toast组件 (对照: mini/tdesign/toast/)
    • 创建 mini/src/components/tdesign/tabs/index.tsx - Tabs组件 (对照: mini/tdesign/tabs/)
  • 实现商品卡片组件 (AC: 3)
    • 创建 mini/src/components/goods-card/index.tsx 商品卡片组件
    • 参照 tcb-shop-demo/components/goods-card/index.wxml 实现商品卡片布局
    • 实现图片、标题、价格、购物车按钮布局
    • 应用tcb-shop-demo的商品卡片样式
  • 实现商品列表组件 (AC: 1)
    • 创建 mini/src/components/goods-list/index.tsx 商品列表组件
    • 参照 tcb-shop-demo/components/goods-list/index.wxml 实现列表结构
    • 实现瀑布流布局
    • 集成商品卡片组件
  • 创建首页组件结构 (AC: 1)
    • 创建 mini/src/pages/index/index.tsx 首页组件
    • 参照 tcb-shop-demo/pages/home/home.wxml 实现页面结构
    • 集成搜索栏组件(带搜索图标,禁用状态)
    • 集成轮播图组件(自动播放,导航指示器)
    • 集成商品列表组件
    • 添加加载状态和下拉刷新功能
  • 应用tcb-shop-demo样式系统 (AC: 2, 4)
    • 应用渐变背景色(#fff 到 #f5f5f5)
    • 应用圆角搜索框样式(32rpx)
    • 应用商品卡片间距和布局
    • 应用主色调(#fa550f, #fa4126)
  • 集成TDesign组件到首页 (AC: 1, 5)
    • 使用TDesign search组件实现搜索栏
    • 在首页组件中导入自定义Search组件
    • 配置搜索栏属性:placeholder、disabled、shape等
    • 应用tcb-shop-demo的搜索栏样式(圆角32rpx,高度64rpx)
    • 使用TDesign swiper组件实现轮播图
    • 在首页组件中导入自定义Swiper组件
    • 配置轮播图属性:autoplay、interval、indicatorDots等
    • 实现轮播图数据绑定和图片展示
    • 使用TDesign icon组件实现图标
    • 在首页组件中导入自定义Icon组件
    • 使用搜索图标、购物车图标等
    • 配置图标颜色和大小匹配tcb-shop-demo设计
    • 使用TDesign toast组件实现提示
    • 在首页组件中导入自定义Toast组件
    • 实现加载状态、成功提示、错误提示等
    • 配置Toast样式和位置
    • 使用TDesign tabs组件实现分类切换
    • 在首页组件中导入自定义Tabs组件
    • 配置分类数据源和切换逻辑
    • 实现分类切换时的商品列表更新
  • 测试和验证 (AC: 5)
    • 创建测试页面验证所有组件功能
    • 验证与现有TabBarLayout的兼容性
    • 验证样式系统正确应用
    • 验证响应式布局

Dev Notes

技术栈信息 [Source: architecture/tech-stack.md]

  • 前端框架: React 18.0.0
  • 小程序框架: Taro 4.1.4
  • 样式系统: Tailwind CSS + 自定义CSS (tcb-theme.css)
  • 组件库: 自定义Taro React组件 (基于TDesign设计规范)
  • 集成方式: 直接使用Taro React组件,无需原生组件集成

项目结构信息 [Source: architecture/source-tree.md]

  • 首页位置: mini/src/pages/index/index.tsx
  • 组件位置: mini/src/components/
  • TDesign组件: mini/src/components/tdesign/ (自定义React组件)
  • TDesign源文件: mini/tdesign/ (原生小程序组件,供参考)
  • 样式文件: mini/src/tcb-theme.css
  • 布局组件: mini/src/layouts/tab-bar-layout.tsx

对照文件路径

  • 页面结构: tcb-shop-demo/pages/home/home.wxml
  • 页面样式: tcb-shop-demo/pages/home/home.wxss
  • 页面逻辑: tcb-shop-demo/pages/home/home.js
  • 商品列表: tcb-shop-demo/components/goods-list/index.wxml
  • 商品卡片: tcb-shop-demo/components/goods-card/index.wxml
  • 商品卡片样式: tcb-shop-demo/components/goods-card/index.wxss

已集成的样式系统

  • 主题变量: 已在 mini/src/tcb-theme.css 中完整集成
  • 颜色系统: 语义化颜色类、层级颜色、背景色、边框色
  • 字体系统: 完整字体大小和字重系统
  • 布局工具类: Flex布局、间距系统、边框处理

设计规范

  • 渐变背景: linear-gradient(#fff, #f5f5f5)
  • 搜索框: 圆角32rpx,高度64rpx
  • 商品卡片: 图片+标题+价格+购物车按钮布局
  • 主色调: 搜索图标颜色、购物车按钮颜色、选中状态颜色使用 #fa550f 和 #fa4126

组件依赖

  • 自定义Taro React组件: TDesignSearch, TDesignSwiper, TDesignIcon, TDesignToast, TDesignTabs
  • 自定义组件: goods-list, goods-card, load-more

TDesign组件转写说明

1. 组件创建策略

  • 基于TDesign原生组件源码转写成Taro React组件
  • 保持TDesign的设计规范和交互体验
  • 使用React Hooks和Taro API实现功能
  • 应用tcb-shop-demo的主题样式

2. 组件实现示例

Search组件 (mini/src/components/tdesign/search/index.tsx)

import { useState } from 'react'
import { View, Input } from '@tarojs/components'
import TDesignIcon from '../icon'

interface SearchProps {
  placeholder?: string
  disabled?: boolean
  shape?: 'round' | 'square'
  value?: string
  onChange?: (value: string) => void
  onFocus?: () => void
  onBlur?: () => void
  onSubmit?: (value: string) => void
}

export default function TDesignSearch({
  placeholder = '搜索商品',
  disabled = false,
  shape = 'round',
  value = '',
  onChange,
  onFocus,
  onBlur,
  onSubmit
}: SearchProps) {
  const [focused, setFocused] = useState(false)

  const handleInput = (e) => {
    onChange?.(e.detail.value)
  }

  const handleFocus = () => {
    setFocused(true)
    onFocus?.()
  }

  const handleBlur = () => {
    setFocused(false)
    onBlur?.()
  }

  const handleConfirm = (e) => {
    onSubmit?.(e.detail.value)
  }

  return (
    <View className={`tdesign-search tdesign-search--${shape}`}>
      <View className={`tdesign-search__input-box ${focused ? 'tdesign-search__input-box--focused' : ''}`}>
        <TDesignIcon name="search" size="32rpx" color="#fa550f" />
        <Input
          type="text"
          placeholder={placeholder}
          disabled={disabled}
          value={value}
          onInput={handleInput}
          onFocus={handleFocus}
          onBlur={handleBlur}
          onConfirm={handleConfirm}
          className="tdesign-search__input"
        />
      </View>
    </View>
  )
}

Icon组件 (mini/src/components/tdesign/icon/index.tsx)

import { View } from '@tarojs/components'

interface IconProps {
  name: string
  size?: string
  color?: string
}

export default function TDesignIcon({ name, size = '32rpx', color = '#fa550f' }: IconProps) {
  return (
    <View
      className={`tdesign-icon tdesign-icon--${name}`}
      style={{ fontSize: size, color }}
    >
      {/* 使用Unicode或SVG图标 */}
    </View>
  )
}

Swiper组件 (mini/src/components/tdesign/swiper/index.tsx)

import { useState } from 'react'
import { Swiper, SwiperItem, Image } from '@tarojs/components'

interface SwiperProps {
  images: string[]
  autoplay?: boolean
  interval?: number
  indicatorDots?: boolean
}

export default function TDesignSwiper({
  images = [],
  autoplay = true,
  interval = 3000,
  indicatorDots = true
}: SwiperProps) {
  return (
    <Swiper
      className="tdesign-swiper"
      autoplay={autoplay}
      interval={interval}
      indicatorDots={indicatorDots}
      indicatorColor="#999"
      indicatorActiveColor="#fa550f"
    >
      {images.map((image, index) => (
        <SwiperItem key={index}>
          <Image src={image} mode="aspectFill" className="tdesign-swiper__image" />
        </SwiperItem>
      ))}
    </Swiper>
  )
}

3. 样式集成

  • 使用Tailwind CSS类名和自定义CSS
  • 应用tcb-theme.css中的主题变量
  • 保持与tcb-shop-demo设计的一致性
  • 使用标准的React className属性

Testing

测试标准 [基于mini项目配置]

  • 测试框架: Jest + Testing Library
  • 测试位置: tests/ 文件夹,按组件和页面组织
  • 测试命令:
    • npm test - 运行所有测试
    • npm run test:components - 运行组件测试
    • npm run test:pages - 运行页面测试
    • npm run test:coverage - 运行覆盖率测试
  • 覆盖率目标: 核心业务逻辑 > 80%
  • 测试类型: 单元测试、集成测试

测试要求

  • 为所有新组件在 tests/components/ 中创建单元测试
  • 为首页页面在 tests/pages/ 中创建集成测试
  • 验证组件渲染和交互功能
  • 测试样式类正确应用
  • 验证与现有TabBarLayout的兼容性
  • 使用Taro Mock模拟小程序API

Change Log

Date Version Description Author
2025-11-20 1.0 初始故事创建 Bob (Scrum Master)

Dev Agent Record

This section is populated by the development agent during implementation

Agent Model Used

Record the specific AI agent model and version used for development

Debug Log References

Reference any debug logs or traces generated during development

Completion Notes List

Notes about the completion of tasks and any issues encountered

File List

List all files created, modified, or affected during story implementation

QA Results

Results from QA Agent QA review of the completed story implementation