Trolley.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. <?php
  2. namespace app\api\controller;
  3. use app\common\model\StoreGoods;
  4. use app\common\model\StoreGoodsItem;
  5. use app\common\model\User;
  6. use think\Db;
  7. use app\common\model\ShoppingTrolley;
  8. use app\common\model\DeliveryAddress;
  9. use think\Exception;
  10. /**
  11. * @title 购物车
  12. * @controller Trolley
  13. * @group base
  14. */
  15. class Trolley extends Base
  16. {
  17. public function initialize()
  18. {
  19. parent::initialize();
  20. parent::checkLogin();
  21. }
  22. /**
  23. * @title 获取购物车商品数量
  24. * @desc 获取购物车商品数量
  25. * @author qc
  26. * @url /api/Trolley/getTrolleyNum
  27. * @method GET
  28. * @header name:Authorization require:1 desc:Token
  29. * @param name:goods_id type:int default:-- desc:商品id(商品id不传查全部的)
  30. * @return name:total_num type:int default:-- desc:购物车商品数量
  31. */
  32. public function getTrolleyNum()
  33. {
  34. $where = [];
  35. $where['user_id'] = $this->user_id;
  36. if($goods_id = input('get.goods_id',0)) $where['goods_id'] = $goods_id;
  37. $total_num = ShoppingTrolley::where($where)->sum('num');
  38. $this->success('ok',['total_num'=>$total_num]);
  39. }
  40. /**
  41. * @title 获取购物车列表
  42. * @desc 获取购物车列表
  43. * @author qc
  44. * @url /api/Trolley/getTrolleyList
  45. * @method GET
  46. * @header name:Authorization require:1 desc:Token
  47. * @return name:goods_id type:int default:-- desc:商品id
  48. * @return name:goods_name type:string default:-- desc:商品名称
  49. * @return name:goods_status type:int default:-- desc:商品状态(1上架,0下架)
  50. * @return name:deleted_status type:string default:-- desc:删除状态(1删除,0未删除)
  51. * @return name:item_list type:array default:-- desc:添加该商品的规格列表
  52. * @return name:item_list.id type:int default:-- desc:购物车记录id
  53. * @return name:item_list.num type:int default:-- desc:数量
  54. * @return name:item_list.goods_id type:int default:-- desc:商品id
  55. * @return name:item_list.spec_id type:int default:-- desc:规格id
  56. * @return name:item_list.goods_no type:int default:-- desc:货号
  57. * @return name:item_list.spec_title type:string default:-- desc:规格名称
  58. * @return name:item_list.cover type:string default:-- desc:规格封面
  59. * @return name:item_list.original_price type:float default:-- desc:规格原价(下划线价格)
  60. * @return name:item_list.sell_price type:float default:-- desc:规格售价
  61. * @return name:total_num type:int default:-- desc:购物车商品数量
  62. */
  63. public function getTrolleyList()
  64. {
  65. $trolley_goods = ShoppingTrolley::field('goods_id')
  66. ->where('user_id',$this->user_id)->group('goods_id')
  67. ->select();
  68. if(!$trolley_goods) $this->success('',['list'=>[]]);
  69. $goods_ids = array_column($trolley_goods->toArray(),'goods_id');
  70. $list = [];
  71. $total_num = 0;
  72. $goods_list = StoreGoods::where('id','in',$goods_ids)->select()->toArray();
  73. foreach ($goods_list as $goods_info){
  74. $trolley_data = ['goods_id'=>$goods_info['id'],'cover'=>$goods_info['cover'],'goods_name'=>$goods_info['name'],'goods_status'=>$goods_info['status'],'deleted_status'=>$goods_info['is_deleted'],'is_combo'=>$goods_info['is_combo'],'full_money'=>0,'sub_money'=>0];
  75. $join_field = 't.id,t.num,t.spec_id,t.goods_id,i.goods_spec,i.cover,i.goods_no,i.spec_title,i.stock,i.is_deleted,i.original_price,i.sell_price,i.weight';
  76. $trolley_data['item_list'] = ShoppingTrolley::field($join_field)->alias('t')
  77. ->where('t.goods_id',$goods_info['id'])
  78. ->leftJoin('StoreGoodsItem i','i.id = t.spec_id')
  79. ->select()->toArray();
  80. $total_num += array_sum(array_column($trolley_data,'num'));
  81. $list[] = $trolley_data;
  82. }
  83. $this->success('ok',['list'=>$list,'total_num'=>$total_num]);
  84. }
  85. /**
  86. * @title 商品添加购物车(按规格加入)
  87. * @desc 商品某个规格加入多少
  88. * @author qc
  89. * @url /api/Trolley/addTrolley
  90. * @method POST
  91. * @header name:Authorization require:1 desc:Token
  92. * @param name:goods_id type:int require:1 default:0 desc:商品id
  93. * @param name:spec_id type:int require:1 default:0 desc:规格id
  94. * @param name:num type:int default:1 desc:数量
  95. */
  96. public function addTrolley()
  97. {
  98. $goods_id = input('post.goods_id');
  99. $spec_id = input('post.spec_id');
  100. $num = input('post.num',1);
  101. if(!$goods_id || !$spec_id) $this->error('请选择商品');
  102. if($num <=0 ) $this->error('添加数量有误');
  103. Db::startTrans();
  104. try {
  105. // 商品详情
  106. $goods_info = StoreGoods::with(['itemList'=>function($query)use($spec_id){
  107. return $query->where('id',$spec_id)->where('is_deleted',0);
  108. }])->where('id',$goods_id)->where('is_deleted',0)->where('status',1)->find();
  109. if(!$goods_info) throw new Exception('商品已下架');
  110. $goods_info = $goods_info->toArray();
  111. if(empty($goods_info['item_list'])) throw new Exception('该规格已下架');
  112. if($goods_info['is_presell']) throw new Exception('预售商品无法加入购物车');
  113. if($goods_info['item_list'][0]['stock'] < $num) throw new Exception('库存不足');
  114. $trolley_id = ShoppingTrolley::checkTrolley($this->user_id,$goods_id,$spec_id);
  115. // 添加到购物车
  116. if($trolley_id) {
  117. ShoppingTrolley::where('id',$trolley_id)->setInc('num',$num);
  118. }else{
  119. $trolley_info = [
  120. 'user_id' => $this->user_id,
  121. 'goods_id' => $goods_id,
  122. 'spec_id' => $spec_id,
  123. 'goods_no' => $goods_info['item_list'][0]['goods_no'],
  124. 'num' => $num,
  125. ];
  126. ShoppingTrolley::create($trolley_info);
  127. }
  128. // 扣减库存
  129. StoreGoods::where('id',$goods_id)->setDec('stock',$num);
  130. StoreGoodsItem::where('id',$spec_id)->setDec('stock',$num);
  131. Db::commit();
  132. }catch (\Exception $e){
  133. $this->is_commit = false;
  134. $this->ret_msg = $e->getMessage();
  135. Db::rollback();
  136. }
  137. $this->is_commit ? $this->success('添加成功'):$this->error($this->ret_msg);
  138. }
  139. /**
  140. * @title 修改购物车商品数量
  141. * @desc 修改购物车商品数量
  142. * @author qc
  143. * @url /api/Trolley/changeTrolleyNum
  144. * @method POST
  145. * @header name:Authorization require:1 desc:Token
  146. * @param name:trolley_id type:int require:1 default:0 desc:购物车记录id
  147. * @return name:num type:int require:1 default:1 desc:变更数量
  148. * @return name:type type:intrequire:1 default:1 desc:变更类型(1增加2扣减)
  149. */
  150. public function changeTrolleyNum()
  151. {
  152. $trolley_id = input('post.trolley_id');
  153. $num = input('post.num',1);
  154. $type = input('post.type',1);
  155. if(!in_array($type,[1,2])) $this->error('变更可类型错误');
  156. Db::startTrans();
  157. try {
  158. $trolley_info = ShoppingTrolley::get($trolley_id);
  159. if(!$trolley_info) $this->exception('记录不存在!');
  160. $goods_info = StoreGoods::getGoodsSpec($trolley_info->goods_id,$trolley_info->spec_id);
  161. if($type == 1){
  162. if(!$goods_info) $this->exception('商品已下架');
  163. if(empty($goods_info['item_list'])) $this->exception('该规格已下架');
  164. if($goods_info['item_list'][0]['stock'] < $num)$this->exception('库存不足');
  165. ShoppingTrolley::where('id',$trolley_id)->setInc('num',$num);
  166. StoreGoods::where('id',$trolley_info->goods_id)->setDec('stock',$num);// 扣减商品库存
  167. StoreGoodsItem::where('id',$trolley_info->spec_id)->setDec('stock',$num);// 扣减规格库存
  168. }else{
  169. if($trolley_info->num < $num) $this->exception('扣减数量有误');
  170. if($trolley_info->num > $num){
  171. ShoppingTrolley::where('id',$trolley_id)->setDec('num',$num);//扣减数量
  172. }else{
  173. ShoppingTrolley::where('id',$trolley_id)->delete();//删除记录
  174. }
  175. StoreGoods::where('id',$trolley_info->goods_id)->setInc('stock',$num);//增加商品库存
  176. StoreGoodsItem::where('id',$trolley_info->spec_id)->setInc('stock',$num);//增加规格库存
  177. }
  178. Db::commit();
  179. }catch (\Exception $e){
  180. $this->ret_msg = $e->getMessage();
  181. $this->is_commit = false;
  182. Db::rollback();
  183. }
  184. $this->is_commit ? $this->success('操作成功') : $this->error($this->ret_msg);
  185. }
  186. /**
  187. * @title 删除购物车记录
  188. * @desc 删除购物车记录
  189. * @author qc
  190. * @url /api/Trolley/cancelTrolleyList
  191. * @method POST
  192. * @header name:Authorization require:1 desc:Token
  193. * @param name:ids type:string require:1 default:0 desc:购物车记录id(多条用逗号隔开)
  194. */
  195. public function cancelTrolleyList()
  196. {
  197. $ids = input('post.ids');
  198. if(!$ids) $this->error('请选择要删除的数据');
  199. $trolley_list = ShoppingTrolley::where('id','in',$ids)->select();
  200. Db::startTrans();
  201. foreach ($trolley_list as $trolley_info) {
  202. StoreGoods::where('id',$trolley_info->goods_id)->setInc('stock',$trolley_info->num);//增加商品库存
  203. StoreGoodsItem::where('id',$trolley_info->spec_id)->setInc('stock',$trolley_info->num);//增加规格库存
  204. }
  205. ShoppingTrolley::where('id','in',$ids)->delete();
  206. Db::commit();
  207. $this->success('删除成功');
  208. }
  209. /**
  210. * @title 某商品是否添加到购物
  211. * @desc 获取某商品添加到购物车规格及数量
  212. * @author qc
  213. * @url /api/Trolley/getTrolleyByGoodsId
  214. * @method GET
  215. * @header name:Authorization require:1 desc:Token
  216. * @param name:goods_id type:int default:1 desc:商品id
  217. * @return name:spec_id type:int default:-- desc:规格id
  218. * @return name:num type:int default:-- desc:数量
  219. */
  220. public function getTrolleyByGoodsId()
  221. {
  222. $goods_id = input('get.goods_id');
  223. $list = ShoppingTrolley::field('id,goods_id,spec_id,goods_no,num')
  224. ->where(['user_id'=>$this->user_id,'goods_id'=>$goods_id])
  225. ->order('id desc')
  226. ->select();
  227. $this->success('ok',['list'=>$list?$list->toArray() : [] ]);
  228. }
  229. /**
  230. * @title 购物车订单确认
  231. * @desc 购物车订单确认
  232. * @author qc
  233. * @url /api/Trolley/confirmTrolleyList
  234. * @method GET
  235. * @header name:Authorization require:1 desc:Token
  236. * @param name:ids type:int default:1 desc:购物车记录id(多条用逗号隔开)
  237. * @return name:goods_id type:int default:-- desc:商品id
  238. * @return name:goods_name type:string default:-- desc:商品名称
  239. * @return name:goods_status type:int default:-- desc:商品状态(1上架,0下架)
  240. * @return name:deleted_status type:string default:-- desc:删除状态(1删除,0未删除)
  241. * @return name:item_list type:array default:-- desc:添加该商品的规格列表
  242. * @return name:item_list.spec_id type:int default:-- desc:规格id
  243. * @return name:item_list.goods_no type:int default:-- desc:货号
  244. * @return name:item_list.goods_spec type:array default:-- desc:规格详情
  245. * @return name:item_list.goods_spec.spec_title type:string default:-- desc:规格名称
  246. * @return name:item_list.goods_spec.cover type:string default:-- desc:规格封面
  247. * @return name:item_list.goods_spec.original_price type:float default:-- desc:规格原价
  248. * @return name:item_list.goods_spec.sell_price type:float default:-- desc:规格售价
  249. * @return name:wallet type:float default:-- desc:金额
  250. * @return name:address_info type:array default:-- desc:默认收货地址
  251. * @return name:wallet type:array default:-- desc:钱包
  252. * @return name:walle.integral type:int default:-- desc:积分
  253. * @return name:walle.money type:int default:-- desc:佣金余额
  254. */
  255. public function confirmTrolleyList()
  256. {
  257. $ids = input('get.ids');
  258. $trolley_goods = ShoppingTrolley::field('goods_id')
  259. ->where('user_id',$this->user_id)
  260. ->where('id','in',$ids)
  261. ->group('goods_id')
  262. ->select();
  263. if(!$trolley_goods) $this->error('请选择商品');
  264. $goods_ids = array_column($trolley_goods->toArray(),'goods_id');
  265. $list = [];
  266. $total_money = 0;
  267. $goods_list = StoreGoods::where('id','in',$goods_ids)->select()->toArray();
  268. foreach ($goods_list as $goods_info){
  269. $trolley_data = ['goods_id'=>$goods_info['id'],'goods_name'=>$goods_info['name'],'goods_status'=>$goods_info['status'],'deleted_status'=>$goods_info['is_deleted'],'is_combo'=>$goods_info['is_combo']];
  270. $trolley_data['item_list'] = ShoppingTrolley::with(['goodsSpec'])->where('id','in',$ids)->where('goods_id',$goods_info['id'])->select()->toArray();
  271. foreach ($trolley_data['item_list'] as $iv){
  272. $total_money = bcadd(bcmul($iv['num'],$iv['goods_spec']['sell_price'],2),$total_money,2);
  273. }
  274. $list[] = $trolley_data;
  275. }
  276. $address_info = DeliveryAddress::where(['user_id'=>$this->user_id,'is_mr'=>1])->find();
  277. $user_info = User::with('wallet')->field('id,level_id')->where('id',$this->user_id)->find()->toArray();
  278. $this->success('ok',[
  279. 'list'=>$list,
  280. 'total_money'=>$total_money,
  281. 'address_info'=>$address_info ? $address_info->toArray():'',
  282. 'wallet'=>$user_info['wallet'],
  283. ]);
  284. }
  285. }