name: 门店首页配置页面 overview: 在 hdApp 新建"门店首页配置"页面,展示 8 项配置模块,支持拖拽排序与开关,并实现"顶部导航与搜索"子页面;配置数据(顺序+开关)通过新增的 Yii2 接口保存到 Redis(key 前缀为 mainId)。 todos:
id: pages-json content: 在 front-end/hdApp/src/pages.json 新增 admin/homePageConfig 分包注册 index、topNavSearch 两个页面 status: completed
项目:hdApp 需求:创建新建页面--门店首页配置(内容写入到 hdApp/src/admin/homePageConfig/index.vue),样式要综合项目原有的页面样式 详细:
按图(门店首页配置.png)实现创建8项配置项
点击配置项名称及描述 或 编辑时,会跳转到对应配置项的页面。初期只实现顶部导航与搜索的跳转(顶部导航与搜索页面的实现如图2),其它先留空后期补上。
每项配置有开启与关闭按钮,初期就用redis保存起它们的设置(设置一个合适的唯一名称,前缀使用 mainId)
8项配置项支持拖拽排序, 拖拽排序实现请参考(hdApp/src/admin/goods/goodsSort.vue),如果拖拽排序算法能优化就直接优化。把排列的数据与一同保存到redis(看看要不要开启关闭结合起来)
顶部导航与搜索页面实现细节:
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/setting、admin/goods 分包写法)。front-end/hdApp/src/admin/goods/goodsSort.vue:touchstart/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\Shop,tableName() 返回 xhShop),全项目通过 $this->shop->merchantName 取门店名称(如 app-hd/controllers/OrderController.php 第470行),后端接口直接返回 $this->shop->merchantName 即可,无需再查表。biz-hd/purchase/classes/PurchaseClearClass.php、biz-hd/lakala/classes/LakalaAccountClass.php 等:统一用 Yii::$app->redis->executeCommand('GET'/'SET', [...]),值用 json_encode/json_decode 存取。$mainColor:#049E2C(front-end/hdApp/src/uni.scss),开关统一用 <switch color="#09C567" />(admin/goods/add.vue、admin/goods/detail.vue 已用此配色)。8 个配置模块的 key/名称/描述/跳转路径 只在前端维护(与 homeMenus.js 现有做法一致,后端不需要关心前端路由):
/admin/homePageConfig/topNavSearch点击标题/描述或"编辑":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'),调用 saveModules,util::complete('保存成功')actionGetTopNav():合并 HomePageConfigClass::getTopNav($this->mainId) 与 merchantName' => $this->shop->merchantName ?? '',util::success()actionSaveTopNav():调用 saveTopNav,util::complete('保存成功')路由(Yii2 kebab-case 规则,参照 shop-ext、category-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)
front-end/hdApp/src/admin/homePageConfig/index.vue(门店首页配置列表)admin-button-com default/blue big 按钮样式)。onLoad/init() 调用 getModules(),与本地 8 项元数据按返回的 key 顺序 merge 成展示列表(enabled 取接口值)。goodsSort.vue 的 touch 方案并做以下优化:
pixelRatio 在 dragStart 时用 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) → 有 path 则 pageTo(item.path);无则 uni.showToast({title:'该模块正在开发中', icon:'none'})。items=[{key,enabled}],调用 saveModules({items}),成功后 $msg('保存成功')。$fontColor2/3、$borderColor、disFlex mixin、卡片圆角、upx 单位,整体保持和 goodsSort.vue/setting/list.vue 一致的视觉语言。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) 或留在本页。pages.json 注册在 subPackages 数组新增:
{
"root": "admin/homePageConfig",
"pages": [
{ "path": "index", "style": { "navigationBarTitleText": "门店首页配置" } },
{ "path": "topNavSearch", "style": { "navigationBarTitleText": "顶部导航与搜索" } }
]
}
huahuibao/biz-hd/homePageConfig/classes/HomePageConfigClass.phphuahuibao/app-hd/controllers/HomePageConfigController.phpunderstand-project 运行 npm run index 刷新索引(npm run validate 用于本项目内容改动,本次主要是业务代码改动,npm run index 更相关)。npm run build:mp-weixin。