Przeglądaj źródła

fix(goods): 校正商品规格封面入库路径

- 新增和编辑多规格商品时,将无效封面回落到对应规格首图并同步首规格图片至主商品
- 统一商品新增、更新及子规格同步的封面规范化逻辑,避免占位值「1」作为图片路径入库
- API: 商品新增与更新接口调整封面持久化规则
- Database: xhGoods.cover 写入语义调整为优先保存 shopImg 中的有效短路径
shizhongqi 11 godzin temu
rodzic
commit
b35b1a8b17

+ 13 - 2
app-hd/models/goods/AddForm.php

@@ -255,6 +255,12 @@ class AddForm extends BaseForm
                 $this->addError($attribute, $name . '已售数量错误');
                 return;
             }
+            $specImg = is_array($spec['shopImg'] ?? null) ? $spec['shopImg'] : [];
+            $specCover = trim($spec['cover'] ?? '');
+            // 封面必须落在该规格图片列表里,占位值「1」回落到第一张
+            if (!empty($specImg) && ($specCover === '' || !in_array($specCover, $specImg, true))) {
+                $specCover = $specImg[0];
+            }
             $formatList[] = [
                 'id' => (int)($spec['id'] ?? 0),
                 'specName' => $specName,
@@ -265,8 +271,8 @@ class AddForm extends BaseForm
                 'flowerNum' => (int)$flowerNum,
                 'weight' => (float)$weight,
                 'sold' => (int)$sold,
-                'shopImg' => is_array($spec['shopImg'] ?? null) ? $spec['shopImg'] : [],
-                'cover' => trim($spec['cover'] ?? ''),
+                'shopImg' => $specImg,
+                'cover' => $specCover,
             ];
         }
         $this->$attribute = $formatList;
@@ -281,6 +287,11 @@ class AddForm extends BaseForm
         $this->flowerNum = $firstSpec['flowerNum'];
         $this->weight = $firstSpec['weight'];
         $this->sold = $firstSpec['sold'];
+        // 规格1即主记录:图片/封面回写主字段,避免把占位值「1」当封面入库
+        if (!empty($firstSpec['shopImg'])) {
+            $this->shopImg = $firstSpec['shopImg'];
+            $this->cover = $firstSpec['cover'];
+        }
     }
 
     /**

+ 13 - 2
app-hd/models/goods/UpdateForm.php

@@ -277,6 +277,12 @@ class UpdateForm extends BaseForm
                 $this->addError($attribute, $name . '已售数量错误');
                 return;
             }
+            $specImg = is_array($spec['shopImg'] ?? null) ? $spec['shopImg'] : [];
+            $specCover = trim($spec['cover'] ?? '');
+            // 封面必须落在该规格图片列表里,占位值「1」回落到第一张
+            if (!empty($specImg) && ($specCover === '' || !in_array($specCover, $specImg, true))) {
+                $specCover = $specImg[0];
+            }
             $formatList[] = [
                 'id' => (int)($spec['id'] ?? 0),
                 'specName' => $specName,
@@ -287,8 +293,8 @@ class UpdateForm extends BaseForm
                 'flowerNum' => (int)$flowerNum,
                 'weight' => (float)$weight,
                 'sold' => (int)$sold,
-                'shopImg' => is_array($spec['shopImg'] ?? null) ? $spec['shopImg'] : [],
-                'cover' => trim($spec['cover'] ?? ''),
+                'shopImg' => $specImg,
+                'cover' => $specCover,
             ];
         }
         $this->$attribute = $formatList;
@@ -303,6 +309,11 @@ class UpdateForm extends BaseForm
         $this->flowerNum = $firstSpec['flowerNum'];
         $this->weight = $firstSpec['weight'];
         $this->sold = $firstSpec['sold'];
+        // 规格1即主记录:图片/封面回写主字段,避免把占位值「1」当封面入库
+        if (!empty($firstSpec['shopImg'])) {
+            $this->shopImg = $firstSpec['shopImg'];
+            $this->cover = $firstSpec['cover'];
+        }
     }
 
     /**

+ 25 - 6
biz-hd/goods/classes/GoodsClass.php

@@ -94,6 +94,23 @@ class GoodsClass extends BaseClass
         return $spec;
     }
 
+    /**
+     * 封面必须是 shopImg 中的真实短路径。
+     * 历史默认值「1」表示第 1 张图,不是路径,不能入库。
+     * @param mixed $cover 提交的封面
+     * @param mixed $shopImg 图片短路径列表
+     * @return string
+     */
+    public static function normalizeGoodsCover($cover, $shopImg)
+    {
+        $list = is_array($shopImg) ? $shopImg : [];
+        $cover = is_string($cover) ? $cover : '';
+        if (!empty($list) && ($cover === '' || !in_array($cover, $list, true))) {
+            return strval($list[0]);
+        }
+        return $cover;
+    }
+
     /**
      * 同步多规格子记录:首规格已由 Form 回写到主记录,这里只维护第 2..n 个规格子行
      * 关闭多规格时软删全部子行;仅一个规格时不建子行
@@ -153,7 +170,7 @@ class GoodsClass extends BaseClass
             $specImg = $spec['shopImg'] ?? [];
             if (is_array($specImg) && !empty($specImg)) {
                 $fields['shopImg'] = json_encode($specImg);
-                $fields['cover'] = !empty($spec['cover']) && in_array($spec['cover'], $specImg, true) ? $spec['cover'] : $specImg[0];
+                $fields['cover'] = self::normalizeGoodsCover($spec['cover'] ?? '', $specImg);
             }
             if ($id && isset($old[$id])) {
                 $kept[] = $id;
@@ -698,6 +715,10 @@ class GoodsClass extends BaseClass
     public static function addGoods($data, $work = null)
     {
         $data['createTime'] = date("Y-m-d H:i:s");
+        // 入库前校正封面:必须是 shopImg 里的路径,避免把历史占位值「1」写入 xhGoods.cover
+        if (isset($data['shopImg']) && is_array($data['shopImg'])) {
+            $data['cover'] = self::normalizeGoodsCover($data['cover'] ?? '', $data['shopImg']);
+        }
         if (!empty($data['shopImg'])) {
             $data['shopImg'] = json_encode($data['shopImg']);
         }
@@ -903,11 +924,9 @@ class GoodsClass extends BaseClass
             }
         }
 
-        // 字符串的,即认为是 图片URL
-        if (isset($data['cover']) && is_string($data['cover'])) {
-
-        } else {
-            $data['cover'] = $data['shopImg'][0] ?? '';
+        // 封面必须是 shopImg 中的真实短路径;历史默认值「1」表示第1张,不是路径
+        if (isset($data['shopImg']) && is_array($data['shopImg'])) {
+            $data['cover'] = self::normalizeGoodsCover($data['cover'] ?? '', $data['shopImg']);
         }
         $data['shopImg'] = json_encode($data['shopImg']);
         $data['py'] = $py;