Explorar o código

feat(goods): 支持主记录承载首个商品规格

- 多规格商品主记录回写首规格价格、库存和名称,子记录仅保存后续规格
- 统一商城下单、商品列表及秒杀团购的规格识别与展示
- 删除或上下架主商品时同步子规格,并补充 masterId 索引

API: 商品详情的 specList 首项改为主商品记录,首规格下单允许 specGoodsId 等于 goodsId
Database: goodsStyle 用作多规格标记,xhGoods.masterId 增加 idx_m 索引
shizhongqi hai 1 día
pai
achega
d16b7ab189

+ 24 - 0
app-hd/models/goods/AddForm.php

@@ -101,6 +101,16 @@ class AddForm extends BaseForm
     public $useCaseIdList;
     public $specEnabled;
     public $specList;
+    /**
+     * 规格名称:多规格时把首规格名称回写到主记录,便于主记录可售
+     * @var string
+     */
+    public $specName;
+    /**
+     * 商品规格形态:0 单规格,1 多规格(主记录承载第一个规格)
+     * @var int
+     */
+    public $goodsStyle;
 
 
     /**
@@ -126,6 +136,8 @@ class AddForm extends BaseForm
             ['catIds', 'default', 'value' => []],
             ['useCaseIdList', 'default', 'value' => []],
             ['specEnabled', 'default', 'value' => 0],
+            ['specName', 'default', 'value' => ''],
+            ['goodsStyle', 'default', 'value' => 0],
             
             // 数据类型验证
             [['name', 'cover'], 'string'],
@@ -141,6 +153,8 @@ class AddForm extends BaseForm
             [['status'], 'in', 'range' => [0, 1]],
             [['autoRise'], 'in', 'range' => [0, 1]],
             [['specEnabled'], 'in', 'range' => [0, 1]],
+            [['goodsStyle'], 'in', 'range' => [0, 1]],
+            [['specName'], 'string'],
             [['useCaseIdList'], 'validateIdList'],
             [['specList'], 'validateSpecList'],
 
@@ -173,10 +187,17 @@ class AddForm extends BaseForm
         if (!is_array($this->$attribute)) $this->addError($attribute, '使用场景格式不正确');
     }
 
+    /**
+     * 校验多规格列表:关闭时清空规格并标记单规格;开启时把首规格价库/名称回写主记录字段
+     * @param string $attribute 属性名
+     */
     public function validateSpecList($attribute)
     {
         if ((int)$this->specEnabled !== 1) {
             $this->$attribute = [];
+            // 单规格:主记录不挂规格名,goodsStyle 标记为单规格
+            $this->specName = '';
+            $this->goodsStyle = 0;
             return;
         }
         $list = $this->$attribute;
@@ -249,7 +270,10 @@ class AddForm extends BaseForm
             ];
         }
         $this->$attribute = $formatList;
+        // 多规格:主记录承载首规格的价库与规格名,goodsStyle=1 供列表/下单判断
         $firstSpec = $formatList[0];
+        $this->specName = $firstSpec['specName'];
+        $this->goodsStyle = 1;
         $this->priceType = $firstSpec['priceType'];
         $this->price = $firstSpec['price'];
         $this->stockSet = $firstSpec['stockSet'];

+ 24 - 0
app-hd/models/goods/UpdateForm.php

@@ -119,6 +119,16 @@ class UpdateForm extends BaseForm
     public $useCaseIdList;
     public $specEnabled;
     public $specList;
