Product.php 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745
  1. <?php
  2. /*
  3. * FecShop file.
  4. *
  5. * @link http://www.fecshop.com/
  6. * @copyright Copyright (c) 2016 FecShop Software LLC
  7. * @license http://www.fecshop.com/license/
  8. */
  9. namespace fecshop\services;
  10. use yii\base\InvalidCallException;
  11. use yii\base\InvalidConfigException;
  12. use Yii;
  13. /**
  14. * Product Service is the component that you can get product info from it.
  15. *
  16. * @property \fecshop\services\Image | \fecshop\services\Product\Image $image image service or product image sub-service
  17. * @property \fecshop\services\product\Info $info product info sub-service
  18. * @property \fecshop\services\product\Stock $stock stock sub-service of product service
  19. *
  20. * @method getByPrimaryKey($primaryKey) get product model by primary key
  21. * @see \fecshop\services\Product::actionGetByPrimaryKey()
  22. * @method getEnableStatus() get enable status
  23. * @see \fecshop\services\Product::actionGetEnableStatus()
  24. *
  25. * @author Terry Zhao <2358269014@qq.com>
  26. * @since 1.0
  27. */
  28. class Product extends Service
  29. {
  30. /**
  31. * @var array 自定义的属性组配置数组
  32. */
  33. public $customAttrGroup;
  34. public $customOptionGroup;
  35. public $categoryAggregateMaxCount = 5000; // Yii::$service->product->categoryAggregateMaxCount;
  36. /**
  37. * 分类页面的产品,如果一个spu下面由多个sku同时在这个分类,
  38. * 那么,是否只显示一个sku(score最高),而不是全部sku
  39. * true: 代表只显示一个sku
  40. * false: 代表产品全部显示
  41. */
  42. public $productSpuShowOnlyOneSku = true;
  43. /**
  44. * $storagePrex , $storage , $storagePath 为找到当前的storage而设置的配置参数
  45. * 可以在配置中更改,更改后,就会通过容器注入的方式修改相应的配置值
  46. */
  47. public $storage; // = 'ProductMysqldb'; // ProductMysqldb | ProductMongodb 当前的storage,如果在config中配置,那么在初始化的时候会被注入修改
  48. /**
  49. * 设置storage的path路径,
  50. * 如果不设置,则系统使用默认路径
  51. * 如果设置了路径,则使用自定义的路径
  52. */
  53. public $storagePath = '';
  54. /**
  55. * @var \fecshop\services\product\ProductInterface 根据 $storage 及 $storagePath 配置的 Product 的实现
  56. */
  57. protected $_product;
  58. /**
  59. * @var string 默认属性组名称
  60. */
  61. protected $_defaultAttrGroup = 'default';
  62. public function init()
  63. {
  64. parent::init();
  65. // init $this->productSpuShowOnlyOneSku
  66. $appName = Yii::$service->helper->getAppName();
  67. $productSpuShowOnlyOneSku = Yii::$app->store->get($appName.'_catalog','category_productSpuShowOnlyOneSku');
  68. $this->productSpuShowOnlyOneSku = ($productSpuShowOnlyOneSku == Yii::$app->store->enable) ? true : false;
  69. // 从数据库配置中得到值, 设置成当前service存储,是Mysqldb 还是 Mongodb
  70. $config = Yii::$app->store->get('service_db', 'category_and_product');
  71. $this->storage = 'ProductMysqldb';
  72. if ($config == Yii::$app->store->serviceMongodbName) {
  73. $this->storage = 'ProductMongodb';
  74. }
  75. $currentService = $this->getStorageService($this);
  76. $this->_product = new $currentService();
  77. $this->initCustomOptionGroup();
  78. // 从数据库配置数据,初始化customAttrGroup
  79. $this->initCustomAttrGroup();
  80. }
  81. // 动态更改为mongodb model
  82. public function changeToMongoStorage()
  83. {
  84. $this->storage = 'ProductMongodb';
  85. $currentService = $this->getStorageService($this);
  86. $this->_product = new $currentService();
  87. }
  88. public function serviceStorageName()
  89. {
  90. return $this->_product->serviceStorageName();
  91. }
  92. // 动态更改为mongodb model
  93. public function changeToMysqlStorage()
  94. {
  95. $this->storage = 'ProductMysqldb';
  96. $currentService = $this->getStorageService($this);
  97. $this->_product = new $currentService();
  98. }
  99. protected function actionGetEnableStatus()
  100. {
  101. return $this->_product->getEnableStatus();
  102. }
  103. // 从数据库配置数据,初始化customAttrGroup
  104. protected function initCustomAttrGroup()
  105. {
  106. $attrPrimaryKey =$this->attr->getPrimaryKey();
  107. $attrGroupPrimaryKey = $this->attrGroup->getPrimaryKey();
  108. $allGroupColl = $this->attrGroup->getActiveAllColl();
  109. // attr
  110. $allAttrColl = $this->attr->getActiveAllColl();
  111. $customOptionGroup=$this->customOptionGroup;
  112. $attrTypeColl = [];
  113. if ($allAttrColl) {
  114. foreach ($allAttrColl as $one) {
  115. $attrTypeColl[$one[$attrPrimaryKey]] = $one;
  116. }
  117. }
  118. $customAttrGroupArr = [];
  119. if ($allGroupColl) {
  120. foreach ($allGroupColl as $one) {
  121. $groupName = $one['name'];
  122. $attr_ids = $one['attr_ids'];
  123. if (!is_array($attr_ids) || empty($attr_ids)) {
  124. continue;
  125. }
  126. $attr_ids = \fec\helpers\CFunc::array_sort($attr_ids, 'sort_order', 'desc');
  127. //var_dump($attr_ids);exit;
  128. foreach ($attr_ids as $attr_id_one) {
  129. if (!is_array($attr_id_one)) {
  130. continue;
  131. }
  132. $attr_id = $attr_id_one['attr_id'];
  133. $attr_sort_order = $attr_id_one['sort_order'];
  134. $attrOne = $attrTypeColl[$attr_id];
  135. if (!$attrOne) {
  136. continue;
  137. }
  138. $attrName = $attrOne['name'];
  139. $attrType = $attrOne['attr_type'];
  140. $attrInfo = [
  141. 'dbtype' => $attrOne['db_type'],
  142. 'name' => $attrName,
  143. 'showAsImg' => $attrOne['show_as_img'] == 1 ? true : false ,
  144. 'sort_order' => $attr_sort_order,
  145. ];
  146. $displayType = $attrOne['display_type'];
  147. $displayInfo = [];
  148. if ($displayType == 'inputString-Lang') {
  149. $displayInfo['type'] = 'inputString';
  150. $displayInfo['lang'] = true;
  151. } else {
  152. $displayInfo['type'] = $displayType;
  153. }
  154. if (is_array($attrOne['display_data'])) {
  155. $d_arr = [];
  156. foreach ($attrOne['display_data'] as $o) {
  157. if ($o['key']) {
  158. $d_arr[] = $o['key'];
  159. }
  160. }
  161. $displayInfo['data'] = $d_arr;
  162. }
  163. $attrInfo['display'] = $displayInfo;
  164. $customAttrGroupArr[$groupName][$attrType][$attrName] = $attrInfo;
  165. }
  166. }
  167. }
  168. foreach($customAttrGroupArr as $k=>$v){
  169. if(isset($customOptionGroup[$k])&& is_array($customOptionGroup[$k])){
  170. $customAttrGroupArr[$k]['custom_options']=$customOptionGroup[$k];
  171. }
  172. }
  173. $this->customAttrGroup = $customAttrGroupArr;
  174. }
  175. protected function initCustomOptionGroup()
  176. {
  177. $attrPrimaryKey =$this->option->getPrimaryKey();
  178. $attrGroupPrimaryKey = $this->optionGroup->getPrimaryKey();
  179. $allGroupColl = $this->optionGroup->getActiveAllColl();
  180. // attr
  181. $allAttrColl = $this->option->getActiveAllColl();
  182. $attrTypeColl = [];
  183. if ($allAttrColl) {
  184. foreach ($allAttrColl as $one) {
  185. $attrTypeColl[$one[$attrPrimaryKey]] = $one;
  186. }
  187. }
  188. $customOptionGroup=[];
  189. if ($allGroupColl) {
  190. foreach ($allGroupColl as $one) {
  191. $groupName = $one['name'];
  192. $attr_ids = $one['attr_ids'];
  193. if (!is_array($attr_ids) || empty($attr_ids)) {
  194. continue;
  195. }
  196. $attr_ids = \fec\helpers\CFunc::array_sort($attr_ids, 'sort_order', 'desc');
  197. //var_dump($attr_ids);exit;
  198. foreach ($attr_ids as $attr_id_one) {
  199. if (!is_array($attr_id_one)) {
  200. continue;
  201. }
  202. $attr_id = $attr_id_one['attr_id'];
  203. $attr_sort_order = $attr_id_one['sort_order'];
  204. $attrOne = $attrTypeColl[$attr_id];
  205. if (!$attrOne) {
  206. continue;
  207. }
  208. $attrName = $attrOne['name'];
  209. $attrType = $attrOne['attr_type'];
  210. $attrInfo = [
  211. 'dbtype' => $attrOne['db_type'],
  212. 'name' => $attrName,
  213. 'showAsImg' => $attrOne['show_as_img'] == 1 ? true : false ,
  214. 'sort_order' => $attr_sort_order,
  215. 'require'=>$attrOne['is_require'] == 1 ? true : false,
  216. ];
  217. $displayType = $attrOne['display_type'];
  218. $displayInfo = [];
  219. if ($displayType == 'inputString-Lang') {
  220. $displayInfo['type'] = 'inputString';
  221. $displayInfo['lang'] = true;
  222. } else {
  223. $displayInfo['type'] = $displayType;
  224. }
  225. if (is_array($attrOne['display_data'])) {
  226. $d_arr = [];
  227. foreach ($attrOne['display_data'] as $o) {
  228. if ($o['key']) {
  229. $d_arr[] = $o;
  230. }
  231. }
  232. $displayInfo['data'] = $d_arr;
  233. }
  234. $attrInfo['display'] = $displayInfo;
  235. $customOptionGroup[$groupName][$attrName]=$attrInfo;
  236. }
  237. }
  238. }
  239. $this->customOptionGroup=$customOptionGroup;
  240. }
  241. /**
  242. * 得到产品的所有的属性组。
  243. */
  244. protected function actionGetCustomAttrGroup()
  245. {
  246. $customAttrGroup = $this->customAttrGroup;
  247. $arr = array_keys($customAttrGroup);
  248. $arr[] = $this->_defaultAttrGroup;
  249. return $arr;
  250. }
  251. /**
  252. * @param $productAttrGroup|string
  253. * 得到这个产品属性组里面的所有的产品属性详细,
  254. * 注解:不同类型的产品,对应不同的属性组,譬如衣服有颜色尺码,电脑类型的有不同cpu型号等
  255. * 属性组,以及属性组对应的属性,是在Product Service config中配置的。
  256. */
  257. protected function actionGetGroupAttrInfo($productAttrGroup)
  258. {
  259. $arr = [];
  260. if ($productAttrGroup == $this->_defaultAttrGroup) {
  261. return [];
  262. }
  263. // 得到普通属性
  264. if (isset($this->customAttrGroup[$productAttrGroup]['general_attr'])
  265. && is_array($this->customAttrGroup[$productAttrGroup]['general_attr'])
  266. ) {
  267. $arr = array_merge($arr, $this->customAttrGroup[$productAttrGroup]['general_attr']);
  268. }
  269. // 得到用于spu,细分sku的属性,譬如颜色尺码之类。
  270. if (isset($this->customAttrGroup[$productAttrGroup]['spu_attr'])
  271. && is_array($this->customAttrGroup[$productAttrGroup]['spu_attr'])
  272. ) {
  273. $arr = array_merge($arr, $this->customAttrGroup[$productAttrGroup]['spu_attr']);
  274. }
  275. return $arr;
  276. }
  277. public function getGroupGeneralAttr($productAttrGroup)
  278. {
  279. $arr = [];
  280. if ($productAttrGroup == $this->_defaultAttrGroup) {
  281. return [];
  282. }
  283. // 得到普通属性
  284. if (isset($this->customAttrGroup[$productAttrGroup]['general_attr'])
  285. && is_array($this->customAttrGroup[$productAttrGroup]['general_attr'])
  286. ) {
  287. $arr = array_merge($arr, $this->customAttrGroup[$productAttrGroup]['general_attr']);
  288. }
  289. return $arr;
  290. }
  291. public function getGroupSpuAttr($productAttrGroup)
  292. {
  293. $arr = [];
  294. if ($productAttrGroup == $this->_defaultAttrGroup) {
  295. return [];
  296. }
  297. // 得到用于spu,细分sku的属性,譬如颜色尺码之类。
  298. if (isset($this->customAttrGroup[$productAttrGroup]['spu_attr'])
  299. && is_array($this->customAttrGroup[$productAttrGroup]['spu_attr'])
  300. ) {
  301. $arr = array_merge($arr, $this->customAttrGroup[$productAttrGroup]['spu_attr']);
  302. }
  303. return $arr;
  304. }
  305. /**
  306. * @param $productAttrGroup|string
  307. * 得到这个产品属性组里面的所有的产品属性,
  308. * 注解:不同类型的产品,对应不同的属性组,譬如衣服有颜色尺码,电脑类型的有不同cpu型号等
  309. * 属性组,以及属性组对应的属性,是在Product Service config中配置的。
  310. */
  311. protected function actionGetGroupAttr($productAttrGroup)
  312. {
  313. $arr = [];
  314. // 得到普通属性
  315. if (isset($this->customAttrGroup[$productAttrGroup]['general_attr'])
  316. && is_array($this->customAttrGroup[$productAttrGroup]['general_attr'])
  317. ) {
  318. $general_attr = $this->customAttrGroup[$productAttrGroup]['general_attr'];
  319. if (is_array($general_attr)) {
  320. foreach ($general_attr as $attr => $info) {
  321. $arr[] = $attr;
  322. }
  323. }
  324. }
  325. // 得到用于spu,细分sku的属性,譬如颜色尺码之类。
  326. if (isset($this->customAttrGroup[$productAttrGroup]['spu_attr'])
  327. && is_array($this->customAttrGroup[$productAttrGroup]['spu_attr'])
  328. ) {
  329. $spu_attr = $this->customAttrGroup[$productAttrGroup]['spu_attr'];
  330. if (is_array($spu_attr)) {
  331. foreach ($spu_attr as $attr => $info) {
  332. $arr[] = $attr;
  333. }
  334. }
  335. }
  336. return $arr;
  337. }
  338. /**
  339. * @param $productAttrGroup|string
  340. * @return array 一维数组
  341. * 得到这个产品属性组里面的属性,也就是原来的产品属性+属性组对应的属性
  342. */
  343. protected function actionGetSpuAttr($productAttrGroup)
  344. {
  345. $arr = [];
  346. if ($productAttrGroup == $this->_defaultAttrGroup) {
  347. return [];
  348. }
  349. // 得到用于spu,细分sku的属性,譬如颜色尺码之类。
  350. if (isset($this->customAttrGroup[$productAttrGroup]['spu_attr'])
  351. && is_array($this->customAttrGroup[$productAttrGroup]['spu_attr'])
  352. ) {
  353. $arr = array_merge($arr, $this->customAttrGroup[$productAttrGroup]['spu_attr']);
  354. }
  355. return array_keys($arr);
  356. }
  357. /**
  358. * @param $productAttrGroup | String
  359. * @return string 显示图片的spu属性。
  360. */
  361. protected function actionGetSpuImgAttr($productAttrGroup)
  362. {
  363. if ($productAttrGroup == $this->_defaultAttrGroup) {
  364. return '';
  365. }
  366. // 得到用于spu,细分sku的属性,譬如颜色尺码之类。
  367. if (isset($this->customAttrGroup[$productAttrGroup]['spu_attr'])
  368. && is_array($this->customAttrGroup[$productAttrGroup]['spu_attr'])
  369. ) {
  370. foreach ($this->customAttrGroup[$productAttrGroup]['spu_attr'] as $attr => $one) {
  371. if (isset($one['showAsImg']) && $one['showAsImg']) {
  372. return $attr;
  373. }
  374. }
  375. }
  376. return '';
  377. }
  378. /**
  379. * 产品状态是否是 active
  380. * @param int $status
  381. * @return boolean 如果产品状态是 active 返回 true, 否则返回 false
  382. */
  383. protected function actionIsActive($status)
  384. {
  385. return ($status == 1) ? true : false;
  386. }
  387. /**
  388. * @param $productAttrGroup | String 产品属性组
  389. * 通过产品属性组,从配置中得到对应的custom_options部分的配置
  390. * @return array
  391. */
  392. protected function actionGetCustomOptionAttrInfo($productAttrGroup)
  393. {
  394. if ($productAttrGroup == $this->_defaultAttrGroup) {
  395. return [];
  396. }
  397. if (isset($this->customOptionGroup[$productAttrGroup])
  398. && is_array($this->customOptionGroup[$productAttrGroup])
  399. ) {
  400. return $this->customOptionGroup[$productAttrGroup];
  401. }
  402. return [];
  403. }
  404. /**
  405. * 得到默认的产品属性组。
  406. */
  407. protected function actionGetDefaultAttrGroup()
  408. {
  409. return $this->_defaultAttrGroup;
  410. }
  411. /**
  412. * 得到主键的名称.
  413. */
  414. protected function actionGetPrimaryKey()
  415. {
  416. return $this->_product->getPrimaryKey();
  417. }
  418. public function getCategoryIdsByProductId($product_id)
  419. {
  420. return $this->_product->getCategoryIdsByProductId($product_id);
  421. }
  422. public function getProductIdsByCategoryId($category_id)
  423. {
  424. return $this->_product->getProductIdsByCategoryId($category_id);
  425. }
  426. /**
  427. * get Product model by primary key.
  428. */
  429. protected function actionGetByPrimaryKey($primaryKey)
  430. {
  431. return $this->_product->getByPrimaryKey($primaryKey);
  432. }
  433. /**
  434. * get Product model by primary key.
  435. */
  436. protected function actionGetArrByPrimaryKey($primaryKey)
  437. {
  438. return $this->_product->getArrByPrimaryKey($primaryKey);
  439. }
  440. /**
  441. * @param $attr_group | String , 属性组名称
  442. * 给product model 增加相应的属性组对应的属性。
  443. */
  444. protected function actionAddGroupAttrs($attr_group)
  445. {
  446. return $this->_product->addGroupAttrs($attr_group);
  447. }
  448. /**
  449. * api部分
  450. * 和coll()的不同在于,该方式不走active record,因此可以获取产品的所有数据的。
  451. */
  452. protected function actionApicoll()
  453. {
  454. return $this->_product->apicoll();
  455. }
  456. /**
  457. * api部分
  458. */
  459. protected function actionApiGetByPrimaryKey($primaryKey)
  460. {
  461. return $this->_product->apiGetByPrimaryKey($primaryKey);
  462. }
  463. /**
  464. * api部分
  465. */
  466. protected function actionApiSave($product_one)
  467. {
  468. return $this->_product->apiSave($product_one);
  469. }
  470. /**
  471. * api部分
  472. */
  473. protected function actionApiDelete($primaryKey)
  474. {
  475. return $this->_product->apiDelete($primaryKey);
  476. }
  477. public function updateProductFavoriteCount($product_id, $count)
  478. {
  479. return $this->_product->updateProductFavoriteCount($product_id, $count);
  480. }
  481. /**
  482. * 得到Product model的全名.
  483. */
  484. protected function actionGetModelName()
  485. {
  486. return get_class($this->_product->getByPrimaryKey());
  487. }
  488. /**
  489. * @param $sku | string
  490. * @param $returnArr | boolean , 是否返回数组格式
  491. * 通过sku查询产品
  492. */
  493. protected function actionGetBySku($sku, $returnArr = true)
  494. {
  495. return $this->_product->getBySku($sku, $returnArr);
  496. }
  497. /**
  498. * @param $spu | string
  499. * 通过spu查询产品
  500. */
  501. protected function actionGetBySpu($spu)
  502. {
  503. return $this->_product->getBySpu($spu);
  504. }
  505. /**
  506. * @param $filter|array
  507. * get artile collection by $filter
  508. * example filter:
  509. * [
  510. * 'numPerPage' => 20,
  511. * 'pageNum' => 1,
  512. * 'orderBy' => ['_id' => SORT_DESC, 'sku' => SORT_ASC ],
  513. * 'where' => [
  514. * ['>','price',1],
  515. * ['<=','price',10]
  516. * ['sku' => 'uk10001'],
  517. * ],
  518. * 'asArray' => true,
  519. * ]
  520. * 根据传入的查询条件,得到产品的列表
  521. */
  522. protected function actionColl($filter = [])
  523. {
  524. return $this->_product->coll($filter);
  525. }
  526. protected function actionCollCount($filter = [])
  527. {
  528. return $this->_product->collCount($filter);
  529. }
  530. /**
  531. * 通过where条件 和 查找的select 字段信息,得到产品的列表信息,
  532. * 这里一般是用于前台的区块性的不分页的产品查找。
  533. * 结果数据没有进行进一步处理,需要前端获取数据后在处理。
  534. */
  535. protected function actionGetProducts($filter)
  536. {
  537. return $this->_product->getProducts($filter);
  538. }
  539. /**
  540. * @param $product_id_arr | Array
  541. * @param $category_id | String
  542. * 在给予的产品id数组$product_id_arr中,找出来那些产品属于分类 $category_id
  543. * 该功能是后台分类编辑中,对应的分类产品列表功能
  544. * 也就是在当前的分类下,查看所有的产品,属于当前分类的产品,默认被勾选。
  545. */
  546. protected function actionGetCategoryProductIds($product_id_arr, $category_id)
  547. {
  548. return $this->_product->getCategoryProductIds($product_id_arr, $category_id);
  549. }
  550. /**
  551. * @param $one|array , 产品数据数组
  552. * @param $originUrlKey|string , 分类的原来的url key ,也就是在前端,分类的自定义url。
  553. * 保存产品(插入和更新),以及保存产品的自定义url
  554. * 如果提交的数据中定义了自定义url,则按照自定义url保存到urlkey中,如果没有自定义urlkey,则会使用name进行生成。
  555. */
  556. protected function actionSave($one, $originUrlKey = 'catalog/product/index', $isLoginUser=true)
  557. {
  558. return $this->_product->save($one, $originUrlKey, $isLoginUser);
  559. }
  560. /**
  561. * @param $ids | Array or String
  562. * 删除产品,如果ids是数组,则删除多个产品,如果是字符串,则删除一个产品
  563. * 在产品产品的同时,会在url rewrite表中删除对应的自定义url数据。
  564. */
  565. protected function actionRemove($ids)
  566. {
  567. return $this->_product->remove($ids);
  568. }
  569. public function spuCollData($select, $spuAttrArr, $spu)
  570. {
  571. return $this->_product->spuCollData($select, $spuAttrArr, $spu);
  572. }
  573. /**
  574. * @param $category_id | String 分类的id的值
  575. * @param $addCateProductIdArr | Array 分类中需要添加的产品id数组,也就是给这个分类增加这几个产品。
  576. * @param $deleteCateProductIdArr | Array 分类中需要删除的产品id数组,也就是在这个分类下面去除这几个产品的对应关系。
  577. * 这个函数是后台分类编辑功能中使用到的函数,在分类中可以一次性添加多个产品,也可以删除多个产品,产品和分类是多对多的关系。
  578. */
  579. protected function actionAddAndDeleteProductCategory($category_id, $addCateProductIdArr, $deleteCateProductIdArr)
  580. {
  581. return $this->_product->addAndDeleteProductCategory($category_id, $addCateProductIdArr, $deleteCateProductIdArr);
  582. }
  583. /**
  584. * [
  585. * 'category_id' => 1,
  586. * 'pageNum' => 2,
  587. * 'numPerPage' => 50,
  588. * 'orderBy' => 'name',
  589. * 'where' => [
  590. * ['>','price',11],
  591. * ['<','price',22],
  592. * ],
  593. * 'select' => ['xx','yy'],
  594. * 'group' => '$spu',
  595. * ]
  596. * 得到分类下的产品,在这里需要注意的是:
  597. * 1.同一个spu的产品,有很多sku,但是只显示score最高的产品,这个score可以通过脚本取订单的销量(最近一个月,或者
  598. * 最近三个月等等),或者自定义都可以。
  599. * 2.结果按照filter里面的orderBy排序
  600. * 3.由于使用的是mongodb的aggregate(管道)函数,因此,此函数有一定的限制,就是该函数
  601. * 处理后的结果不能大约32MB,因此,如果一个分类下面的产品几十万的时候可能就会出现问题,
  602. * 这种情况可以用专业的搜索引擎做聚合工具。
  603. * 不过,对于一般的用户来说,这个不会成为瓶颈问题,一般一个分类下的产品不会出现几十万的情况。
  604. * 4.最后就得到spu唯一的产品列表(多个spu相同,sku不同的产品,只要score最高的那个).
  605. */
  606. protected function actionGetFrontCategoryProducts($filter)
  607. {
  608. return $this->_product->getFrontCategoryProducts($filter);
  609. }
  610. public function actionSync($arr)
  611. {
  612. return $this->_product->sync($arr);
  613. }
  614. /**
  615. * @param $filter_attr | String 需要进行统计的字段名称
  616. * @propertuy $where | Array 搜索条件。这个需要些mongodb的搜索条件。
  617. * 得到的是个属性,以及对应的个数。
  618. * 这个功能是用于前端分类侧栏进行属性过滤。
  619. */
  620. protected function actionGetFrontCategoryFilter($filter_attr, $where)
  621. {
  622. return $this->_product->getFrontCategoryFilter($filter_attr, $where);
  623. }
  624. /**
  625. * 全文搜索
  626. * $filter Example:
  627. * $filter = [
  628. * 'pageNum' => $this->getPageNum(),
  629. * 'numPerPage' => $this->getNumPerPage(),
  630. * 'where' => $this->_where,
  631. * 'product_search_max_count' => Yii::$app->controller->module->params['product_search_max_count'],
  632. * 'select' => $select,
  633. * ];
  634. * 因为mongodb的搜索涉及到计算量,因此产品过多的情况下,要设置 product_search_max_count的值。减轻服务器负担
  635. * 因为对客户来说,前10页的产品已经足矣,后面的不需要看了,限定一下产品个数,减轻服务器的压力。
  636. * 多个spu,取score最高的那个一个显示。
  637. * 按照搜索的匹配度来进行排序,没有其他排序方式.
  638. */
  639. //protected function actionFullTearchText($filter){
  640. // return $this->_product->fullTearchText($filter);
  641. //}
  642. /**
  643. * @param $ids | Array
  644. * 通过产品ids得到产品sku
  645. */
  646. public function getSkusByIds($ids)
  647. {
  648. return $this->_product->getSkusByIds($ids);
  649. }
  650. /**
  651. * @param $spu | String
  652. * @param $avag_rate | Int 产品的总平均得分
  653. * @param $count | Int 产品的总评论数
  654. * @param $avag_lang_rate | 当前语言的总平均得分
  655. * @param $lang_count | 当前语言的总评论数
  656. */
  657. protected function actionUpdateProductReviewInfo($spu, $avag_rate, $count, $lang_code, $avag_lang_rate, $lang_count, $rate_total_arr, $rate_lang_total_arr)
  658. {
  659. return $this->_product->updateProductReviewInfo($spu, $avag_rate, $count, $lang_code, $avag_lang_rate, $lang_count, $rate_total_arr, $rate_lang_total_arr);
  660. }
  661. public function updateAllScoreToZero()
  662. {
  663. return $this->_product->updateAllScoreToZero();
  664. }
  665. public function excelSave($productArr)
  666. {
  667. return $this->_product->excelSave($productArr);
  668. }
  669. }