Kaynağa Gözat

feat(home-page): 支持金刚区关联花材分类

- 新增花材分类关联类型并限制为单个有效分类 ID
- 样例门店复制时按名称重映射花材分类,避免跨门店引用
- 明确花材分类接口用途并清理未使用依赖

API: 金刚区保存接口新增 type=5 花材分类关联类型,item-class/all 响应结构不变
shizhongqi 2 gün önce
ebeveyn
işleme
0b91f9cd3c

+ 1 - 2
app-hd/controllers/ItemClassController.php

@@ -7,7 +7,6 @@
 namespace hd\controllers;
 namespace hd\controllers;
 
 
 use bizGhs\item\classes\ItemClassClass;
 use bizGhs\item\classes\ItemClassClass;
-use bizGhs\item\services\ItemClassService;
 use bizHd\product\classes\ProductClass;
 use bizHd\product\classes\ProductClass;
 use bizHd\shop\classes\ShopClass;
 use bizHd\shop\classes\ShopClass;
 use common\components\dict;
 use common\components\dict;
@@ -258,7 +257,7 @@ class ItemClassController extends BaseController
         }
         }
     }
     }
 
 
-    //开单: 获取所有分类
+    //开单 / 首页金刚区关联花材分类:获取当前门店全部花材分类
     public function actionAll()
     public function actionAll()
     {
     {
         $data = ItemClassClass::getGhsItemClassAll($this->mainId);
         $data = ItemClassClass::getGhsItemClassAll($this->mainId);

+ 15 - 1
app-hd/models/homePageConfig/SaveNavGridForm.php

@@ -68,10 +68,24 @@ class SaveNavGridForm extends BaseForm
                 $this->addError($attribute, "请完善第{$no}个导航项");
                 $this->addError($attribute, "请完善第{$no}个导航项");
                 return;
                 return;
             }
             }
-            if (!in_array($type, [HomePageModuleClass::LINK_CATEGORY, HomePageModuleClass::LINK_USE_CASE], true)) {
+            $allowedTypes = [
+                HomePageModuleClass::LINK_CATEGORY,
+                HomePageModuleClass::LINK_USE_CASE,
+                HomePageModuleClass::LINK_ITEM_CLASS,
+            ];
+            if (!in_array($type, $allowedTypes, true)) {
                 $this->addError($attribute, "第{$no}个导航关联类型无效");
                 $this->addError($attribute, "第{$no}个导航关联类型无效");
                 return;
                 return;
             }
             }
+            // 花材分类只能关联一个分类 ID,避免商城首页无法定位到具体花材分类
+            if ($type === HomePageModuleClass::LINK_ITEM_CLASS) {
+                $itemClassIds = array_values(array_filter(array_map('intval', explode(',', $value))));
+                if (count($itemClassIds) !== 1 || $itemClassIds[0] <= 0) {
+                    $this->addError($attribute, "第{$no}个导航请选择一个花材分类");
+                    return;
+                }
+                $value = strval($itemClassIds[0]);
+            }
             $list[] = [
             $list[] = [
                 'id' => strval($item['id'] ?? ('nav_' . ($index + 1))),
                 'id' => strval($item['id'] ?? ('nav_' . ($index + 1))),
                 'name' => mb_substr($name, 0, 20),
                 'name' => mb_substr($name, 0, 20),

+ 4 - 2
biz-hd/homePageConfig/classes/HomePageModuleClass.php

@@ -39,10 +39,12 @@ class HomePageModuleClass
 
 
     /** 关联:商品 */
     /** 关联:商品 */
     const LINK_GOODS = 2;
     const LINK_GOODS = 2;
-    /** 关联:分类 */
+    /** 关联:花束分类(可多选) */
     const LINK_CATEGORY = 3;
     const LINK_CATEGORY = 3;
-    /** 关联:场景 */
+    /** 关联:场景(可多选) */
     const LINK_USE_CASE = 4;
     const LINK_USE_CASE = 4;
+    /** 关联:花材分类(仅单选一个) */
+    const LINK_ITEM_CLASS = 5;
 
 
     /** 排序:按商品排序 */
     /** 排序:按商品排序 */
     const SORT_PRODUCT = 1;
     const SORT_PRODUCT = 1;

+ 45 - 9
biz-hd/shop/classes/ShopTemplateClass.php

@@ -16,7 +16,9 @@ use bizHd\goods\classes\GoodsUseCaseClass;
 use bizHd\goods\classes\KindClass;
 use bizHd\goods\classes\KindClass;
 use bizHd\goods\classes\UseCaseClass;
 use bizHd\goods\classes\UseCaseClass;
 use bizHd\homePageConfig\classes\HomePageConfigClass;
 use bizHd\homePageConfig\classes\HomePageConfigClass;
+use bizHd\homePageConfig\classes\HomePageModuleClass;
 use bizHd\homePageConfig\classes\HomePageModuleConfigClass;
 use bizHd\homePageConfig\classes\HomePageModuleConfigClass;
+use bizHd\item\classes\ItemClassClass;
 use bizHd\seckill\classes\SeckillActivityClass;
 use bizHd\seckill\classes\SeckillActivityClass;
 use bizHd\seckill\classes\SeckillGoodsClass;
 use bizHd\seckill\classes\SeckillGoodsClass;
 use Yii;
 use Yii;
@@ -61,7 +63,8 @@ class ShopTemplateClass extends BaseClass
             self::copyUseCaseRelations($tplMainId, $newShop, $goodsMap, $useCaseMap);
             self::copyUseCaseRelations($tplMainId, $newShop, $goodsMap, $useCaseMap);
             $activityMap = self::copySeckillActivities($tplMainId, $tplShopId, $newShop);
             $activityMap = self::copySeckillActivities($tplMainId, $tplShopId, $newShop);
             self::copySeckillGoods($tplMainId, $tplShopId, $newShop, $activityMap, $goodsMap);
             self::copySeckillGoods($tplMainId, $tplShopId, $newShop, $activityMap, $goodsMap);
-            self::copyHomePageConfig($tplShopId, $newShop, $goodsMap, $categoryMap, $useCaseMap);
+            $itemClassMap = self::buildItemClassMap($tplMainId, $newMainId);
+            self::copyHomePageConfig($tplShopId, $newShop, $goodsMap, $categoryMap, $useCaseMap, $itemClassMap);
             $transaction->commit();
             $transaction->commit();
             return true;
             return true;
         } catch (\Throwable $e) {
         } catch (\Throwable $e) {
@@ -157,6 +160,34 @@ class ShopTemplateClass extends BaseClass
         return $map;
         return $map;
     }
     }
 
 
