Browse Source

fix:优化商品的

super-yimizi 1 month ago
parent
commit
f51bc77d41

+ 24 - 6
application/admin/controller/shop/Goods.php

@@ -223,7 +223,8 @@ class Goods extends Backend
                         'key' => $subitem['spec_name'],
                         'key' => $subitem['spec_name'],
                         'value' => $subitem['spec_value_value'],
                         'value' => $subitem['spec_value_value'],
                         'key_id' => $subitem['spec_id'],
                         'key_id' => $subitem['spec_id'],
-                        'value_id' => $subitem['spec_value_id']
+                        'value_id' => $subitem['spec_value_id'],
+                        'type' => $specArr['type'] ?? 'basic' // 增加规格类型字段
                     ];
                     ];
                     break;
                     break;
                 }
                 }
@@ -370,9 +371,9 @@ class Goods extends Backend
     //添加商品多规格
     //添加商品多规格
     protected function addMultiSpecSku($skus, $spec, $goods_id)
     protected function addMultiSpecSku($skus, $spec, $goods_id)
     {
     {
-        //属性入库
+        //属性入库,传递规格类型信息
         $specList = Spec::push($spec);
         $specList = Spec::push($spec);
-        $newSpec = GoodsSkuSpec::push($specList, $goods_id);
+        $newSpec = GoodsSkuSpec::push($specList, $goods_id, $spec);
         //匹配属性
         //匹配属性
         $list = $this->sku_model->where('goods_id', $goods_id)->select();
         $list = $this->sku_model->where('goods_id', $goods_id)->select();
         $newData = [];
         $newData = [];
@@ -706,11 +707,12 @@ class Goods extends Backend
     
     
         // 构造规格数据结构
         // 构造规格数据结构
         $spec_data = [];
         $spec_data = [];
+        $spec_values = []; // 用于传递给前端的规格值完整数据
         if ($row->spec_type == 1) { // 多规格商品
         if ($row->spec_type == 1) { // 多规格商品
-            // 查询规格和规格值
+            // 查询规格和规格值,包含规格类型
             $specs = Db::name('shop_goods_sku_spec')
             $specs = Db::name('shop_goods_sku_spec')
                 ->alias('gss')
                 ->alias('gss')
-                ->field('sp.id as spec_id, sp.name as spec_name, sv.id as spec_value_id, sv.value, sv.image, sv.desc')
+                ->field('sp.id as spec_id, sp.name as spec_name, sp.type as spec_type, sv.id as spec_value_id, sv.value, sv.image, sv.desc')
                 ->join('shop_spec sp', 'sp.id = gss.spec_id', 'LEFT')
                 ->join('shop_spec sp', 'sp.id = gss.spec_id', 'LEFT')
                 ->join('shop_spec_value sv', 'sv.id = gss.spec_value_id', 'LEFT')
                 ->join('shop_spec_value sv', 'sv.id = gss.spec_value_id', 'LEFT')
                 ->where('gss.goods_id', $row->id)
                 ->where('gss.goods_id', $row->id)
@@ -720,11 +722,25 @@ class Goods extends Backend
             // 按规格分组
             // 按规格分组
             $spec_groups = [];
             $spec_groups = [];
             foreach ($specs as $spec) {
             foreach ($specs as $spec) {
-                $spec_groups[$spec['spec_id']]['name'] = $spec['spec_name'];
+                if (!isset($spec_groups[$spec['spec_id']])) {
+                    $spec_groups[$spec['spec_id']]['name'] = $spec['spec_name'];
+                    $spec_groups[$spec['spec_id']]['type'] = $spec['spec_type'] == 2 ? 'custom' : 'basic';
+                    $spec_groups[$spec['spec_id']]['value'] = [];
+                }
                 $spec_groups[$spec['spec_id']]['value'][] = [
                 $spec_groups[$spec['spec_id']]['value'][] = [
                     'id' => $spec['spec_value_id'],
                     'id' => $spec['spec_value_id'],
                     'name' => $spec['value'],
                     'name' => $spec['value'],
                     'image' => $spec['image'] ?: '',
                     'image' => $spec['image'] ?: '',
+                    'description' => $spec['desc'] ?: ''
+                ];
+                
+                // 构造规格值数据,用于前端初始化
+                $spec_values[] = [
+                    'spec_name' => $spec['spec_name'],
+                    'spec_type' => $spec['spec_type'],
+                    'value' => $spec['value'],
+                    'image' => $spec['image'] ?: '',
+                    'description' => $spec['desc'] ?: ''
                 ];
                 ];
             }
             }
             
             
@@ -733,6 +749,7 @@ class Goods extends Backend
                 $spec_data[] = [
                 $spec_data[] = [
                     'id' => $spec_id,
                     'id' => $spec_id,
                     'name' => $spec_info['name'],
                     'name' => $spec_info['name'],
+                    'type' => $spec_info['type'],
                     'value' => $spec_info['value']
                     'value' => $spec_info['value']
                 ];
                 ];
             }
             }
@@ -742,6 +759,7 @@ class Goods extends Backend
         $this->assignconfig('goods', $row);
         $this->assignconfig('goods', $row);
         $this->assignconfig('goods_skus', $list);
         $this->assignconfig('goods_skus', $list);
         $this->assignconfig('spec_data', $spec_data); // 传递规格数据结构
         $this->assignconfig('spec_data', $spec_data); // 传递规格数据结构
+        $this->assignconfig('spec_values', $spec_values); // 传递规格值完整数据
 
 
         return $this->view->fetch();
         return $this->view->fetch();
     }
     }

