2-门店首页配置页面(hdApp).md 11 KB


name: 门店首页配置页面 overview: 在 hdApp 新建"门店首页配置"页面,展示 8 项配置模块,支持拖拽排序与开关,并实现"顶部导航与搜索"子页面;配置数据(顺序+开关)通过新增的 Yii2 接口保存到 Redis(key 前缀为 mainId)。 todos:

  • id: backend-class content: 新增 biz-hd/homePageConfig/classes/HomePageConfigClass.php 实现 Redis 读写(模块顺序+开关、topNav详情) status: completed
  • id: backend-controller content: 新增 app-hd/controllers/HomePageConfigController.php 四个 action(get/save modules、get/save top-nav) status: completed
  • id: frontend-api content: 新增 front-end/hdApp/src/api/home-page-config/index.js 四个接口封装 status: completed
  • id: frontend-index content: 实现 front-end/hdApp/src/admin/homePageConfig/index.vue:8项配置卡片、优化版拖拽排序、开关、保存/预览按钮 status: completed
  • id: frontend-topnav content: 实现 front-end/hdApp/src/admin/homePageConfig/topNavSearch.vue:门店名称只读展示、占位文案、颜色选择弹层、客服开关、简单预览 status: completed
  • id: pages-json content: 在 front-end/hdApp/src/pages.json 新增 admin/homePageConfig 分包注册 index、topNavSearch 两个页面 status: completed

    isProject: false

    计划需求指令:

    项目:hdApp 需求:创建新建页面--门店首页配置(内容写入到 hdApp/src/admin/homePageConfig/index.vue),样式要综合项目原有的页面样式 详细:

  • 按图(门店首页配置.png)实现创建8项配置项

  • 点击配置项名称及描述 或 编辑时,会跳转到对应配置项的页面。初期只实现顶部导航与搜索的跳转(顶部导航与搜索页面的实现如图2),其它先留空后期补上。

  • 每项配置有开启与关闭按钮,初期就用redis保存起它们的设置(设置一个合适的唯一名称,前缀使用 mainId)

  • 8项配置项支持拖拽排序, 拖拽排序实现请参考(hdApp/src/admin/goods/goodsSort.vue),如果拖拽排序算法能优化就直接优化。把排列的数据与一同保存到redis(看看要不要开启关闭结合起来)

顶部导航与搜索页面实现细节:

  1. 门店名称直接取自 xhShop 表的merchantName字段
  2. 预览效果可以不要或简单实现下

门店首页配置页面(hdApp)

背景确认

  • 菜单入口已存在:front-end/hdApp/src/admin/home/homeMenus.js 第20行已经配置了 { name: '首页配置', url: '/admin/homePageConfig/index' },无需再加菜单项。
  • 页面文件已存在但为空文件:front-end/hdApp/src/admin/homePageConfig/index.vue(0字节),本次直接写入实现。
  • pages.json 尚未注册 admin/homePageConfig 分包,需要补充,否则页面无法访问(参照 front-end/hdApp/src/pages.json 第314-365行 admin/settingadmin/goods 分包写法)。
  • 拖拽排序参考 front-end/hdApp/src/admin/goods/goodsSort.vuetouchstart/touchmove/touchend + upx/px 换算 + list.data splice 提交排序。
  • 门店名称字段来源确认:app-hd/controllers/BaseController.php 第72-85行中 $this->shop = ShopClass::getById($currentShopId, true)bizHd\merchant\classes\ShopClass → 模型 bizHd\merchant\models\ShoptableName() 返回 xhShop),全项目通过 $this->shop->merchantName 取门店名称(如 app-hd/controllers/OrderController.php 第470行),后端接口直接返回 $this->shop->merchantName 即可,无需再查表。
  • Redis 用法参考 biz-hd/purchase/classes/PurchaseClearClass.phpbiz-hd/lakala/classes/LakalaAccountClass.php 等:统一用 Yii::$app->redis->executeCommand('GET'/'SET', [...]),值用 json_encode/json_decode 存取。
  • 主色/开关色沿用项目现有风格:$mainColor:#049E2Cfront-end/hdApp/src/uni.scss),开关统一用 <switch color="#09C567" />admin/goods/add.vueadmin/goods/detail.vue 已用此配色)。

