hdApp首页商品区自动排列-2.md 7.7 KB


name: hdApp首页商品区自动排列 overview: 在 hdApp 后台"热门推荐/今日上新/下拉商品"配置页隐藏"排列规则"与"商品展示数量"字段,改为后端按已添加商品真实数量自动推导列数与展示条数,并据此驱动 mallApp 店铺首页的展示效果与"更多"链接。 todos:

  • id: backend-layout-helper content: "HomePageModuleClass.php: 移除 saveGoodsSection/getGoodsSection 中的 layoutCols/displayCount,新增 resolveGoodsSectionLayout,删除废弃的 normalizeDisplayCount" status: completed
  • id: backend-display-format content: "HomePageDisplayClass.php: 重写 formatGoodsSection,按真实商品总数与 moduleKey 自动推导 layoutCols 并截断/不截断" status: completed
  • id: frontend-goods-section content: "hdApp goodsSection.vue: 删除排列规则与商品展示数量的表单 UI、数据字段与提交参数" status: completed

    isProject: false

    计划需求指令:

    项目:hdApp 页面:hdApp/src/admin/homePageConfig/hot.vue 、hdApp/src/admin/homePageConfig/new.vue 与 hdApp/src/admin/homePageConfig/pullGoods.vue 需求:

  • 隐藏(或删除)商品展示数量,按照下面2的规则进行自动设置展示数量

  • 把 hdApp/src/admin/homePageConfig/hot.vue 页面下的“排列规则”删除掉(或隐藏),使用如下隐藏规则:

    1. 当只添加了一个商品时,按1排1列来展示
    2. 当只添加了两个商品时,按1排2列来展示
    3. 当添加了三个及以上商品时,按1排3列来展示且把展示数量设置为3个。当添加商品数量超出3个时,那么mallApp下的店铺首页的热门推荐的右上角要显示“更多”链接。
    • hdApp/src/admin/homePageConfig/new.vue 页面也做以上同样的处理。
    • hdApp/src/admin/homePageConfig/pullGoods.vue 页面下的商品展示数量隐藏(或删除),“排列规则”删除掉(或隐藏),使用如下隐藏规则:
    • 当只添加了一个商品时,按1排1列来展示
    • 当只添加了两个商品时,按1排2列来展示
    • 当添加了三个及以上商品时,还是按1排2列来展示(且把展示数量设置为全部x),且在mallApp下的店铺首页的下拉商品中把所有的商品都展示。由于全部商品都显示了,右上角没有“更多”链接。

背景

hdApp/src/admin/homePageConfig/hot.vuenew.vuepullGoods.vue 都只是薄壳组件,实际表单在共用组件 goodsSection.vue 里(通过 module-key 区分 hot/new/pullGoods)。当前该组件里有"排列规则"(form.layoutCols) 和"商品展示数量"(form.displayCount) 两个可手动配置的字段,保存后由后端 Redis 存储,mallApp 首页读取 layoutCols 决定列数,用 goodsTotal > goods.length 决定是否显示"更多"。

代码库里秒杀/团购模块(HomePageModuleClass.php 中的 resolveActivityLayout)已经是完全相同的模式:不让商家手动配置排列规则,而是在读取时按已添加商品数量自动推导 layoutCols/displayCount。本次改造对热门/上新/下拉商品复用同样的思路。

规则设计

新增 HomePageModuleClass::resolveGoodsSectionLayout($goodsTotal, $moduleKey)

  • goodsTotal <= 1layoutCols=1displayCount=0(全部,即1个)
  • goodsTotal == 2layoutCols=2displayCount=0(全部,即2个)
  • goodsTotal >= 3
    • moduleKey === 'pullGoods'layoutCols=2displayCount=0(不截断,全部展示)
    • 否则(hot / new)→ layoutCols=3displayCount=3(截断为3个)

goodsTotal 取的是关联配置(商品/分类/场景)实际解析出的真实商品数,而不是后台勾选的 ID 个数,这样分类/场景关联同样能正确套用规则。

