name: 首页模块商品展示数量与更多页 overview: 为 hdApp 门店首页配置的秒杀/团购/热门推荐/今日上新/下拉商品新增"商品展示数量"设置,mallApp 首页对应模块据此显示"更多"按钮并跳转到新建的模块商品列表页;同时移除秒杀/团购编辑页中冗余的"商品首页展开"开关(后端已确认该字段未参与任何展示逻辑,属于死代码)。 todos: []
expandHome 字段:仅在 HomePageModuleClass.php 的 validateActivityBase/normalizeActivityBase 中写入/读出 Redis,全仓库无任何展示分支依赖它,确认为冗余字段,可删除。HomePageDisplayClass::buildHome 组装,秒杀/团购走 formatActivity(无条数截断),热门/上新/下拉走 formatGoodsSection→resolveDisplayGoods(硬编码 DISPLAY_GOODS_LIMIT=20 截断,且不返回总数)。goodsSection.vue(热门/上新/下拉)已有无条件的"更多"(跳店铺分类页);activitySection.vue(秒杀/团购)没有"更多"入口。goods/list.vue 卡片布局。displayCount 字段,移除 expandHome文件:biz-hd/homePageConfig/classes/HomePageModuleClass.php
validateActivityBase(行 641-686)、normalizeActivityBase(行 627-639):删除 expandHome 读写;新增 displayCount(0=全部,1-10=具体数量)。新增校验方法:
public static function normalizeDisplayCount($value)
{
if ($value === '' || $value === null || intval($value) === 0) {
return 0;
}
$count = intval($value);
if ($count < 1 || $count > 10) {
util::fail('商品展示数量范围为1-10,留空表示全部');
}
return $count;
}
秒杀/团购:validateActivityBase 用 'displayCount' => self::normalizeDisplayCount($data['displayCount'] ?? 0) 替换 expandHome 那一行;normalizeActivityBase 同理用 intval($saved['displayCount'] ?? 0) 替换。
热门/上新/下拉:getGoodsSection(行 438-456)、saveGoodsSection(行 458-494)同样新增 displayCount 的读取与保存(复用 normalizeDisplayCount)。
旧 Redis 缓存中残留的 expandHome 字段无需专门迁移:整个模块配置以 JSON 整体 SET 覆盖存储,下次管理员保存后该字段自然被新结构替换;读取时不再解析它即不产生任何影响。
文件:biz-hd/homePageConfig/classes/HomePageModuleClass.php
resolveDisplayGoods(行 519-610)拆分为:
matchGoodsRows($mainId, $type, $value, $sort):保留现有匹配+排序逻辑,返回未截断的原始行数组。formatGoodsRows($rows):现有"组装输出字段(含 coverUrl)"部分抽出为独立方法。resolveDisplayGoodsPaged($mainId, $type, $value, $sort, $page, $pageSize):调用 matchGoodsRows 取总数,再按 page/pageSize 切片、formatGoodsRows 格式化,返回 ['list' => [...], 'total' => n]。文件:biz-hd/homePageConfig/classes/HomePageDisplayClass.php
formatActivity(行 119-141):抽出"状态过滤 + coverUrl 补全"为私有方法 filterActivityGoods($rawList)(不做截断),供 formatActivity 和后面的分页接口共用;formatActivity 内使用该方法取全量后计算 $total = count($goods),再按 $limit = 1<=displayCount<=10 ? displayCount : HomePageModuleClass::DISPLAY_GOODS_LIMIT 截断,返回时新增 goodsTotal 字段。formatGoodsSection(行 150-164):改为调用 resolveDisplayGoodsPaged($mainId, type, value, sort, 1, $limit)($limit 同上取 displayCount 或默认 20),返回时新增 goodsTotal 字段(取分页结果里的 total)。getSectionGoodsPage($mainId, $moduleKey, $page, $pageSize):统一入口,供"更多"列表页调用:
moduleKey 为 seckill/groupBuy:取 getSeckill/getGroupBuy → filterActivityGoods 取全量 → 按 page/pageSize 切片,标题取 title(与首页展示一致的兜底文案)。moduleKey 为 hot/new/pullGoods:取 getGoodsSection → resolveDisplayGoodsPaged,标题取 name。{ list, total, totalPage, page, pageSize, moreData, title }(与 GoodsCategoryClass::getGoodsList 分页返回约定一致,供前端 mixins/list.js 直接消费)。actionGetSectionGoods(),读取 moduleKey/page/pageSize,调用 HomePageDisplayClass::getSectionGoodsPage;加入 guestAccess。actionSaveSeckill/actionSaveGroupBuy/actionSaveHot/actionSaveNew/actionSavePullGoods 无需改动(内部已透传 Yii::$app->request->post() 给业务类,业务类新增字段即可生效)。文件:hdApp/src/admin/homePageConfig/seckill.vue、groupBuy.vue(两文件结构一致,逐一同步修改)
tui-list-cell(seckill.vue 行 51-56)。原位置新增"商品展示数量"字段:
<tui-list-cell class="line-cell" :hover="false">
<view class="tui-title">商品展示数量</view>
<input
v-model="form.displayCount"
class="tui-input"
type="number"
maxlength="2"
placeholder="默认全部"
/>
</tui-list-cell>
<view class="field-hint">范围1-10,留空为全部;设置数量超出商品总数时按全部展示</view>
data().form:删除 expandHome: 0,新增 displayCount: ''。
normalizeForm:删除 expandHome 映射,新增 displayCount: data.displayCount ? String(data.displayCount) : ''。
删除 onExpandHomeChange 方法。
saveFn 提交参数:删除 expandHome,新增 displayCount: this.form.displayCount === '' ? 0 : parseInt(this.form.displayCount, 10);提交前校验:非空时必须在 1-10 之间,否则 this.$msg('商品展示数量范围为1-10') 并中断。
文件:hdApp/src/admin/homePageConfig/goodsSection.vue
data().form 新增 displayCount: '';init() 中回填 displayCount: d.displayCount ? String(d.displayCount) : '';saveFn 提交与校验逻辑同上。文件:hdApp/src/api/home-page-config/index.js — 无需新增(displayCount 随现有 saveSeckill/saveGroupBuy/saveHot/saveNew/savePullGoods 一起提交)。
goodsTotal 显示"更多"文件:mallApp/src/components/home/activitySection.vue
showMore():return Number(this.data.goodsTotal || 0) > (this.data.goods || []).length。activity-head 内新增"更多"按钮(放在标题行右侧,需要把当前 .activity-title-row 包一层并用 justify-content: space-between 让"更多"贴右,倒计时与标题保持左侧一组),v-if="showMore",点击调用 goMore()。新增方法:
goMore() {
const title = this.data.title || (this.isGroupBuy ? '团购优惠' : '限时秒杀')
this.pageTo({
url: `/pages/goods/section-list?moduleKey=${this.type}&title=${encodeURIComponent(title)}&account=${this.account}&hdId=${this.hdId}`
})
}
文件:mallApp/src/components/home/goodsSection.vue
moduleKey(hot/new/pullGoods)。.section-more 增加 v-if="showMore"(computed 同上)。goMore() 改为跳转新页面:/pages/goods/section-list?moduleKey=${this.moduleKey}&title=${encodeURIComponent(this.data.name)}&account=...&hdId=...(替换现有跳店铺分类页的逻辑)。文件:mallApp/src/pages/home/index.vue
home-goods-section 实例分别加上 module-key="hot" / "new" / "pullGoods"(行 54-71 附近)。文件:mallApp/src/api/home-page-config/index.js
export const getSectionGoods = data => https.get('/home-page-config/get-section-goods', data)
新文件:mallApp/src/pages/goods/section-list.vue
mixins/list、下拉刷新/触底加载、空态),但不含搜索栏与筛选弹窗(整段移除)。moduleKey、title、account、hdId;onLoad/init 中 uni.setNavigationBarTitle({ title })。buildQuery() 返回 { moduleKey, page, pageSize: 10 },loadGoods() 调 getSectionGoods(...).then(res => this.completes(res))。{id,name,price,stock,cover,coverUrl,sold} — 展示价格 + 已售数量。{id,name,price,originPrice,cover,coverUrl,groupSize?} — 展示活动价 + 原价划线,团购额外显示"XX人团"角标。moduleKey 判断展示分支(isActivity = moduleKey === 'seckill' || moduleKey === 'groupBuy')。/pages/goods/detail?id=${item.id}&account=...&hdId=...。在 mallApp/src/pages.json 的 pages/goods 分包(行 74-80)追加:
{ "path": "section-list", "style": { "navigationBarTitleText": "商品列表", "enablePullDownRefresh": true } }
hdApp/src/admin/homePageConfig/preview.vue 及其 previewParts/* 组件为只读预览(不支持下单/跳转交互),不新增"更多"按钮,维持现状。seckillGoodsEdit.vue / groupBuyGoodsEdit.vue 中的"单人限购"字段与本次"商品展示数量"无关,不改动。npm run build:mp-weixin(按项目规则,由用户自行运行)。npm run index(understand-project)刷新索引,npm run validate 校验。