SyncMallGoodsService.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. <?php
  2. namespace addons\Store\common\services;
  3. use addons\Store\common\enums\StoreEnum;
  4. use addons\Store\common\models\Store;
  5. use addons\Store\common\models\StoreGoods;
  6. use addons\Store\common\models\StoreGoodsCate;
  7. use addons\WuzhouChain\common\models\WuzhouChainStorage;
  8. use addons\WuzhouChain\common\services\SettingService;
  9. use common\enums\AddonsEnum;
  10. use common\enums\GoodsTypeEnum;
  11. use common\enums\StatusEnum;
  12. use common\helpers\ArrayHelper;
  13. use common\models\goods\GoodsCate;
  14. use common\models\goods\GoodsReserveSku;
  15. use common\models\mall\MallAddons;
  16. class SyncMallGoodsService
  17. {
  18. // 同步商品到门店---分类也同步
  19. public static function syncMallGoods($params)
  20. {
  21. try {
  22. $mall_id = $params['mall_id'];
  23. $selected_goods_ids = $params['goods_ids'];
  24. $store_id = $params['store_id'];
  25. self::checkWuzhouChain($mall_id);
  26. /**
  27. * @var $goods_list \common\models\goods\Goods[]
  28. */
  29. $goods_list = \common\models\goods\Goods::findAll(['mall_id' => $mall_id, 'id' => $selected_goods_ids]);
  30. $goods_list = $goods_list ?? [];
  31. foreach ($goods_list as $goods) {
  32. $chainStorage = WuzhouChainStorage::findOne(['mall_id' => $mall_id, 'goods_id' => $goods['id'], 'store_id' => $store_id, 'status' => StatusEnum::ENABLED]);
  33. if ($chainStorage) continue;
  34. // 商品分类-生成或者获取门店分类
  35. $cats = self::getCate($mall_id, $goods['id'], $store_id);
  36. try {
  37. $store_goods = StoreGoods::findOne(['mall_id' => $mall_id, 'store_id' => $store_id, 'mall_goods_id' => $goods['id'], 'status' => StatusEnum::ENABLED, 'supplier_type' => StoreEnum::SELF_MALL_WUZHOU]);
  38. if ($store_goods) {
  39. continue;
  40. }
  41. $base_params = [
  42. 'mall_id' => $mall_id,
  43. 'store_id' => $store_id,
  44. 'supplier_id' => $store_id,
  45. 'supplier_type' => StoreEnum::SELF_MALL_WUZHOU,
  46. 'cats' => $cats,
  47. 'mall_goods_id' => $goods['id'],
  48. 'id' => $store_goods['id'] ?? 0,
  49. 'coupon_selection' => [],
  50. 'check_status' => StatusEnum::ENABLED
  51. ];
  52. $mall_goods = $goods['attributes'];
  53. $base_params['extra'] = !empty($goods->extra) ? ArrayHelper::toArray($goods->extra) : [];
  54. if (isset($base_params['extra']['goods_id'])) unset($base_params['extra']['goods_id']);
  55. if (empty($mall_goods['services'])) {
  56. $mall_goods['services'] = [];
  57. } else {
  58. $mall_goods['services'] = explode(',', $mall_goods['services']);
  59. }
  60. if (empty($mall_goods['labels'])) {
  61. $mall_goods['labels'] = [];
  62. } else {
  63. $mall_goods['labels'] = explode(',', $mall_goods['labels']);
  64. }
  65. if (empty($mall_goods['freight_type'])) {
  66. $mall_goods['freight_type'] = [];
  67. } else {
  68. $mall_goods['freight_type'] = explode(',', $mall_goods['freight_type']);
  69. }
  70. !empty($mall_goods['attr_groups']) && $mall_goods['attr_groups'] = json_decode($mall_goods['attr_groups'], true);
  71. !empty($mall_goods['bannar_pic']) && $mall_goods['bannar_pic'] = json_decode($mall_goods['bannar_pic'], true);
  72. !empty($mall_goods['area_limit']) && $mall_goods['area_limit'] = json_decode($mall_goods['area_limit'], true);
  73. // 预约商品
  74. if ($mall_goods['goods_type'] == GoodsTypeEnum::GoodsTypeReserved) {
  75. $reserve = ArrayHelper::toArray($goods->reserve);
  76. unset($reserve['id'], $reserve['goods_id']);
  77. $skus = GoodsReserveSku::lists([
  78. 'where' => [['goods_id' => $goods['id']]],
  79. 'with' => ['times' => function ($query) {
  80. $query->with(['timeSpec']);
  81. }]
  82. ]);
  83. foreach ($skus as &$sku) {
  84. unset($sku['id'], $sku['goods_id']);
  85. foreach ($sku['times'] as &$time) {
  86. unset($time['id'], $time['reserve_sku_id']);
  87. if (!empty($time['timeSpec'])) {
  88. foreach ($time['timeSpec'] as &$time_spec) {
  89. unset($time_spec['id'], $time_spec['reserve_time_id'], $time_spec['reserve_sku_id']);
  90. }
  91. $time['time_spec'] = $time['timeSpec'];
  92. unset($time_spec, $time['timeSpec']);
  93. }
  94. }
  95. unset($time);
  96. }
  97. unset($sku);
  98. $reserve['skus'] = $skus;
  99. $mall_goods['reserve'] = $reserve;
  100. } else {
  101. if ($mall_goods['is_attr'] == 1) {
  102. $temp_attrs = ArrayHelper::toArray($goods->attr);
  103. $attr_groups = $mall_goods['attr_groups'];
  104. $attr = [];
  105. foreach ($temp_attrs as $val) {
  106. $val['mall_attr_id'] = $val['id'];
  107. unset($val['id']);
  108. unset($val['goods_id']);
  109. $sku_group_name = explode(',', $val['name']);
  110. $attr_list = [];
  111. foreach ($sku_group_name as $name) {
  112. $name_arr = explode(':', $name);
  113. foreach ($attr_groups as $group) {
  114. if ($group['attr_group_name'] == $name_arr[0]) {
  115. foreach ($group['attr_list'] as $v) {
  116. if ($v['attr_name'] == $name_arr[1]) {
  117. $attr_list[] = [
  118. 'attr_id' => $v['attr_id'],
  119. 'attr_name' => $v['attr_name'],
  120. 'pic_url' => '',
  121. 'attr_group_id' => $group['attr_group_id'],
  122. 'attr_group_name' => $group['attr_group_name'],
  123. ];
  124. break;
  125. }
  126. }
  127. break;
  128. }
  129. }
  130. }
  131. $val['attr_list'] = $attr_list;
  132. $attr[] = $val;
  133. }
  134. $base_params['attr'] = $attr;
  135. }
  136. }
  137. unset($mall_goods['id']);
  138. $res = StoreGoods::setData(array_merge($mall_goods, $base_params));
  139. if ($res === false) throw new \Exception(StoreGoods::getStaticError());
  140. // 更新导入表
  141. $data = [
  142. 'mall_id' => $mall_id,
  143. 'store_id' => $store_id,
  144. 'goods_id' => $goods['id'],
  145. 'status' => StatusEnum::ENABLED,
  146. 'store_goods_id' => $res->id,
  147. ];
  148. $res = WuzhouChainStorage::setData($data);
  149. if ($res === false) throw new \Exception(WuzhouChainStorage::$static_error);
  150. } catch (\Exception $e) {
  151. \Yii::error(self::class . '->' . __FUNCTION__ . '//errMsg2:' . $e->getMessage() . '//params:' . json_encode(array_merge($mall_goods, $base_params)));
  152. }
  153. }
  154. } catch (\Exception $e) {
  155. \Yii::error(self::class . '->' . __FUNCTION__ . '//errMsg1:' . $e->getMessage());
  156. return false;
  157. }
  158. return true;
  159. }
  160. public static function getCate($mall_id, $goods_id, $store_id)
  161. {
  162. $cats = \common\models\goods\Goods::find()->where(['id' => $goods_id])->with(['cats'])->asArray()->one();
  163. $cates = [];
  164. foreach ($cats['cats'] as $cate) {
  165. if (!$cate['parent_id']) {
  166. // 一级分类
  167. $cates[] = self::checkAndAddCate($mall_id, $store_id, $cate['name']);
  168. } else {
  169. // 二级分类 || 三级分类
  170. $temp = GoodsCate::find()->where(['id' => $cate['parent_id']])->with(['parent'])->asArray()->one();
  171. if (!$temp) {
  172. throw new \Exception('分类不存在');
  173. }
  174. if (!$temp['parent']) {
  175. // 二级分类
  176. // 添加、获取一级分类
  177. $parent_id = self::checkAndAddCate($mall_id, $store_id, $temp['name']);
  178. $cates[] = self::checkAndAddCate($mall_id, $store_id, $cate['name'], $parent_id);
  179. } else {
  180. // 三级分类
  181. // 添加、获取一级分类
  182. $parent_id = self::checkAndAddCate($mall_id, $store_id, $temp['parent']['name']);
  183. // 添加、获取二级分类
  184. $grand_parent_id = self::checkAndAddCate($mall_id, $store_id, $temp['name'], $parent_id);
  185. $cates[] = self::checkAndAddCate($mall_id, $store_id, $cate['name'], $grand_parent_id);
  186. }
  187. }
  188. }
  189. return $cates;
  190. }
  191. public static function formatCate($mall_id, $store_id, $cate_name, $parent_id = 0)
  192. {
  193. return [
  194. 'mall_id' => $mall_id,
  195. 'store_id' => $store_id,
  196. 'parent_id' => $parent_id,
  197. 'name' => $cate_name,
  198. 'pic' => '',
  199. 'big_pic' => '',
  200. 'advert_pic' => '',
  201. 'advert_url' => '',
  202. 'advert_open_type' => '',
  203. 'advert_params' => '',
  204. 'is_show' => 1,
  205. ];
  206. }
  207. // 检测和添加分类
  208. public static function checkAndAddCate($mall_id, $store_id, $cate_name, $parent_id = 0)
  209. {
  210. $temp = StoreGoodsCate::findOne(['mall_id' => $mall_id, 'name' => $cate_name, 'store_id' => $store_id]);
  211. if (!$temp) {
  212. $add_cate = self::formatCate($mall_id, $store_id, $cate_name, $parent_id);
  213. $res = StoreGoodsCate::setData($add_cate);
  214. if ($res === false) throw new \Exception(StoreGoodsCate::getStaticError());
  215. return $res->id;
  216. }
  217. return $temp->id;
  218. }
  219. // 更新商品
  220. public static function saveGoods($params)
  221. {
  222. try {
  223. $goods_id = $params['goods_id'];
  224. $goods = \common\models\goods\Goods::findOne(['id' => $goods_id]);
  225. if ($goods) {
  226. $mall_id = $goods->mall_id;
  227. self::checkWuzhouChain($mall_id);
  228. // 获取所有门店的这个商品
  229. $store_goods_list = StoreGoods::find()->where(['mall_id' => $mall_id, 'mall_goods_id' => $goods->id, 'status' => StatusEnum::ENABLED, 'supplier_type' => StoreEnum::SELF_MALL_WUZHOU])->asArray()->all();
  230. if ($store_goods_list) {
  231. foreach ($store_goods_list as $store_goods) {
  232. $store_id = $store_goods['store_id'];
  233. $cats = self::getCate($mall_id, $goods_id, $store_goods['store_id']);
  234. try {
  235. $store_goods = StoreGoods::findOne(['mall_id' => $mall_id, 'store_id' => $store_id, 'mall_goods_id' => $goods_id, 'status' => StatusEnum::ENABLED, 'supplier_type' => StoreEnum::SELF_MALL_WUZHOU]);
  236. $base_params = [
  237. 'mall_id' => $mall_id,
  238. 'store_id' => $store_id,
  239. 'supplier_id' => $store_id,
  240. 'supplier_type' => StoreEnum::SELF_MALL_WUZHOU,
  241. 'cats' => $cats,
  242. 'mall_goods_id' => $goods_id,
  243. 'id' => $store_goods['id'] ?? 0,
  244. 'coupon_selection' => [],
  245. 'check_status' => StatusEnum::ENABLED
  246. ];
  247. $mall_goods = $goods['attributes'];
  248. $base_params['extra'] = !empty($goods->extra) ? ArrayHelper::toArray($goods->extra) : [];
  249. if (isset($base_params['extra']['goods_id'])) unset($base_params['extra']['goods_id']);
  250. if (empty($mall_goods['services'])) {
  251. $mall_goods['services'] = [];
  252. } else {
  253. $mall_goods['services'] = explode(',', $mall_goods['services']);
  254. }
  255. if (empty($mall_goods['labels'])) {
  256. $mall_goods['labels'] = [];
  257. } else {
  258. $mall_goods['labels'] = explode(',', $mall_goods['labels']);
  259. }
  260. if (empty($mall_goods['freight_type'])) {
  261. $mall_goods['freight_type'] = [];
  262. } else {
  263. $mall_goods['freight_type'] = explode(',', $mall_goods['freight_type']);
  264. }
  265. !empty($mall_goods['attr_groups']) && $mall_goods['attr_groups'] = json_decode($mall_goods['attr_groups'], true);
  266. !empty($mall_goods['bannar_pic']) && $mall_goods['bannar_pic'] = json_decode($mall_goods['bannar_pic'], true);
  267. !empty($mall_goods['area_limit']) && $mall_goods['area_limit'] = json_decode($mall_goods['area_limit'], true);
  268. // 预约商品
  269. if ($mall_goods['goods_type'] == GoodsTypeEnum::GoodsTypeReserved) {
  270. $reserve = ArrayHelper::toArray($goods->reserve);
  271. unset($reserve['id'], $reserve['goods_id']);
  272. $skus = GoodsReserveSku::lists([
  273. 'where' => [['goods_id' => $goods['id']]],
  274. 'with' => ['times' => function ($query) {
  275. $query->with(['timeSpec']);
  276. }]
  277. ]);
  278. foreach ($skus as &$sku) {
  279. unset($sku['id'], $sku['goods_id']);
  280. foreach ($sku['times'] as &$time) {
  281. unset($time['id'], $time['reserve_sku_id']);
  282. if (!empty($time['timeSpec'])) {
  283. foreach ($time['timeSpec'] as &$time_spec) {
  284. unset($time_spec['id'], $time_spec['reserve_time_id'], $time_spec['reserve_sku_id']);
  285. }
  286. $time['time_spec'] = $time['timeSpec'];
  287. unset($time_spec, $time['timeSpec']);
  288. }
  289. }
  290. unset($time);
  291. }
  292. unset($sku);
  293. $reserve['skus'] = $skus;
  294. $mall_goods['reserve'] = $reserve;
  295. } else {
  296. if ($mall_goods['is_attr'] == 1) {
  297. $temp_attrs = ArrayHelper::toArray($goods->attr);
  298. $attr_groups = $mall_goods['attr_groups'];
  299. $attr = [];
  300. foreach ($temp_attrs as $val) {
  301. $val['mall_attr_id'] = $val['id'];
  302. unset($val['id']);
  303. unset($val['goods_id']);
  304. $sku_group_name = explode(',', $val['name']);
  305. $attr_list = [];
  306. foreach ($sku_group_name as $name) {
  307. $name_arr = explode(':', $name);
  308. foreach ($attr_groups as $group) {
  309. if ($group['attr_group_name'] == $name_arr[0]) {
  310. foreach ($group['attr_list'] as $v) {
  311. if ($v['attr_name'] == $name_arr[1]) {
  312. $attr_list[] = [
  313. 'attr_id' => $v['attr_id'],
  314. 'attr_name' => $v['attr_name'],
  315. 'pic_url' => '',
  316. 'attr_group_id' => $group['attr_group_id'],
  317. 'attr_group_name' => $group['attr_group_name'],
  318. ];
  319. break;
  320. }
  321. }
  322. break;
  323. }
  324. }
  325. }
  326. $val['attr_list'] = $attr_list;
  327. $attr[] = $val;
  328. }
  329. $base_params['attr'] = $attr;
  330. }
  331. }
  332. unset($mall_goods['id']);
  333. $res = StoreGoods::setData(array_merge($mall_goods, $base_params));
  334. if ($res === false) throw new \Exception(StoreGoods::getStaticError());
  335. } catch (\Exception $e) {
  336. \Yii::error(self::class . '->' . __FUNCTION__ . '//errMsg2:' . $e->getMessage() . '//params:' . json_encode(array_merge($mall_goods, $base_params)));
  337. }
  338. }
  339. }
  340. }
  341. } catch (\Exception $e) {
  342. \Yii::error(self::class . '->' . __FUNCTION__ . '//errMsg1:' . $e->getMessage());
  343. return false;
  344. }
  345. return true;
  346. }
  347. public static function checkWuzhouChain($mall_id)
  348. {
  349. if (!MallAddons::isInstall($mall_id, AddonsEnum::ADDONS_NAME_WUZHOU_CHAIN)) {
  350. throw new \Exception('请先安装五洲供应链插件');
  351. }
  352. $serv = new SettingService();
  353. $data = $serv->getSetting($mall_id);
  354. if (!$data || empty($data['is_enable'])) {
  355. throw new \Exception('请先在五洲供应链插件中开启供应链功能');
  356. }
  357. }
  358. // 删除商品
  359. public static function deleteGoods($goods_id, $mall_id)
  360. {
  361. try {
  362. if (empty($goods_id) || empty($mall_id)) return false;
  363. self::checkWuzhouChain($mall_id);
  364. $storage = WuzhouChainStorage::findOne(['store_goods_id' => $goods_id, 'mall_id' => $mall_id, 'status' => StatusEnum::ENABLED]);
  365. if ($storage) {
  366. $storage->status = StatusEnum::DELETE;
  367. if ($storage->save() === false) {
  368. throw new \Exception($storage->getError());
  369. }
  370. }
  371. } catch (\Exception $e) {
  372. return false;
  373. }
  374. }
  375. }