ShopCart.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412
  1. <?php namespace App\Http\Controllers\Api;
  2. use App\Http\Controllers\Api\Api;
  3. use App\Http\Requests\Api\ShopCart as Request;
  4. use App\Models\Business;
  5. use App\Models\Product\Skus as ProductSkus;
  6. use App\Models\PromoRebate;
  7. use App\Models\ShopCart as Model;
  8. use App\Models\PromoProduct as PromoProduct;
  9. use App\Models\PayCity;
  10. use App\Models\Product\City as ProductCity;
  11. use App\Models\Custom as Custom;
  12. use App\Models\WeiBan\Tags as WeiBanTags;
  13. /**
  14. * 购物车接口
  15. *
  16. * @author 刘相欣
  17. *
  18. * */
  19. class ShopCart extends Api{
  20. /**
  21. * 添加 /api/shop_cart/add
  22. *
  23. * @param int $product_id 产品ID
  24. * @param int $buy_num 添加数量
  25. *
  26. * */
  27. public function add(Request $request,Model $Model){
  28. // 接口验签
  29. // $this->verify_sign();
  30. // 验证参数
  31. $request->scene('add')->validate();
  32. // 检查登录
  33. $uid = $this->checkLogin();
  34. // 接收参数
  35. $data['product_id'] = request('product_id',0);
  36. $data['skuid'] = request('skuid',0);
  37. $data['buy_num'] = request('buy_num',1);
  38. $data['custom_uid'] = $uid;
  39. // 查询
  40. $id = $Model->query()->where([['custom_uid','=',$uid],['product_id','=',$data['product_id']],['skuid','=',$data['skuid']]])->value('id');
  41. // 如果存在id,更新数量
  42. $result = $id ? $Model->incrBuyNum($id,$uid,$data['buy_num']) : $Model->add($data);
  43. // 提交结果
  44. if( !$result ) return json_send(['code'=>'success','msg'=>'加入购物车失败','data'=>['error'=>'加入购物车失败']]);
  45. // 返回结果
  46. return json_send(['code'=>'success','msg'=>'添加成功','data'=>$data]);
  47. }
  48. /**
  49. * 更新 /api/shop_cart/edit
  50. *
  51. * @param int $id 购物车id
  52. *
  53. * */
  54. public function edit(Request $request,Model $Model){
  55. // 接口验签
  56. // $this->verify_sign();
  57. // 验证参数
  58. $request->scene('edit')->validate();
  59. // 检查登录
  60. $uid = $this->checkLogin();
  61. // 接收参数
  62. $id = request('id',0);
  63. $data['buy_num'] = request('buy_num',1);
  64. // 如果存在id,更新数量
  65. $result = $Model->edit($id,$uid,$data);
  66. // 提交结果
  67. if( !$result ) return json_send(['code'=>'success','msg'=>'更新失败','data'=>['error'=>'更新购物车失败']]);
  68. // 返回结果
  69. return json_send(['code'=>'success','msg'=>'更新成功','data'=>$data]);
  70. }
  71. /**
  72. * 更新 /api/shop_cart/del
  73. *
  74. * @param int $id 购物车id
  75. *
  76. * */
  77. public function del(Request $request,Model $Model){
  78. // 接口验签
  79. // $this->verify_sign();
  80. // 验证参数
  81. $request->scene('del')->validate();
  82. // 检查登录
  83. $uid = $this->checkLogin();
  84. // 接收参数
  85. $id = request('id',0);
  86. // 如果存在id,更新数量
  87. $result = $Model->del($id,$uid);
  88. // 提交结果
  89. if( !$result ) return json_send(['code'=>'success','msg'=>'删除失败','data'=>['error'=>'删除购物车失败']]);
  90. // 返回结果
  91. return json_send(['code'=>'success','msg'=>'删除成功','data'=>['id'=>$id]]);
  92. }
  93. /**
  94. * 获取列表 /api/shop_cart/get_list
  95. *
  96. * @param int $id 购物车id
  97. *
  98. * */
  99. public function get_list(Request $request,Model $Model,ProductSkus $ProductSkus,Business $Business,PromoProduct $PromoProduct,Custom $Custom,WeiBanTags $WeiBanTags,ProductCity $ProductCity,PayCity $PayCity){
  100. // 接口验签
  101. // $this->verify_sign();
  102. // 验证参数
  103. $request->scene('get_list')->validate();
  104. // 检查登录
  105. $uid = $this->checkLogin();
  106. // 获取客户信息
  107. $custom = $uid ? $Custom->getOne($uid) : [];
  108. // 显示
  109. $map = [['shop_cart.custom_uid','=',$uid]];
  110. // 查询
  111. $list = $Model->query()
  112. ->join('product','shop_cart.product_id','=','product.id')
  113. ->where($map)
  114. ->get([
  115. 'shop_cart.id','shop_cart.checked','shop_cart.product_id','shop_cart.skuid','shop_cart.buy_num',
  116. 'product.stock','product.business_id','product.spec','product.thumb','product.name','product.price','product.market_price','product.status as product_status'
  117. ])
  118. ->toArray();
  119. // 判断结果
  120. $skusList = $ProductSkus->getListByIds(array_column($list,'skuid'));
  121. //查询产品活动
  122. $promoList = $PromoProduct->getListByIds(array_column($list,'product_id'));
  123. // 查询用户标签
  124. $tags = empty($custom['weiban_extid']) ? [] : $WeiBanTags->getListByWeibanExtid($custom['weiban_extid']);
  125. // 用户所在城市
  126. $cityId = empty($custom['city_id']) ? 0 : $custom['city_id'];
  127. // 循环处理数据
  128. foreach ($list as $key => $value) {
  129. // 获取店铺名称
  130. $value['business_name'] = $value['business_id'] ? (string) $Business->getOne($value['business_id'],'name') : '';
  131. // 如果有sku
  132. if( $value['skuid'] ) {
  133. // 是否存在
  134. $isExist = false;
  135. // 循环SKU
  136. foreach ($skusList as $sku) {
  137. // 如果SKU存在的话
  138. if( $sku['sku_id'] == $value['skuid'] ) {
  139. $value['price'] = $sku['price'];
  140. $value['spec'] = $sku['sku_attr_names'];
  141. $value['stock'] = $sku['stock'];
  142. $isExist = true;
  143. }
  144. }
  145. // 如果不存在,状态变动
  146. if( !$isExist ) $value['product_status'] = 4;
  147. }
  148. // 满减活动
  149. if ($promoList && $cityId){
  150. if (isset($promoList[$value['product_id']])){
  151. $promoInfo = $promoList[$value['product_id']];
  152. $promoTitle = "满". $promoInfo['std_pay']. "元";
  153. if ($promoInfo['rebate_type'] == 1){
  154. $promoTitle .= "减". $promoInfo['rebate']. "元";
  155. }elseif ($promoInfo['rebate_type'] == 2){
  156. $promoTitle .= "打". $promoInfo['rebate']. "折";
  157. }elseif ($promoInfo['rebate_type'] == 3){
  158. $rebate = (string) PromoRebate::query()->join('product','promo_rebate.product_id','=','product.id')->where([['promo_id','=',$promoInfo['id']]])->value('product.name');
  159. $promoTitle .= "赠送". $rebate;
  160. }
  161. $promoInfoCity = [];
  162. if ($promoInfo['city_ids']){
  163. $promoInfoCity = explode(',',$promoInfo['city_ids']);
  164. }
  165. // 判断是不是可以参与
  166. if (!$promoInfoCity || in_array($cityId,$promoInfoCity)){
  167. if( $promoInfo['tag_scope']) {
  168. // 解析数组
  169. $promoInfo['tag_scope'] = explode(',',$promoInfo['tag_scope']);
  170. // 标签范围限定时,默认不能参与
  171. $allowJoin = 0;
  172. // 判断标签是不是存在
  173. if ($tags){
  174. foreach ($tags as $v) {
  175. // 标签范围内,允许参加
  176. if( in_array($v['name'],$promoInfo['tag_scope']) ) $allowJoin = 1;
  177. }
  178. // 在范围
  179. if( $allowJoin ) {
  180. $value['promo_title'] = $promoTitle;
  181. }
  182. }
  183. }else{
  184. $value['promo_title'] = $promoTitle;
  185. }
  186. }
  187. }
  188. }
  189. // 产品图路径
  190. $value['thumb'] = path_compat($value['thumb']);
  191. // 库存超出的时候
  192. if($value['buy_num'] > $value['stock'] ) $value['buy_num'] = $value['stock'];
  193. // 允许城市
  194. $allowCity = $ProductCity->where([['product_id','=',$value['product_id']]])->pluck('city_id')->toArray();
  195. //判断产品城市是否设置了支付
  196. $payCity = $PayCity->where([['status','=',0]])->first();
  197. $isPay = 0;
  198. if ($payCity && $payCity['city_ids']) {
  199. $cityIds = explode(',',$payCity['city_ids']);
  200. foreach ($allowCity as $item) {
  201. if ($item == 1 || in_array($item,$cityIds)) $isPay = 1;
  202. }
  203. }
  204. $value['is_pay'] = $isPay;
  205. // 重组
  206. $list[$key] = $value;
  207. }
  208. // 返回结果
  209. return json_send(['code'=>'success','msg'=>'获取成功','data'=>$list]);
  210. }
  211. /**
  212. * 结算列表 /api/shop_cart/check_list
  213. *
  214. * @param int $id 购物车id
  215. *
  216. * */
  217. public function check_list(Request $request,Model $Model,ProductSkus $ProductSkus,Business $Business,PromoProduct $PromoProduct,Custom $Custom,WeiBanTags $WeiBanTags,PayCity $PayCity,ProductCity $ProductCity){
  218. // 接口验签
  219. // $this->verify_sign();
  220. // 验证参数
  221. $request->scene('check_list')->validate();
  222. // 检查登录
  223. $uid = $this->checkLogin();
  224. // 获取客户信息
  225. $custom = $uid ? $Custom->getOne($uid) : [];
  226. // 接收参数
  227. $cartIds = request('cart_ids','');
  228. // 转成数组
  229. $cartIds = explode(',',$cartIds);
  230. // 循环处理
  231. foreach ($cartIds as $key => $value) {
  232. // 如果不是数值
  233. if( $value < 1 ) unset($cartIds[$key]);
  234. }
  235. // 如果不存在的话
  236. if( !$cartIds ) return json_send(['code'=>'error','msg'=>'请选择可用产品','data'=>['error'=>request('cart_ids','')]]);
  237. // 显示
  238. $map = [['shop_cart.custom_uid','=',$uid],['product.status','=',0]];
  239. // 查询
  240. $list = $Model->query()
  241. ->join('product','shop_cart.product_id','=','product.id')
  242. ->whereIn('shop_cart.id',$cartIds)->where($map)
  243. ->get([
  244. 'shop_cart.id','shop_cart.checked','shop_cart.product_id','shop_cart.skuid','shop_cart.buy_num',
  245. 'product.stock','product.business_id','product.spec','product.thumb','product.name','product.price','product.market_price','product.status as product_status'
  246. ])->toArray();
  247. // 判断结果
  248. $skusList = $ProductSkus->getListByIds(array_column($list,'skuid'));
  249. //查询产品活动
  250. $promoList = $PromoProduct->getListByIds(array_column($list,'product_id'));
  251. // 查询用户标签
  252. $tags = empty($custom['weiban_extid']) ? [] : $WeiBanTags->getListByWeibanExtid($custom['weiban_extid']);
  253. // 用户所在城市
  254. $cityId = empty($custom['city_id']) ? 0 : $custom['city_id'];
  255. // 满减活动
  256. $promoProductList = [];
  257. // 循环处理数据
  258. foreach ($list as $key => $value) {
  259. // 获取店铺名称
  260. $value['business_name'] = $value['business_id'] ? (string)$Business->getOne($value['business_id'],'name') : '';
  261. // 如果有sku
  262. if( $value['skuid'] ) {
  263. // 是否存在
  264. $isExist = false;
  265. // 循环SKU
  266. foreach ($skusList as $sku) {
  267. // 如果SKU存在的话
  268. if( $sku['sku_id'] == $value['skuid'] ) {
  269. $value['price'] = $sku['price'];
  270. $value['spec'] = $sku['sku_attr_names'];
  271. $value['stock'] = $sku['stock'];
  272. $isExist = true;
  273. }
  274. }
  275. // 如果不存在,状态变动
  276. if( !$isExist ) {
  277. unset($list[$key]);
  278. continue;
  279. }
  280. }
  281. // 如果不存在,状态变动
  282. if( $value['stock'] <= 0 ) {
  283. unset($list[$key]);
  284. continue;
  285. }
  286. if ($promoList && $cityId){
  287. if (isset($promoList[$value['product_id']])){
  288. $promoInfo = $promoList[$value['product_id']];
  289. $promoInfo['price'] = $value['price'] * $value['buy_num'];
  290. $promoTitle = "满". $promoInfo['std_pay']. "元";
  291. if ($promoInfo['rebate_type'] == 1){
  292. $promoTitle .= "减". $promoInfo['rebate']. "元";
  293. }elseif ($promoInfo['rebate_type'] == 2){
  294. $promoTitle .= "打". $promoInfo['rebate']. "折";
  295. }elseif ($promoInfo['rebate_type'] == 3){
  296. $rebate = (string) PromoRebate::query()->join('product','promo_rebate.product_id','=','product.id')->where([['promo_id','=',$promoInfo['id']]])->value('product.name');
  297. $promoTitle .= "赠送". $rebate;
  298. }
  299. $promoInfoCity = [];
  300. if ($promoInfo['city_ids']){
  301. $promoInfoCity = explode(',',$promoInfo['city_ids']);
  302. }
  303. // 判断是不是可以参与
  304. if (!$promoInfoCity || in_array($cityId,$promoInfoCity)){
  305. if( $promoInfo['tag_scope']) {
  306. // 解析数组
  307. $promoInfo['tag_scope'] = explode(',',$promoInfo['tag_scope']);
  308. // 标签范围限定时,默认不能参与
  309. $allowJoin = 0;
  310. // 判断标签是不是存在
  311. if ($tags){
  312. foreach ($tags as $v) {
  313. // 标签范围内,允许参加
  314. if( in_array($v['name'],$promoInfo['tag_scope']) ) $allowJoin = 1;
  315. }
  316. // 在范围
  317. if( $allowJoin ) {
  318. $value['promo_title'] = $promoTitle;
  319. $promoProductList[$promoInfo['id']][] = $promoInfo;
  320. }
  321. }
  322. }else{
  323. $value['promo_title'] = $promoTitle;
  324. $promoProductList[$promoInfo['id']][] = $promoInfo;
  325. }
  326. }
  327. }
  328. }
  329. // 产品图路径
  330. $value['thumb'] = path_compat($value['thumb']);
  331. // 库存超出的时候
  332. if($value['buy_num'] > $value['stock'] ) $value['buy_num'] = $value['stock'];
  333. // 允许城市
  334. $allowCity = $ProductCity->where([['product_id','=',$value['product_id']]])->pluck('city_id')->toArray();
  335. //判断产品城市是否设置了支付
  336. $payCity = $PayCity->where([['status','=',0]])->first();
  337. $isPay = 0;
  338. if ($payCity && $payCity['city_ids']) {
  339. $cityIds = explode(',',$payCity['city_ids']);
  340. foreach ($allowCity as $item) {
  341. if (($item == 1 || in_array($item,$cityIds)) && in_array($custom['city_id'],$cityIds)) $isPay = 1;
  342. }
  343. }
  344. $value['is_pay'] = $isPay;
  345. // 重组
  346. $list[$key] = $value;
  347. }
  348. $promoRebateIds = [];
  349. //满折扣
  350. $discount = 0;
  351. //满减
  352. $reduction = 0;
  353. //计算产品促销活动优惠价格
  354. if ($promoProductList){
  355. foreach ($promoProductList as $key => $value){
  356. $priceSum = array_sum(array_column($value,'price'));
  357. if ($priceSum >= $value[0]['std_pay']) {
  358. switch ($value[0]['rebate_type']){
  359. case 1:
  360. $reduction += $value[0]['rebate'];
  361. break;
  362. case 2:
  363. $discount += $priceSum - number_format($priceSum * $value[0]['rebate']/10,2);
  364. break;
  365. case 3:
  366. $promoRebateIds[] = $key;
  367. }
  368. }
  369. }
  370. }
  371. $promoRebateList = [];
  372. //如果有赠品
  373. if ($promoRebateIds){
  374. $promoRebateList = PromoRebate::query()
  375. ->join('product','promo_rebate.product_id','=','product.id')
  376. ->where('status','=',0)
  377. ->whereIn('promo_id',$promoRebateIds)
  378. ->select(['promo_rebate.id as promo_rebate_id','promo_rebate.rebate_num as buy_num','product.stock','product.spec','product.thumb','product.name','product.price','product.market_price','product.status as product_status'])
  379. ->get()
  380. ->toArray();
  381. if ($promoRebateList){
  382. foreach ($promoRebateList as &$value){
  383. // 产品图路径
  384. $value['thumb'] = path_compat($value['thumb']);
  385. // 库存超出的时候
  386. if($value['buy_num'] > $value['stock'] && $value['stock'] > 0) $value['buy_num'] = $value['stock'];
  387. }
  388. }
  389. }
  390. $discount = number_format($discount,2);
  391. // 重组数组
  392. $list = array_values($list);
  393. // 返回结果
  394. return json_send(['code'=>'success','msg'=>'获取成功','data'=>$list,'discount'=>$discount,'reduction'=>$reduction,'promoRebateList'=>$promoRebateList]);
  395. }
  396. }