ShoppingCartServer.php 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531
  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. use App\Models\ShoppingDetail;
  8. use Illuminate\Support\Facades\DB;
  9. /**
  10. * 购物车服务
  11. */
  12. class ShoppingCartServer
  13. {
  14. static private $server = null;
  15. private $errorMsg = '';
  16. private function __construct()
  17. {
  18. }
  19. /**
  20. * 创建对象
  21. * @return ShoppingCartServer
  22. */
  23. static function creatServer()
  24. {
  25. if (empty(self::$server)) self::$server = new ShoppingCartServer();
  26. return self::$server;
  27. }
  28. /**
  29. * 获取购物车列表
  30. * @param $m_id
  31. * @param $shop_id
  32. * @return array
  33. */
  34. function getShoppingList($m_id,$shop_id)
  35. {
  36. //获取购物车商品数据
  37. $where = [['p.m_id',$m_id], ['p.shop_id',$shop_id], ['g.is_del',0], ['g.status',1]];
  38. $shopping = Shopping::from('shopping as p')
  39. ->leftJoin('goods as g','g.id','=','p.goods_id')
  40. ->where($where)
  41. ->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'])
  42. ->orderBy('p.id','asc')
  43. ->get();
  44. $total_num = 0;//总商品数
  45. $total_goods_money = '0.00';//总商品费用
  46. $total_pack_price = 0;//打包费
  47. $goods_list = [];//商品列表
  48. foreach ($shopping as $value){
  49. $goods_id = $value->{'goods_id'};//商品id
  50. $goods_price = $value->{'price'};//商品金额
  51. $goods_spec_price = 0;//商品规格金额
  52. $spec_type = $value->{'spec_type'};//商品类型
  53. $status_str = '';
  54. $goods_attr = "";//规则值
  55. $goods_number = $value['number'];//商品数量
  56. $goods_spec_list = [];//商品所选规格信息
  57. if ($spec_type == 2){//存在规格
  58. $details = ShoppingDetail::from('shopping_details as d')
  59. ->leftJoin('goods_spec as s','s.id','=','d.goods_spec_id')
  60. ->where('d.shopping_id',$value->{'shopping_id'})
  61. ->where('d.goods_id',$value->{'goods_id'})
  62. ->where('s.is_del',0)
  63. ->select(['d.id','d.goods_id','d.goods_spec_id','d.number','s.spec_name','s.spec_price'])
  64. ->get();
  65. foreach ($details as $detail){
  66. if ($detail->{'number'} > 1){
  67. $goods_attr .= $detail['spec_name'].'x'.$detail->{'number'} . ',';
  68. }else{
  69. $goods_attr .= $detail['spec_name'] . ',';
  70. }
  71. $goods_spec_price = bcadd($goods_spec_price,bcmul($detail['number'],$detail['spec_price'],2),2);//规格数量乘以价格等于 规格总价
  72. }
  73. $goods_spec_list = $details;
  74. }
  75. //计算价格
  76. $goods_money = bcmul($goods_number,bcadd($goods_price,$goods_spec_price,2),2);//商品价格等于 商品数量X(商品底价+商品规格总价)
  77. $goods_list[] = [
  78. 'shop_id' => $value['shop_id'],
  79. 'category_id' => $value['category_id'],
  80. 'goods_id' => $goods_id,
  81. 'goods_money' => rtrim(rtrim($goods_money, '0'),'.'),
  82. 'goods_number' => $goods_number,
  83. 'goods_name' => $value['goods_name'],
  84. 'goods_image' => $value['goods_image'],
  85. 'spec_type' => $value['spec_type'],
  86. 'price' => $goods_price,
  87. 'pack_price' => $value['pack_price'],
  88. 'goods_spec_id' => $value['goods_spec_id'],
  89. 'goods_attr' => trim($goods_attr,','),
  90. 'status_str' => $status_str,
  91. 'spec_list' => $goods_spec_list,
  92. ];
  93. //计算打包费
  94. $total_pack_price = bcadd($total_pack_price,bcmul($goods_number,$value['pack_price'],2),2);
  95. //计算总数量
  96. $total_num += $goods_number;
  97. //计算总商品费用
  98. $total_goods_money = bcadd($total_goods_money,$goods_money,2);
  99. }
  100. //订单总价-商品总价+总包装费
  101. $total_price = bcadd($total_goods_money,$total_pack_price,2);
  102. $data['total_price'] = rtrim(rtrim($total_price, '0'),'.');
  103. $data['total_num'] = (int)$total_num;
  104. $data['total_goods_money'] = rtrim(rtrim($total_goods_money, '0'),'.');
  105. $data['pack_price'] = $total_pack_price;
  106. $data['err_msg'] = $this->errorMsg;
  107. $data['goods_list'] = $goods_list;
  108. $this->errorMsg = '';
  109. return $data;
  110. }
  111. function saveShopping($m_id,$shop_id,$category_id,$goods_id,$goods_spec_id,$goods_spec,$number)
  112. {
  113. if (empty($goods_spec)){
  114. $goods_spec = [];
  115. }
  116. $goods_spec_ids = [];
  117. $goods_spec_data = [];
  118. //获取商品
  119. $goods = Goods::where('is_del',0)
  120. ->where('id',$goods_id)
  121. ->where('shop_id',$shop_id)
  122. ->where('category_id',$category_id)
  123. ->select(['id as goods_id','status','spec_type'])
  124. ->first();
  125. if (empty($goods)) return ['code' => 0, 'msg' => '当前商品不存在'];
  126. if ($goods->{'status'} != 1) return ['code' => 0, 'msg' => '当前商品已下架'];
  127. //如果是单规格但是选择了规格
  128. if ($goods->{'spec_type'} == 1 && !empty($goods_spec)){
  129. return ['code' => 0, 'msg' => '该商品没有规格'];
  130. }
  131. if (!empty($goods_spec)){
  132. foreach ($goods_spec as $spec){
  133. $spec_number = $spec['number'];
  134. $sku_id = GoodsSpec::where('goods_id',$goods_id)->where('id',$spec['id'])->where('is_del',0)->value('sku_id');
  135. if (empty($sku_id)){
  136. return ['code' => 0, 'msg' => '商品规格错误'];
  137. }
  138. $skuInfo = GoodsSku::where('goods_id',$goods_id)->where('id',$sku_id)->where('is_del',0)->first();
  139. if (empty($skuInfo)){
  140. return ['code' => 0, 'msg' => '商品规格不存在'];
  141. }
  142. if ($skuInfo->{'sku_type'} == 1){//商品只能单选
  143. $spec_number = 1;//单选购物数量只能为1
  144. }elseif ($skuInfo->{'sku_type'} == 2 && $skuInfo->{'affect_quantity'} == 0){//可多选规格但是不能多添加购物车数量
  145. $spec_number = 1;//数量只能为1
  146. }
  147. $goods_spec_ids[] = $spec['id'];
  148. $goods_spec_data[] = [
  149. 'id' => $spec['id'],
  150. 'number' => $spec_number,
  151. ];
  152. }
  153. sort($goods_spec_ids);
  154. $goods_spec_id = implode('_',$goods_spec_ids);
  155. }
  156. DB::beginTransaction();
  157. //获取购物车是否存在此商品
  158. $where = [['m_id',$m_id], ['shop_id',$shop_id], ['category_id',$category_id], ['goods_id',$goods_id]];
  159. if ($goods_spec_id) $where[] = ['goods_spec_id',$goods_spec_id];
  160. //查询此商品购物车数量
  161. $shopping_info = Shopping::where($where)->select(['id', 'goods_id', 'number'])->first();
  162. try {
  163. if (empty($shopping_info)) {//没购物车信息
  164. if ($number <= 0){
  165. DB::rollBack();
  166. return ['code' => 0, 'msg' => '请选择数量'];
  167. }
  168. //如果商品是多规格但是没选规格
  169. if ($goods->{'spec_type'} == 2 && empty($goods_spec)){
  170. return ['code' => 0, 'msg' => '请选择商品规格'];
  171. }
  172. //入库
  173. $shopping = Shopping::create([
  174. 'm_id' => $m_id,
  175. 'shop_id' => $shop_id,
  176. 'category_id' => $category_id,
  177. 'goods_id' => $goods_id,
  178. 'goods_spec_id' => $goods_spec_id,
  179. 'number' => $number,
  180. ]);
  181. $shopping_id = $shopping->{'id'};
  182. if (empty($shopping_id)) {
  183. DB::rollBack();
  184. return ['code' => 0, 'msg' => '操作失败'];
  185. }
  186. if (!empty($goods_spec_data)){//规则明细存入
  187. foreach ($goods_spec_data as $spec){
  188. ShoppingDetail::create([
  189. 'shopping_id' => $shopping_id,
  190. 'goods_id' => $goods_id,
  191. 'goods_spec_id' => $spec['id'],
  192. 'number' => $spec['number'],
  193. ]);
  194. }
  195. }
  196. }else{
  197. if ($number <= 0){//数量为0直接删除
  198. Shopping::where('id',$shopping_info->{'id'})->delete();//删除主表
  199. ShoppingDetail::where('shopping_id',$shopping_info->{'id'})->delete();//删除详情表
  200. }else{
  201. //如果存在购物车
  202. if (!empty($goods_spec)){//多规格商品
  203. $is_create = false;
  204. foreach ($goods_spec as $spec){
  205. $shopping_spec_number = ShoppingDetail::where('shopping_id',$shopping_info->{'id'})
  206. ->where('goods_id',$goods_id)
  207. ->where('goods_spec_id',$spec['id'])
  208. ->value('number');
  209. if ($shopping_spec_number != $spec['number']){
  210. $is_create = true;
  211. }
  212. }
  213. if ($is_create){//规格数量不一样,创建新的
  214. //入库
  215. $shopping = Shopping::create([
  216. 'm_id' => $m_id,
  217. 'shop_id' => $shop_id,
  218. 'category_id' => $category_id,
  219. 'goods_id' => $goods_id,
  220. 'goods_spec_id' => $goods_spec_id,
  221. 'number' => $number,
  222. ]);
  223. $shopping_id = $shopping->{'id'};
  224. if (empty($shopping_id)) {
  225. DB::rollBack();
  226. return ['code' => 0, 'msg' => '操作失败'];
  227. }
  228. if (!empty($goods_spec_data)){//规则明细存入
  229. foreach ($goods_spec_data as $spec){
  230. ShoppingDetail::create([
  231. 'shopping_id' => $shopping_id,
  232. 'goods_id' => $goods_id,
  233. 'goods_spec_id' => $spec['id'],
  234. 'number' => $spec['number'],
  235. ]);
  236. }
  237. }
  238. }else{//规格数量一样,在原来基础上增加
  239. Shopping::where('id',$shopping_info->{'id'})->increment('number',$number);
  240. }
  241. }else{
  242. Shopping::where('id',$shopping_info->{'id'})->update(['number' => $number]);
  243. }
  244. }
  245. }
  246. DB::commit();
  247. return ['code' => 1, 'msg' => '操作成功'];
  248. }catch (\Exception $e){
  249. DB::rollBack();
  250. return ['code' => 0, 'msg' => '操作失败'];
  251. }
  252. }
  253. // /**
  254. // * 添加购物车
  255. // * @param $m_id
  256. // * @param $shop_id
  257. // * @param $category_id
  258. // * @param $goods_id
  259. // * @param $goods_spec_id
  260. // * @param $number
  261. // * @return array
  262. // */
  263. // function saveShopping($m_id,$shop_id,$category_id,$goods_id,$goods_spec_id,$number)
  264. // {
  265. // if (empty($goods_spec_id)){
  266. // $goods_spec_id = '';
  267. // }
  268. // //获取商品
  269. // $goods = Goods::where('is_del',0)
  270. // ->where('id',$goods_id)
  271. // ->where('shop_id',$shop_id)
  272. // ->where('category_id',$category_id)
  273. // ->select(['id as goods_id','status','spec_type'])
  274. // ->first();
  275. // if (empty($goods)) return ['code' => 0, 'msg' => '当前商品不存在'];
  276. // if ($goods->{'status'} != 1) return ['code' => 0, 'msg' => '当前商品已下架'];
  277. // //如果是单规格但是选择了规格
  278. // if ($goods->{'spec_type'} == 1 && !empty($goods_spec_id)){
  279. // return ['code' => 0, 'msg' => '该商品没有规格'];
  280. // }
  281. // if (!empty($goods_spec_id)){
  282. // $sku_id = GoodsSpec::where('goods_id',$goods_id)->where('id',$goods_spec_id)->where('is_del',0)->value('sku_id');
  283. // if (empty($sku_id)){
  284. // return ['code' => 0, 'msg' => '商品规格错误'];
  285. // }
  286. // $skuInfo = GoodsSku::where('goods_id',$goods_id)->where('id',$sku_id)->where('is_del',0)->first();
  287. // if (empty($skuInfo)){
  288. // return ['code' => 0, 'msg' => '商品规格不存在'];
  289. // }
  290. // }
  291. // DB::beginTransaction();
  292. // try {
  293. // //获取购物车是否存在此商品
  294. // $where = [['m_id',$m_id], ['shop_id',$shop_id], ['category_id',$category_id], ['goods_id',$goods_id]];
  295. // //查询此商品购物车数量
  296. // $shopping_info = Shopping::where($where)->select(['id', 'goods_id', 'number'])->first();
  297. //
  298. // if (empty($shopping_info)) {//没用购物车信息
  299. // //如果商品是多规格但是没选规格
  300. // if ($goods->{'spec_type'} == 2 && empty($goods_spec_id)){
  301. // return ['code' => 0, 'msg' => '请选择商品规格'];
  302. // }
  303. // if ($number <= 0){
  304. // DB::rollBack();
  305. // return ['code' => 0, 'msg' => '请选择数量'];
  306. // }
  307. // //入库
  308. // $shopping = Shopping::create([
  309. // 'm_id' => $m_id,
  310. // 'shop_id' => $shop_id,
  311. // 'category_id' => $category_id,
  312. // 'goods_id' => $goods_id,
  313. // 'number' => $number,
  314. // ]);
  315. // $shopping_id = $shopping->{'id'};
  316. // if (empty($shopping_id)) {
  317. // DB::rollBack();
  318. // return ['code' => 0, 'msg' => '添加失败'];
  319. // }
  320. // //如果有规则就入库规则信息
  321. // if (!empty($goods_spec_id)){
  322. // if ($skuInfo->{'sku_type'} == 1){//商品只能单选
  323. // $number = 1;//单选购物数量只能为1
  324. // }elseif ($skuInfo->{'sku_type'} == 2 && $skuInfo->{'affect_quantity'} == 0){//可多选规格但是不能多添加购物车数量
  325. // $number = 1;//数量只能为1
  326. // }
  327. // ShoppingDetail::create([
  328. // 'shopping_id' => $shopping_id,
  329. // 'goods_id' => $goods_id,
  330. // 'goods_spec_id' => $goods_spec_id,
  331. // 'number' => $number,
  332. // ]);
  333. // }
  334. // }else{//有购物车信息,更新
  335. // $shopping_id = $shopping_info->{'id'};
  336. //
  337. // if (!empty($goods_spec_id)){//选择了规则就是更新购物车详情表
  338. // if ($number <= 0){//数量为0直接删除
  339. // ShoppingDetail::where('shopping_id',$shopping_info->{'id'})->where('goods_id',$goods_id)->where('goods_spec_id',$goods_spec_id)->delete();//删除详情表
  340. // }else{
  341. // //检查该规格信息是否讯息
  342. // $details = ShoppingDetail::where('shopping_id',$shopping_info->{'id'})->where('goods_id',$goods_id)->where('goods_spec_id',$goods_spec_id)->select(['id'])->first();
  343. //
  344. // if ($skuInfo->{'sku_type'} == 1){//商品只能单选
  345. // $number = 1;//单选购物数量只能为1
  346. // }elseif ($skuInfo->{'sku_type'} == 2 && $skuInfo->{'affect_quantity'} == 0){//可多选规格但是不能多添加购物车数量
  347. // $number = 1;//数量只能为1
  348. // }
  349. // if (empty($details)){
  350. // ShoppingDetail::create([
  351. // 'shopping_id' => $shopping_id,
  352. // 'goods_id' => $goods_id,
  353. // 'goods_spec_id' => $goods_spec_id,
  354. // 'number' => $number,
  355. // ]);
  356. // }elseif ($skuInfo->{'sku_type'} == 2 && $skuInfo->{'affect_quantity'} == 1){//可多选规格并且能多添加购物车数量
  357. // ShoppingDetail::where('shopping_id',$shopping_info->{'id'})->where('goods_id',$goods_id)->where('goods_spec_id',$goods_spec_id)->update(['number' => $number]);//跟新购物车
  358. // }
  359. // }
  360. // }else{//没选规则就是更新主表
  361. // if ($number <= 0){//数量为0直接删除
  362. // Shopping::where('id',$shopping_info->{'id'})->delete();//删除主表
  363. // ShoppingDetail::where('shopping_id',$shopping_info->{'id'})->delete();//删除详情表
  364. // }else{
  365. // Shopping::where('id',$shopping_info->{'id'})->update(['number' => $number]);
  366. // }
  367. // }
  368. //
  369. // }
  370. //
  371. //
  372. // DB::commit();
  373. // return ['code' => 1, 'msg' => '添加成功'];
  374. // }catch (\Exception $e){
  375. // DB::rollBack();
  376. // return ['code' => 0, 'msg' => '添加失败'];
  377. // }
  378. //
  379. // }
  380. /**
  381. * 删除购物车
  382. * @param $m_id
  383. * @param $shop_id
  384. * @return array
  385. */
  386. function delShopping($m_id,$shop_id)
  387. {
  388. //删除数据
  389. DB::beginTransaction();
  390. try {
  391. $where = [['m_id',$m_id], ['shop_id',$shop_id]];
  392. $shopping_info = Shopping::where($where)->select(['id', 'goods_id', 'number'])->get();
  393. foreach ($shopping_info as $v){
  394. Shopping::where('id',$v->{'id'})->delete();//删除主表
  395. ShoppingDetail::where('shopping_id',$v->{'id'})->delete();//删除详情表
  396. }
  397. DB::commit();
  398. return ['code' => 1, 'msg' => '删除成功'];
  399. }catch (\Exception $e){
  400. DB::rollBack();
  401. return ['code' => 0, 'msg' => '删除失败'];
  402. }
  403. }
  404. /**
  405. * 本地购物车数据组装获取
  406. * @param $cartInfo
  407. * @return array
  408. */
  409. function getCartList($cartInfo)
  410. {
  411. $total_num = 0;//总商品数
  412. $total_goods_money = '0.00';//总商品费用
  413. $total_pack_price = 0;//打包费
  414. $goods_list = [];
  415. foreach ($cartInfo['goods_list'] as $value){
  416. $goods = Goods::where('id',$value['goods_id'])
  417. ->select(['id as goods_id','shop_id','status','goods_name','goods_image','price','spec_type','category_id','pack_price'])
  418. ->orderBy('id','asc')
  419. ->first();
  420. if (empty($goods)){
  421. return ['code' => 0, 'msg' => '商品不存在'];
  422. }
  423. if ($goods->{'status'} != 1){
  424. return ['code' => 0, 'msg' => '商品已下架'];
  425. }
  426. $goods_price = $goods->{'price'};//商品价格
  427. $goods_number = $value['goods_number'];//商品购买数量
  428. $goods_spec_list = [];
  429. $goods_spec_price = 0;
  430. $goods_attr = '';
  431. if ($goods->{'spec_type'} == 2 && !empty($value['goods_spec'])){//存在规格
  432. foreach ($value['goods_spec'] as $spec){
  433. $specInfo = GoodsSpec::where('goods_id',$value['goods_id'])
  434. ->where('id',$spec['id'])
  435. ->where('is_del',0)
  436. ->select(['spec_name','spec_price'])
  437. ->first();
  438. if (empty($specInfo)){
  439. return ['code' => 0, 'msg' => '规则不存在'];
  440. }
  441. if ($spec['number'] > 1){
  442. $goods_attr .= $specInfo['spec_name'].'x'.$spec['number'] . ',';
  443. }else{
  444. $goods_attr .= $specInfo['spec_name'] . ',';
  445. }
  446. $goods_spec_price = bcadd($goods_spec_price,bcmul($spec['number'],$specInfo['spec_price'],2),2);//规格数量乘以价格等于 规格总价
  447. $goods_spec_list[] = [
  448. 'goods_id' => $value['goods_id'],
  449. 'goods_spec_id' => $spec['id'],
  450. 'spec_price' => $specInfo['spec_price'],
  451. 'spec_name' => $specInfo['spec_name'],
  452. 'number' => $spec['number'],
  453. ];
  454. }
  455. }
  456. //计算价格
  457. $goods_money = bcmul($goods_number,bcadd($goods_price,$goods_spec_price,2),2);//商品价格等于 商品数量X(商品底价+商品规格总价)
  458. $goods_list[] = [
  459. 'shop_id' => $goods['shop_id'],
  460. 'category_id' => $goods['category_id'],
  461. 'goods_id' => $goods['goods_id'],
  462. 'goods_money' => rtrim(rtrim($goods_money, '0'),'.'),
  463. 'goods_number' => $goods_number,
  464. 'goods_name' => $goods['goods_name'],
  465. 'goods_image' => $goods['goods_image'],
  466. 'spec_type' => $goods['spec_type'],
  467. 'price' => $goods_price,
  468. 'pack_price' => $goods['pack_price'],
  469. 'goods_spec_id' => $goods['goods_spec_id'],
  470. 'goods_attr' => trim($goods_attr,','),
  471. 'spec_list' => $goods_spec_list,
  472. ];
  473. //计算打包费
  474. $total_pack_price = bcadd($total_pack_price,bcmul($goods_number,$goods['pack_price'],2),2);
  475. //计算总数量
  476. $total_num += $goods_number;
  477. //计算总商品费用
  478. $total_goods_money = bcadd($total_goods_money,$goods_money,2);
  479. }
  480. //订单总价-商品总价+总包装费
  481. $total_price = bcadd($total_goods_money,$total_pack_price,2);
  482. $data['total_price'] = rtrim(rtrim($total_price, '0'),'.');
  483. $data['total_num'] = (int)$total_num;
  484. $data['total_goods_money'] = rtrim(rtrim($total_goods_money, '0'),'.');
  485. $data['pack_price'] = $total_pack_price;
  486. $data['goods_list'] = $goods_list;
  487. return ['code' => 1, 'msg' => '成功', 'data'=>$data];
  488. }
  489. }