数据与接口设计

8 个配置模块的 key/名称/描述/跳转路径 只在前端维护(与 homeMenus.js 现有做法一致,后端不需要关心前端路由):

  • topNav:顶部导航与搜索 → /admin/homePageConfig/topNavSearch
  • banner:首页轮播图 → 空(先留空)
  • navGrid:分类金刚区导航 → 空
  • seckill:秒杀专区 → 空
  • groupBuy:团购专区 → 空
  • hot:热门推荐 → 空
  • new:今日上新 → 空
  • pullGoods:下拉商品 → 空

点击标题/描述或"编辑":topNav 跳转到子页面;其余 7 项弹提示"该模块正在开发中"(不跳转)。

Redis key(前缀为 mainId,按需求4点"排序与开关合并保存"):

  • 模块顺序+开关:{mainId}_home_page_config_modules,值为 JSON 数组 [{key,enabled}, ...],数组顺序即展示顺序。
  • 顶部导航与搜索详情设置:{mainId}_home_page_config_top_nav,值为 JSON 对象 {enabled, placeholder, searchBtnColor, searchFontColor, customerServiceEnabled}(门店名称不存,实时取 shop.merchantName)。

新增后端类:biz-hd/homePageConfig/classes/HomePageConfigClass.php

  • DEFAULT_KEYS 常量定义合法 key 白名单(8个),用于校验/补全。
  • getModules($mainId) / saveModules($mainId, $items):读取时若 Redis 无数据或缺项,用默认顺序+enabled=1补全;保存时校验 key 合法且不重复、数量为8,enabled 强制转 0/1。
  • getTopNav($mainId) / saveTopNav($mainId, $data):带默认值合并,字段做基础类型转换。

新增后端控制器:app-hd/controllers/HomePageConfigController.php extends BaseController

  • actionGetModules()util::success(['list' => HomePageConfigClass::getModules($this->mainId)])
  • actionSaveModules():读取 Yii::$app->request->post('items'),调用 saveModulesutil::complete('保存成功')
  • actionGetTopNav():合并 HomePageConfigClass::getTopNav($this->mainId)merchantName' => $this->shop->merchantName ?? ''util::success()
  • actionSaveTopNav():调用 saveTopNavutil::complete('保存成功')

路由(Yii2 kebab-case 规则,参照 shop-extcategory-setting): /home-page-config/get-modules/home-page-config/save-modules/home-page-config/get-top-nav/home-page-config/save-top-nav

新增前端 API:front-end/hdApp/src/api/home-page-config/index.js

import https from '@/plugins/luch-request_0.0.7/request'
export const getModules = data => https.get('/home-page-config/get-modules', data)
export const saveModules = data => https.post('/home-page-config/save-modules', data)
export const getTopNav = data => https.get('/home-page-config/get-top-nav', data)
export const saveTopNav = data => https.post('/home-page-config/save-top-nav', data)

前端页面实现

