浏览代码

淘宝模式加入 初步完成

chengwl 5 年之前
父节点
当前提交
e1f98fd32b
共有 19 个文件被更改,包括 1330 次插入24 次删除
  1. 2 0
      vendor/fancyecommerce/fecshop/app/appadmin/languages/zh-CN/appadmin.php
  2. 2 1
      vendor/fancyecommerce/fecshop/app/appadmin/modules/AppadminbaseBlock.php
  3. 0 1
      vendor/fancyecommerce/fecshop/app/appadmin/modules/Catalog/block/productinfo/Manageredit.php
  4. 185 0
      vendor/fancyecommerce/fecshop/app/appadmin/modules/Catalog/block/productoption/Manager.php
  5. 244 0
      vendor/fancyecommerce/fecshop/app/appadmin/modules/Catalog/block/productoption/Manageredit.php
  6. 138 0
      vendor/fancyecommerce/fecshop/app/appadmin/modules/Catalog/block/productoptiongroup/Manager.php
  7. 165 0
      vendor/fancyecommerce/fecshop/app/appadmin/modules/Catalog/block/productoptiongroup/Manageredit.php
  8. 45 0
      vendor/fancyecommerce/fecshop/app/appadmin/modules/Catalog/controllers/ProductoptionController.php
  9. 45 0
      vendor/fancyecommerce/fecshop/app/appadmin/modules/Catalog/controllers/ProductoptiongroupController.php
  10. 41 0
      vendor/fancyecommerce/fecshop/app/appadmin/theme/base/default/catalog/productoption/manager.php
  11. 205 0
      vendor/fancyecommerce/fecshop/app/appadmin/theme/base/default/catalog/productoption/manageredit.php
  12. 41 0
      vendor/fancyecommerce/fecshop/app/appadmin/theme/base/default/catalog/productoptiongroup/manager.php
  13. 157 0
      vendor/fancyecommerce/fecshop/app/appadmin/theme/base/default/catalog/productoptiongroup/manageredit.php
  14. 3 2
      vendor/fancyecommerce/fecshop/app/appfront/modules/Catalog/block/product/CustomOption.php
  15. 0 1
      vendor/fancyecommerce/fecshop/app/appfront/modules/Catalog/block/product/Index.php
  16. 22 1
      vendor/fancyecommerce/fecshop/app/appfront/theme/base/front/catalog/product/index.php
  17. 10 0
      vendor/fancyecommerce/fecshop/config/services/Admin.php
  18. 17 10
      vendor/fancyecommerce/fecshop/services/Product.php
  19. 8 8
      vendor/fancyecommerce/fecshop/services/product/ProductMongodb.php

+ 2 - 0
vendor/fancyecommerce/fecshop/app/appadmin/languages/zh-CN/appadmin.php

