GoodsService.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501
  1. <?php
  2. namespace addons\ReservationService\common\services;
  3. use addons\ReservationService\common\enums\ReservationServiceEnum;
  4. use addons\ReservationService\common\models\ReservationServiceGoods;
  5. use addons\ReservationService\common\models\ReservationServiceStoreGoods;
  6. use addons\ReservationService\common\models\ReservationServiceUser;
  7. use addons\Store\common\models\StoreGoods;
  8. use addons\Store\common\models\StoreGoodsCate;
  9. use addons\Store\common\models\StoreGoodsCateRelate;
  10. use common\enums\GoodsTypeEnum;
  11. use common\enums\StatusEnum;
  12. use common\models\goods\Goods;
  13. use common\models\goods\GoodsCate;
  14. use common\models\goods\GoodsCateRelate;
  15. use common\models\goods\GoodsReserve;
  16. use Yii;
  17. class GoodsService
  18. {
  19. /**
  20. * 获取所有类目
  21. * @param int $mall_id
  22. * @param int $user_id
  23. * @param int $parent_id
  24. * @return array|false|mixed
  25. */
  26. public function cate(int $mall_id, int $user_id, int $parent_id = 0)
  27. {
  28. // 取出类目
  29. $cats = GoodsCate::lists([
  30. 'where' => [
  31. // ['id' => $cat_ids],
  32. ['mall_id' => $mall_id],
  33. ['status' => StatusEnum::ENABLED],
  34. ['parent_id' => $parent_id]
  35. ],
  36. 'select'=> 'id, name, pic'
  37. ]);
  38. if (!empty($cats)) {
  39. $b_goods_ids = $this->getUserBindGoodsIds($mall_id, $user_id);
  40. foreach ($cats as $key => &$cat) {
  41. $ggids = array_unique(GoodsCateRelate::find()
  42. ->where(['cate_id' => GoodsCate::getAllCate($mall_id, [$cat['id']])])
  43. ->select('goods_id')->column());
  44. $ggids = Goods::find()->where(['id' => $ggids])
  45. ->andWhere(['status' => StatusEnum::ENABLED])
  46. ->andWhere(['goods_type' => 3])
  47. ->andWhere(['is_on_sale' => StatusEnum::ENABLED])
  48. ->select('id')->column();
  49. $ggids = GoodsReserve::find()->where(['goods_id' => $ggids])
  50. ->andWhere(['reserve_type' => StatusEnum::ENABLED])->select('goods_id')->column();
  51. if (empty($ggids)) unset($cats[$key]);
  52. $cat['total_project'] = count($ggids);
  53. $cat['total_add'] = count(array_intersect($ggids, $b_goods_ids));
  54. }
  55. }
  56. return $cats;
  57. // 取出商品
  58. // 通过商品ID取出类目
  59. $gids = $this->getReserveGoodsIds($mall_id);
  60. $cats = [];
  61. if (empty($parent_id)) {
  62. if (!empty($gids)) {
  63. // 取出类目ID
  64. $g_m_c = GoodsCateRelate::lists([
  65. 'where' => [
  66. ['goods_id' => $gids]
  67. ],
  68. 'select'=> 'goods_id, cate_id',
  69. 'index' => 'goods_id'
  70. ]);
  71. if (!empty($g_m_c)) {
  72. $b_goods_ids = $this->getUserBindGoodsIds($mall_id, $user_id);
  73. $cat_ids = array_unique(array_column($g_m_c, 'cate_id'));
  74. // 如果上级ID为0那么
  75. $cats = GoodsCate::lists([
  76. 'where' => [
  77. ['id' => $cat_ids],
  78. ['status' => StatusEnum::ENABLED],
  79. ['parent_id' => $parent_id]
  80. ],
  81. 'select'=> 'id, name, pic'
  82. ]);
  83. foreach ($cats as &$cat) {
  84. $ggids = array_unique(GoodsCateRelate::find()
  85. ->where(['cate_id' => GoodsCate::getAllCate($mall_id, [$cat['id']])])
  86. ->select('goods_id')->column());
  87. $ggids = Goods::find()->where(['id' => $ggids])
  88. ->andWhere(['status' => StatusEnum::ENABLED])
  89. ->andWhere(['goods_type' => 3])
  90. ->andWhere(['is_on_sale' => StatusEnum::ENABLED])
  91. ->select('id')->column();
  92. $ggids = GoodsReserve::find()->where(['goods_id' => $ggids])
  93. ->andWhere(['reserve_type' => StatusEnum::ENABLED])->select('goods_id')->column();
  94. $cat['total_project'] = count($ggids);
  95. $cat['total_add'] = count(array_intersect($ggids, $b_goods_ids));
  96. }
  97. }
  98. }
  99. } else {
  100. $cats = GoodsCate::lists([
  101. 'where' => [
  102. ['status' => StatusEnum::ENABLED],
  103. ['parent_id' => $parent_id]
  104. ],
  105. 'select'=> 'id, name, pic'
  106. ]);
  107. }
  108. return $cats;
  109. }
  110. /**
  111. * 获取商品
  112. * @param int $mall_id
  113. * @param int $user_id
  114. * @param int $cate_id
  115. * @return array|false|mixed
  116. */
  117. public function goods(int $mall_id, int $user_id, int $cate_id = 0)
  118. {
  119. $ids = $this->getUserBindGoodsIds($mall_id, $user_id);
  120. if (empty($cate_id)) {
  121. $goods_ids = $this->getReserveGoodsIds($mall_id);
  122. } else {
  123. // 类目下面的所有商品ID
  124. $goods_ids = GoodsCateRelate::find()->where(['cate_id' => GoodsCate::getAllCate($mall_id, [$cate_id])])->select('goods_id')->column();
  125. // 过滤掉非预约项目的商品
  126. if (!empty($goods_ids)) {
  127. $goods_ids = GoodsReserve::find()->where(['goods_id' => $goods_ids])
  128. ->andWhere(['reserve_type' => StatusEnum::ENABLED])->select('goods_id')->column();
  129. }
  130. }
  131. if (empty($goods_ids)) return [];
  132. $where = [
  133. ['mall_id' => $mall_id],
  134. ['status' => StatusEnum::ENABLED],
  135. ['is_on_sale' => StatusEnum::ENABLED],
  136. ['id' => $goods_ids],
  137. ];
  138. if (!empty($ids)) {
  139. // $where[] = ['not in', 'id', $ids];
  140. }
  141. // 取出商品数据
  142. $goods = Goods::lists([
  143. 'where' => $where,
  144. 'select' => 'id, goods_name, price, original_price, unit, cover_pic',
  145. ]);
  146. if (!empty($goods)) {
  147. foreach ($goods as &$item) {
  148. $item['is_selected'] = in_array($item['id'], $ids) ? StatusEnum::ENABLED : StatusEnum::DISABLED;
  149. }
  150. }
  151. return $goods;
  152. }
  153. /**
  154. * @param int $mall_id
  155. * @param int $user_id
  156. * @return array
  157. */
  158. public function getUserBindGoodsIds(int $mall_id, int $user_id)
  159. {
  160. return ReservationServiceGoods::find()->where(['mall_id' => $mall_id])
  161. ->andWhere(['user_id' => $user_id])
  162. ->andWhere(['status' => StatusEnum::ENABLED])
  163. ->select('goods_id')->column();
  164. }
  165. /**
  166. * 移除已经绑定的商品
  167. * @param int $mall_id
  168. * @param int $user_id
  169. * @param array $goods_ids
  170. * @return int
  171. */
  172. public function remove(int $mall_id, int $user_id, array $goods_ids)
  173. {
  174. return ReservationServiceGoods::updateAll(['status' => StatusEnum::DELETE],
  175. ['and', ['mall_id' => $mall_id], ['user_id' => $user_id], ['goods_id' => $goods_ids]]);
  176. }
  177. /**
  178. * 绑定项目
  179. * @param int $mall_id
  180. * @param int $user_id
  181. * @param array $goods_ids
  182. * @param array $remove_goods_ids
  183. * @return string|bool
  184. */
  185. public function create(int $mall_id, int $user_id, array $goods_ids, array $remove_goods_ids = [])
  186. {
  187. if (!empty($goods_ids)) {
  188. // 判断是否为预约项目
  189. $t_goods_ids = GoodsReserve::find()->where(['mall_id' => $mall_id])
  190. ->andWhere(['reserve_type' => StatusEnum::ENABLED])
  191. ->andWhere(['goods_id' => $goods_ids])
  192. ->andWhere(['mch_id' => 0])->select('goods_id')->column();
  193. if (count($t_goods_ids) != count($goods_ids)) return '非法操作';
  194. /**
  195. * @var $data ReservationServiceGoods[]
  196. */
  197. $data = ReservationServiceGoods::lists([
  198. 'where' => [
  199. ['mall_id' => $mall_id],
  200. ['goods_id' => $goods_ids],
  201. ['user_id' => $user_id]
  202. ],
  203. 'index' => 'goods_id',
  204. 'select'=> 'id, user_id, goods_id, status, mall_id'
  205. ], false);
  206. }
  207. $t = \Yii::$app->db->beginTransaction();
  208. try {
  209. // 有需要删除的那么直接删除
  210. if (!empty($remove_goods_ids)) {
  211. ReservationServiceGoods::updateAll(['status' => StatusEnum::DELETE],
  212. ['and', ['mall_id' => $mall_id], ['user_id' => $user_id], ['goods_id' => $remove_goods_ids]]);
  213. }
  214. $insert_arr = [];
  215. foreach ($goods_ids as $goods_id) {
  216. if (!empty($data[$goods_id])) {
  217. $data[$goods_id]->status = StatusEnum::ENABLED;
  218. if (!$data[$goods_id]->save()) throw new \Exception($data[$goods_id]->getErrorMessage());
  219. } else {
  220. $insert_arr[] = [
  221. 'created_at' => time(),
  222. 'updated_at' => time(),
  223. 'user_id' => $user_id,
  224. 'goods_id' => $goods_id,
  225. 'mall_id' => $mall_id
  226. ];
  227. }
  228. }
  229. if (!empty($insert_arr)) {
  230. ReservationServiceGoods::find()->createCommand()
  231. ->batchInsert(ReservationServiceGoods::tableName(), array_keys($insert_arr[0]), $insert_arr)->execute();
  232. }
  233. $t->commit();
  234. } catch (\Exception $e) {
  235. $t->rollBack();
  236. return $e->getMessage();
  237. }
  238. return true;
  239. }
  240. /**
  241. * 获取预约项目的商品ID
  242. * @param int $mall_id
  243. * @return array
  244. */
  245. public function getReserveGoodsIds(int $mall_id)
  246. {
  247. $gids = GoodsReserve::find()->where(['mall_id' => $mall_id])
  248. ->andWhere(['reserve_type' => StatusEnum::ENABLED])->andWhere(['mch_id' => 0])->select('goods_id')->column();
  249. if (!empty($gids)) {
  250. $gids = Goods::find()->where(['id' => $gids])->andWhere(['status' => StatusEnum::ENABLED])
  251. ->andWhere(['is_on_sale' => StatusEnum::ENABLED])->select('id')->column();
  252. }
  253. return $gids;
  254. }
  255. /**
  256. * 获取技师绑定的商品
  257. * @param int $mall_id
  258. * @param int $id
  259. * @return array|false|mixed
  260. */
  261. public function getStaffBinGoods(int $mall_id, int $id)
  262. {
  263. // 获取用户ID
  264. /**
  265. * @var $user ReservationServiceUser
  266. */
  267. $user = ReservationServiceUser::getOne([
  268. ['mall_id' => $mall_id],
  269. ['id' => $id],
  270. ['status' => StatusEnum::ENABLED],
  271. ['check_status' => StatusEnum::ENABLED]
  272. ], false, [], 'id asc', 'user_id');
  273. if (empty($user)) return '技师不存在';
  274. $goods_ids = $this->getUserBindGoodsIds($mall_id, $user->user_id);
  275. if (empty($goods_ids)) return [];
  276. $where = [
  277. ['mall_id' => $mall_id],
  278. ['status' => StatusEnum::ENABLED],
  279. ['is_on_sale' => StatusEnum::ENABLED],
  280. ['id' => $goods_ids],
  281. ];
  282. if (!empty($ids)) {
  283. $where[] = ['not in', 'id', $ids];
  284. }
  285. // 取出商品数据
  286. $list = Goods::lists([
  287. 'where' => $where,
  288. 'select' => 'id, goods_name, price, original_price, unit, cover_pic, virtual_sales, sales_num',
  289. 'with' => ['reserve' => function ($query) {
  290. $query->select('goods_id, service_type');
  291. }]
  292. ]);
  293. if (!empty(Goods::getStaticError())) return Goods::getStaticError();
  294. if (!empty($list)) {
  295. foreach ($list as &$item) {
  296. $item['sales_num'] += $item['virtual_sales'];
  297. $item['service_type'] = [];
  298. switch ($item['reserve']['service_type']) {
  299. case 1:
  300. $item['service_type'][] = '上门服务';
  301. break;
  302. case 2:
  303. $item['service_type'][] = '到店服务';
  304. break;
  305. case 3:
  306. $item['service_type'][] = '上门服务';
  307. $item['service_type'][] = '到店服务';
  308. break;
  309. }
  310. unset($item['virtual_sales'], $item['reserve']);
  311. }
  312. }
  313. return $list;
  314. }
  315. public function globalSave(array $params)
  316. {
  317. // 后台页面组件展示
  318. if ($params['type'] == 'show_component') {
  319. return [
  320. 'component' => 'com-reservation-service-goods',
  321. 'path' => Yii::$app->basePath . '/../addons/ReservationService/backend/views/components',
  322. ];
  323. } else {
  324. if (empty($params['setting'][ReservationServiceEnum::ADDONS_NAME])) return true;
  325. $post = $params['setting'][ReservationServiceEnum::ADDONS_NAME];
  326. $post['mall_id'] = $params['mall_id'];
  327. $mall_id = $params['mall_id'];
  328. $goods_id = $params['goods_id'];
  329. $status = $post['status'];
  330. $model = ValetOrderGoods::getOne([
  331. ['mall_id' => $mall_id],
  332. ['goods_id' => $goods_id]
  333. ]);
  334. if (empty($model)) {
  335. $model = new ValetOrderGoods();
  336. $model->mall_id = $mall_id;
  337. $model->goods_id = $goods_id;
  338. }
  339. $model->status = $status;
  340. if (!$model->save()) return $model->getErrorMessage();
  341. return true;
  342. }
  343. }
  344. public function cateStore(int $mall_id, int $user_id, int $parent_id = 0)
  345. {
  346. // 取出类目
  347. $staff_user = ReservationServiceUser::getOne([
  348. ['user_id'=>$user_id],
  349. ['mall_id'=>$mall_id],
  350. ['status'=>StatusEnum::ENABLED]
  351. ]);
  352. if(empty($staff_user['store_id'])){
  353. return [];
  354. }
  355. $user_goods_ids = ReservationServiceStoreGoods::find()->where(['user_id'=>$user_id, 'status'=>1])
  356. ->select('goods_id')->column();
  357. $user_goods_list = ReservationServiceStoreGoods::find()->where(['rssg.user_id'=>$user_id, 'rssg.status'=>1])
  358. ->alias('rssg')
  359. ->leftJoin(StoreGoodsCateRelate::tableName().' as sgcr','sgcr.goods_id=rssg.goods_id')
  360. ->groupBy('sgcr.cate_id')
  361. ->select('count(sgcr.goods_id) as counts,sgcr.cate_id')
  362. ->asArray()
  363. ->all();
  364. if(!empty($user_goods_list)){
  365. $user_goods_list = array_column($user_goods_list,null,'cate_id');
  366. }
  367. $where = [
  368. ['goods_id' => $user_goods_ids]
  369. ];
  370. if ($parent_id > 0) {
  371. $where[] = ['cate_id' => $parent_id];
  372. }
  373. $list = StoreGoodsCateRelate::lists([
  374. 'where' => $where,
  375. 'select'=>'cate_id',
  376. 'group'=>'cate_id'
  377. ]);
  378. $store_goods_cate_list = StoreGoodsCate::lists([
  379. 'where'=>[
  380. ['id'=>array_column($list,'cate_id')]
  381. ],
  382. 'select'=>'id,name',
  383. 'index'=>'id'
  384. ]);
  385. $goods_ids = StoreGoods::find()->where(['store_id'=>$staff_user['store_id'],
  386. 'goods_type'=>GoodsTypeEnum::GoodsTypeReserved,'status'=>StatusEnum::ENABLED])
  387. ->select('id')->column();
  388. $goods_list = StoreGoods::find()->where(['sg.id'=>$goods_ids])
  389. ->alias('sg')
  390. ->leftJoin(StoreGoodsCateRelate::tableName().' as sgcr','sgcr.goods_id=sg.id')
  391. ->groupBy('sgcr.cate_id')
  392. ->select('count(sgcr.goods_id) as counts,sgcr.cate_id')
  393. ->asArray()
  394. ->all();
  395. if(!empty($goods_list)){
  396. $goods_list = array_column($goods_list,null,'cate_id');
  397. }
  398. foreach ($list as &$item){
  399. $item['add_count'] = $user_goods_list[$item['cate_id']]['counts']??0;
  400. $item['total_count'] = $goods_list[$item['cate_id']]['counts']??0;
  401. $item['name'] = $store_goods_cate_list[$item['cate_id']]['name']??'';
  402. }
  403. return $list;
  404. }
  405. public function goodsStore(int $mall_id, int $user_id, int $cate_id = 0)
  406. {
  407. // 取出类目
  408. $staff_user = ReservationServiceUser::getOne([
  409. ['user_id'=>$user_id],
  410. ['mall_id'=>$mall_id],
  411. ['status'=>StatusEnum::ENABLED]
  412. ]);
  413. if(empty($staff_user['store_id'])){
  414. return [];
  415. }
  416. $user_goods_ids = ReservationServiceStoreGoods::find()->where(['rssg.user_id'=>$user_id,'rssg.status'=>1,'sgcr.cate_id'=>$cate_id])
  417. ->alias('rssg')
  418. ->leftJoin(StoreGoodsCateRelate::tableName().' as sgcr','sgcr.goods_id=rssg.goods_id')
  419. ->select('sgcr.goods_id')->column();
  420. $where = [
  421. ['store_id'=>$staff_user['store_id']],
  422. ['id'=>$user_goods_ids]
  423. ];
  424. // 取出商品数据
  425. $goods = StoreGoods::lists([
  426. 'where' => $where,
  427. 'select' => 'id, goods_name, cover_pic',
  428. 'order'=>'created_at desc'
  429. ]);
  430. return $goods;
  431. }
  432. }