1. front-end/hdApp/src/admin/homePageConfig/index.vue(门店首页配置列表)

  • 布局对齐图2:顶部说明文字"支持上下拖拽调整展示顺序" + 8 行配置卡片(编号圆圈、标题、描述、"编辑 ›"、开关)+ 底部"预览"/"保存配置"按钮(复用 admin-button-com default/blue big 按钮样式)。
  • onLoad/init() 调用 getModules(),与本地 8 项元数据按返回的 key 顺序 merge 成展示列表(enabled 取接口值)。
  • 拖拽排序:复用 goodsSort.vue 的 touch 方案并做以下优化:
    • pixelRatiodragStart 时用 uni.getSystemInfoSync() 计算一次并缓存,不在 touchmove 里重复调用(原实现每次 move 都调用,浪费性能)。
    • 增加实时位移预览:dragMove 中不仅更新 targetIndex,还为处于"拖拽起点与当前目标之间"的其它行实时设置 translateY(±itemHeight),被拖拽行跟随手指位移,做到真正的实时排序预览(比 goodsSort.vue 仅高亮目标行更直观)。
    • 只在 touchend 时一次性 splice 提交数组顺序,去掉本页面不需要的置顶/置底/上移/下移按钮(图2设计中无此按钮,8项定长列表也无需分页/mixin)。
    • 拖拽手柄:整行可拖拽,但"编辑"文字和 switch 区域各自 @touchstart.stop 阻止冒泡,避免和点击/开关手势冲突。
  • 开关:<switch color="#09C567" :checked="item.enabled==1" @change="toggleEnabled(item)" />,仅改本地状态,不即时请求接口。
  • 点击标题/描述区域或"编辑":goEdit(item) → 有 pathpageTo(item.path);无则 uni.showToast({title:'该模块正在开发中', icon:'none'})
  • "保存配置":整理当前展示顺序为 items=[{key,enabled}],调用 saveModules({items}),成功后 $msg('保存成功')
  • "预览":先简单实现为 toast 提示(如"预览功能开发中"),或后续可跳转小程序首页真实预览,符合用户"预览效果可以不要或简单实现"的说明(此为主列表页,非 topNav 详情页的预览)。
  • 样式沿用项目变量:$fontColor2/3$borderColordisFlex mixin、卡片圆角、upx 单位,整体保持和 goodsSort.vue/setting/list.vue 一致的视觉语言。

2. front-end/hdApp/src/admin/homePageConfig/topNavSearch.vue(顶部导航与搜索)

对齐图1布局:

  • 模块开关:<switch> 绑定 form.enabled
  • 门店名称:只读展示 merchantName(接口 getTopNav 返回,来自 shop.merchantName),用禁用态输入框或纯文本展示,明确提示"门店名称在店铺资料中修改"(可参考已有 admin/home/edit.vue 花店名称修改页做跳转提示,非必须)。
  • 搜索占位文案:<input v-model="form.placeholder" placeholder="请输入搜索占位文案" />,复用 tui-list-cell + line-cell + tui-title/tui-input 样式(同 admin/goods/detail.vue 输入行写法)。
  • 搜索按钮颜色 / 搜索字体颜色:点击弹出 tui-bottom-popup(复用 components/plugin/bottom-popup.vue),列出预设色块(如 绿色#09C567/橙色#ff6900/黑色 等,字体颜色为 白色/黑色),选中后回填 form.searchBtnColor/form.searchFontColor 并关闭弹层。
  • 客服入口:<switch v-model="form.customerServiceEnabled">
  • 预览效果:按需求"可以不要或简单实现",做一个简化的静态预览条(门店名 + 搜索框 + 客服图标),根据 form 里选中的颜色实时变色即可,不做真机高保真复刻。
  • init() 调用 getTopNav() 填充表单;保存按钮调用 saveTopNav(form)(不含 merchantName),成功后 $msg('保存成功') 并可 pageTo(-1) 或留在本页。

3. pages.json 注册

subPackages 数组新增:

{
  "root": "admin/homePageConfig",
  "pages": [
    { "path": "index", "style": { "navigationBarTitleText": "门店首页配置" } },
    { "path": "topNavSearch", "style": { "navigationBarTitleText": "顶部导航与搜索" } }
  ]
}

后端改动文件清单

  • 新增 huahuibao/biz-hd/homePageConfig/classes/HomePageConfigClass.php
  • 新增 huahuibao/app-hd/controllers/HomePageConfigController.php

校验步骤

  • 后端改动后按 AGENTS.md 要求,若涉及项目结构变化,在 understand-project 运行 npm run index 刷新索引(npm run validate 用于本项目内容改动,本次主要是业务代码改动,npm run index 更相关)。
  • 不新增/修改前端构建脚本,不主动执行 npm run build:mp-weixin

Todos