Cart.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2017~2021 https://www.yiovo.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
  8. // +----------------------------------------------------------------------
  9. // | Author: 萤火科技 <admin@yiovo.com>
  10. // +----------------------------------------------------------------------
  11. declare (strict_types = 1);
  12. namespace app\api\model;
  13. use app\api\model\Goods as GoodsModel;
  14. use app\api\model\GoodsSku as GoodsSkuModel;
  15. use app\api\model\shop\Shops;
  16. use app\api\model\User as UserModel;
  17. use app\api\service\User as UserService;
  18. use app\common\model\Cart as CartModel;
  19. use app\common\enum\goods\Status as GoodsStatusEnum;
  20. use app\common\enum\goods\GoodsType as GoodsTypeEnum;
  21. use app\common\exception\BaseException;
  22. /**
  23. * 购物车管理
  24. * Class Cart
  25. * @package app\api\model
  26. */
  27. class Cart extends CartModel
  28. {
  29. /**
  30. * 加入购物车
  31. * @param int $goodsId 商品ID
  32. * @param string $goodsSkuId 商品sku唯一标识
  33. * @param int $goodsNum 商品数量
  34. * * @param int $staffUserId 链接分享者ID
  35. * @return bool
  36. * @throws BaseException
  37. * @throws \think\db\exception\DataNotFoundException
  38. * @throws \think\db\exception\DbException
  39. * @throws \think\db\exception\ModelNotFoundException
  40. */
  41. public function add(int $goodsId, string $goodsSkuId, int $goodsNum, int $staffUserId = 0)
  42. {
  43. // 判断是否已存在购物车记录
  44. $detail = $this->getInfo($goodsId, $goodsSkuId, false);
  45. // 如果已存在购物车记录, 则累计商品数量
  46. !empty($detail) && $goodsNum += $detail['goods_num'];
  47. // 验证商品的状态
  48. $this->checkGoodsStatus($goodsId, $goodsSkuId, $goodsNum);
  49. // 获取链接分享者的用户ID和店铺ID
  50. // 获取当前用户ID
  51. $user = UserService::getCurrentLoginUser(true);
  52. $userId = $user['user_id'];
  53. $data = $this->getStaffUserId($staffUserId);
  54. // 实例化模型
  55. $model = $detail ?: (new static);
  56. // 写入商品加购数
  57. Goods::setIncByField($goodsId, 'cart_num', 1);
  58. self::where(['user_id' => $userId])->update([//当前所有的加购的商品都
  59. 'staff_user_id' => $data['staffUserId'],
  60. 'shop_id' => $data['shopId'],
  61. 'is_staff' => $data['isStaff'],
  62. ]);
  63. return $model->save([
  64. 'goods_id' => $goodsId,
  65. 'goods_sku_id' => $goodsSkuId,
  66. 'goods_num' => $goodsNum,
  67. 'user_id' => $userId,
  68. 'store_id' => self::$storeId,
  69. 'staff_user_id' => $data['staffUserId'],
  70. 'shop_id' => $data['shopId'],
  71. 'is_staff' => $data['isStaff'],
  72. ]);
  73. }
  74. /**
  75. * 更新购物车记录
  76. * @param int $goodsId 商品ID
  77. * @param string $goodsSkuId 商品sku唯一标识
  78. * @param int $goodsNum 商品数量
  79. * @return bool
  80. * @throws BaseException
  81. * @throws \think\db\exception\DataNotFoundException
  82. * @throws \think\db\exception\DbException
  83. * @throws \think\db\exception\ModelNotFoundException
  84. */
  85. public function sUpdate(int $goodsId, string $goodsSkuId, int $goodsNum)
  86. {
  87. // 验证商品的状态
  88. $this->checkGoodsStatus($goodsId, $goodsSkuId, $goodsNum);
  89. // 获取购物车记录
  90. $model = $this->getInfo($goodsId, $goodsSkuId, true);
  91. // 更新记录
  92. return $model->save(['goods_num' => $goodsNum]);
  93. }
  94. /**
  95. * 验证商品的状态
  96. * @param int $goodsId 商品ID
  97. * @param string $goodsSkuId 商品sku唯一标识
  98. * @param int $goodsNum 商品数量
  99. * @return bool
  100. * @throws BaseException
  101. */
  102. private function checkGoodsStatus(int $goodsId, string $goodsSkuId, int &$goodsNum)
  103. {
  104. if ($goodsNum<=0) {
  105. throwError('很抱歉, 商品数量必须大于0');
  106. }
  107. // 获取商品详情
  108. $goods = GoodsModel::detail($goodsId);
  109. // 商品不存在
  110. if (empty($goods) || $goods['is_delete']) {
  111. throwError('很抱歉, 商品信息不存在');
  112. }
  113. // 商品已下架
  114. if ($goods['status'] == GoodsStatusEnum::OFF_SALE) {
  115. throwError('很抱歉, 该商品已经下架');
  116. }
  117. // 赠品不能添加
  118. if ($goods['goods_type'] == GoodsTypeEnum::GIFT) {
  119. throwError('很抱歉, 赠品不能添加购物车');
  120. }
  121. // 获取SKU信息
  122. $skuInfo = GoodsSkuModel::detail($goodsId, $goodsSkuId);
  123. if ($skuInfo['stock_num'] < $goodsNum) {
  124. $goodsNum = $skuInfo['stock_num'];
  125. // throwError('很抱歉, 该商品库存数量不足');
  126. }
  127. return true;
  128. }
  129. /**
  130. * 获取分享链接的用户ID
  131. * @param int $staffUserId
  132. * @return mixed
  133. * @author: zjwhust
  134. * @Time: 2021/9/30 13:32
  135. */
  136. private function getStaffUserId( int $staffUserId)
  137. {
  138. // 获取当前用户ID
  139. $user = UserService::getCurrentLoginUser(true);
  140. $data['isStaff'] = 1;
  141. if($staffUserId<=0 || $staffUserId==$user['user_id']){
  142. if(in_array($user['role'],[1,99])){//用户角色1:普通用户 99:分销员
  143. $staffUserId = $user['upper_user_id'];
  144. $data['isStaff'] = 0;
  145. }else{
  146. $staffUserId = 0;
  147. }
  148. }
  149. $data['staffUserId'] = $staffUserId;
  150. $data['shopId'] = 0;
  151. if ($staffUserId>0) {
  152. // 获取分享链接的用户信息
  153. $user = User::detail($staffUserId);
  154. if($user){
  155. $data['shopId'] = !in_array($user['role'],[1,99]) ? $user['shop_id'] : $user['bind_shop_id'];
  156. }
  157. }
  158. return $data;
  159. }
  160. /**
  161. * 获取购物车记录
  162. * @param int $goodsId 商品ID
  163. * @param string $goodsSkuId 商品sku唯一标识
  164. * @param bool $isForce
  165. * @return static|bool
  166. * @throws BaseException
  167. * @throws \think\db\exception\DataNotFoundException
  168. * @throws \think\db\exception\DbException
  169. * @throws \think\db\exception\ModelNotFoundException
  170. */
  171. private function getInfo(int $goodsId, string $goodsSkuId, bool $isForce = true)
  172. {
  173. // 获取当前用户ID
  174. $userId = UserService::getCurrentLoginUserId();
  175. // 获取购物车记录
  176. $model = static::detail($userId, $goodsId, $goodsSkuId);
  177. if (empty($model)) {
  178. $isForce && throwError('购物车中没有该记录');
  179. return false;
  180. }
  181. return $model;
  182. }
  183. /**
  184. * 删除购物车中指定记录
  185. * @param array $cartIds 购物车ID集, 如果为空删除所有
  186. * @return bool
  187. * @throws BaseException
  188. */
  189. public function clear(array $cartIds = [])
  190. {
  191. // 获取当前用户ID
  192. $userId = UserService::getCurrentLoginUserId();
  193. // 设置更新条件
  194. $where = [['user_id', '=', $userId]];
  195. // 购物车ID集
  196. !empty($cartIds) && $where[] = ['id', 'in', $cartIds];
  197. // 更新记录
  198. return $this->deleteAll($where);
  199. }
  200. /**
  201. * 获取当前用户购物车商品数量(以商品id为键 商品数量为值)
  202. * @return array
  203. */
  204. public function getCartGoodsIdNums()
  205. {
  206. if (!UserService::isLogin()) return [];
  207. $userId = UserService::getCurrentLoginUserId();
  208. return $this->where('user_id', '=', $userId)
  209. ->where('is_delete', '=', 0)
  210. ->column('goods_num','goods_id');
  211. }
  212. /**
  213. * 获取当前用户购物车商品总数量
  214. * @return float
  215. * @throws BaseException
  216. */
  217. public function getCartTotal()
  218. {
  219. if (!UserService::isLogin()) return 0;
  220. $userId = UserService::getCurrentLoginUserId();
  221. return $this->where('user_id', '=', $userId)
  222. ->where('is_delete', '=', 0)
  223. ->sum('goods_num');
  224. }
  225. /**
  226. * 获取当前用户购物车商品类型数量
  227. * @return float
  228. * @throws BaseException
  229. */
  230. public function getCartGoodsTotal()
  231. {
  232. if (!UserService::isLogin()) return 0;
  233. $userId = UserService::getCurrentLoginUserId();
  234. return $this->where('user_id', '=', $userId)
  235. ->where('is_delete', '=', 0)
  236. ->count();
  237. }
  238. /**
  239. * 更新购物车的商品选中状态
  240. * @param array $cartIds 购物车ID集, 如果为空删除所有
  241. * @return bool
  242. * @throws BaseException
  243. */
  244. public function updateSelected($cartIds,$selected){
  245. // 获取当前用户ID
  246. $userId = UserService::getCurrentLoginUserId();
  247. // 设置更新条件
  248. $where = [['user_id', '=', $userId]];
  249. // 购物车ID集
  250. !empty($cartIds) && $where[] = ['id', 'in', $cartIds];
  251. // 更新记录
  252. if(!empty($cartIds)){
  253. return $this->updateBase(['selected'=>$selected],$where);
  254. }else{
  255. return $this->updateBase(['selected'=>0],$where);
  256. }
  257. }
  258. /**
  259. * 更改购物车商品规格
  260. * @param $cartId
  261. * @param $goodsId
  262. * @param $goodsSkuId
  263. * @return mixed
  264. * @throws BaseException
  265. * @author: zjwhust
  266. * @Time: 2021/9/26 18:10
  267. */
  268. public function updSku($cartId, $goodsId, $goodsSkuId){
  269. // 获取当前用户ID
  270. $userId = UserService::getCurrentLoginUserId();
  271. $cart = $this->find($cartId);
  272. //如果没有更改规格,直接返回
  273. if($cart['goods_sku_id']==$goodsSkuId){
  274. return true;
  275. }
  276. // 设置更新条件
  277. return $this->transaction(function () use ($userId, $cartId, $goodsId, $goodsSkuId) {
  278. //删除商品规格相同的购物车数据
  279. $this->deleteAll([['user_id', '=', $userId],['goods_sku_id', '=', $goodsSkuId],['goods_id', '=', $goodsId]]);
  280. //更新当前的购物车属性
  281. $where = [['user_id', '=', $userId],['id', '=', $cartId],['goods_id', '=', $goodsId]];
  282. return $this->updateBase(['goods_sku_id'=>$goodsSkuId],$where);
  283. });
  284. }
  285. }