+    /**
+     * 按分类名称把模板店花材分类映射到新店已初始化的花材分类
+     * @param int $tplMainId
+     * @param int $newMainId
+     * @return array 旧花材分类id => 新花材分类id
+     */
+    protected static function buildItemClassMap($tplMainId, $newMainId)
+    {
+        $map = [];
+        $oldList = ItemClassClass::getAllByCondition(['mainId' => $tplMainId], null, 'id,name');
+        $newList = ItemClassClass::getAllByCondition(['mainId' => $newMainId], null, 'id,name');
+        $newByName = [];
+        foreach ($newList as $item) {
+            $name = trim(strval($item['name'] ?? ''));
+            if ($name !== '') {
+                $newByName[$name] = intval($item['id'] ?? 0);
+            }
+        }
+        foreach ($oldList as $item) {
+            $name = trim(strval($item['name'] ?? ''));
+            $oldId = intval($item['id'] ?? 0);
+            if ($oldId > 0 && isset($newByName[$name]) && $newByName[$name] > 0) {
+                $map[$oldId] = $newByName[$name];
+            }
+        }
+        return $map;
+    }
+
     /**
     /**
      * 复制商品:先主记录再子规格,销量清零,masterId/kindId 按映射重写
      * 复制商品:先主记录再子规格,销量清零,masterId/kindId 按映射重写
      * 商品按 mainId 归属,xhGoods 没有 shopId,不能按门店过滤
      * 商品按 mainId 归属,xhGoods 没有 shopId,不能按门店过滤
@@ -373,15 +404,16 @@ class ShopTemplateClass extends BaseClass
     }
     }
 
 
     /**
     /**
-     * 复制首页模块配置,并把 JSON 里引用的商品/分类/场景 ID 换成新店 ID
+     * 复制首页模块配置,并把 JSON 里引用的商品/分类/场景/花材分类 ID 换成新店 ID
      * @param int $tplShopId
      * @param int $tplShopId
      * @param array $newShop
      * @param array $newShop
      * @param array $goodsMap
      * @param array $goodsMap
      * @param array $categoryMap
      * @param array $categoryMap
      * @param array $useCaseMap
      * @param array $useCaseMap
+     * @param array $itemClassMap
      * @return void
      * @return void
      */
      */
-    protected static function copyHomePageConfig($tplShopId, $newShop, $goodsMap, $categoryMap, $useCaseMap)
+    protected static function copyHomePageConfig($tplShopId, $newShop, $goodsMap, $categoryMap, $useCaseMap, $itemClassMap)
     {
     {
         $list = HomePageModuleConfigClass::getAllByCondition(['shopId' => $tplShopId], 'id ASC');
         $list = HomePageModuleConfigClass::getAllByCondition(['shopId' => $tplShopId], 'id ASC');
         if (empty($list)) {
         if (empty($list)) {
@@ -396,7 +428,7 @@ class ShopTemplateClass extends BaseClass
             if (!is_array($payload)) {
             if (!is_array($payload)) {
                 $payload = [];
                 $payload = [];
             }
             }
-            $payload = self::remapHomePagePayload($moduleKey, $payload, $goodsMap, $categoryMap, $useCaseMap);
+            $payload = self::remapHomePagePayload($moduleKey, $payload, $goodsMap, $categoryMap, $useCaseMap, $itemClassMap);
             HomePageModuleConfigClass::saveConfigValue($newShop['mainId'], $newShop['shopId'], $moduleKey, $payload);
             HomePageModuleConfigClass::saveConfigValue($newShop['mainId'], $newShop['shopId'], $moduleKey, $payload);
         }
         }
     }
     }
