Product.php 26 KB

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