+    /**
+     * 规格名称:多规格时把首规格名称回写到主记录,便于主记录可售
+     * @var string
+     */
+    public $specName;
+    /**
+     * 商品规格形态:0 单规格,1 多规格(主记录承载第一个规格)
+     * @var int
+     */
+    public $goodsStyle;
 
     /**
      * {@inheritdoc}
@@ -161,7 +171,11 @@ class UpdateForm extends BaseForm
             ['stock', 'default', 'value' => 0],
             ['useCaseIdList', 'default', 'value' => []],
             ['specEnabled', 'default', 'value' => 0],
+            ['specName', 'default', 'value' => ''],
+            ['goodsStyle', 'default', 'value' => 0],
             [['specEnabled'], 'in', 'range' => [0, 1]],
+            [['goodsStyle'], 'in', 'range' => [0, 1]],
+            [['specName'], 'string'],
             [['useCaseIdList'], 'validateUseCaseIdList'],
             [['specList'], 'validateSpecList'],
         ];
@@ -195,10 +209,17 @@ class UpdateForm extends BaseForm
         if (!is_array($this->$attribute)) $this->addError($attribute, '使用场景格式不正确');
     }
 
+    /**
+     * 校验多规格列表:关闭时清空规格并标记单规格;开启时把首规格价库/名称回写主记录字段
+     * @param string $attribute 属性名
+     */
     public function validateSpecList($attribute)
     {
         if ((int)$this->specEnabled !== 1) {
             $this->$attribute = [];
+            // 关闭多规格:清空主记录规格名,标记为单规格
+            $this->specName = '';
+            $this->goodsStyle = 0;
             return;
         }
         $list = $this->$attribute;
@@ -271,7 +292,10 @@ class UpdateForm extends BaseForm
             ];
         }
         $this->$attribute = $formatList;
+        // 多规格:主记录承载首规格的价库与规格名,goodsStyle=1 供列表/下单判断
         $firstSpec = $formatList[0];
+        $this->specName = $firstSpec['specName'];
+        $this->goodsStyle = 1;
         $this->priceType = $firstSpec['priceType'];
         $this->price = $firstSpec['price'];
         $this->stockSet = $firstSpec['stockSet'];

+ 21 - 17
app-mall/controllers/OrderController.php