@@ -409,9 +441,10 @@ class ShopTemplateClass extends BaseClass
      * @param array $goodsMap
      * @param array $goodsMap
      * @param array $categoryMap
      * @param array $categoryMap
      * @param array $useCaseMap
      * @param array $useCaseMap
+     * @param array $itemClassMap
      * @return array
      * @return array
      */
      */
-    protected static function remapHomePagePayload($moduleKey, $payload, $goodsMap, $categoryMap, $useCaseMap)
+    protected static function remapHomePagePayload($moduleKey, $payload, $goodsMap, $categoryMap, $useCaseMap, $itemClassMap)
     {
     {
         if ($moduleKey === 'banner' || $moduleKey === 'navGrid') {
         if ($moduleKey === 'banner' || $moduleKey === 'navGrid') {
             if (empty($payload['list']) || !is_array($payload['list'])) {
             if (empty($payload['list']) || !is_array($payload['list'])) {
@@ -423,14 +456,14 @@ class ShopTemplateClass extends BaseClass
                 }
                 }
                 $type = intval($item['type'] ?? 0);
                 $type = intval($item['type'] ?? 0);
                 $value = strval($item['value'] ?? '');
                 $value = strval($item['value'] ?? '');
-                $payload['list'][$index]['value'] = self::remapLinkedValue($type, $value, $goodsMap, $categoryMap, $useCaseMap);
+                $payload['list'][$index]['value'] = self::remapLinkedValue($type, $value, $goodsMap, $categoryMap, $useCaseMap, $itemClassMap);
             }
             }
             return $payload;
             return $payload;
         }
         }
         if (in_array($moduleKey, ['hot', 'new', 'pullGoods'], true)) {
         if (in_array($moduleKey, ['hot', 'new', 'pullGoods'], true)) {
             $type = intval($payload['type'] ?? 0);
             $type = intval($payload['type'] ?? 0);
             $value = strval($payload['value'] ?? '');
             $value = strval($payload['value'] ?? '');
-            $payload['value'] = self::remapLinkedValue($type, $value, $goodsMap, $categoryMap, $useCaseMap);
+            $payload['value'] = self::remapLinkedValue($type, $value, $goodsMap, $categoryMap, $useCaseMap, $itemClassMap);
             return $payload;
             return $payload;
         }
         }
         return $payload;
         return $payload;
@@ -438,15 +471,16 @@ class ShopTemplateClass extends BaseClass
 
 
     /**
     /**
      * 把关联配置的 value(单个 ID 或逗号拼接)按 type 映射到新店
      * 把关联配置的 value(单个 ID 或逗号拼接)按 type 映射到新店
-     * type:2 商品、3 分类、4 使用场景;未映射到的 ID 丢弃,避免新店引用模板店数据
+     * type:2 商品、3 分类、4 使用场景、5 花材分类;未映射到的 ID 丢弃,避免新店引用模板店数据
      * @param int $type
      * @param int $type
      * @param string $value
      * @param string $value
      * @param array $goodsMap
      * @param array $goodsMap
      * @param array $categoryMap
      * @param array $categoryMap
      * @param array $useCaseMap
      * @param array $useCaseMap
+     * @param array $itemClassMap
      * @return string
      * @return string
      */
      */
-    protected static function remapLinkedValue($type, $value, $goodsMap, $categoryMap, $useCaseMap)
+    protected static function remapLinkedValue($type, $value, $goodsMap, $categoryMap, $useCaseMap, $itemClassMap)
     {
     {
         $map = [];
         $map = [];
         if ($type === HomePageConfigClass::BANNER_TYPE_GOODS) {
         if ($type === HomePageConfigClass::BANNER_TYPE_GOODS) {
@@ -455,6 +489,8 @@ class ShopTemplateClass extends BaseClass
             $map = $categoryMap;
             $map = $categoryMap;
         } elseif ($type === HomePageConfigClass::BANNER_TYPE_USE_CASE) {
         } elseif ($type === HomePageConfigClass::BANNER_TYPE_USE_CASE) {
             $map = $useCaseMap;
             $map = $useCaseMap;
+        } elseif ($type === HomePageModuleClass::LINK_ITEM_CLASS) {
+            $map = $itemClassMap;
         } else {
         } else {
             return $value;
             return $value;
         }
         }