displayCount=0 语义在这里表示"不截断,展示全部已解析商品";配合 mallApp 已有的 showMore = goodsTotal > goods.length 判断:

  • hot/new 超过3个时会被截断为3个 → goodsTotal > 3 → 自动显示"更多"
  • pullGoods 不截断 → goodsTotal === goods.length → 永远不显示"更多"

mallApp 端 components/home/goodsSection.vuecols/showMore 逻辑已经是通用实现,无需改动

后端改动(huahuibao)

biz-hd/homePageConfig/classes/HomePageModuleClass.php

  1. saveGoodsSection():删除对 layoutCols/displayCount 的读取、校验与持久化,Redis 只再存 name/type/value/sort
  2. getGoodsSection():返回结构去掉 layoutCols/displayCount(不再持久化,也不需要预填到编辑表单)。
  3. 新增 resolveGoodsSectionLayout($goodsTotal, $moduleKey)(规则见上)。
  4. 删除已不再被调用的 normalizeDisplayCount()(原本只服务于 saveGoodsSection 里的展示数量校验)。resolveHomeDisplayLimit() 继续保留给秒杀/团购使用,不受影响。

biz-hd/homePageConfig/classes/HomePageDisplayClass.php

重写 formatGoodsSection($mainId, $moduleKey)

public static function formatGoodsSection($mainId, $moduleKey)
{
    $data = HomePageModuleClass::getGoodsSection($mainId, $moduleKey);
    if (empty($data['enabled'])) {
        $data['goods'] = [];
        $data['goodsTotal'] = 0;
        $data['layoutCols'] = 1;
        return $data;
    }
    $rows = HomePageModuleClass::matchGoodsRows($mainId, $data['type'], $data['value'], $data['sort']);
    $total = count($rows);
    $layout = HomePageModuleClass::resolveGoodsSectionLayout($total, $moduleKey);
    $data['layoutCols'] = $layout['layoutCols'];
    if ($layout['displayCount'] > 0 && $layout['displayCount'] < $total) {
        $rows = array_slice($rows, 0, $layout['displayCount']);
    }
    $data['goods'] = HomePageModuleClass::formatGoodsRows($rows);
    $data['goodsTotal'] = $total;
    return $data;
}

getSectionGoodsPage()("更多"分页列表接口)不受影响,继续按 page/pageSize 分页返回全部真实商品。

app-hd/app-mallHomePageConfigController 无需改动,它们只是调用上述两个类的方法。

前端改动(front-end)

hdApp/src/admin/homePageConfig/goodsSection.vue

  1. 删除模板中"排列规则"整块(radio-row + layoutColsOptions,约115-128行)。
  2. 删除模板中"商品展示数量"整块(count-input + hint,约130-141行)。
  3. data()form 去掉 layoutColsdisplayCount 两个字段;删除 layoutColsOptions
  4. 删除 parseDisplayCount() 方法。
  5. init() 里不再从接口返回值回填 layoutCols/displayCount
  6. saveFn() 里的 saveApi() 调用去掉 layoutColsdisplayCount 两个字段(同时去掉 parseDisplayCount() 的调用与其失败提前 return 的判断)。

hot.vue/new.vue/pullGoods.vue 三个壳页面本身不需要改动(它们只是传入不同 module-key)。

previewParts/goodsSection.vue(hd 后台预览组件)和 mallApp 的 components/home/goodsSection.vue 都是纯读取 data.layoutCols/data.goodsTotal/data.goods,无需改动,会自动反映后端新算出的值。

影响范围确认

  • 不改动秒杀 (seckill.vue)、团购 (groupBuy.vue) 相关逻辑(它们已有独立的 resolveActivityLayout/expand 机制,未在本次需求范围内)。
  • 不改动 ad-goods-select.vue(商品选择页),商品数量本身没有上限限制,规则要求未提及需要新增上限。