文档目录
商品页面模块

简介

本模块面向DouPHP小程序的商品页面,覆盖商品列表页、商品分类页与商品详情页的完整实现。重点说明:

  • 商品数据的获取、展示与交互逻辑
  • 列表筛选与排序(按价格、销量、评分等维度)及关键词搜索能力
  • 详情页图片轮播、规格选择(SKU管理)、库存显示、价格计算
  • 性能优化策略(图片懒加载、分页加载、数据缓存)
  • 完整的页面开发示例(API调用、收藏、分享)
  • 常见问题解决方案(图片加载失败、库存实时更新、价格变动同步)

项目结构

小程序端采用多主题结构(default、company),商品相关页面位于 miniprogram//pages/product;后端API控制器位于 api/controller/product;路由定义在 api/route/product.php;业务服务在前端服务层 front/service/product/ProductService.php。

graph TB
subgraph "小程序端"
PList["商品分类页<br/>product_category.ts"]
PDetail["商品详情页<br/>product.ts"]
end
subgraph "API层"
R["路由<br/>api/route/product.php"]
C["控制器<br/>ProductController.php"]
end
subgraph "服务层"
S["产品服务<br/>ProductService.php"]
end
PList --> R --> C --> S
PDetail --> R --> C --> S

核心组件

  • 商品列表/分类页(product_category.ts)
    • 负责分类树切换、品牌过滤、排序维度(by/sort)、分页加载、分享标题设置
    • 通过 product API 拉取商品列表、分类树、排序选项与当前分类信息
  • 商品详情页(product.ts)
    • 负责商品详情加载、图片轮播、规格选择(SKU)、评论分页、收藏、优惠券领取、加入购物车/立即购买、分享
    • 通过 product.show 与 product.attribute_list 接口获取详情与规格数据
  • 后端控制器(ProductController.php)
    • index:商品列表(支持分类、品牌、排序、分页、归档时间)
    • show:商品详情(含是否开启订单功能、优惠券列表)
    • attribute_list:根据已选规格动态返回可选属性、价格、库存等

架构总览

小程序页面通过统一HTTP客户端调用API路由,路由将请求分发至ProductController对应方法,控制器调用前端服务层进行数据组装与业务处理,最终返回JSON给小程序渲染。

sequenceDiagram
participant U as "用户"
participant M as "小程序页面<br/>product.ts / product_category.ts"
participant H as "HTTP客户端"
participant R as "API路由<br/>product.php"
participant C as "控制器<br/>ProductController.php"
participant S as "服务层<br/>ProductService.php"
U->>M : 打开商品列表/详情
M->>H : 发起GET/POST请求
H->>R : 路由匹配
R->>C : 调用index/show/attribute_list
C->>S : 构建数据列表/详情/SKU
S-->>C : 返回结构化数据
C-->>H : ApiResponse : : success(...)
H-->>M : 解析并更新UI

详细组件分析

商品分类页(列表)

  • 功能要点
    • 分类树切换:点击左侧分类项刷新右侧列表
    • 品牌过滤:支持 brand_id 参数
    • 排序:by/sort 控制排序维度与方向
    • 分页:onReachBottom 触发下一页加载
    • 分享:设置 shareTitle 为当前分类标题
  • 关键流程
    • onLoad/onShow 初始化并加载数据
    • loadData 调用 product 接口,传入 category_id、brand_id、by、sort、page
    • 下拉刷新与上拉加载更多
flowchart TD
Start(["进入商品分类页"]) --> Init["初始化参数<br/>category_id, brand_id"]
Init --> Load["loadData() 请求 product 接口"]
Load --> Data{"返回数据?"}
Data -- 否 --> Error["提示错误并停止加载"]
Data -- 是 --> Render["渲染列表/分类树/排序选项"]
Render --> Sort{"用户点击排序?"}
Sort -- 是 --> Reset["重置页码=1, nomore=false"] --> Load
Sort -- 否 --> More{"触底加载更多?"}
More -- 是 --> NextPage["page+1"] --> Load
More -- 否 --> End(["结束"])

商品详情页

  • 功能要点
    • 详情加载:product.show 返回商品基础信息、是否开启订单、优惠券列表
    • 规格选择:product.attribute_list 根据已选属性动态返回可选属性、价格、库存、SKU盒信息
    • 图片轮播:swiper 自动播放与手动切换,监听 imageLoad 计算高度避免抖动
    • 评论分页:comment.list 支持拼接加载
    • 收藏:favorites.user.store 切换收藏状态
    • 购物车/购买:order.cart.store 支持加入购物车或立即购买
    • 分享:设置分享标题
  • 关键流程
sequenceDiagram
participant P as "详情页<br/>product.ts"
participant A as "API : product.show"
participant B as "API : product.attribute_list"
participant F as "API : favorites.user.store"
participant O as "API : order.cart.store"
P->>A : GET 商品详情(id)
A-->>P : 返回商品数据/开关/优惠券
P->>B : GET 规格属性(含已选attribute_data)
B-->>P : 返回attribute_list/box(价格/库存/SKU)
P->>F : POST 收藏(可取消)
F-->>P : 返回最新收藏状态
P->>O : POST 加入购物车/立即购买
O-->>P : 跳转结算或购物车