@@ -479,6 +479,8 @@ return [
     
     'Product Attribute' => '产品属性管理',
     'Product Attribute Group' => '产品属性组管理',
+    'Product Custom Option'=>'自定义属性管理',
+    'Product Custom Option Group'=>'自定义属性组管理',
     'Product Param Config' => '产品参数管理',
     'Product Excel Upload' => '产品批量上传',
     'Category Sort Config' => '分类排序配置',

+ 2 - 1
vendor/fancyecommerce/fecshop/app/appadmin/modules/AppadminbaseBlock.php

@@ -523,6 +523,7 @@ class AppadminbaseBlock extends BaseObject
         $fields = $this->getTableFieldArr();
         $str = '';
         $csrfString = CRequest::getCsrfString();
+        
         foreach ($data as $one) {
             $str .= '<tr target="sid_user" rel="'.$one[$this->_primaryKey].'">';
             $str .= '<td><input name="'.$this->_primaryKey.'s" value="'.$one[$this->_primaryKey].'" type="checkbox"></td>';
@@ -532,7 +533,7 @@ class AppadminbaseBlock extends BaseObject
                 $translate = $field['translate'];
                 $val = $one[$orderField];
                 $display_title = '';
-                if ($val) {
+                if (isset($val)) {
                     if (isset($field['display']) && !empty($field['display'])) {
                         $display = $field['display'];
                         $val = $display[$val] ? $display[$val] : $val;

+ 0 - 1
vendor/fancyecommerce/fecshop/app/appadmin/modules/Catalog/block/productinfo/Manageredit.php

@@ -423,7 +423,6 @@ class Manageredit extends AppadminbaseBlockEdit implements AppadminbaseBlockEdit
                 //exit;
             }
         }
-        
         $this->_service->save($this->_param, 'catalog/product/index');
         
         $errors = Yii::$service->helper->errors->get();

+ 185 - 0
vendor/fancyecommerce/fecshop/app/appadmin/modules/Catalog/block/productoption/Manager.php

@@ -0,0 +1,185 @@
+<?php
+/**
+ * FecShop file.
+ *
+ * @link http://www.fecshop.com/
+ * @copyright Copyright (c) 2016 FecShop Software LLC
+ * @license http://www.fecshop.com/license/
+ */
+
+namespace fecshop\app\appadmin\modules\Catalog\block\productoption;
+
+use fec\helpers\CUrl;
+use fec\helpers\CRequest;
+use fecshop\app\appadmin\interfaces\base\AppadminbaseBlockInterface;
+use fecshop\app\appadmin\modules\AppadminbaseBlock;
+use Yii;
+
+/**
+ * @author Terry Zhao <2358269014@qq.com>
+ * @since 1.0
+ */
+class Manager extends AppadminbaseBlock implements AppadminbaseBlockInterface
+{
+    /**
+     * init param function ,execute in construct.
+     */
+    public function init()
+    {
+        /*
+         * edit data url
+         */
+        $this->_editUrl = CUrl::getUrl('catalog/productoption/manageredit');
+        /*
+         * delete data url
+         */
+        $this->_deleteUrl = CUrl::getUrl('catalog/productoption/managerdelete');
+        /*
+         * service component, data provider
+         */
+        $this->_service = Yii::$service->product->option;
+        parent::init();
+    }
+
+    public function getLastData()
+    {
+        // hidden section ,that storage page info
+        $pagerForm = $this->getPagerForm();
+        // search section
+        $searchBar = $this->getSearchBar();
+        // edit button, delete button,
+        $editBar = $this->getEditBar();
+        // table head
+        $thead = $this->getTableThead();
+        // table body
+        $tbody = $this->getTableTbody();
+        // paging section
+        $toolBar = $this->getToolBar($this->_param['numCount'], $this->_param['pageNum'], $this->_param['numPerPage']);
+        return [
+            'pagerForm'     => $pagerForm,
+            'searchBar'      => $searchBar,
+            'editBar'          => $editBar,
+            'thead'            => $thead,
+            'tbody'            => $tbody,
+            'toolBar'          => $toolBar,
+        ];
+    }
+    /**
+     * get search bar Arr config.
+     */
+    public function getSearchArr()
+    {
+        $data = [
+            [    // selecit的Int 类型
+                'type' => 'select',
+                'title'  => Yii::$service->page->translate->__('Status'),
+                'name' => 'status',
+                'columns_type' => 'int',  // int使用标准匹配, string使用模糊查询
+                'value' => [                    // select 类型的值
+                    1 => Yii::$service->page->translate->__('Enable'),
+                    2 => Yii::$service->page->translate->__('Disable'),
+                ],
+            ],
+            
+        ];
+
+        return $data;
+    }
+
+    /**
+     * config function ,return table columns config.
+     */
+    public function getTableFieldArr()
+    {
+        $table_th_bar = [
+            [
+                'orderField'    => $this->_primaryKey,
+                'label'           => Yii::$service->page->translate->__('Id'),
+                'width'          => '50',
+                'align'           => 'center',
+            ],
+            [
+                'orderField'    => 'attr_type',
+                'label'           => Yii::$service->page->translate->__('Attr Type'),
+                'width'          => '100',
+                'align'           => 'left',
+                'translate'     => true,
+            ],
+            [
+                'orderField'    => 'name',
+                'label'           => Yii::$service->page->translate->__('Attr Name'),
+                'width'          => '110',
+                'align'           => 'left',
+            ],
+            
+            [
+                'orderField'    => 'status',
+                'label'           => Yii::$service->page->translate->__('Status'),
+                'width'          => '50',
+                'align'           => 'center',
+                'display'        => [
+                    1 => Yii::$service->page->translate->__('Enable'),
+                    2 => Yii::$service->page->translate->__('Disable'),
+                ],
+            ],
+            
+            [
+                'orderField'    => 'db_type',
+                'label'           => Yii::$service->page->translate->__('Db Type'),
+                'width'          => '110',
+                'align'           => 'center',
+            ],
+            
+            [
+                'orderField'    => 'show_as_img',
+                'label'           => Yii::$service->page->translate->__('Show As Img'),
+                'width'          => '50',
+                'align'           => 'center',
+                'display'        => [
+                    1 => Yii::$service->page->translate->__('Yes'),
+                    2 => Yii::$service->page->translate->__('No'),
+                ],
+            ],
+            
+            [
+                'orderField'    => 'display_type',
+                'label'           => Yii::$service->page->translate->__('Display Type'),
+                'width'          => '110',
+                'align'           => 'center',
+            ],
+            [
+                'orderField'    => 'is_require',
+                'label'           => Yii::$service->page->translate->__('Is Required'),
+                'width'          => '50',
+                'align'           => 'center',
+                'display'        => [
+                    0 => Yii::$service->page->translate->__('No'),
+                    1 => Yii::$service->page->translate->__('Yes'),
+                ],
+            ],
+            [
+                'orderField'    => 'default',
+                'label'           => Yii::$service->page->translate->__('Default Value'),
+                'width'          => '110',
+                'align'           => 'center',
+            ],
+            [
+                'orderField'    => 'created_at',
+                'label'           => Yii::$service->page->translate->__('Created At'),
+                'width'          => '110',
+                'align'           => 'center',
+                'convert'       => ['int' => 'datetime'],
+            ],
+            [
+                'orderField'    => 'updated_at',
+                'label'           => Yii::$service->page->translate->__('Updated At'),
+                'width'          => '110',
+                'align'           => 'center',
+                'convert'       => ['int' => 'datetime'],
+            ],
+        ];
+
+        return $table_th_bar;
+    }
+
+}

+ 244 - 0
vendor/fancyecommerce/fecshop/app/appadmin/modules/Catalog/block/productoption/Manageredit.php

@@ -0,0 +1,244 @@
+<?php
+/**
+ * FecShop file.
+ *
+ * @link http://www.fecshop.com/
+ * @copyright Copyright (c) 2016 FecShop Software LLC
+ * @license http://www.fecshop.com/license/
+ */
+
+namespace fecshop\app\appadmin\modules\Catalog\block\productoption;
+
+use fec\helpers\CRequest;
+use fec\helpers\CUrl;
+use fecshop\app\appadmin\interfaces\base\AppadminbaseBlockEditInterface;
+use fecshop\app\appadmin\modules\AppadminbaseBlockEdit;
+use Yii;
+
+/**
+ * block cms\article.
+ * @author Terry Zhao <2358269014@qq.com>
+ * @since 1.0
+ */
+class Manageredit extends AppadminbaseBlockEdit implements AppadminbaseBlockEditInterface
+{
+    public $_saveUrl;
+
+    public function init()
+    {
+        $this->_saveUrl = CUrl::getUrl('catalog/productoption/managereditsave');
+        parent::init();
+    }
+
+    // 传递给前端的数据 显示编辑form
+    public function getLastData()
+    {
+        
+        $display_data = $this->_one['display_data'];
+        $display_type = $this->_one['display_type'];
+        if ($display_data) {
+            $display_data = unserialize($display_data);
+        }
+        $displayTypes = Yii::$service->product->option->getDisplayTypes();
+        return [
+            'editBar'      => $this->getEditBar(),
+            'display_data' => $display_data,
+            'display_type' => $display_type,
+            'display_types' => $displayTypes,
+            'textareas'   => $this->_textareas,
+            'lang_attr'   => $this->_lang_attr,
+            'saveUrl'     => $this->_saveUrl,
+        ];
+    }
+
+    public function setService()
+    {
+        $this->_service = Yii::$service->product->option;
+    }
+
+    public function getEditArr()
+    {
+        $attrTypes = Yii::$service->product->attr->getAttrTypes();
+        $dbTypes = Yii::$service->product->attr->getDbTypes();
+        
+        return [
+            [
+                'label'  => Yii::$service->page->translate->__('Attr Type'),
+                'name' => 'attr_type',
+                'display' => [
+                    'type' => 'select',
+                    'data' => $attrTypes,
+                ],
+                'require' => 1,
+                'default' => 'general_attr',
+            ],
+            
+            [
+                'label'  => Yii::$service->page->translate->__('Attr Name'),
+                'name' => 'name',
+                'display' => [
+                    'type' => 'inputString',
+                ],
+                'require' => 1,
+            ],
+            [
+                'label'  => Yii::$service->page->translate->__('Status'),
+                'name' => 'status',
+                'display' => [
+                    'type' => 'select',
+                    'data' => [
+                        1   => Yii::$service->page->translate->__('Enable'),
+                        2   => Yii::$service->page->translate->__('Disable'),
+                    ],
+                ],
+                'require' => 1,
+                'default' => 1,
+            ],
+            [
+                'label'  => Yii::$service->page->translate->__('Db Type'),
+                'name' => 'db_type',
+                'display' => [
+                    'type' => 'select',
+                    'data' => $dbTypes,
+                ],
+                'require' => 1,
+                'default' => 'String',
+            ],
+            
+            [
+                'label'  => Yii::$service->page->translate->__('Show As Img'),
+                'name' => 'show_as_img',
+                'display' => [
+                    'type' => 'select',
+                    'data' => [
+                        1   => Yii::$service->page->translate->__('Yes'),
+                        2   => Yii::$service->page->translate->__('No'),
+                    ],
+                ],
+                'require' => 1,
+                'default' => 2,
+            ],
+            /*
+            [
+                'label'  => Yii::$service->page->translate->__('Display Type'),
+                'name' => 'display_type',
+                'display' => [
+                    'type' => 'select',
+                    'data' => $displayTypes,
+                ],
+                'require' => 1,
+            ],
+            
+            [
+                'label'  => Yii::$service->page->translate->__('display_data Type'),
+                'name' => 'display_data',
+                'display' => [
+                    'type' => 'textarea',
+                    'notEditor' => true,
+                ],
+                'require' => 1,
+            ],
+            */
+            
+            [
+                'label'  => Yii::$service->page->translate->__('Is Require'),
+                'name' => 'is_require',
+                'display' => [
+                    'type' => 'select',
+                    'data' => [
+                        0   => Yii::$service->page->translate->__('No'),
+                        1   => Yii::$service->page->translate->__('Yes'),
+                    ],
+                ],
+                'require' => 1,
+                'default' => 0,
+            ],
+            
+            
+            [
+                'label'  => Yii::$service->page->translate->__('Default Value'),
+                'name' => 'default',
+                'display' => [
+                    'type' => 'inputString',
+                ],
+                'require' => 0,
+            ],
+            
+        ];
+    }
+    // display_data
+    public function getSaveDisplayData()
+    {
+        $dd = $this->_param['display_data'];
+        $display_data_arr = [];
+        if ($dd) {
+            $arr = explode('||', $dd );
+            foreach ($arr as $a) {
+                if ($a) {
+                    $display_data_arr[] = [
+                        'key' => $a,
+                    ];
+                }
+            }
+        }
+        if (empty($display_data_arr)) {
+            return '';
+        }
+        
+        return serialize($display_data_arr);
+    }
+    /**
+     * save article data,  get rewrite url and save to article url key.
+     */
+    public function save()
+    {
+        $request_param = CRequest::param();
+        $this->_param = $request_param[$this->_editFormData];
+        /*
+         * if attribute is date or date time , db storage format is int ,by frontend pass param is int ,
+         * you must convert string datetime to time , use strtotime function.
+         */
+        $this->_param['display_data'] = $this->getSaveDisplayData();
+        $this->_service->save($this->_param);
+        $errors = Yii::$service->helper->errors->get();
+        if (!$errors) {
+            echo  json_encode([
+                'statusCode' => '200',
+                'message'    => Yii::$service->page->translate->__('Save Success') ,
+            ]);
+            exit;
+        } else {
+            echo  json_encode([
+                'statusCode' => '300',
+                'message'    => $errors,
+            ]);
+            exit;
+        }
+    }
+
+    // 批量删除
+    public function delete()
+    {
+        $ids = '';
+        if ($id = CRequest::param($this->_primaryKey)) {
+            $ids = $id;
+        } elseif ($ids = CRequest::param($this->_primaryKey.'s')) {
+            $ids = explode(',', $ids);
+        }
+        $this->_service->remove($ids);
+        $errors = Yii::$service->helper->errors->get();
+        if (!$errors) {
+            echo  json_encode([
+                'statusCode' => '200',
+                'message'    => Yii::$service->page->translate->__('Remove Success'),
+            ]);
+            exit;
+        } else {
+            echo  json_encode([
+                'statusCode' => '300',
+                'message'    => $errors,
+            ]);
+            exit;
+        }
+    }
+}

+ 138 - 0
vendor/fancyecommerce/fecshop/app/appadmin/modules/Catalog/block/productoptiongroup/Manager.php

@@ -0,0 +1,138 @@
+<?php
+/**
+ * FecShop file.
+ *
+ * @link http://www.fecshop.com/
+ * @copyright Copyright (c) 2016 FecShop Software LLC
+ * @license http://www.fecshop.com/license/
+ */
+
+namespace fecshop\app\appadmin\modules\Catalog\block\productoptiongroup;
+
+use fec\helpers\CUrl;
+use fec\helpers\CRequest;
+use fecshop\app\appadmin\interfaces\base\AppadminbaseBlockInterface;
+use fecshop\app\appadmin\modules\AppadminbaseBlock;
+use Yii;
+
+/**
+ * @author Terry Zhao <2358269014@qq.com>
+ * @since 1.0
+ */
+class Manager extends AppadminbaseBlock implements AppadminbaseBlockInterface
+{
+    /**
+     * init param function ,execute in construct.
+     */
+    public function init()
+    {
+        /*
+         * edit data url
+         */
+        $this->_editUrl = CUrl::getUrl('catalog/productoptiongroup/manageredit');
+        /*
+         * delete data url
+         */
+        $this->_deleteUrl = CUrl::getUrl('catalog/productoptiongroup/managerdelete');
+        /*
+         * service component, data provider
+         */
+        $this->_service = Yii::$service->product->optionGroup;
+        parent::init();
+    }
+
+    public function getLastData()
+    {
+        // hidden section ,that storage page info
+        $pagerForm = $this->getPagerForm();
+        // search section
+        $searchBar = $this->getSearchBar();
+        // edit button, delete button,
+        $editBar = $this->getEditBar();
+        // table head
+        $thead = $this->getTableThead();
+        // table body
+        $tbody = $this->getTableTbody();
+        // paging section
+        $toolBar = $this->getToolBar($this->_param['numCount'], $this->_param['pageNum'], $this->_param['numPerPage']);
+
+        return [
+            'pagerForm'     => $pagerForm,
+            'searchBar'      => $searchBar,
+            'editBar'          => $editBar,
+            'thead'            => $thead,
+            'tbody'            => $tbody,
+            'toolBar'          => $toolBar,
+        ];
+    }
+    /**
+     * get search bar Arr config.
+     */
+    public function getSearchArr()
+    {
+        $data = [
+            [    // selecit的Int 类型
+                'type' => 'select',
+                'title'  => Yii::$service->page->translate->__('Status'),
+                'name' => 'status',
+                'columns_type' => 'int',  // int使用标准匹配, string使用模糊查询
+                'value' => [                    // select 类型的值
+                    1 => Yii::$service->page->translate->__('Enable'),
+                    2 => Yii::$service->page->translate->__('Disable'),
+                ],
+            ],
+            
+        ];
+
+        return $data;
+    }
+
+    /**
+     * config function ,return table columns config.
+     */
+    public function getTableFieldArr()
+    {
+        $table_th_bar = [
+            [
+                'orderField'    => $this->_primaryKey,
+                'label'           => Yii::$service->page->translate->__('Id'),
+                'width'          => '50',
+                'align'           => 'center',
+            ],
+            [
+                'orderField'    => 'name',
+                'label'           => Yii::$service->page->translate->__('Attr Group Name'),
+                'width'          => '100',
+                'align'           => 'left',
+            ],
+            [
+                'orderField'    => 'status',
+                'label'           => Yii::$service->page->translate->__('Status'),
+                'width'          => '50',
+                'align'           => 'center',
+                'display'        => [
+                    1 => Yii::$service->page->translate->__('Enable'),
+                    2 => Yii::$service->page->translate->__('Disable'),
+                ],
+            ],
+            
+            [
+                'orderField'    => 'created_at',
+                'label'           => Yii::$service->page->translate->__('Created At'),
+                'width'          => '110',
+                'align'           => 'center',
+                'convert'       => ['int' => 'datetime'],
+            ],
+            [
+                'orderField'    => 'updated_at',
+                'label'           => Yii::$service->page->translate->__('Updated At'),
+                'width'          => '110',
+                'align'           => 'center',
+                'convert'       => ['int' => 'datetime'],
+            ],
+        ];
+
+        return $table_th_bar;
+    }
+
+}

+ 165 - 0
vendor/fancyecommerce/fecshop/app/appadmin/modules/Catalog/block/productoptiongroup/Manageredit.php

@@ -0,0 +1,165 @@
+<?php
+/**
+ * FecShop file.
+ *
+ * @link http://www.fecshop.com/
+ * @copyright Copyright (c) 2016 FecShop Software LLC
+ * @license http://www.fecshop.com/license/
+ */
+
+namespace fecshop\app\appadmin\modules\Catalog\block\productoptiongroup;
+
+use fec\helpers\CRequest;
+use fec\helpers\CUrl;
+use fecshop\app\appadmin\interfaces\base\AppadminbaseBlockEditInterface;
+use fecshop\app\appadmin\modules\AppadminbaseBlockEdit;
+use Yii;
+
+/**
+ * block cms\article.
+ * @author Terry Zhao <2358269014@qq.com>
+ * @since 1.0
+ */
+class Manageredit extends AppadminbaseBlockEdit implements AppadminbaseBlockEditInterface
+{
+    public $_saveUrl;
+
+    public function init()
+    {
+        $this->_saveUrl = CUrl::getUrl('catalog/productoptiongroup/managereditsave');
+        parent::init();
+    }
+
+    // 传递给前端的数据 显示编辑form
+    public function getLastData()
+    {
+        $filter = [
+            'where' => [
+                ['status' => Yii::$service->product->option->getEnableStatus()]
+            ],
+            'orderBy' => ['id' => SORT_DESC],
+            'fetchAll' => true,
+            'asArray' => true,
+        ];
+        $data = Yii::$service->product->option->coll($filter);
+        $attrs = $data['coll'];
+        $select_attr_ids = $this->_one['attr_ids'];
+        if ($select_attr_ids) {
+            $select_attr_ids = unserialize($select_attr_ids);
+        }
+        return [
+            'editBar'      => $this->getEditBar(),
+            'attrs' => $attrs,
+            'select_attr_ids' => $select_attr_ids,
+            'textareas'   => $this->_textareas,
+            'lang_attr'   => $this->_lang_attr,
+            'saveUrl'     => $this->_saveUrl,
+        ];
+    }
+
+    public function setService()
+    {
+        $this->_service = Yii::$service->product->optionGroup;
+    }
+
+    public function getEditArr()
+    {
+        // $attrTypes = Yii::$service->product->attr->getAttrTypes();
+        // $dbTypes = Yii::$service->product->attr->getDbTypes();
+        
+        return [
+            [
+                'label'  => Yii::$service->page->translate->__('Attr Group Name'),
+                'name' => 'name',
+                'display' => [
+                    'type' => 'inputString',
+                ],
+                'require' => 1,
+            ],
+            [
+                'label'  => Yii::$service->page->translate->__('Status'),
+                'name' => 'status',
+                'display' => [
+                    'type' => 'select',
+                    'data' => [
+                        1   => Yii::$service->page->translate->__('Enable'),
+                        2   => Yii::$service->page->translate->__('Disable'),
+                    ],
+                ],
+                'require' => 1,
+                'default' => 1,
+            ],
+            
+            
+        ];
+    }
+    
+    /**
+     * save article data,  get rewrite url and save to article url key.
+     */
+    public function save()
+    {
+        $request_param = CRequest::param();
+        $this->_param = $request_param[$this->_editFormData];
+        $attr_ids = $this->_param['attr_ids'];
+        if ($attr_ids) {
+            $attr_ids = trim($attr_ids, '||');
+            $attr_id_arr = explode('||', $attr_ids);
+            if (is_array($attr_id_arr) && !empty($attr_id_arr)) {
+                $arr = [];
+                foreach ($attr_id_arr as $one) {
+                    list($attr_id, $sort_order) = explode('##', $one);
+                    if ($attr_id) {
+                        $arr[] = [
+                            'attr_id' => $attr_id,
+                            'sort_order' => (int)$sort_order
+                        ];
+                    }
+                }
+                $this->_param['attr_ids'] = serialize($arr);
+            }
+        }
+        
+        $this->_service->save($this->_param);
+        $errors = Yii::$service->helper->errors->get();
+        if (!$errors) {
+            echo  json_encode([
+                'statusCode' => '200',
+                'message'    => Yii::$service->page->translate->__('Save Success') ,
+            ]);
+            exit;
+        } else {
+            echo  json_encode([
+                'statusCode' => '300',
+                'message'    => $errors,
+            ]);
+            exit;
+        }
+    }
+
+    // 批量删除
+    public function delete()
+    {
+        $ids = '';
+        if ($id = CRequest::param($this->_primaryKey)) {
+            $ids = $id;
+        } elseif ($ids = CRequest::param($this->_primaryKey.'s')) {
+            $ids = explode(',', $ids);
+        }
+        $this->_service->remove($ids);
+        $errors = Yii::$service->helper->errors->get();
+        if (!$errors) {
+            echo  json_encode([
+                'statusCode' => '200',
+                'message'    => Yii::$service->page->translate->__('Remove Success'),
+            ]);
+            exit;
+        } else {
+            echo  json_encode([
+                'statusCode' => '300',
+                'message'    => $errors,
+            ]);
+            exit;
+        }
+    }
+}

+ 45 - 0
vendor/fancyecommerce/fecshop/app/appadmin/modules/Catalog/controllers/ProductoptionController.php

@@ -0,0 +1,45 @@
+<?php
+/**
+ * FecShop file.
+ *
+ * @link http://www.fecshop.com/
+ * @copyright Copyright (c) 2016 FecShop Software LLC
+ * @license http://www.fecshop.com/license/
+ */
+
+namespace fecshop\app\appadmin\modules\Catalog\controllers;
+
+use fecshop\app\appadmin\modules\Catalog\CatalogController;
+
+/**
+ * @author Terry Zhao <2358269014@qq.com>
+ * @since 1.0
+ */
+class ProductoptionController extends CatalogController
+{
+    public $enableCsrfValidation = true;
+    
+    public function actionManager()
+    {
+        $data = $this->getBlock()->getLastData();
+
+        return $this->render($this->action->id, $data);
+    }
+
+    public function actionManageredit()
+    {
+        $data = $this->getBlock()->getLastData();
+
+        return $this->render($this->action->id, $data);
+    }
+
+    public function actionManagereditsave()
+    {
+        $data = $this->getBlock('manageredit')->save();
+    }
+
+    public function actionManagerdelete()
+    {
+        $this->getBlock('manageredit')->delete();
+    }
+}

+ 45 - 0
vendor/fancyecommerce/fecshop/app/appadmin/modules/Catalog/controllers/ProductoptiongroupController.php

@@ -0,0 +1,45 @@
+<?php
+/**
+ * FecShop file.
+ *
+ * @link http://www.fecshop.com/
+ * @copyright Copyright (c) 2016 FecShop Software LLC
+ * @license http://www.fecshop.com/license/
+ */
+
+namespace fecshop\app\appadmin\modules\Catalog\controllers;
+
+use fecshop\app\appadmin\modules\Catalog\CatalogController;
+
+/**
+ * @author Terry Zhao <2358269014@qq.com>
+ * @since 1.0
+ */
+class ProductoptiongroupController extends CatalogController
+{
+    public $enableCsrfValidation = true;
+    
+    public function actionManager()
+    {
+        $data = $this->getBlock()->getLastData();
+
+        return $this->render($this->action->id, $data);
+    }
+
+    public function actionManageredit()
+    {
+        $data = $this->getBlock()->getLastData();
+
+        return $this->render($this->action->id, $data);
+    }
+
+    public function actionManagereditsave()
+    {
+        $data = $this->getBlock('manageredit')->save();
+    }
+
+    public function actionManagerdelete()
+    {
+        $this->getBlock('manageredit')->delete();
+    }
+}

+ 41 - 0
vendor/fancyecommerce/fecshop/app/appadmin/theme/base/default/catalog/productoption/manager.php

@@ -0,0 +1,41 @@
+<?php
+/**
+ * FecShop file.
+ *
+ * @link http://www.fecshop.com/
+ * @copyright Copyright (c) 2016 FecShop Software LLC
+ * @license http://www.fecshop.com/license/
+ */
+use fec\helpers\CRequest;
+/** 
+ * @author Terry Zhao <2358269014@qq.com>
+ * @since 1.0
+ */
+?>
+<form id="pagerForm" method="post" action="<?= \fec\helpers\CUrl::getCurrentUrl();  ?>">
+	<?=  CRequest::getCsrfInputHtml();  ?>
+	<?=  $pagerForm;  ?>
+</form>
+<div class="pageHeader">
+	<form rel="pagerForm" onsubmit="return navTabSearch(this);" action="<?= \fec\helpers\CUrl::getCurrentUrl();  ?>" method="post">
+		<?php echo CRequest::getCsrfInputHtml();  ?>
+		<div class="searchBar">
+			<?php  echo $searchBar; ?>
+		</div>
+	</form>
+</div>
+<div class="pageContent">
+	<div class="panelBar">
+		<?= $editBar;  ?>
+	</div>
+	<div class="panelBar">
+		<?= $toolBar; ?>
+	</div>
+	<table class="table" width="100%" layoutH="138">
+		<?= $thead; ?>
+		<tbody>
+			<?= $tbody; ?>
+		</tbody>
+	</table>
+	
+</div>

+ 205 - 0
vendor/fancyecommerce/fecshop/app/appadmin/theme/base/default/catalog/productoption/manageredit.php

@@ -0,0 +1,205 @@
+<?php
+/**
+ * FecShop file.
+ *
+ * @link http://www.fecshop.com/
+ * @copyright Copyright (c) 2016 FecShop Software LLC
+ * @license http://www.fecshop.com/license/
+ */
+use yii\helpers\Html;
+use fec\helpers\CRequest;
+use fecadmin\models\AdminRole;
+/** 
+ * @author Terry Zhao <2358269014@qq.com>
+ * @since 1.0
+ */
+?>
+<style>
+.checker{float:left;}
+.dialog .pageContent {background:none;}
+.dialog .pageContent .pageFormContent{background:none;}
+</style>
+
+<script>
+
+
+function thissubmit(thiss){
+	var fill = true;
+	items_input = "";
+    
+    var display_type_select = $(".display_type_select").val();
+    if (display_type_select == 'select' || display_type_select == 'editSelect') {
+        $(".pageContent .items table tbody tr").each(function(){
+            key_name = $(this).find(".key_name").val();
+            //alert(search_engine);
+            if (key_name){
+                items_input += key_name + "||";
+            } else {
+                fill = false
+            }
+        });
+        if (fill == false) {
+            alert('<?= Yii::$service->page->translate->__('can not empty'); ?>');
+            return false;
+        }
+        $(".items_input").val(items_input);
+    } else {
+        $(".items_input").val();
+    }
+	return validateCallback(thiss, dialogAjaxDoneCloseAndReflush);
+}
+
+</script>
+
+<div class="pageContent"> 
+	<form  method="post" action="<?= $saveUrl ?>" class="pageForm required-validate" onsubmit="return thissubmit(this)">
+		<?php echo CRequest::getCsrfInputHtml();  ?>	
+		<div layouth="56" class="pageFormContent" style="height: 240px; overflow: auto;">
+			    <input type="hidden"  value="<?=  $product_id; ?>" size="30" name="product_id" class="textInput ">
+				<fieldset id="fieldset_table_qbe">
+					<legend style="color:#009688"><?= Yii::$service->page->translate->__('Edit Info') ?></legend>
+					<div>
+						<?= $editBar; ?>
+					</div>
+				</fieldset>
+                
+                <fieldset id="fieldset_table_qbe">
+					<legend style="color:#009688"><?= Yii::$service->page->translate->__('Attr Display') ?></legend>
+					<div>
+						<p class="edit_p" style="width:100%">
+                            <label><?=  Yii::$service->page->translate->__('Display Type');?>:</label>
+                            
+                            <select  class=" required display_type_select" name="editFormData[display_type]" >
+                                <?php if (is_array($display_types)): ?>
+                                    <?php foreach ($display_types as $d_type): ?>
+                                            
+                                        <?php if ($display_type == $d_type): ?>
+                                            <option  selected="selected" value="<?= $d_type?>"><?= Yii::$service->page->translate->__($d_type) ?></option>
+                                        <?php else: ?>
+                                            <option value="<?= $d_type ?>"><?= Yii::$service->page->translate->__($d_type) ?></option>
+                                        <?php endif; ?>
+                                        
+                                    <?php endforeach; ?>
+                                <?php endif; ?>
+                            </select>
+                            <span class="remark-text"></span>
+                            
+                            <div class="edit_p display_itemcs" style="display:<?= ($display_type=='select' || $display_type=='editSelect')    ? 'block' : 'none'  ?>">
+                                <label><?=  Yii::$service->page->translate->__('Display Items') ?>:</label>
+                                <input type="hidden" name="editFormData[display_data]" class="items_input"  />
+                                <div class="items" style="float:left;width:700px;">
+                                    <table style="">
+                                        <thead>
+                                            <tr>
+                                                <th><?=  Yii::$service->page->translate->__('Items') ?></th>
+                                                <th><?=  Yii::$service->page->translate->__('Action') ?></th>
+                                            </tr>
+                                        </thead>
+                                        <tbody>
+                                            <?php if(is_array($display_data) && !empty($display_data)){  ?>
+                                                <?php foreach($display_data as $one){ ?>
+                                                <tr>
+                                                    <td>
+                                                        <input class="key_name" type="text" value="<?= $one['key'] ?>">
+                                                    </td>
+                                                    <td>
+                                                        <i class="fa fa-trash-o"></i>
+                                                    </td>
+                                                </tr>
+                                                <?php } ?>
+                                            <?php } ?>
+                                        </tbody>
+                                        <tfoot style="text-align:right;">
+                                            <tr>
+                                                <td colspan="100" style="text-align:right;">						
+                                                    <a rel="2" style="text-align:right;margin-top:15px;" href="javascript:void(0)" class="addItems button">
+                                                        <span><?=  Yii::$service->page->translate->__('Add Items') ?></span>
+                                                    </a>					
+                                                </td>				
+                                            </tr>			
+                                        </tfoot>
+                                    </table>
+                                    <script>
+                                        $(document).ready(function(){
+                                            $(".addItems").click(function(){
+                                                str = "<tr>";
+                                                str +="<td><input class=\"key_name textInput\" type=\"text\"   /></td>";
+                                                str +="<td><i class='fa fa-trash-o'></i></td>";
+                                                str +="</tr>";
+                                                $(".items table tbody").append(str);
+                                            });
+                                            $("body").off("click").on("click",".pageContent .items table tbody tr td .fa-trash-o",function(){
+                                                $(this).parent().parent().remove();
+                                            });
+                                            
+                                            $("body").off("change").on("change",".pageContent .select_attr_type",function(){
+                                                var val = $(this).val();
+                                                if (val == 'spu_attr') {
+                                                    $(".pageContent .display_type_select").val('select');
+                                                    $(".display_itemcs").show;
+                                                    $(".display_itemcs").show();
+                                                }
+                                            });
+                                            
+                                            $("body").on("change",".pageContent .display_type_select",function(){
+                                                var val = $(this).val();
+                                                if (val != 'select' && val != 'editSelect' ) {
+                                                    $(".display_itemcs").hide();
+                                                    
+                                                } else {
+                                                    $(".display_itemcs").show();
+                                                }
+                                            });
+                                        });
+                                    </script>
+                                </div>
+                            </div>
+                        </p>
+					</div>
+				</fieldset>
+                
+				<?= $lang_attr ?>
+				<?= $textareas ?>
+                
+		</div>
+		<div class="formBar">
+			<ul>
+				<!--<li><a class="buttonActive" href="javascript:;"><span>保存</span></a></li>-->
+				<li>
+                    <div class="buttonActive"><div class="buttonContent"><button onclick="func('accept')"  value="accept" name="accept" type="submit"><?= Yii::$service->page->translate->__('Save') ?></button></div></div>
+                </li>
+				<li>
+					<div class="button"><div class="buttonContent"><button type="button" class="close"><?= Yii::$service->page->translate->__('Cancel') ?></button></div></div>
+				</li>
+			</ul>
+		</div>
+	</form>
+</div>	
+
+<style>
+.edit_p .items input{
+	width:100px;
+}
+.edit_remark p{
+    width:500px;font-size:14px;
+    line-height:30px;
+    height:auto;
+    color:#777;
+}
+.items table thead tr th{
+	 background: #ddd none repeat scroll 0 0;
+    border: 1px solid #ccc;
+    padding: 4px 10px;
+    width: 100px;
+}
+
+.items table tbody tr td{
+	background: #fff;
+    border-right: 1px solid #ccc;
+	border-bottom: 1px solid #ccc;
+    padding:3px;
+    width: 100px;
+}
+
+.edit_p .items input{width:100px;}
+</style>

+ 41 - 0
vendor/fancyecommerce/fecshop/app/appadmin/theme/base/default/catalog/productoptiongroup/manager.php

@@ -0,0 +1,41 @@
+<?php
+/**
+ * FecShop file.
+ *
+ * @link http://www.fecshop.com/
+ * @copyright Copyright (c) 2016 FecShop Software LLC
+ * @license http://www.fecshop.com/license/
+ */
+use fec\helpers\CRequest;
+/** 
+ * @author Terry Zhao <2358269014@qq.com>
+ * @since 1.0
+ */
+?>
+<form id="pagerForm" method="post" action="<?= \fec\helpers\CUrl::getCurrentUrl();  ?>">
+	<?=  CRequest::getCsrfInputHtml();  ?>
+	<?=  $pagerForm;  ?>
+</form>
+<div class="pageHeader">
+	<form rel="pagerForm" onsubmit="return navTabSearch(this);" action="<?= \fec\helpers\CUrl::getCurrentUrl();  ?>" method="post">
+		<?php echo CRequest::getCsrfInputHtml();  ?>
+		<div class="searchBar">
+			<?php  echo $searchBar; ?>
+		</div>
+	</form>
+</div>
+<div class="pageContent">
+	<div class="panelBar">
+		<?= $editBar;  ?>
+	</div>
+	<div class="panelBar">
+		<?= $toolBar; ?>
+	</div>
+	<table class="table" width="100%" layoutH="138">
+		<?= $thead; ?>
+		<tbody>
+			<?= $tbody; ?>
+		</tbody>
+	</table>
+	
+</div>

+ 157 - 0
vendor/fancyecommerce/fecshop/app/appadmin/theme/base/default/catalog/productoptiongroup/manageredit.php

@@ -0,0 +1,157 @@
+<?php
+/**
+ * FecShop file.
+ *
+ * @link http://www.fecshop.com/
+ * @copyright Copyright (c) 2016 FecShop Software LLC
+ * @license http://www.fecshop.com/license/
+ */
+use yii\helpers\Html;
+use fec\helpers\CRequest;
+use fecadmin\models\AdminRole;
+/** 
+ * @author Terry Zhao <2358269014@qq.com>
+ * @since 1.0
+ */
+?>
+<style>
+.checker{float:left;}
+.dialog .pageContent {background:none;}
+.dialog .pageContent .pageFormContent{background:none;}
+</style>
+
+<script>
+
+
+function thissubmit(thiss){
+	var fill = true;
+	items_input = "";
+    
+    var selected_product_attr = '';
+    $(".selected_product_attr:checked").each(function(){
+        attrId = $(this).val();
+        
+        sortOrderI = ".selected_product_sort_order_" + attrId;
+        sort_order = $(sortOrderI).val();
+        selected_product_attr += attrId + '##' + sort_order + "||";
+    });
+    //alert(selected_product_attr);
+    $(".attr_ids_c").val(selected_product_attr);
+    
+	return validateCallback(thiss, dialogAjaxDoneCloseAndReflush);
+}
+
+</script>
+
+<div class="pageContent"> 
+	<form  method="post" action="<?= $saveUrl ?>" class="pageForm required-validate" onsubmit="return thissubmit(this)">
+		<?php echo CRequest::getCsrfInputHtml();  ?>	
+		<div layouth="56" class="pageFormContent" style="height: 240px; overflow: auto;">
+			    <input type="hidden"  value="<?=  $product_id; ?>" size="30" name="product_id" class="textInput ">
+				<fieldset id="fieldset_table_qbe">
+					<legend style="color:#009688"><?= Yii::$service->page->translate->__('Edit Info') ?></legend>
+					<div>
+						<?= $editBar; ?>
+					</div>
+				</fieldset>
+                
+				<?= $lang_attr ?>
+				<?= $textareas ?>
+                
+                <input type="hidden" name="editFormData[attr_ids]"  class="attr_ids_c"  />
+                <div>
+                    <table class="table" width="100%" layoutH="138">
+                        <thead>
+                            <tr>
+                                <th width="22"><input type="checkbox" group="ids" class="checkboxCtrl"></th>
+                                <th width="110" align="left" orderField="sort_order" class="">Sort Order</th>
+                                
+                                <th width="110" align="left" orderField="name" class="">属性名称</th>
+                                <th width="100" align="left" orderField="attr_type" class="">属性类型</th>
+                                
+                                <th width="50" align="center" orderField="status" class="">状态</th>
+                                <th width="110" align="center" orderField="db_type" class="">数据类型</th>
+                                <th width="50" align="center" orderField="show_as_img" class="">图片显示</th>
+                                <th width="110" align="center" orderField="display_type" class="">类型</th>
+                                <th width="50" align="center" orderField="is_require" class="">必填</th>
+                                <th width="110" align="center" orderField="default" class="">默认值</th>
+                                </tr>
+                        </thead>
+                        <tbody>
+                            <?php foreach ($attrs  as $attr): ?>
+                            <?php 
+                                $select_checkbox = '';
+                                $s_sort_order = '';
+                                if (is_array($select_attr_ids)) {
+                                    foreach ($select_attr_ids as $select_attr_id) {
+                                        if ($select_attr_id['attr_id'] == $attr['id']) {
+                                            $select_checkbox = 'checked="checked"';
+                                            $s_sort_order = $select_attr_id['sort_order'];
+                                        }
+                                    }
+                                }
+                                
+                            ?>
+                            <tr target="sid_user" rel="<?= $attr['id'] ?>">
+                                <td>
+                                    <input class="selected_product_attr" <?= $select_checkbox ?> name="ids" value="<?= $attr['id'] ?>" type="checkbox">
+                                </td>
+                                <td><span title=""><input  value="<?= $s_sort_order ?>" class="selected_product_sort_order_<?= $attr['id'] ?>" type="text"  style="width: 50px;height: 10px;margin-top: 2px;"  /></span></td>
+                                
+                                <td><span title=""><?= $attr['name'] ?></span></td>
+                                <td><span title=""><?= Yii::$service->page->translate->__($attr['attr_type']); ?></span></td>
+                                
+                                <td><span title=""><?= $attr['status'] == 1 ? Yii::$service->page->translate->__('Enable') :  Yii::$service->page->translate->__('Disable')  ?></span></td>
+                                <td><span title=""><?= $attr['db_type'] ?></span></td>
+                                <td><span title=""><?= $attr['show_as_img'] == 1 ? Yii::$service->page->translate->__('Yes') :  Yii::$service->page->translate->__('No')  ?></span></td>
+                                <td><span title=""><?= $attr['display_type'] ?></span></td>
+                                <td><span title=""><?= $attr['is_require'] == 1 ? Yii::$service->page->translate->__('Yes') :  Yii::$service->page->translate->__('No')  ?></span></td>
+                                <td><span title=""><?= $attr['default'] ?></span></td>
+                                
+                            </tr>
+                            <?php endforeach; ?>
+                        </tbody>
+                    </table>
+                </div>
+		</div>
+		<div class="formBar">
+			<ul>
+				<!--<li><a class="buttonActive" href="javascript:;"><span>保存</span></a></li>-->
+				<li>
+                    <div class="buttonActive"><div class="buttonContent"><button onclick="func('accept')"  value="accept" name="accept" type="submit"><?= Yii::$service->page->translate->__('Save') ?></button></div></div>
+                </li>
+				<li>
+					<div class="button"><div class="buttonContent"><button type="button" class="close"><?= Yii::$service->page->translate->__('Cancel') ?></button></div></div>
+				</li>
+			</ul>
+		</div>
+	</form>
+</div>	
+
+<style>
+.edit_p .items input{
+	width:100px;
+}
+.edit_remark p{
+    width:500px;font-size:14px;
+    line-height:30px;
+    height:auto;
+    color:#777;
+}
+.items table thead tr th{
+	 background: #ddd none repeat scroll 0 0;
+    border: 1px solid #ccc;
+    padding: 4px 10px;
+    width: 100px;
+}
+
+.items table tbody tr td{
+	background: #fff;
+    border-right: 1px solid #ccc;
+	border-bottom: 1px solid #ccc;
+    padding:3px;
+    width: 100px;
+}
+
+.edit_p .items input{width:100px;}
+</style>

+ 3 - 2
vendor/fancyecommerce/fecshop/app/appfront/modules/Catalog/block/product/CustomOption.php

@@ -26,7 +26,7 @@ class CustomOption
     public function getLastData()
     {
         $items = $this->getAllItems();
-        //var_dump($items);exit;
+
         return [
             'items' => $items,
             'product_id'        => $this->product_id,
@@ -72,7 +72,7 @@ class CustomOption
         }
         if (is_array($custom_option_attr_info) && !empty($custom_option_attr_info)) {
             foreach ($custom_option_attr_info as $attr => $info) {
-                if (isset($info['display']['type']) && ($info['display']['type'] == 'select')) {
+                if (isset($info['display']['type']) && (in_array($info['display']['type'],['select','editSelect']))) {
                     if (isset($info['display']['data']) && is_array($info['display']['data'])) {
                         foreach ($info['display']['data'] as $val) {
                             if (is_array($my_arr[$attr]) && in_array($val, $my_arr[$attr])) {
@@ -95,6 +95,7 @@ class CustomOption
             }
         }
 
+
         return $arr;
     }
 }

+ 0 - 1
vendor/fancyecommerce/fecshop/app/appfront/modules/Catalog/block/product/Index.php

@@ -75,7 +75,6 @@ class Index
         $groupAttrInfo = Yii::$service->product->getGroupAttrInfo($this->_product['attr_group']);
         //var_dump($groupAttrInfo);
         $groupAttrArr = $this->getGroupAttrArr($groupAttrInfo);
-        //var_dump($groupAttrArr );
         return [
             'groupAttrArr'              => $groupAttrArr,
             'name'                      => Yii::$service->store->getStoreAttrVal($this->_product['name'], 'name'),

+ 22 - 1
vendor/fancyecommerce/fecshop/app/appfront/theme/base/front/catalog/product/index.php

@@ -40,6 +40,26 @@
 						
 						</div>
 						
+						<div class="product_custom_options">
+							<?php # custom options部分
+								$optionsView = [
+									'class' =>  'fecshop\app\appfront\modules\Catalog\block\product\CustomOption',
+									'view'	=> 'catalog/product/index/custom_option.php',
+									'custom_option' 	=> $custom_option,
+									'attr_group'		=> $attr_group,
+									'product_id'		=> $_id ,
+									'middle_img_width' 	=> $media_size['middle_img_width'],
+								];
+								$optionsParam = [
+									
+								];
+								
+								
+							?>
+							<?= Yii::$service->page->widget->render($optionsView,$optionsParam); ?>
+						
+						</div>
+						
 						<div class="product_qty pg">
 							<div class="label"><?= Yii::$service->page->translate->__('Qty:'); ?></div>
 							<div class="rg">
@@ -153,7 +173,8 @@
 	// add to cart js	
 	<?php $this->beginBlock('add_to_cart') ?>
 	$(document).ready(function(){
-		$(".addProductToCart").click(function(){
+		$(".addProductToCart").click(function(){	
+		
 			i = 1;
 			$(".product_custom_options .pg .rg ul.required").each(function(){
 				val = $(this).find("li.current a.current").attr("value");

+ 10 - 0
vendor/fancyecommerce/fecshop/config/services/Admin.php

@@ -17,6 +17,8 @@ return [
 					'catalog_product_info_manager' 			=> 'Catalog-Product',
                     'catalog_product_attr_manager' 		    => 'Catalog-Product-Attr',
                     'catalog_product_attr_group_manager' 		=> 'Catalog-Product-Attr-Group',
+                    'catalog_product_custom_option_manager' 		    => 'Catalog-Product-Custom-Option',
+                    'product_custom_option_group_manager' 		=> 'Product-Custom-Option-Group',
 					'catalog_product_review_manager' 		=> 'Catalog-Product-Review',
 					'catalog_product_search_manager' 		=> 'Catalog-Product-Search',
 					'catalog_product_favorite_manager' 	=> 'Catalog-Product-Favorite',
@@ -89,6 +91,14 @@ return [
                                         'label' => 'Product Attribute Group',
                                         'url_key' => '/catalog/productattrgroup/manager',
                                     ],
+                                    'product_custom_option_manager' => [
+                                        'label' => 'Product Custom Option',
+                                        'url_key' => '/catalog/productoption/manager',
+                                    ],
+                                    'product_custom_option_group_manager' => [
+                                        'label' => 'Product Custom Option Group',
+                                        'url_key' => '/catalog/productoptiongroup/manager',
+                                    ],
                                     'product_param_manager' => [
                                         'label' => 'Product Param Config',
                                         'url_key' => '/config/product/manager',

+ 17 - 10
vendor/fancyecommerce/fecshop/services/Product.php

@@ -36,6 +36,9 @@ class Product extends Service
      */
     public $customAttrGroup;
 
+    public $customOptionGroup;
+    public $customOptionArr;
+
     public $categoryAggregateMaxCount = 5000; // Yii::$service->product->categoryAggregateMaxCount;
     /**
       * 分类页面的产品,如果一个spu下面由多个sku同时在这个分类,
@@ -83,6 +86,7 @@ class Product extends Service
         }
         $currentService = $this->getStorageService($this);
         $this->_product = new $currentService();
+        $this->initCustomOptionGroup();
         // 从数据库配置数据,初始化customAttrGroup
         $this->initCustomAttrGroup();
     }
@@ -119,8 +123,7 @@ class Product extends Service
         $allGroupColl = $this->attrGroup->getActiveAllColl();
         // attr
         $allAttrColl = $this->attr->getActiveAllColl();
-        $customOptionGroupArr=[];
-        $customOptionGroupArr=$this->initCustomOptionGroup();
+        $customOptionArr=$this->customOptionArr;
         $attrTypeColl = [];
         if ($allAttrColl) {
             foreach ($allAttrColl as $one) {
@@ -180,12 +183,12 @@ class Product extends Service
             }
         }
         foreach($customAttrGroupArr as $k=>$v){
-            if(isset($customOptionGroupArr[$k])&& is_array($customOptionGroupArr[$k])){
-                $customAttrGroupArr[$k]['custom_options']=$customOptionGroupArr[$k];
+            if(isset($customOptionArr[$k])&& is_array($customOptionArr[$k])){
+                $customAttrGroupArr[$k]['custom_options']=$customOptionArr[$k];
             }
         }
-
         $this->customAttrGroup = $customAttrGroupArr;
+
     }
     
     protected function initCustomOptionGroup()
@@ -202,6 +205,7 @@ class Product extends Service
             }
         }
         $customOptionGroupArr = [];
+        $customOptionArr=[];
         if ($allGroupColl) {
             foreach ($allGroupColl as $one) {
                 $groupName = $one['name'];
@@ -229,6 +233,7 @@ class Product extends Service
                         'name'       => $attrName,
                         'showAsImg'  => $attrOne['show_as_img'] == 1 ? true : false ,
                         'sort_order'   => $attr_sort_order,
+                        'require'=>$attrOne['is_require'] == 1 ? true : false,
                     ];
                     $displayType = $attrOne['display_type'];
                     $displayInfo = [];
@@ -248,11 +253,13 @@ class Product extends Service
                         $displayInfo['data'] = $d_arr;
                     }
                     $attrInfo['display'] = $displayInfo;
-                    $customOptionGroupArr[$groupName][$attrName] = $attrInfo;
+                    $customOptionGroupArr[$groupName][$attrType][$attrName] = $attrInfo;
+                    $customOptionArr[$groupName][$attrName]=$attrInfo;
                 }
             }
         }
-        return $customOptionGroupArr;
+        $this->customOptionGroup=$customOptionGroupArr;
+        $this->customOptionArr=$customOptionArr;
     }
 
 
@@ -429,10 +436,10 @@ class Product extends Service
         if ($productAttrGroup == $this->_defaultAttrGroup) {
             return [];
         }
-        if (isset($this->customAttrGroup[$productAttrGroup]['custom_options'])
-                && is_array($this->customAttrGroup[$productAttrGroup]['custom_options'])
+        if (isset($this->customOptionArr[$productAttrGroup])
+                && is_array($this->customOptionArr[$productAttrGroup])
         ) {
-            return $this->customAttrGroup[$productAttrGroup]['custom_options'];
+            return $this->customOptionArr[$productAttrGroup];
         }
         return [];
     }

+ 8 - 8
vendor/fancyecommerce/fecshop/services/product/ProductMongodb.php

@@ -625,14 +625,14 @@ class ProductMongodb extends Service implements ProductInterface
 
             return false;
         }
-        if (is_array($one['custom_option']) && !empty($one['custom_option'])) {
-           $new_custom_option = [];
-           foreach ($one['custom_option'] as $k=>$v) {
-               $k = preg_replace('/[^A-Za-z0-9\-_]/', '', $k);
-               $new_custom_option[$k] = $v;
-           }
-           $one['custom_option'] = $new_custom_option;
-        }
+        // if (is_array($one['custom_option']) && !empty($one['custom_option'])) {
+        //    $new_custom_option = [];
+        //    foreach ($one['custom_option'] as $k=>$v) {
+        //        $k = preg_replace('/[^A-Za-z0-9\-_]/', '', $k);
+        //        $new_custom_option[$k] = $v;
+        //    }
+        //    $one['custom_option'] = $new_custom_option;
+        // }
 
         return true;
     }