+ 18 - 1
application/admin/model/shop/GoodsSkuSpec.php

@@ -23,11 +23,20 @@ class GoodsSkuSpec extends Model
     // 追加属性
     // 追加属性
     protected $append = [];
     protected $append = [];
 
 
-    public static function push($spec_list, $goods_id)
+    public static function push($spec_list, $goods_id, $spec_data = [])
     {
     {
         $data = [];
         $data = [];
         $old_list = self::where('goods_id', $goods_id)->select(); //原有的
         $old_list = self::where('goods_id', $goods_id)->select(); //原有的
         $new_list = $spec_list; //现有的
         $new_list = $spec_list; //现有的
+        
+        // 构建规格类型映射表
+        $spec_type_map = [];
+        if (!empty($spec_data)) {
+            foreach ($spec_data as $spec) {
+                $spec_type_map[$spec['name']] = $spec['type'] ?? 'basic';
+            }
+        }
+        
         //匹配相等的不动
         //匹配相等的不动
         foreach ($old_list as $key => $item) {
         foreach ($old_list as $key => $item) {
             foreach ($new_list as $index => $res) {
             foreach ($new_list as $index => $res) {
@@ -42,15 +51,23 @@ class GoodsSkuSpec extends Model
         //不等的替换
         //不等的替换
         $k = 0;
         $k = 0;
         foreach ($new_list as $idx => $row) {
         foreach ($new_list as $idx => $row) {
+            // 确定规格类型
+            $spec_type = 1; // 默认为基础规格
+            if (isset($row['spec_name']) && isset($spec_type_map[$row['spec_name']])) {
+                $spec_type = $spec_type_map[$row['spec_name']] === 'custom' ? 2 : 1;
+            }
+            
             if (isset($old_list[$k])) {
             if (isset($old_list[$k])) {
                 $spec = $old_list[$k];
                 $spec = $old_list[$k];
                 $row['id'] = $spec['id'];
                 $row['id'] = $spec['id'];
                 $spec->spec_id = $row['spec_id'];
                 $spec->spec_id = $row['spec_id'];
                 $spec->spec_value_id = $row['spec_value_id'];
                 $spec->spec_value_id = $row['spec_value_id'];
+                $spec->type = $spec_type; // 更新规格类型
                 $spec->save();
                 $spec->save();
                 unset($old_list[$k]);
                 unset($old_list[$k]);
             } else { //多余的
             } else { //多余的
                 $row['goods_id'] = $goods_id;
                 $row['goods_id'] = $goods_id;
+                $row['type'] = $spec_type; // 添加规格类型
                 $model = new self();
                 $model = new self();
                 $model->allowField(true);
                 $model->allowField(true);
                 $model->save($row);
                 $model->save($row);

+ 59 - 41
application/admin/view/shop/goods/add_sku.html

@@ -1156,41 +1156,50 @@
                                             <!-- 规格值图像 -->
                                             <!-- 规格值图像 -->
                                             <div class="spec-col-image">
                                             <div class="spec-col-image">
                                                 <div class="spec-image-container">
                                                 <div class="spec-image-container">
-                                                    <div class="image-thumb" :id="'p-spec-image-'+key+'-'+index" data-template="p-spec-image-tpl">
-                                                        <img v-if="specList[key].value[index].image" :src="Fast.api.cdnurl(specList[key].value[index].image)"/>
+                                                    <div class="image-thumb" :id="'p-spec-image-'+key+'-'+index" data-template="p-spec-image-tpl" v-if="specList[key].value[index].image">
+                                                        <img :src="Fast.api.cdnurl(specList[key].value[index].image)"/>
                                                     </div>
                                                     </div>
-                                                                                                    <div class="input-group">
-                                                    <input type="hidden" 
-                                                           :id="'c-spec-image-'+key+'-'+index" 
-                                                           class="form-control spec-image-input" 
-                                                           :data-spec-key="key"
-                                                           :data-value-index="index"
-                                                           v-model="specList[key].value[index].image"/>
-                                                    <div class="input-group-addon no-border no-padding">
-                                                        <span>
-                                                            <button type="button"
-                                                                    class="btn btn-danger spec-upload-btn"
-                                                                    :data-spec-key="key"
-                                                                    :data-value-index="index"
-                                                                    data-mimetype="image/gif,image/jpeg,image/png,image/jpg,image/bmp,image/webp"
-                                                                    data-multiple="false">
-                                                                <i class="fa fa-upload"></i>
-                                                                上传
-                                                            </button>
-                                                        </span>
-                                                        <span>
-                                                            <button type="button" 
-                                                                    class="btn btn-primary spec-choose-btn"
-                                                                    :data-spec-key="key"
-                                                                    :data-value-index="index"
-                                                                    data-mimetype="image/*" 
-                                                                    data-multiple="false">
-                                                                <i class="fa fa-list"></i>
-                                                                选择
-                                                            </button>
-                                                        </span>
+                                                    <div class="spec-thumb-placeholder" v-else>
+                                                        <i class="fa fa-image"></i>
+                                                        <span>规格图</span>
+                                                    </div>
+                                                    <div class="input-group">
+                                                        <input type="hidden" 
+                                                               :id="'c-spec-image-'+key+'-'+index" 
+                                                               class="form-control spec-image-input" 
+                                                               :data-spec-key="key"
+                                                               :data-value-index="index"
+                                                               v-model="specList[key].value[index].image"/>
+                                                        <div class="input-group-addon no-border no-padding">
+                                                            <span>
+                                                                <button type="button"
+                                                                        class="btn btn-danger btn-xs spec-upload-btn"
+                                                                        :data-spec-key="key"
+                                                                        :data-value-index="index"
+                                                                        data-mimetype="image/gif,image/jpeg,image/png,image/jpg,image/bmp,image/webp"
+                                                                        data-multiple="false"
+                                                                        title="上传规格值图片">
+                                                                    <i class="fa fa-upload"></i>
+                                                                    上传
+                                                                </button>
+                                                            </span>
+                                                            <span>
+                                                                <button type="button" 
+                                                                        class="btn btn-primary btn-xs spec-choose-btn"
+                                                                        :data-spec-key="key"
+                                                                        :data-value-index="index"
+                                                                        data-mimetype="image/*" 
+                                                                        data-multiple="false"
+                                                                        title="从附件库选择图片">
+                                                                    <i class="fa fa-list"></i>
+                                                                    选择
+                                                                </button>
+                                                            </span>
+                                                        </div>
+                                                    </div>
+                                                    <div class="upload-hint text-muted">
+                                                        推荐尺寸: 400x400px
                                                     </div>
                                                     </div>
-                                                </div>
                                                 </div>
                                                 </div>
                                             </div>
                                             </div>
                                             
                                             
@@ -1293,8 +1302,12 @@
                         {{specValueText(item.skus,ik)}}
                         {{specValueText(item.skus,ik)}}
                     </td>
                     </td>
                     <td class="td-img">
                     <td class="td-img">
-                        <div class="image-thumb" :id="'p-image-'+index" data-template="p-image-tpl">
-                            <img src=""/>
+                        <div class="image-thumb" :id="'p-image-'+index" data-template="p-image-tpl" v-if="item.image">
+                            <img :src="Fast.api.cdnurl(item.image)"/>
+                        </div>
+                        <div class="spec-thumb-placeholder" v-else style="width: 40px; height: 40px; margin: 0 auto 5px;">
+                            <i class="fa fa-image"></i>
+                            <span style="font-size: 8px;">SKU图</span>
                         </div>
                         </div>
                         <div class="input-group">
                         <div class="input-group">
                             <input type="hidden" id="a" :id="'c-image-'+index" class="form-control sku-images" :data-index="index" :value="item.image?item.image:''"/>
                             <input type="hidden" id="a" :id="'c-image-'+index" class="form-control sku-images" :data-index="index" :value="item.image?item.image:''"/>
@@ -1303,22 +1316,27 @@
                                         <button type="button"
                                         <button type="button"
                                                 :disabled="tableData[index].status == 0"
                                                 :disabled="tableData[index].status == 0"
                                                 :id="'faupload-image-'+index"
                                                 :id="'faupload-image-'+index"
-                                                class="btn btn-danger faupload"
+                                                class="btn btn-danger btn-xs faupload"
                                                 :data-input-id="'c-image-'+index" data-mimetype="image/gif,image/jpeg,image/png,image/jpg,image/bmp,image/webp"
                                                 :data-input-id="'c-image-'+index" data-mimetype="image/gif,image/jpeg,image/png,image/jpg,image/bmp,image/webp"
-                                                data-multiple="false" :data-preview-id="'p-image-'+index">
+                                                data-multiple="false" :data-preview-id="'p-image-'+index"
+                                                title="上传SKU封面图片">
                                         <i class="fa fa-upload"></i>
                                         <i class="fa fa-upload"></i>
-                                            {:__('Upload')}
+                                            上传
                                         </button>
                                         </button>
                                     </span>
                                     </span>
                                 <span>
                                 <span>
-                                        <button type="button" :disabled="tableData[index].status == 0" :id="'fachoose-image-'+index" class="btn btn-primary fachoose"
-                                                :data-input-id="'c-image-'+index" data-mimetype="image/*" data-multiple="false">
+                                        <button type="button" :disabled="tableData[index].status == 0" :id="'fachoose-image-'+index" class="btn btn-primary btn-xs fachoose"
+                                                :data-input-id="'c-image-'+index" data-mimetype="image/*" data-multiple="false"
+                                                title="从附件库选择图片">
                                             <i class="fa fa-list"></i>
                                             <i class="fa fa-list"></i>
-                                            {:__('Choose')}
+                                            选择
                                         </button>
                                         </button>
                                     </span>
                                     </span>
                             </div>
                             </div>
                         </div>
                         </div>
+                        <div class="upload-hint text-center">
+                            <small class="text-muted" style="font-size: 9px;">推荐: 400x400px</small>
+                        </div>
                     </td>
                     </td>
                     <td class="scrollable-columns">
                     <td class="scrollable-columns">
                         <input class="form-control" :disabled="tableData[index].status == 0" id="a" :id="'sku_sn'+index" type="text" v-model="tableData[index].sku_sn">
                         <input class="form-control" :disabled="tableData[index].status == 0" id="a" :id="'sku_sn'+index" type="text" v-model="tableData[index].sku_sn">

+ 1 - 1
application/api/controller/inspection/Order.php

@@ -74,7 +74,7 @@ class Order extends Base
 
 
           // 查询对应的工厂 信息
           // 查询对应的工厂 信息
           $supplierId = $this->application->supplier_id;
           $supplierId = $this->application->supplier_id;
-          $list = OrderService::getOrderList($userId ,$param, $status,$supplierId);
+          $list = OrderService::getSupplierOrderList($supplierId ,$userId, $param, $status);
           foreach ($list as $item) {
           foreach ($list as $item) {
              // $item->append(['order_status_text']);
              // $item->append(['order_status_text']);
               $field = 'id,order_sn,amount,goods_price,order_amount,express_name,express_no,order_goods,order_status_text,order_status';
               $field = 'id,order_sn,amount,goods_price,order_amount,express_name,express_no,order_goods,order_status_text,order_status';

+ 88 - 1
application/common/Service/OrderService.php

@@ -633,8 +633,95 @@ class OrderService
         return $order;
         return $order;
     }
     }
 
 
-    
+    /**
+     * 获取供应商订单列表 - 关联查询方式
+     * @param int $supplierId 供应商ID  
+     * @param int $userId 用户ID(可选)
+     * @param array $param 查询参数
+     * @param array $status 订单状态筛选
+     * @return \think\Paginator
+     */
+    public static function getSupplierOrderList($supplierId, $userId = 0, $param = [], $status = [])
+    {
+        $pageSize = $param['page_size'] ?? 10;
+        
+        return Order::alias('o')
+            ->join('shop_order_goods og', 'o.order_sn = og.order_sn', 'inner')
+            ->with(['orderGoods' => function($query) use ($supplierId) {
+                $query->where('supplier_id', $supplierId);
+            }])
+            ->where('og.supplier_id', $supplierId)
+            ->where(function ($query) use ($param, $userId, $status) {
+                if (!empty($userId)) {
+                    $query->where('o.user_id', $userId);
+                }
+                
+                if (!empty($status)) {
+                    $query->whereIn('o.order_status', $status);
+                }
+                
+                if (isset($param['keywords']) && $param['keywords'] != '') {
+                    $query->where(function($subQuery) use ($param) {
+                        $subQuery->where('o.order_sn', 'like', '%' . $param['keywords'] . '%')
+                                ->whereOr('og.goods_title', 'like', '%' . $param['keywords'] . '%');
+                    });
+                }
+            })
+            ->field('o.*')
+            ->group('o.id')
+            ->order('o.createtime desc')
+            ->paginate($pageSize, false, ['query' => request()->get()]);
+    }
 
 
+    /**
+     * 获取供应商订单详情 - 只返回该供应商的商品
+     * @param string $orderSn 订单号
+     * @param int $supplierId 供应商ID
+     * @return array|null
+     */
+    public static function getSupplierOrderDetail($orderSn, $supplierId)
+    {
+        $order = Order::where('order_sn', $orderSn)->find();
+        if (!$order) {
+            return null;
+        }
+        
+        // 获取该供应商在此订单中的商品
+        $orderGoods = OrderGoods::where('order_sn', $orderSn)
+            ->where('supplier_id', $supplierId)
+            ->select();
+        
+        $order->orderGoods = $orderGoods;
+        return $order;
+    }
 
 
+    /**
+     * 获取供应商订单统计
+     * @param int $supplierId 供应商ID
+     * @param int $userId 用户ID(可选)
+     * @return array
+     */
+    public static function getSupplierOrderStatusCount($supplierId, $userId = 0)
+    {
+        $baseQuery = function($status) use ($supplierId, $userId) {
+            $query = Order::alias('o')
+                ->join('shop_order_goods og', 'o.order_sn = og.order_sn', 'inner')
+                ->where('og.supplier_id', $supplierId)
+                ->where('o.order_status', $status);
+            
+            if (!empty($userId)) {
+                $query->where('o.user_id', $userId);
+            }
+            
+            return $query->count('DISTINCT o.id');
+        };
+        
+        return [
+            'unpay'  => $baseQuery(OrderEnum::STATUS_CREATE),  // 待付款
+            'unsend' => $baseQuery(OrderEnum::STATUS_PAY),     // 待发货
+            'unrec'  => $baseQuery(OrderEnum::STATUS_SHIP),    // 待收货
+            'uneva'  => $baseQuery(OrderEnum::STATUS_CONFIRM), // 待评价
+        ];
+    }
 
 
 } 
 } 

+ 88 - 1
application/common/service/OrderService.php

@@ -633,8 +633,95 @@ class OrderService
         return $order;
         return $order;
     }
     }
 
 
-    
+    /**
+     * 获取供应商订单列表 - 关联查询方式
+     * @param int $supplierId 供应商ID  
+     * @param int $userId 用户ID(可选)
+     * @param array $param 查询参数
+     * @param array $status 订单状态筛选
+     * @return \think\Paginator
+     */
+    public static function getSupplierOrderList($supplierId, $userId = 0, $param = [], $status = [])
+    {
+        $pageSize = $param['page_size'] ?? 10;
+        
+        return Order::alias('o')
+            ->join('shop_order_goods og', 'o.order_sn = og.order_sn', 'inner')
+            ->with(['orderGoods' => function($query) use ($supplierId) {
+                $query->where('supplier_id', $supplierId);
+            }])
+            ->where('og.supplier_id', $supplierId)
+            ->where(function ($query) use ($param, $userId, $status) {
+                if (!empty($userId)) {
+                    $query->where('o.user_id', $userId);
+                }
+                
+                if (!empty($status)) {
+                    $query->whereIn('o.order_status', $status);
+                }
+                
+                if (isset($param['keywords']) && $param['keywords'] != '') {
+                    $query->where(function($subQuery) use ($param) {
+                        $subQuery->where('o.order_sn', 'like', '%' . $param['keywords'] . '%')
+                                ->whereOr('og.goods_title', 'like', '%' . $param['keywords'] . '%');
+                    });
+                }
+            })
+            ->field('o.*')
+            ->group('o.id')
+            ->order('o.createtime desc')
+            ->paginate($pageSize, false, ['query' => request()->get()]);
+    }
 
 
+    /**
+     * 获取供应商订单详情 - 只返回该供应商的商品
+     * @param string $orderSn 订单号
+     * @param int $supplierId 供应商ID
+     * @return array|null
+     */
+    public static function getSupplierOrderDetail($orderSn, $supplierId)
+    {
+        $order = Order::where('order_sn', $orderSn)->find();
+        if (!$order) {
+            return null;
+        }
+        
+        // 获取该供应商在此订单中的商品
+        $orderGoods = OrderGoods::where('order_sn', $orderSn)
+            ->where('supplier_id', $supplierId)
+            ->select();
+        
+        $order->orderGoods = $orderGoods;
+        return $order;
+    }
 
 
+    /**
+     * 获取供应商订单统计
+     * @param int $supplierId 供应商ID
+     * @param int $userId 用户ID(可选)
+     * @return array
+     */
+    public static function getSupplierOrderStatusCount($supplierId, $userId = 0)
+    {
+        $baseQuery = function($status) use ($supplierId, $userId) {
+            $query = Order::alias('o')
+                ->join('shop_order_goods og', 'o.order_sn = og.order_sn', 'inner')
+                ->where('og.supplier_id', $supplierId)
+                ->where('o.order_status', $status);
+            
+            if (!empty($userId)) {
+                $query->where('o.user_id', $userId);
+            }
+            
+            return $query->count('DISTINCT o.id');
+        };
+        
+        return [
+            'unpay'  => $baseQuery(OrderEnum::STATUS_CREATE),  // 待付款
+            'unsend' => $baseQuery(OrderEnum::STATUS_PAY),     // 待发货
+            'unrec'  => $baseQuery(OrderEnum::STATUS_SHIP),    // 待收货
+            'uneva'  => $baseQuery(OrderEnum::STATUS_CONFIRM), // 待评价
+        ];
+    }
 
 
 } 
 } 

+ 255 - 141
public/assets/js/backend/shop/goods.js

@@ -1056,56 +1056,84 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                 // 多规格验证
                 // 多规格验证
                 console.log('验证多规格');
                 console.log('验证多规格');
                 
                 
-                if (typeof vm !== 'undefined' && vm && vm.tableData) {
-                    var hasValidSku = false;
-                    var validSkuCount = 0;
-                    
-                    console.log('检查SKU数据, tableData长度:', vm.tableData.length);
-                    
-                    for (var i = 0; i < vm.tableData.length; i++) {
-                        var sku = vm.tableData[i];
-                        console.log('检查SKU[' + i + ']:', {
-                            status: sku.status,
-                            price: sku.price,
-                            stocks: sku.stocks,
-                            sku_sn: sku.sku_sn
-                        });
+                if (typeof vm !== 'undefined' && vm && vm.specList && vm.specList.length > 0) {
+                    // 验证规格值图片 - 定制规格必须上传图片
+                    console.log('验证规格值图片');
+                    for (var i = 0; i < vm.specList.length; i++) {
+                        var spec = vm.specList[i];
+                        console.log('检查规格[' + i + ']:', spec);
                         
                         
-                        // 只检查状态为显示的SKU
-                        var isVisible = (sku.status === 1 || sku.status === '1' || sku.status === true);
+                        if (spec.type === 'custom') {
+                            // 定制规格必须上传图片
+                            if (spec.value && spec.value.length > 0) {
+                                for (var j = 0; j < spec.value.length; j++) {
+                                    var value = spec.value[j];
+                                    if (value.name && value.name.trim() !== '') {
+                                        if (!value.image || value.image.trim() === '') {
+                                            errors.push('定制规格"' + spec.name + '"的规格值"' + value.name + '"必须上传图片');
+                                            console.log('定制规格值图片验证失败:', spec.name, value.name);
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    
+                    // 验证SKU数据
+                    if (vm.tableData && vm.tableData.length > 0) {
+                        var hasValidSku = false;
+                        var validSkuCount = 0;
                         
                         
-                        console.log('SKU[' + i + '] 显示状态:', sku.status, '可见:', isVisible);
+                        console.log('检查SKU数据, tableData长度:', vm.tableData.length);
                         
                         
-                        if (isVisible) {
-                            var price = parseFloat(sku.price);
-                            var stocks = parseInt(sku.stocks);
-                            
-                            console.log('SKU[' + i + '] 检查通过, price:', price, 'stocks:', stocks);
+                        for (var i = 0; i < vm.tableData.length; i++) {
+                            var sku = vm.tableData[i];
+                            console.log('检查SKU[' + i + ']:', {
+                                status: sku.status,
+                                price: sku.price,
+                                stocks: sku.stocks,
+                                sku_sn: sku.sku_sn
+                            });
                             
                             
-                            hasValidSku = true;
-                            validSkuCount++;
+                            // 只检查状态为显示的SKU
+                            var isVisible = (sku.status === 1 || sku.status === '1' || sku.status === true);
                             
                             
-                            // 验证价格必须大于0
-                            if (!price || price <= 0) {
-                                errors.push('SKU销售价必须大于0');
-                                console.log('SKU[' + i + ']销售价验证失败:', price);
-                                break;
-                            }
+                            console.log('SKU[' + i + '] 显示状态:', sku.status, '可见:', isVisible);
                             
                             
-                            // 验证库存
-                            if (isNaN(stocks) || stocks <= 0) {
-                                errors.push('SKU库存必须大于0');
-                                console.log('SKU[' + i + ']库存验证失败:', stocks);
-                                break;
+                            if (isVisible) {
+                                var price = parseFloat(sku.price);
+                                var stocks = parseInt(sku.stocks);
+                                
+                                console.log('SKU[' + i + '] 检查通过, price:', price, 'stocks:', stocks);
+                                
+                                hasValidSku = true;
+                                validSkuCount++;
+                                
+                                // 验证价格必须大于0
+                                if (!price || price <= 0) {
+                                    errors.push('SKU销售价必须大于0');
+                                    console.log('SKU[' + i + ']销售价验证失败:', price);
+                                    break;
+                                }
+                                
+                                // 验证库存
+                                if (isNaN(stocks) || stocks <= 0) {
+                                    errors.push('SKU库存必须大于0');
+                                    console.log('SKU[' + i + ']库存验证失败:', stocks);
+                                    break;
+                                }
                             }
                             }
                         }
                         }
-                    }
-                    
-                    console.log('有效SKU数量:', validSkuCount);
-                    
-                    if (!hasValidSku) {
-                        errors.push('请至少设置一个有效的SKU');
-                        console.log('没有有效的SKU');
+                        
+                        console.log('有效SKU数量:', validSkuCount);
+                        
+                        if (!hasValidSku) {
+                            errors.push('请至少设置一个有效的SKU');
+                            console.log('没有有效的SKU');
+                        }
+                    } else {
+                        errors.push('请设置SKU数据');
+                        console.log('SKU数据不存在');
                     }
                     }
                 } else {
                 } else {
                     errors.push('请设置商品规格');
                     errors.push('请设置商品规格');
@@ -2065,6 +2093,29 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                     isValid = false;
                     isValid = false;
                     errors.push('请设置商品规格');
                     errors.push('请设置商品规格');
                 } else {
                 } else {
+                    // 验证规格值图片 - 定制规格必须上传图片
+                    console.log('第二次验证: 验证规格值图片');
+                    for (var i = 0; i < vm.specList.length; i++) {
+                        var spec = vm.specList[i];
+                        console.log('第二次验证: 检查规格[' + i + ']:', spec);
+                        
+                        if (spec.type === 'custom') {
+                            // 定制规格必须上传图片
+                            if (spec.value && spec.value.length > 0) {
+                                for (var j = 0; j < spec.value.length; j++) {
+                                    var value = spec.value[j];
+                                    if (value.name && value.name.trim() !== '') {
+                                        if (!value.image || value.image.trim() === '') {
+                                            isValid = false;
+                                            errors.push('定制规格"' + spec.name + '"的规格值"' + value.name + '"必须上传图片');
+                                            console.log('第二次验证: 定制规格值图片验证失败:', spec.name, value.name);
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    
                     // 检查是否有有效的规格组合
                     // 检查是否有有效的规格组合
                     if (!vm.tableData || vm.tableData.length === 0) {
                     if (!vm.tableData || vm.tableData.length === 0) {
                         isValid = false;
                         isValid = false;
@@ -2607,116 +2658,179 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                                     if (Config.goods && Config.goods.spec_type == '1') {
                                     if (Config.goods && Config.goods.spec_type == '1') {
                                         console.log('初始化多规格数据');
                                         console.log('初始化多规格数据');
                                         let specList = [];
                                         let specList = [];
-                                        let specName = {};
                                         
                                         
-                                        for (let item of Config.goods_skus) {
-                                            console.log('处理SKU项:', item);
-                                            if (item.sku_attr) {
-                                                console.log('SKU属性数据:', item.sku_attr);
-                                                let attr = [];
-                                                let skuAttrs = [];
-                                                
-                                                // 尝试解析JSON格式
-                                                try {
-                                                    skuAttrs = JSON.parse(item.sku_attr);
-                                                    console.log('解析JSON格式成功:', skuAttrs);
-                                                } catch (e) {
-                                                    // 如果JSON解析失败,尝试旧的字符串格式
-                                                    console.log('JSON解析失败,尝试字符串格式:', e);
-                                                    let sku_attr = item.sku_attr.split(',');
-                                                    skuAttrs = [];
-                                                    for (let res of sku_attr) {
-                                                        let sku = res.split(':');
-                                                        if (sku.length >= 2) {
-                                                            skuAttrs.push({
-                                                                name: sku[0],
-                                                                value: sku[1]
-                                                            });
+                                        // 优先使用后端传递的spec_data结构化数据(编辑模式)
+                                        if (Config.spec_data && Config.spec_data.length > 0) {
+                                            console.log('使用后端提供的spec_data结构化数据:', Config.spec_data);
+                                            
+                                            // 直接使用后端传递的结构化规格数据
+                                            specList = Config.spec_data.map(spec => {
+                                                return {
+                                                    name: spec.name,
+                                                    type: spec.type || 'basic',
+                                                    value: spec.value || []
+                                                };
+                                            });
+                                            
+                                            // 重构SKU映射,基于新的规格结构
+                                            for (let item of Config.goods_skus) {
+                                                if (item.sku_attr) {
+                                                    let attr = [];
+                                                    let skuAttrs = [];
+                                                    
+                                                    try {
+                                                        skuAttrs = JSON.parse(item.sku_attr);
+                                                    } catch (e) {
+                                                        let sku_attr = item.sku_attr.split(',');
+                                                        skuAttrs = [];
+                                                        for (let res of sku_attr) {
+                                                            let sku = res.split(':');
+                                                            if (sku.length >= 2) {
+                                                                skuAttrs.push({
+                                                                    key: sku[0],
+                                                                    value: sku[1]
+                                                                });
+                                                            }
+                                                        }
+                                                    }
+                                                    
+                                                    for (let attrObj of skuAttrs) {
+                                                        let specName_key = attrObj.key || attrObj.name;
+                                                        let specValue = attrObj.value;
+                                                        if (specName_key && specValue) {
+                                                            attr.push(specValue);
                                                         }
                                                         }
                                                     }
                                                     }
-                                                    console.log('转换字符串格式为对象:', skuAttrs);
+                                                    
+                                                    let attrKey = attr.join(',');
+                                                    skus[attrKey] = item;
                                                 }
                                                 }
-                                                
-                                                // 处理规格属性数组
-                                                for (let attrObj of skuAttrs) {
-                                                    if (attrObj.name && attrObj.value) {
-                                                        attr.push(attrObj.value);
-                                                        //属性名
-                                                        if (!specName[attrObj.name]) {
-                                                            specName[attrObj.name] = [];
+                                            }
+                                            
+                                            console.log('使用结构化数据初始化规格列表:', specList);
+                                        } else {
+                                            // 回退到原有的解析逻辑(新增模式或无结构化数据)
+                                            console.log('使用原有解析逻辑初始化规格数据');
+                                            let specName = {};
+                                            let specTypeMap = {}; // 用于记录规格类型
+                                            
+                                            for (let item of Config.goods_skus) {
+                                                console.log('处理SKU项:', item);
+                                                if (item.sku_attr) {
+                                                    console.log('SKU属性数据:', item.sku_attr);
+                                                    let attr = [];
+                                                    let skuAttrs = [];
+                                                    
+                                                    // 尝试解析JSON格式
+                                                    try {
+                                                        skuAttrs = JSON.parse(item.sku_attr);
+                                                        console.log('解析JSON格式成功:', skuAttrs);
+                                                    } catch (e) {
+                                                        // 如果JSON解析失败,尝试旧的字符串格式
+                                                        console.log('JSON解析失败,尝试字符串格式:', e);
+                                                        let sku_attr = item.sku_attr.split(',');
+                                                        skuAttrs = [];
+                                                        for (let res of sku_attr) {
+                                                            let sku = res.split(':');
+                                                            if (sku.length >= 2) {
+                                                                skuAttrs.push({
+                                                                    key: sku[0],
+                                                                    value: sku[1],
+                                                                    type: 'basic' // 默认为基础规格类型
+                                                                });
+                                                            }
                                                         }
                                                         }
-                                                        if (!specName[attrObj.name].includes(attrObj.value)) {
-                                                            specName[attrObj.name].push(attrObj.value);
+                                                        console.log('转换字符串格式为对象:', skuAttrs);
+                                                    }
+                                                    
+                                                    // 处理规格属性数组
+                                                    for (let attrObj of skuAttrs) {
+                                                        let specName_key = attrObj.key || attrObj.name;
+                                                        let specValue = attrObj.value;
+                                                        let specType = attrObj.type || 'basic';
+                                                        
+                                                        if (specName_key && specValue) {
+                                                            attr.push(specValue);
+                                                            //属性名和类型
+                                                            if (!specName[specName_key]) {
+                                                                specName[specName_key] = [];
+                                                            }
+                                                            if (!specName[specName_key].includes(specValue)) {
+                                                                specName[specName_key].push(specValue);
+                                                            }
+                                                            // 记录规格类型
+                                                            specTypeMap[specName_key] = specType;
                                                         }
                                                         }
                                                     }
                                                     }
+                                                    // 使用字符串作为键,与renderTableData中的查找方式一致
+                                                    let attrKey = attr.join(',');
+                                                    skus[attrKey] = item;
+                                                    console.log('SKU映射:', attrKey, '->', item);
+                                                } else {
+                                                    console.warn('SKU缺少sku_attr字段:', item);
                                                 }
                                                 }
-                                                // 使用字符串作为键,与renderTableData中的查找方式一致
-                                                let attrKey = attr.join(',');
-                                                skus[attrKey] = item;
-                                                console.log('SKU映射:', attrKey, '->', item);
-                                            } else {
-                                                console.warn('SKU缺少sku_attr字段:', item);
                                             }
                                             }
-                                        }
-                                        console.log('解析完成的规格名称映射:', specName);
-                                        
-                                        // 构建规格值映射表(从数据库获取的完整数据)
-                                        let specValueMap = {};
-                                        if (Config.spec_values && Config.spec_values.length > 0) {
-                                            console.log('发现规格值数据:', Config.spec_values);
-                            console.log('规格值数据类型:', typeof Config.spec_values);
-                            console.log('规格值数据结构样例:', Config.spec_values[0]);
-                            
-                                            Config.spec_values.forEach(function(item) {
-                                                if (!specValueMap[item.spec_name]) {
-                                                    specValueMap[item.spec_name] = {};
-                                                }
-                                                specValueMap[item.spec_name][item.value] = {
-                                                    name: item.value,
-                                                    image: item.image || '',
-                                                    description: item.description || ''
-                                                };
-                                            });
-                                            console.log('规格值映射表:', specValueMap);
-                        } else {
-                            console.log('没有发现规格值数据,使用默认处理方式');
-                            console.log('Config.spec_values:', Config.spec_values);
-                                        }
-                                        
-                                        for (let i in specName) {
-                                            // 转换旧格式数据为新格式,优先使用数据库中的完整数据
-                                            let valueList = specName[i].map(val => {
-                                                if (typeof val === 'string') {
-                                                    // 从映射表中查找完整数据,如果没有则使用默认值
-                                                    if (specValueMap[i] && specValueMap[i][val]) {
-                                                        console.log('找到规格值完整数据:', i, val, specValueMap[i][val]);
-                                        return {
-                                            name: specValueMap[i][val].name,
-                                            image: specValueMap[i][val].image || '',
-                                            description: specValueMap[i][val].description || ''
-                                        };
-                                                    } else {
-                                                        console.log('使用默认规格值数据:', i, val);
-                                                        return {
-                                                            name: val,
-                                                            image: '',
-                                                            description: ''
-                                                        };
+                                            console.log('解析完成的规格名称映射:', specName);
+                                            console.log('规格类型映射:', specTypeMap);
+                                            
+                                            // 构建规格值映射表(从数据库获取的完整数据)
+                                            let specValueMap = {};
+                                            if (Config.spec_values && Config.spec_values.length > 0) {
+                                                console.log('发现规格值数据:', Config.spec_values);
+                                                console.log('规格值数据类型:', typeof Config.spec_values);
+                                                console.log('规格值数据结构样例:', Config.spec_values[0]);
+                                                
+                                                Config.spec_values.forEach(function(item) {
+                                                    if (!specValueMap[item.spec_name]) {
+                                                        specValueMap[item.spec_name] = {};
                                                     }
                                                     }
-                                                }
-                                // 如果已经是对象格式,确保结构完整
-                                return {
-                                    name: val.name || val,
-                                    image: val.image || '',
-                                    description: val.description || ''
-                                };
-                                            });
+                                                    specValueMap[item.spec_name][item.value] = {
+                                                        name: item.value,
+                                                        image: item.image || '',
+                                                        description: item.description || ''
+                                                    };
+                                                });
+                                                console.log('规格值映射表:', specValueMap);
+                                            } else {
+                                                console.log('没有发现规格值数据,使用默认处理方式');
+                                                console.log('Config.spec_values:', Config.spec_values);
+                                            }
                                             
                                             
-                                            specList.push({
-                                                name: i,
-                                                type: 'basic', // 默认为基础规格
-                                                value: valueList
-                                            });
+                                            for (let i in specName) {
+                                                // 转换旧格式数据为新格式,优先使用数据库中的完整数据
+                                                let valueList = specName[i].map(val => {
+                                                    if (typeof val === 'string') {
+                                                        // 从映射表中查找完整数据,如果没有则使用默认值
+                                                        if (specValueMap[i] && specValueMap[i][val]) {
+                                                            console.log('找到规格值完整数据:', i, val, specValueMap[i][val]);
+                                                            return {
+                                                                name: specValueMap[i][val].name,
+                                                                image: specValueMap[i][val].image || '',
+                                                                description: specValueMap[i][val].description || ''
+                                                            };
+                                                        } else {
+                                                            console.log('使用默认规格值数据:', i, val);
+                                                            return {
+                                                                name: val,
+                                                                image: '',
+                                                                description: ''
+                                                            };
+                                                        }
+                                                    }
+                                                    // 如果已经是对象格式,确保结构完整
+                                                    return {
+                                                        name: val.name || val,
+                                                        image: val.image || '',
+                                                        description: val.description || ''
+                                                    };
+                                                });
+                                                
+                                                specList.push({
+                                                    name: i,
+                                                    type: specTypeMap[i] || 'basic', // 使用从SKU属性中解析的规格类型
+                                                    value: valueList
+                                                });
+                                            }
                                         }
                                         }
                                         
                                         
                                         this.skus = skus;
                                         this.skus = skus;