后端控制器与数据构建

  • index(商品列表)
    • 接收 id/category_slug、year/month(归档)、brand_id、by、sort、page
    • 使用 ProductService.buildProductListData 构建列表数据,包含分页、排序、分类树、标题等
  • show(商品详情)
    • 校验id后调用 buildProductShowData,返回商品详情、开关配置、优惠券列表
  • attribute_list(规格属性)
    • 解析 attribute_data,调用 buildApiAttributeData 返回可选属性、价格、库存、SKU盒等信息
classDiagram
class ProductController {
+index(request)
+show(request)
+attributeList(request)
-buildProductCategoryInfo(catId)
}
class FrontProductService {
+buildProductListData(...)
+buildProductShowData(...)
+buildApiAttributeData(...)
+findCategoryById(...)
}
ProductController --> FrontProductService : "依赖"

依赖关系分析

  • 小程序页面依赖
    • HTTP客户端 services/http.js
    • 路由工具 utils/route.js
    • 全局状态 stores/commonStore(features、site、lang等)
    • 认证 stores/authStore(登录态检查)
  • API层依赖
    • 路由 api/route/product.php 映射到 ProductController
    • 控制器依赖前端服务层 front/service/product/ProductService.php
  • 外部模块
    • 优惠券模块(coupon):在详情中提供可用优惠券列表
    • 收藏模块(favorites):收藏/取消收藏
graph LR
M["小程序页面"] --> H["http.js"]
M --> R["route.js"]
M --> S["stores/*"]
H --> API["/api/product/*"]
API --> CTRL["ProductController"]
CTRL --> SVC["FrontProductService"]
CTRL --> MOD["Coupon/Favorites 模块"]

性能考虑

  • 图片懒加载
    • 详情页监听 imageLoad 计算高度,避免大图导致布局抖动;建议结合小程序原生 lazy-load 与缩略图策略
  • 分页加载
    • 列表与评论均实现 onReachBottom 分页加载,减少首屏数据量
  • 数据缓存
    • 使用 wx.setStorageSync 缓存分享标题、购买模式等轻量数据;对分类树、排序选项等可考虑本地缓存提升二次打开速度
  • 网络优化
    • 合理拆分请求:详情与规格属性分离,按需加载;对频繁访问的分类/品牌结果做短期缓存
  • 渲染优化
    • 列表项使用虚拟滚动或分页;图片尺寸统一,避免重排

故障排查指南

  • 图片加载失败
    • 现象:详情页图片不显示或占位异常
    • 排查:检查图片URL有效性、CDN可达性;确认 imageLoad 回调是否正确计算高度;必要时降级显示占位图
  • 库存实时更新
    • 现象:选择规格后库存未变化或显示不一致
    • 排查:确认 attribute_list 返回的 box/attribute_list 包含最新库存;检查 selectAttribute 是否正确更新 attribute_data_box 并重新请求
  • 价格变动同步
    • 现象:切换规格后价格未更新
    • 排查:确保 attribute_list 返回的价格字段正确绑定;检查前端是否重复使用旧数据或未刷新
  • 收藏状态不同步
    • 现象:收藏按钮状态与实际不符
    • 排查:确认 favorites.user.store 返回的 favorites 对象已更新到 data;检查登录态是否正常
  • 评论分页卡顿
    • 现象:加载更多无响应或重复加载
    • 排查:检查 loadpage 标志位与 nomore 状态;确保 onReachBottom 节流有效

结论

本模块以小程序页面与后端控制器/服务分层清晰的方式实现了商品列表、分类与详情页的核心能力。通过统一的API与模块化服务,支撑了筛选排序、规格选择、库存与价格联动、收藏与分享等功能。建议在现有基础上进一步完善图片懒加载、数据缓存与错误重试机制,以提升用户体验与系统稳定性。

附录:接口与示例

  • 商品列表接口
    • 路径:/api/product
    • 方法:GET
    • 参数:category_id、brand_id、by、sort、page、year、month
    • 返回:product_list、product_category、sort_list、cate_info、title、category_id
    • 参考:ProductController.php:48-84
  • 商品详情接口
    • 路径:/api/product/show
    • 方法:GET
    • 参数:id、category_slug、slug
    • 返回:product、defined、open、coupon_list
    • 参考:ProductController.php:87-113
  • 规格属性接口
    • 路径:/api/product/attribute_list
    • 方法:GET
    • 参数:id、mode、attribute_data
    • 返回:attribute_list、box
    • 参考:ProductController.php:116-137
  • 收藏接口
    • 路径:/api/favorites/user/store
    • 方法:POST
    • 参数:module、item_id
    • 返回:favorites、__message
    • 参考:product.ts(默认主题):210-229
  • 购物车/购买接口
    • 路径:/api/order/cart.store
    • 方法:POST
    • 参数:post(JSON字符串)、mode、action
    • 返回:mode、跳转指示
    • 参考:product.ts(默认主题):101-128
添加日期:2026-10-05