@@ -598,14 +598,16 @@ class OrderController extends BaseController
             util::fail('不是你的商品');
         }
         if ($specGoodsId > 0) {
-            $specGoods = GoodsClass::getById($specGoodsId, true);
-            if (empty($specGoods) || $specGoods->mainId != $mainId || $specGoods->masterId != $goodsId || $specGoods->delStatus != 0 || $specGoods->status != 1) {
-                util::fail('规格不可用');
+            // 首规格落在主记录:specGoodsId 可以等于主商品 id,直接用主记录行售卖
+            if ($specGoodsId != $goodsId) {
+                $specGoods = GoodsClass::getById($specGoodsId, true);
+                if (empty($specGoods) || $specGoods->mainId != $mainId || $specGoods->masterId != $goodsId || $specGoods->delStatus != 0 || $specGoods->status != 1) {
+                    util::fail('规格不可用');
+                }
+                $goodsInfo = $specGoods;
             }
-            $goodsInfo = $specGoods;
-        } elseif ((int)($goodsInfo->masterId ?? 0) === 0) {
-            $hasSpecs = GoodsClass::getByCondition(['masterId'=>$goodsId, 'delStatus'=>0], true);
-            if (!empty($hasSpecs)) util::fail('请选择规格');
+        } elseif ((int)($goodsInfo->masterId ?? 0) === 0 && (int)($goodsInfo->goodsStyle ?? 0) === 1) {
+            util::fail('请选择规格');
         }
         $stock = $goodsInfo->stock ?? 0;
         if ($stock <= 0) {
@@ -1187,18 +1189,20 @@ class OrderController extends BaseController
                         util::fail('不是你的商品');
                     }
                     if ($specGoodsId > 0) {
-                        $specGoods = GoodsClass::getById($specGoodsId, true);
-                        if (empty($specGoods) || $specGoods->mainId != $mainId || $specGoods->masterId != $goodsId || $specGoods->delStatus != 0 || $specGoods->status != 1) {
-                            util::fail('规格不可用');
+                        // 首规格落在主记录:specGoodsId 可以等于主商品 id,直接用主记录行售卖
+                        if ($specGoodsId != $goodsId) {
+                            $specGoods = GoodsClass::getById($specGoodsId, true);
+                            if (empty($specGoods) || $specGoods->mainId != $mainId || $specGoods->masterId != $goodsId || $specGoods->delStatus != 0 || $specGoods->status != 1) {
+                                util::fail('规格不可用');
+                            }
+                            $goodsInfo = $specGoods;
+                            $saleGoodsId = $specGoodsId;
+                        } else {
+                            $saleGoodsId = $goodsId;
                         }
-                        $goodsInfo = $specGoods;
-                        $saleGoodsId = $specGoodsId;
                     } else {
-                        if ((int)($goodsInfo->masterId ?? 0) === 0) {
-                            $hasSpecs = GoodsClass::getByCondition(['masterId' => $goodsId, 'delStatus' => 0], true);
-                            if (!empty($hasSpecs)) {
-                                util::fail('请选择规格');
-                            }
+                        if ((int)($goodsInfo->masterId ?? 0) === 0 && (int)($goodsInfo->goodsStyle ?? 0) === 1) {
+                            util::fail('请选择规格');
                         }
                         $saleGoodsId = $goodsId;
                     }

+ 117 - 30
biz-hd/goods/classes/GoodsClass.php

@@ -20,6 +20,11 @@ use Yii;
 use bizHd\base\classes\BaseClass;
 use bizHd\goods\models\GoodsCategory;
 
+/**
+ * 花店商品业务类
+ * 谁用:hd 后台商品管理、mall 商品详情/下单、首页模块
+ * 解决问题:单规格与多规格存储(多规格主记录承载首规格,goodsStyle=1)
+ */
 class GoodsClass extends BaseClass
 {
 
@@ -40,28 +45,66 @@ class GoodsClass extends BaseClass
         }
     }
 
+    /**
+     * 详情附加使用场景与规格列表
+     * specEnabled 按主记录 goodsStyle 判定;多规格时 specList 第一项是主记录自身(可售首规格),其后是子规格
+     * @param array $goods 主商品或规格商品行
+     * @param int $mainId 门店主体 id
+     * @return array
+     */
     public static function appendUseCasesAndSpecs($goods, $mainId)
     {
         $id = $goods['id'];
         $relations = GoodsUseCaseClass::getAllByCondition(['goodsId'=>$id], null, 'useCaseId');
         $goods['useCaseIdList'] = array_map('intval', array_column($relations, 'useCaseId'));
-        $specs = self::getAllByCondition(['masterId'=>$id, 'delStatus'=>0], 'id ASC', '*');
-        foreach ($specs as &$spec) {
-            $spec = business::formatGoodsImg($spec);
-            $shortCover = $spec['cover'] ?? '';
-            $spec['shortCover'] = $shortCover;
-            $spec['cover'] = $shortCover;
+        $specEnabled = intval($goods['goodsStyle'] ?? 0) === 1 ? 1 : 0;
+        $goods['specEnabled'] = $specEnabled;
+        if ($specEnabled !== 1) {
+            $goods['specList'] = [];
+            return $goods;
+        }
+        // 主记录已由 getGoodsInfo 格式化过图片,这里只抽出规格展示字段,避免二次拼接 OSS 地址
+        $firstSpec = $goods;
+        unset($firstSpec['useCaseIdList'], $firstSpec['specEnabled'], $firstSpec['specList']);
+        $firstSpec['id'] = $id;
+        $firstSpec['masterId'] = 0;
+        $firstSpec['goodsStyle'] = 1;
+        // 与子规格一致:cover 用短路径,避免编辑页把 OSS 完整 URL 当短路径回写
+        $firstSpec['cover'] = $firstSpec['shortCover'] ?? ($firstSpec['cover'] ?? '');
+        $children = self::getAllByCondition(['masterId'=>$id, 'delStatus'=>0], 'id ASC', '*');
+        foreach ($children as &$spec) {
+            $spec = self::formatSpecRow($spec);
         }
         unset($spec);
-        $goods['specEnabled'] = empty($specs) ? 0 : 1;
-        $goods['specList'] = $specs;
+        $goods['specList'] = array_merge([$firstSpec], $children);
         return $goods;
     }
 
+    /**
+     * 规格子记录图片格式化:短路径 cover 保留,供后台编辑回显
+     * @param array $row 规格商品行
+     * @return array
+     */
+    private static function formatSpecRow($row)
+    {
+        $spec = business::formatGoodsImg($row);
+        $shortCover = $spec['cover'] ?? '';
+        $spec['shortCover'] = $shortCover;
+        $spec['cover'] = $shortCover;
+        return $spec;
+    }
+
+    /**
+     * 同步多规格子记录:首规格已由 Form 回写到主记录,这里只维护第 2..n 个规格子行
+     * 关闭多规格时软删全部子行;仅一个规格时不建子行
+     * @param array|object $master 主商品
+     * @param array $data 含 specEnabled、specList
+     * @return void
+     */
     public static function syncSpecs($master, $data)
     {
-        $masterId = $master['id'];
-        $enabled = (int)($data['specEnabled']);
+        $masterId = (int)(is_array($master) ? $master['id'] : $master->id);
+        $enabled = (int)($data['specEnabled'] ?? 0);
         $old = self::getAllByCondition(['masterId'=>$masterId, 'delStatus'=>0], null, '*', 'id');
         if (!$enabled) {
             if (!empty($old)) {
@@ -69,17 +112,29 @@ class GoodsClass extends BaseClass
             }
             return;
         }
+        $list = $data['specList'] ?? [];
+        $firstSpec = $list[0] ?? [];
+        $firstId = (int)($firstSpec['id'] ?? 0);
+        // 编辑时把原来的子规格挪到首位:该子行数据已落到主记录,软删旧子行避免双份
+        if ($firstId && isset($old[$firstId])) {
+            self::updateById($firstId, ['delStatus'=>1]);
+            unset($old[$firstId]);
+        }
         $base = self::getById($masterId);
         if (empty($base)) {
             $base = is_array($master) ? $master : $master->attributes;
         }
         unset($base['id'], $base['sn']);
-        $list = $data['specList'] ?? [];
         $kept = [];
-        foreach ($list as $spec) {
-            $id = (int)($spec['id'] ?? 0); $kept[] = $id;
+        $childList = array_slice($list, 1);
+        foreach ($childList as $spec) {
+            $id = (int)($spec['id'] ?? 0);
+            // 原主记录上的首规格被挪到后面:不能拿主 id 去更新主行,改为新建子行
+            if ($id === $masterId) {
+                $id = 0;
+            }
             $fields = $base;
-            unset($fields['createTime']);
+            unset($fields['createTime'], $fields['goodsStyle']);
             $fields = array_merge($fields, [
                     'specName'=>trim($spec['specName'] ?? ''),
                     'price'=>(float)($spec['price'] ?? 0),
@@ -90,6 +145,7 @@ class GoodsClass extends BaseClass
                     'weight'=>(float)($spec['weight'] ?? 1),
                     'sold'=>(int)($spec['sold'] ?? 0),
                     'masterId'=>$masterId,
+                    'goodsStyle'=>0,
                     'status'=>(int)($data['status'] ?? 1),
                     'delStatus'=>0
                 ]
@@ -100,18 +156,39 @@ class GoodsClass extends BaseClass
                 $fields['cover'] = !empty($spec['cover']) && in_array($spec['cover'], $specImg, true) ? $spec['cover'] : $specImg[0];
             }
             if ($id && isset($old[$id])) {
+                $kept[] = $id;
                 self::updateById($id, $fields);
             } else {
-                $child = $fields; $child['sn'] = orderSn::getGoodsSn($child); $child['createTime']=date('Y-m-d H:i:s'); self::add($child, true);
+                $child = $fields;
+                $child['sn'] = orderSn::getGoodsSn($child);
+                $child['createTime'] = date('Y-m-d H:i:s');
+                self::add($child, true);
             }
         }
 
-        $remove = array_diff(array_keys($old), array_filter($kept));
+        $remove = array_diff(array_keys($old), $kept);
         if ($remove) {
             \bizHd\goods\models\Goods::updateAll(['delStatus'=>1], ['and', ['masterId'=>$masterId], ['in', 'id', $remove]]);
         }
     }
 
+    /**
+     * 带规格名的展示名称:specName 非空即拼到商品名后(主记录承载首规格时也要带规格名)
+     * @param array|object $goods 商品行
+     * @return string
+     */
+    public static function formatSpecDisplayName($goods)
+    {
+        if (is_object($goods)) {
+            $name = strval($goods->name ?? '');
+            $specName = trim(strval($goods->specName ?? ''));
+        } else {
+            $name = strval($goods['name'] ?? '');
+            $specName = trim(strval($goods['specName'] ?? ''));
+        }
+        return $specName !== '' ? $name . '(' . $specName . ')' : $name;
+    }
+
     public static function orderCreateGoods($data)
     {
         $name = $data['name'] ?? '';
@@ -527,7 +604,7 @@ class GoodsClass extends BaseClass
     }
 
     /**
-     * 批量判断主商品是否启用多规格(masterId 指向该商品且未删除
+     * 批量判断主商品是否启用多规格(读主记录 goodsStyle,不再靠子记录存在性
      * @param array $goodsIds 主商品 id 列表
      * @return array [goodsId => 1|0]
      * @throws \Exception
@@ -545,16 +622,16 @@ class GoodsClass extends BaseClass
         foreach ($goodsIds as $gid) {
             $map[$gid] = 0;
         }
-        $specs = self::getAllByCondition(
-            ['masterId' => ['in', $goodsIds], 'delStatus' => 0],
+        $rows = self::getAllByCondition(
+            ['id' => ['in', $goodsIds]],
             null,
-            'masterId'
+            'id,goodsStyle'
         );
-        if (!empty($specs)) {
-            foreach ($specs as $spec) {
-                $masterId = intval($spec['masterId'] ?? 0);
-                if ($masterId > 0) {
-                    $map[$masterId] = 1;
+        if (!empty($rows)) {
+            foreach ($rows as $row) {
+                $gid = intval($row['id'] ?? 0);
+                if ($gid > 0) {
+                    $map[$gid] = intval($row['goodsStyle'] ?? 0) === 1 ? 1 : 0;
                 }
             }
         }
@@ -570,7 +647,7 @@ class GoodsClass extends BaseClass
         $goodsIds = array_column($list, 'id');
         // 一次性获取所有商品的分类关系
         $allGoodsCategories = GoodsCategoryClass::getGoodsHasCategoryIdsBatch($goodsIds);
-        $specEnabledMap = self::getSpecEnabledMap($goodsIds);
+        // 列表行已含 goodsStyle,直接映射为 specEnabled,避免再查子记录
         // &$val 这里的指向符号不能去掉
         foreach ($list as $key => &$val) {
             $id = $val['id'];
@@ -605,13 +682,19 @@ class GoodsClass extends BaseClass
             $val['classId'] = 0;
             $val['bigPrice'] = $price;
             $val['smallPrice'] = $price;
-            $val['specEnabled'] = intval($specEnabledMap[$id] ?? 0);
+            $val['specEnabled'] = intval($val['goodsStyle'] ?? 0) === 1 ? 1 : 0;
         }
         //获取最终需要的价格
         return $list;
     }
 
-    //新建商品 ssh 20220404
+    /**
+     * 新建商品
+     * @param array $data 商品数据
+     * @param \bizHd\work\models\Work $work 工作单
+     * @return array | \common\base\models\Base  goods商品信息
+     * @throws \Exception
+     */
     public static function addGoods($data, $work = null)
     {
         $data['createTime'] = date("Y-m-d H:i:s");
@@ -626,7 +709,7 @@ class GoodsClass extends BaseClass
         $data['sn'] = $sn;
         $addStock = $data['stock'] ?? 0;
         unset($data['stock']);
-        $info = self::add($data, true);
+        $info = self::add($data, true); // 添加商品
         $id = $info->id;
         $name = $info->name;
         $py = $data['py'] ?? '';
@@ -719,7 +802,7 @@ class GoodsClass extends BaseClass
         } else {
             $itemList = $data['itemList'] ?? '';
             $itemArr = json_decode($itemList, true);
-            //新建花束有子项,采购绿植没有子项 
+            //新建花束有子项,采购绿植没有子项
             if (!empty($itemArr)) {
                 foreach ($itemArr as $item) {
                     $goodsItemData = [
@@ -909,6 +992,8 @@ class GoodsClass extends BaseClass
         CategoryClass::counters(['goodsNum' => -1], ['id' => $goodsHasCategoryIds]);
         GoodsClass::updateById($id, ['delStatus' => 1]);
         GoodsCategoryClass::updateByCondition(['gId' => $id], ['delStatus' => 1]);
+        // 级联软删规格子记录,避免主商品删除后留下可售孤儿规格
+        self::updateByCondition(['masterId' => $id], ['delStatus' => 1]);
     }
 
     //产品上下架 ssh 2019.12.8
@@ -916,6 +1001,8 @@ class GoodsClass extends BaseClass
     {
         self::updateById($id, ['status' => $status]);
         GoodsCategoryClass::updateByCondition(['gId' => $id], ['status' => $status]);
+        // 规格子记录与主商品同步上下架
+        self::updateByCondition(['masterId' => $id], ['status' => $status]);
     }
 
     //验证商品的有效性 ssh 20201.2.1

+ 1 - 1
biz-hd/groupBuy/classes/GroupBuyActivityClass.php

@@ -260,7 +260,7 @@ class GroupBuyActivityClass extends BaseClass
             }
             $virtualGroup = !empty($item['virtualGroup']) ? 1 : 0;
             $virtualMinutes = intval($item['virtualMinutes'] ?? 0);
-            $name = $goods->masterId > 0 ? $goods->name . '(' . $goods->specName . ')' : $goods->name;
+            $name = GoodsClass::formatSpecDisplayName($goods);
             $list[] = [
                 'id' => intval($item['id'] ?? 0),
                 'goodsId' => $goodsId,

+ 7 - 15
biz-hd/homePageConfig/classes/HomePageModuleClass.php

@@ -242,16 +242,13 @@ class HomePageModuleClass
             if ($realStock < $stock) {
                 $status = 0;
             }
-            if ($goods->masterId > 0) {
-                $goods->name = $goods->name . '(' . $goods->specName . ')';
-            }
             $list[] = [
                 'goodsId' => $goodsId,
                 'price' => round($price, 2),
                 'stock' => $stock,
                 'limit' => $limit,
                 'status' => $status,
-                'name' => $goods->name ?? ($item['name'] ?? ''),
+                'name' => GoodsClass::formatSpecDisplayName($goods),
                 'cover' => strval($goods->shortCover ?? ($goods->cover ?? ($item['cover'] ?? ''))),
                 'originPrice' => floatval($goods->price ?? ($item['originPrice'] ?? 0)),
             ];
@@ -285,12 +282,9 @@ class HomePageModuleClass
             if ($refreshStock) {
                 $goods = GoodsClass::getById($row['goodsId'], true);
                 if (!empty($goods) && intval($goods->mainId) === intval($mainId)) {
-                    if ($goods->masterId > 0) {
-                        $goods->name = $goods->name . '(' . $goods->specName . ')';
-                    }
                     $realStock = intval($goods->stock);
                     $row['realStock'] = $realStock;
-                    $row['name'] = strval($goods->name ?? $row['name']);
+                    $row['name'] = GoodsClass::formatSpecDisplayName($goods);
                     $row['cover'] = strval($goods->shortCover ?? ($goods->cover ?? $row['cover']));
                     $row['originPrice'] = floatval($goods->price ?? $row['originPrice']);
                     $row['priceType'] = $goods->priceType;
@@ -516,7 +510,7 @@ class HomePageModuleClass
             }
             $virtualGroup = !empty($item['virtualGroup']) ? 1 : 0;
             $virtualMinutes = intval($item['virtualMinutes'] ?? 0);
-            $name = $goods->masterId > 0 ? $goods->name . '(' . $goods->specName . ')' : $goods->name;
+            $name = GoodsClass::formatSpecDisplayName($goods);
             $list[] = [
                 'goodsId' => $goodsId,
                 'price' => round($price, 2),
@@ -802,6 +796,7 @@ class HomePageModuleClass
 
     /**
      * 将原始商品行格式化为首页/列表展示结构(含 coverUrl)
+     * goodsStyle=1 表示多规格,同时输出 specEnabled 兼容旧前端
      *
      * @param array $rows
      * @return array
@@ -809,15 +804,11 @@ class HomePageModuleClass
     public static function formatGoodsRows($rows)
     {
         $list = [];
-        $goodsIds = [];
-        foreach ($rows as $row) {
-            $goodsIds[] = intval($row['id'] ?? 0);
-        }
-        $specEnabledMap = GoodsClass::getSpecEnabledMap($goodsIds);
         foreach ($rows as $row) {
             $id = intval($row['id']);
             $cover = strval($row['cover'] ?? '');
             $coverUrl = $cover !== '' ? imgUtil::groupImg($cover) . '?x-oss-process=image/resize,m_fill,h_700,w_700' : '';
+            $goodsStyle = intval($row['goodsStyle'] ?? 0);
             $list[] = [
                 'id' => $id,
                 'name' => strval($row['name'] ?? ''),
@@ -827,7 +818,8 @@ class HomePageModuleClass
                 'cover' => $cover,
                 'coverUrl' => $coverUrl,
                 'sold' => intval(bcadd($row['actualSold'] ?? 0, $row['sold'] ?? 0)),
-                'specEnabled' => intval($specEnabledMap[$id] ?? 0),
+                'goodsStyle' => $goodsStyle,
+                'specEnabled' => $goodsStyle === 1 ? 1 : 0,
             ];
         }
         return $list;

+ 1 - 1
biz-hd/seckill/classes/SeckillActivityClass.php

@@ -255,7 +255,7 @@ class SeckillActivityClass extends BaseClass
             if ($realStock < $stock) {
                 $status = 0;
             }
-            $name = $goods->masterId > 0 ? $goods->name . '(' . $goods->specName . ')' : $goods->name;
+            $name = GoodsClass::formatSpecDisplayName($goods);
             $list[] = [
                 'id' => intval($item['id'] ?? 0),
                 'goodsId' => $goodsId,

+ 5 - 1
sql/20260714_goods_use_case.sql

@@ -31,4 +31,8 @@ ALTER TABLE xhHd
 
 
 ALTER TABLE xhCustom
-  add COLUMN `homeRule` tinyint(4) NOT NULL DEFAULT '0' COMMENT '上门遵循规则 0遵循总设置 1遵循自定义' after `updateTime`;
+  add COLUMN `homeRule` tinyint(4) NOT NULL DEFAULT '0' COMMENT '上门遵循规则 0遵循总设置 1遵循自定义' after `updateTime`;
+
+
+-- 商品表添加索引
+ALTER TABLE xhGoods ADD KEY `idx_m` (`masterId`);