3-店铺首页预览 + mallApp 商城首页 实现计划.md 12 KB


name: mallApp店铺首页与hdApp预览 overview: 在 huahuibao 后端新增一个"首页展示数据组装"共享类,供 app-mall(真实店铺首页)与 app-hd(预览接口)共用;在 mallApp 中实现真正的店铺首页页面(挂到现有空壳 pages/home/index.vue,并把"进入店铺"入口指向它);在 hdApp 中实现与之视觉一致的预览页面,接入 index.vue 的"预览"按钮;同时给秒杀/团购/热门推荐/今日上新/下拉商品补充"排列规则"(1排1/2/3列)配置项,并统一店铺首页相关 UI 为粉红色调。 todos:

  • id: backend-layoutcols content: HomePageModuleClass 新增 layoutCols 字段与校验(seckill/groupBuy/goodsSection) status: pending
  • id: backend-resolve-goods content: 新增 resolveDisplayGoods 方法解析 type/value/sort 为真实商品列表 status: pending
  • id: backend-display-class content: 新建 HomePageDisplayClass,迁移 format* 方法并新增 buildHome/formatGoodsSection status: pending
  • id: backend-mall-controller content: 重构 app-mall HomePageConfigController 使用 HomePageDisplayClass status: pending
  • id: backend-hd-preview-api content: app-hd HomePageConfigController 新增 actionGetHome 预览接口 status: pending
  • id: hd-layoutcols-ui content: hdApp 的 seckill/groupBuy/goodsSection 页面新增排列规则单选UI status: pending
  • id: hd-preview-page content: hdApp 新建 preview.vue 及 previewParts 子组件,接入 index.vue 预览按钮与 pages.json status: pending
  • id: mall-home-page content: mallApp 实现 pages/home/index.vue 店铺首页及 components/home/* 子组件 status: pending
  • id: mall-entry-redirect content: mallApp recent.vue 的进入店铺入口改为跳转新首页 status: pending
  • id: color-unify content: 统一 hdApp 预览与 mallApp 首页相关按钮/图标为粉红色调 status: pending isProject: false ---

店铺首页预览 + mallApp 商城首页 实现计划

背景与关键决策(已与用户确认)

  • mallApp 目前"进入店铺"(recent.vueenterShop/bug())跳转到花材选购页 /pages/item/itempages/home/index.vue 是已在 pages.json 注册为"首页"的空壳页面。决定:用 pages/home/index.vue 做真正的店铺首页,并把 enterShop/bug() 改为先跳店铺首页,首页内再链接到花材/分类页。
  • hdApp 与 mallApp 是两个独立项目,不能共享 Vue 组件。决定:后端新增一个统一的"首页数据组装"类,保证两端拿到的数据结构完全一致;前端在两个项目里各自实现一份视觉一致的展示页面(非 webview)。

一、后端改动(huahuibao)

1. biz-hd/homePageConfig/classes/HomePageModuleClass.php

  • seckillgroupBuy、以及 hot/new/pullGoodsgetGoodsSection/saveGoodsSection)的存储结构新增字段 layoutCols(取值 1|2|3,默认 3),并在对应 save* 方法中校验合法性(非法值 util::fail('排列规则无效'))。
  • 新增静态方法 resolveDisplayGoods($mainId, $type, $value, $sort, $limit = 20),用于把 hot/new/pullGoods 存的 type(2商品/3分类/4场景) + value(逗号ID) + sort(1自定义/2销量/3上新时间) 解析为真实商品列表:
    • type=2explode(',', value) 得到 goodsId,按该顺序 GoodsClass::getByIds($ids)
    • type=3GoodsCategoryClass::getAllByCondition(['cId'=>['in',$cIds],'delStatus'=>0], null, null, 'gId') 取商品ID,再 GoodsClass::getByIds
    • type=4:同上思路用 GoodsUseCaseClass::getAllByCondition(['useCaseId'=>['in',$ids]], null, null, 'goodsId')
    • sort=2actualSold+sold 降序,sort=3createTime 降序,sort=1 保持解析出的原始顺序。
    • 过滤 delStatus=0status=1(如有 masterId 字段则只取主规格),限制 $limit 条。
    • 返回精简字段:id,name,price,stock,cover,soldsold = actualSold+sold),封面沿用现有 OSS 拼接惯例(imgUtil::groupImg() + x-oss-process=image/resize,m_fill,h_700,w_700,参考 GoodsClass.php:528-538)。

2. 新建 biz-hd/homePageConfig/classes/HomePageDisplayClass.php

把当前 app-mall/controllers/HomePageConfigController.php 里的 formatBanner/formatNavGrid/formatActivity 三个私有方法搬到这里做成 public static,并新增:

  • formatGoodsSection($mainId, $moduleKey):读取 HomePageModuleClass::getGoodsSection,关闭时返回 goods=[];开启时调用 resolveDisplayGoods 补上 goods 列表(含 coverUrl)与 layoutCols
  • buildHome($mainId):一次性组装 modules/topNav/banner/navGrid/seckill/groupBuy/hot/new/pullGoods,内部分别调用上面的 format 方法,供 mall 端与 hd 预览共用同一份数据格式。

3. app-mall/controllers/HomePageConfigController.php

actionGetHome 及各单模块 action(get-banner/get-nav-grid/get-seckill/get-group-buy/get-hot/get-new/get-pull-goods)改为调用 HomePageDisplayClass 的对应方法,删除原来内联的 formatBanner/formatNavGrid/formatActivityget-hot/get-new/get-pull-goods 改为返回 formatGoodsSection 的结果(带真实商品列表,而非仅配置)。

4. app-hd/controllers/HomePageConfigController.php

新增 actionGetHome()(管理端,$mainId 取自登录态,非 guest),内部调用 HomePageDisplayClass::buildHome($this->mainId),返回与 mall 端一致的数据结构,供 hdApp 预览页使用。

5. common/components/oss.php / OSS 目录

无需新增目录(复用现有 uploads_home_banneruploads_home_nav)。

二、hdApp 前端改动

1. 排列规则 UI(新增,3 处)

  • seckill.vuegroupBuy.vue:在表单中加入"排列规则"单选(1排1列/1排2列/1排3列),form.layoutCols 默认 3,参考 navGrid.vue:60-69 的 radio-group 写法;保存时带上 layoutCols
  • goodsSection.vue(hot/new/pullGoods 共用):同样加入"排列规则"单选,form.layoutCols 默认 3,保存时带上。

2. 新增预览页面 admin/homePageConfig/preview.vue

  • 调用新的 getHomePreview()(对应 API 新增在 src/api/home-page-config/index.js,路由 /home-page-config/get-home)。
  • 只读渲染整页:顶部导航与搜索(店铺名+搜索框+客服图标)、轮播图(悬浮客服图标按 topNav.customerServiceEnabled 显隐)、静态公告条、金刚区(4/5列)、秒杀区、团购区、热门推荐、今日上新、下拉商品;商品图默认正方形,轮播图保持矩形。
  • 为便于维护,按区块拆成小组件放在 admin/homePageConfig/previewParts/topNav.vuebannerSwiper.vuenoticeBar.vuenavGrid.vueactivitySection.vue(秒杀/团购通用,按 layoutCols 渲染 1/2/3 列,含倒计时)、goodsSection.vue(热门/上新/下拉通用,按 layoutCols 渲染 1/2/3 列)。
  • 统一使用粉红色调(主色 #FF6B88,深色 #FF4D6D,浅底 #FFF3F5),替换掉这些新页面里原本可能沿用的绿色按钮/图标。

3. index.vue 接入预览

previewFn 由 Toast 占位改为 uni.navigateTo({ url: '/admin/homePageConfig/preview' })

4. pages.json

admin/homePageConfig 分包下新增 preview 页面路由。

三、mallApp 前端改动

1. 实现 pages/home/index.vue(当前为空壳)

  • 通过 account(shopId,来自 query 或 storage)调用 api/home-page-config/index.jsgetHome
  • 页面结构(自上而下,均按 modules 的顺序 + 各自 enabled 控制显隐):
    1. 顶部导航与搜索:店铺名(来自接口 merchantName)+ 搜索框(点击跳转商品搜索/花材页)+ 客服入口(按钮色取 searchBtnColor/searchFontColor)。
    2. 首页轮播图:复用现有 components/app-swiper.vue;右下角客服悬浮图标按 topNav.customerServiceEnabled 显隐,点击跳转 /pages/chat/chatPage(参考 goods/detail.vue:387-391eventChannel 用法)。
    3. 公告条:纯静态样式(无开关配置),仿照 ghsProduct.vue 的纵向 swiper 公告条结构自建一个简化版本(文案先写死或后续再接配置)。
    4. 金刚区导航:按 cols(4/5)渲染图标网格。
    5. 秒杀专区 / 团购专区:倒计时 + 按 layoutCols(1/2/3) 渲染商品,按钮分别为"立即抢购"/"去开团"(均为粉色主色)。
    6. 热门推荐 / 今日上新:按 layoutCols(1/2/3) 渲染,"+"/购物车按钮改为粉色。
    7. 下拉商品:追加在页面底部,同样按 layoutCols 渲染。
  • 建议拆成 components/home/ 下的子组件(topNav.vue/bannerSwiper.vue/noticeBar.vue/navGrid.vue/activitySection.vue/goodsSection.vue),与 hdApp 预览页保持一致的视觉规范但各自独立实现(两项目不共享代码)。
  • 商品图默认正方形(aspectFill),轮播图保持矩形;跳转商品详情用 /pages/item/detail?id=..&account=..;金刚区/更多点击分类类简单跳 /pages/home/category?...,非分类类型(如场景/商品聚合)先给出简化跳转或提示,不在本次深入打通全链路点击跳转。

2. recent.vue 入口调整

bug(item)(被 enterShop 调用)里的目标地址由 /pages/item/item?account=...&hdId=... 改为 /pages/home/index?account=...&hdId=...,其余跳转(hs分类、tj相册等)保持不变。

3. 颜色统一

新页面/组件统一使用与 hdApp 预览一致的粉红主色(#FF6B88/#FF4D6D/浅底 #FFF3F5),替换参考图里出现的绿色按钮(如"去开团""+"购物车图标)。

四、涉及文件一览

五、验证方式

因无法在本环境运行小程序/App 真机预览,将通过:静态检查各 Vue 文件语法、核对接口字段与前端使用是否一致、以及(如可行)用现有 /scripts/db_struct.sh 或直接读 Redis 校验保存的 layoutCols 字段格式。不涉及自动化 UI 测试。