Cart.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2016~2024 https://www.crmeb.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  8. // +----------------------------------------------------------------------
  9. // | Author: CRMEB Team <admin@crmeb.com>
  10. // +----------------------------------------------------------------------
  11. namespace app\controller\merchant\store\behalfcustomerorder;
  12. use think\App;
  13. use crmeb\basic\BaseController;
  14. use app\validate\merchant\CartValidate;
  15. use app\common\repositories\user\UserRepository;
  16. use app\common\repositories\store\product\ProductRepository;
  17. use app\common\repositories\store\order\StoreCartRepository;
  18. use app\common\repositories\store\product\ProductAttrValueRepository;
  19. class Cart extends BaseController
  20. {
  21. protected $validate;
  22. protected $repository;
  23. protected $userRepository;
  24. public function __construct(App $app, CartValidate $validate, StoreCartRepository $repository, UserRepository $userRepository)
  25. {
  26. parent::__construct($app);
  27. $this->validate = $validate;
  28. $this->repository = $repository;
  29. $this->userRepository = $userRepository;
  30. }
  31. public function __destruct()
  32. {
  33. unset($this->validate);
  34. unset($this->repository);
  35. unset($this->userRepository);
  36. }
  37. public function getValidate()
  38. {
  39. return $this->validate;
  40. }
  41. public function getRepository()
  42. {
  43. return $this->repository;
  44. }
  45. public function getUserRepository()
  46. {
  47. return $this->userRepository;
  48. }
  49. /**
  50. * 购物车列表
  51. *
  52. * @return void
  53. */
  54. public function list()
  55. {
  56. $params = $this->request->params(['uid', 'tourist_unique_key']);
  57. $validate = $this->getValidate();
  58. if (!$validate->listCheck($params)) {
  59. return app('json')->fail($validate->getError());
  60. }
  61. // 如果存在uid则获取用户信息。如果不存在,则不检测用户信息,视为游客
  62. $user = null;
  63. if (!empty($params['uid'])) {
  64. $user = $this->getUserRepository()->userInfo($params['uid']);
  65. if (!$user) {
  66. return app('json')->fail('用户不存在');
  67. }
  68. }
  69. $repository = $this->getRepository();
  70. $merId = $this->request->merId();
  71. $cartIds = $repository->getCartIds($params['uid'], $merId, $params['tourist_unique_key']);
  72. // 获取购物车列表
  73. $data = $repository->getMerchantList($user, $merId, $cartIds);
  74. return app('json')->success($data);
  75. }
  76. /**
  77. * 购物车创建
  78. *
  79. * @return void
  80. */
  81. public function create()
  82. {
  83. $params = $this->request->params(['uid', 'cart_num', 'product_id', 'product_attr_unique', 'tourist_unique_key']);
  84. $validate = $this->getValidate();
  85. if (!$validate->createCheck($params)) {
  86. return app('json')->fail($validate->getError());
  87. }
  88. // 如果存在uid则获取用户信息。如果不存在,则不检测用户信息,视为游客
  89. $user = null;
  90. if (!empty($params['uid'])) {
  91. $user = $this->getUserRepository()->userInfo($params['uid']);
  92. if (!$user) {
  93. return app('json')->fail('用户不存在');
  94. }
  95. }
  96. $params['is_new'] = 0;
  97. // 触发购物车添加前的事件,允许其他功能插件在此事件中进行干预
  98. event('user.cart.before', compact('user', 'params'));
  99. $repository = $this->getRepository();
  100. // 检测商品是否存在。如果购物车中已存在该商品,则更新数量;否则添加到购物车。
  101. $check = app()->make(ProductRepository::class)->merchantCartCheck($params, $user, $params['tourist_unique_key']);
  102. if ($cart = $check['cart']) {
  103. $cart_id = $cart['cart_id'];
  104. $cart_num = ['cart_num' => ($cart['cart_num'] + $params['cart_num'])];
  105. $storeCart = $repository->update($cart_id, $cart_num);
  106. } else {
  107. $params['mer_id'] = $this->request->merId();
  108. $cart = $storeCart = $repository->create($params);
  109. }
  110. // 触发购物车处理后的事件
  111. event('user.cart', compact('user', 'storeCart'));
  112. $result['cart_id'] = (int)$cart['cart_id'];
  113. return app('json')->success('添加成功', $result);
  114. }
  115. /**
  116. * 购物车修改
  117. *
  118. * @return void
  119. */
  120. public function change($id)
  121. {
  122. if (!$id) {
  123. return app('json')->fail('参数错误');
  124. }
  125. $params = $this->request->params(['uid', 'cart_num', 'product_attr_unique']);
  126. $validate = $this->getValidate();
  127. if (!$validate->changeCheck($params)) {
  128. return app('json')->fail($validate->getError());
  129. }
  130. $cart = $this->repository->getOne($id, $params['uid']);
  131. if (!$cart) {
  132. return app('json')->fail('购物车信息不存在');
  133. }
  134. $params['cart_num'] = $params['cart_num'] ?? $cart['cart_num'];
  135. $params['product_attr_unique'] = !empty($params['product_attr_unique']) ? $params['product_attr_unique'] : $cart['product_attr_unique'];
  136. // 如果商品有单次购买限制,检查此次购买数量是否超过限制
  137. if ($cart->product->once_count) {
  138. if (!app()->make(ProductRepository::class)->isOverLimit($cart, $params)) {
  139. return app('json')->fail('单次购买限制 ' . $cart->product->once_count . ' 件');
  140. }
  141. }
  142. // 根据唯一属性ID检查SKU是否存在,如果不存在,则返回错误信息
  143. if (!$res = app()->make(ProductAttrValueRepository::class)->getOptionByUnique($params['product_attr_unique'], $cart['product_id'])) {
  144. return app('json')->fail('SKU不存在');
  145. }
  146. // 检查库存是否足够,如果不足,则返回错误信息
  147. if ($res['stock'] < $params['cart_num']) {
  148. return app('json')->fail('库存不足');
  149. }
  150. // 检测购物车是否存在和该商品相同sku的购物车记录,如果有则合并加数量,并删除多余的
  151. if(!empty($params['product_attr_unique'])){
  152. $isExist = $this->repository->getCartByProductSku($params['product_attr_unique'], $params['uid'], $cart['tourist_unique_key'], $id);
  153. if($isExist){
  154. $params['cart_num'] = bcadd($cart['cart_num'], $isExist['cart_num']);
  155. $this->repository->delete($isExist['cart_id']);
  156. }
  157. }
  158. $this->repository->update($id, $params);
  159. return app('json')->success('修改成功');
  160. }
  161. /**
  162. * 购物车数量
  163. *
  164. * @return void
  165. */
  166. public function count()
  167. {
  168. $params = $this->request->params(['uid', 'tourist_unique_key']);
  169. $validate = $this->getValidate();
  170. if (!$validate->listCheck($params)) {
  171. return app('json')->fail($validate->getError());
  172. }
  173. $repository = $this->getRepository();
  174. $merId = $this->request->merId();
  175. $cartIds = $repository->getCartIds($params['uid'], $merId, $params['tourist_unique_key']);
  176. $data = $repository->getMerchantCartCount($params['uid'], $cartIds);
  177. return app('json')->success($data);
  178. }
  179. /**
  180. * 购物车删除
  181. *
  182. * @return void
  183. */
  184. public function delete($id)
  185. {
  186. if (!$id) {
  187. return app('json')->fail('参数错误');
  188. }
  189. $repository = $this->getRepository();
  190. $cart = $repository->get($id);
  191. if (!$cart) {
  192. return app('json')->fail('购物车信息不存在');
  193. }
  194. $repository->delete($id);
  195. return app('json')->success('删除成功');
  196. }
  197. /**
  198. * 购物车清空
  199. *
  200. * @return void
  201. */
  202. public function clear()
  203. {
  204. $params = $this->request->params(['uid', 'tourist_unique_key']);
  205. $validate = $this->getValidate();
  206. if (!$validate->listCheck($params)) {
  207. return app('json')->fail($validate->getError());
  208. }
  209. $repository = $this->getRepository();
  210. $merId = $this->request->merId();
  211. $cartIds = $repository->getCartIds($params['uid'], $merId, $params['tourist_unique_key']);
  212. // 批量删除指定的购物车项
  213. $repository->batchDelete($cartIds, $params['uid']);
  214. return app('json')->success('清空成功');
  215. }
  216. /**
  217. * 单个购物车更新价格
  218. *
  219. * @return void
  220. */
  221. public function updatePrice($id)
  222. {
  223. if (!$id) {
  224. return app('json')->fail('参数错误');
  225. }
  226. // 获取参数
  227. $params = $this->request->params(['old_price', 'type', 'reduce_price', 'discount_rate', 'new_price']);
  228. $validate = $this->getValidate();
  229. if (!$validate->updatePriceCheck($params)) {
  230. return app('json')->fail($validate->getError());
  231. }
  232. // 获取购物车信息
  233. $repository = $this->getRepository();
  234. $cart = $repository->get($id);
  235. if (!$cart) {
  236. return app('json')->fail('购物车信息不存在');
  237. }
  238. // 更新价格
  239. $res = $repository->updatePrice($id, $params);
  240. if (!$res) {
  241. return app('json')->fail('修改失败');
  242. }
  243. return app('json')->success('修改成功');
  244. }
  245. /**
  246. * 批量更新购物车价格
  247. *
  248. * @return void
  249. */
  250. public function batchUpdatePrice()
  251. {
  252. $params = $this->request->params(['cart_ids', 'uid', 'old_pay_price', 'change_fee_type', 'reduce_price', 'discount_rate', 'new_pay_price']);
  253. $validate = $this->getValidate();
  254. if (!$validate->batchUpdatePriceCheck($params)) {
  255. return app('json')->fail($validate->getError());
  256. }
  257. $params['merId'] = $this->request->merId();
  258. $repository = $this->getRepository();
  259. $res = $repository->batchUpdatePrice($params);
  260. if (!$res) {
  261. return app('json')->fail('更新失败');
  262. }
  263. return app('json')->success('更新成功');
  264. }
  265. }