ShoppingCartServer.php 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. <?php
  2. namespace App\Servers;
  3. use App\Models\Goods;
  4. use App\Models\GoodsSku;
  5. use App\Models\GoodsSpec;
  6. use App\Models\Shopping;
  7. /**
  8. * 购物车服务
  9. */
  10. class ShoppingCartServer
  11. {
  12. static private $server = null;
  13. private $errorMsg = '';
  14. private function __construct()
  15. {
  16. }
  17. /**
  18. * 创建对象
  19. * @return ShoppingCartServer
  20. */
  21. static function creatServer()
  22. {
  23. if (empty(self::$server)) self::$server = new ShoppingCartServer();
  24. return self::$server;
  25. }
  26. /**
  27. * 获取购物车列表
  28. * @param $m_id
  29. * @param $shop_id
  30. * @return array
  31. */
  32. function getShoppingList($m_id,$shop_id)
  33. {
  34. //获取购物车商品数据
  35. $where = [['p.m_id',$m_id], ['p.shop_id',$shop_id], ['p.type',1], ['g.is_del',0], ['g.status',1]];
  36. $shopping = Shopping::from('shopping as p')
  37. ->leftJoin('goods as g','g.id','=','p.goods_id')
  38. ->where($where)
  39. ->select(['p.id as shopping_id','p.number','p.goods_spec_id','g.id as goods_id','g.shop_id','g.goods_name','g.goods_image','g.price','g.spec_type','g.category_id','g.pack_price','g.is_infinite','g.stock'])
  40. ->orderBy('p.id','asc')
  41. ->get();
  42. $total_num = 0;//总商品数
  43. $total_goods_money = '0.00';//总商品费用
  44. $total_pack_price = 0;//打包费
  45. $goods_list = [];//商品列表
  46. $goodsNumber = [];//记录商品一共点了多少,判断是否限购超库存
  47. foreach ($shopping as $value){
  48. $goods_id = $value->{'goods_id'};//商品id
  49. $goods_price = $value->{'price'};//商品金额
  50. $spec_type = $value->{'spec_type'};//商品类型
  51. $goods_spec_id = $value->{'goods_spec_id'};//商品规格id
  52. $status_str = '';
  53. $goods_attr = "";//规则值
  54. $goods_number = $value['number'];//商品数量
  55. $goods_spec = [];
  56. //记录商品一共点了多少,判断是否限购超库存
  57. if (isset($goodsNumber[$goods_id])){
  58. $goodsNumber[$goods_id] = bcadd($goodsNumber[$goods_id],$goods_number);
  59. }else{
  60. $goodsNumber[$goods_id] = $goods_number;
  61. }
  62. if ($goods_spec_id && $spec_type == 2){//存在规格
  63. $specIds = array_filter(explode('_', $goods_spec_id));
  64. $goods_spec = GoodsSpec::where('goods_id',$goods_id)
  65. ->whereIn('id',$specIds)
  66. ->where('is_del',0)
  67. ->select(['spec_name','spec_price'])
  68. ->get();
  69. foreach ($goods_spec as $spec_value){
  70. $goods_attr .= $spec_value['spec_name'] . ',';
  71. $goods_price = bcadd($spec_value['spec_price'],$goods_price,2);
  72. }
  73. }
  74. //商品不是无限库存,判断库存是否足够
  75. if ($value->{'is_infinite'} != 1){
  76. if ($value->{'stock'} < $goodsNumber[$goods_id]){
  77. $status_str = '库存不足';
  78. $this->errorMsg = $value['goods_name'].'库存不足';
  79. }
  80. }
  81. //计算价格
  82. $goods_money = bcmul($goods_price,$goods_number,2);
  83. $goods_list[] = [
  84. 'shop_id' => $value['shop_id'],
  85. 'category_id' => $value['category_id'],
  86. 'goods_id' => $goods_id,
  87. 'goods_spec_id' => $goods_spec_id,
  88. 'goods_money' => rtrim(rtrim($goods_money, '0'),'.'),
  89. 'goods_number' => $goods_number,
  90. 'goods_name' => $value['goods_name'],
  91. 'goods_image' => $value['goods_image'],
  92. 'spec_type' => $value['spec_type'],
  93. 'price' => $goods_price,
  94. 'pack_price' => $value['pack_price'],
  95. 'goods_attr' => $goods_attr,
  96. 'is_infinite' => $value['is_infinite'],
  97. 'status_str' => $status_str,
  98. ];
  99. //计算打包费
  100. $total_pack_price = bcadd($total_pack_price,bcmul($goods_number,$value['pack_price'],2),2);
  101. //计算总数量
  102. $total_num += $goods_number;
  103. //计算总商品费用
  104. $total_goods_money = bcadd($total_goods_money,$goods_money,2);
  105. }
  106. //订单总价-商品总价+总包装费
  107. $total_price = bcadd($total_goods_money,$total_pack_price,2);
  108. $data['total_price'] = rtrim(rtrim($total_price, '0'),'.');
  109. $data['total_num'] = (int)$total_num;
  110. $data['total_goods_money'] = rtrim(rtrim($total_goods_money, '0'),'.');
  111. $data['pack_price'] = $total_pack_price;
  112. $data['err_msg'] = $this->errorMsg;
  113. $data['goods_list'] = $goods_list;
  114. $this->errorMsg = '';
  115. return $data;
  116. }
  117. /**
  118. * 添加购物车
  119. * @param $m_id
  120. * @param $shop_id
  121. * @param $category_id
  122. * @param $goods_id
  123. * @param $goods_spec_id
  124. * @param $number
  125. * @return array
  126. */
  127. function saveShopping($m_id,$shop_id,$category_id,$goods_id,$goods_spec_id,$number)
  128. {
  129. if (empty($goods_spec_id)){
  130. $goods_spec_id = '';
  131. }
  132. //获取商品
  133. $goods = Goods::where('is_del',0)
  134. ->where('id',$goods_id)
  135. ->where('shop_id',$shop_id)
  136. ->where('category_id',$category_id)
  137. ->select(['id as goods_id','is_infinite','stock','status','spec_type'])
  138. ->first();
  139. if (empty($goods)) return ['code' => 0, 'msg' => '当前商品不存在'];
  140. if ($goods->{'status'} != 1) return ['code' => 0, 'msg' => '当前商品已下架'];
  141. //如果商品是多规格但是没选规格
  142. if ($goods->{'spec_type'} == 2 && empty($goods_spec_id)){
  143. return ['code' => 0, 'msg' => '请选择商品规格'];
  144. }elseif ($goods->{'spec_type'} == 2 && $goods_spec_id){
  145. //如果商品是多规格,查询规格商品是否选择全
  146. $skuIds = GoodsSku::where('goods_id',$goods->{'goods_id'})->where('is_del',0)->pluck('id')->toArray();
  147. $spec = array_filter(explode('_', $goods_spec_id));
  148. foreach ($skuIds as $skuId){
  149. $specIds = GoodsSpec::where('goods_id',$goods->{'goods_id'})->where('is_del',0)->where('sku_id',$skuId)->pluck('id')->toArray();
  150. if (!array_intersect($spec,$specIds)){
  151. return ['code' => 0, 'msg' => '请完整选择规格'];
  152. }
  153. }
  154. }
  155. //获取购物车是否存在此商品
  156. $where = [['m_id',$m_id], ['shop_id',$shop_id], ['category_id',$category_id], ['goods_id',$goods_id]];
  157. //获取此商品数量
  158. $shopping_number = Shopping::where($where)->sum('number');
  159. $total_number = bcadd($shopping_number,$number);
  160. if ($goods_spec_id) $where[] = ['goods_spec_id',$goods_spec_id];
  161. //查询
  162. $shopping_info = Shopping::where($where)->select(['id', 'goods_id', 'number'])->first();
  163. //商品不是无限库存,判断库存是否足够
  164. if ($goods->{'is_infinite'} != 1){
  165. if ($goods->{'stock'} < $total_number){
  166. return ['code' => 0, 'msg' => '商品库存余'.$goods->{'stock'}.'份'];
  167. }
  168. }
  169. if (empty($shopping_info)) {
  170. if ($number <= 0){
  171. return ['code' => 0, 'msg' => '请选择数量'];
  172. }
  173. //入库
  174. $shopping = Shopping::create([
  175. 'm_id' => $m_id,
  176. 'type' => 1,
  177. 'shop_id' => $shop_id,
  178. 'category_id' => $category_id,
  179. 'goods_id' => $goods_id,
  180. 'goods_spec_id' => $goods_spec_id,
  181. 'number' => $number,
  182. ]);
  183. }else{
  184. if ($number <= 0){//数量为0直接删除
  185. $shopping = Shopping::where('id',$shopping_info->{'id'})->delete();
  186. }else{
  187. $shopping = Shopping::where('id',$shopping_info->{'id'})->update(['number' => $number]);
  188. }
  189. }
  190. if (empty($shopping)){
  191. return ['code' => 0, 'msg' => '添加失败'];
  192. }
  193. return ['code' => 1, 'msg' => '添加成功'];
  194. }
  195. /**
  196. * 删除购物车
  197. * @param $m_id
  198. * @param $shop_id
  199. * @return array
  200. */
  201. function delShopping($m_id,$shop_id)
  202. {
  203. //删除数据
  204. $where = [['m_id',$m_id], ['shop_id',$shop_id]];
  205. $res = Shopping::where($where)->delete();
  206. if (empty($res)){
  207. return ['code' => 0, 'msg' => '删除失败'];
  208. }
  209. return ['code' => 1, 'msg' => '删除成功'];
  210. }
  211. }