OrderServer.php 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. <?php
  2. namespace App\Servers;
  3. use App\Models\Config;
  4. use App\Models\ErrorRecord;
  5. use App\Models\Goods;
  6. use App\Models\Order;
  7. use App\Models\OrderItem;
  8. use Carbon\Carbon;
  9. use Illuminate\Support\Facades\DB;
  10. /**
  11. * 外卖订单管理
  12. */
  13. class OrderServer
  14. {
  15. static private $server = null;
  16. private function __construct()
  17. {
  18. }
  19. /**
  20. * 创建对象
  21. * @return OrderServer
  22. */
  23. static function creatServer()
  24. {
  25. if (empty(self::$server)) self::$server = new OrderServer();
  26. return self::$server;
  27. }
  28. function createOrder($m_id,$shop_id,$order_type,$table_number,$diner_number,$note,$goods_data)
  29. {
  30. DB::beginTransaction();
  31. try {
  32. //手续费比例
  33. $service_num = CommonServer::creatServer()->getConfigValue('service_num');
  34. if (empty($service_num)) {
  35. $service_num = 0.6;
  36. }
  37. //商品金额
  38. $goods_money = $goods_data['total_goods_money'];//商品总价
  39. $goods_number = $goods_data['total_num'];//商品总数
  40. $pack_price = $goods_data['pack_price'];//打包费
  41. $order_money = bcadd($goods_money, $pack_price, 2);//订单金额 =(商品金额 + 打包费)
  42. //预留优惠卷金额
  43. $coupon_money = 0;
  44. //用户支付金额=订单金额 - 优惠卷金额
  45. $pay_money = bcsub($order_money,$coupon_money,2);
  46. $service_money = bcdiv(bcmul($pay_money,$service_num,2),100,2);//交易支付手续费
  47. //商家到账金额 = 订单金额-交易支付手续费
  48. $shop_money = bcsub($order_money,$service_money,2);
  49. //信息入库
  50. $order_info = [
  51. 'order_sn' => CommonServer::creatServer()->createOrderNo('WDO'),
  52. 'order_type' => $order_type,
  53. 'm_id' => $m_id,
  54. 'shop_id' => $shop_id,
  55. 'order_money' => $order_money,
  56. 'pay_money' => $pay_money,
  57. 'goods_number' => $goods_number,
  58. 'table_number' => $table_number,
  59. 'diner_number' => $diner_number,
  60. 'note' => $note,
  61. 'service_num' => $service_num,
  62. 'service_money' => $service_money,
  63. 'pack_price' => $pack_price,
  64. 'shop_money' => $shop_money,
  65. ];
  66. //主表信息入库
  67. $order = Order::create($order_info);
  68. $order_id = $order->{'id'};
  69. if (empty($order_id)){
  70. DB::rollBack();
  71. return ['code' => 0, 'msg' => '订单创建失败'];
  72. }
  73. //商品信息入库
  74. $goods_total_money = 0;//商品总金额
  75. foreach ($goods_data['goods_list'] as $goods){
  76. if ($shop_id != $goods['shop_id']){
  77. DB::rollBack();
  78. return ['code' => 0, 'msg' => '商品与商家不符'];
  79. }
  80. $goods_info = [
  81. 'm_id' => $m_id,
  82. 'shop_id' => $shop_id,
  83. 'order_id' => $order_id,
  84. 'goods_id' => $goods['goods_id'],
  85. 'goods_spec_id' => empty($goods['goods_spec_id']) ? '' : $goods['goods_spec_id'],
  86. 'goods_name' => $goods['goods_name'],
  87. 'goods_img' => $goods['goods_image'],
  88. 'goods_attr' => trim($goods['goods_attr'],','),
  89. 'goods_price' => $goods['price'],
  90. 'goods_number' => $goods['goods_number'],
  91. 'goods_money' => $goods['goods_money'],
  92. ];
  93. //总商品金额
  94. $goods_total_money = bcadd($goods_total_money,$goods_info['goods_money'],2);
  95. //商品没有设置无限库存,扣减库存
  96. if ($goods['is_infinite'] != 1){
  97. $goodsStock = Goods::where('id',$goods_info['goods_id'])->select(['id','stock'])->first();
  98. if (empty($goodsStock)){
  99. DB::rollBack();
  100. return ['code' => 0, 'msg' => '商品不存在'];
  101. }
  102. //剩余库存
  103. $surplus_stock = bcsub($goodsStock->{'stock'},$goods_info['goods_number']);
  104. if ($surplus_stock < 0){
  105. DB::rollBack();
  106. return ['code' => 0, 'msg' => $goods_info['goods_name'].'商品库存不足'];
  107. }
  108. $update['stock'] = $surplus_stock;
  109. if ($surplus_stock <= 0){//设置商品售罄
  110. $update['status'] = 3;
  111. }
  112. Goods::where('id',$goods_info['goods_id'])->update($update);
  113. }
  114. OrderItem::create($goods_info);
  115. }
  116. //删除购物车
  117. $shopping = ShoppingCartServer::creatServer()->delShopping($m_id,$shop_id);
  118. if ($shopping['code'] == 0){
  119. DB::rollBack();
  120. return ['code' => 0, 'msg' => '下单失败'];
  121. }
  122. DB::commit();
  123. return ['code' => 1, 'msg' => '成功', 'data' => ['order_id'=>$order_id]];
  124. }catch (\Exception $e){
  125. DB::rollBack();
  126. return ['code'=>0,'msg'=>'下单出错'];
  127. }
  128. }
  129. /**
  130. * 支付回调
  131. * @param $pay_type
  132. * @param $order_sn
  133. * @param $pay_code
  134. * @param $pay_money
  135. * @param $notify_info
  136. * @return bool
  137. */
  138. function NotifyPay($pay_type,$order_sn, $pay_code, $pay_money, $notify_info)
  139. {
  140. $order_info = Order::where('order_sn', $order_sn)->where('order_status', 1)->first();
  141. if (empty($order_info)) {
  142. ErrorRecord::create(['msg' => $order_sn . '订单支付状态错误', 'data' => serialize($notify_info)]);
  143. return false;
  144. }
  145. // $is_test = env('TEST_SERVE', false);
  146. $is_test=config('weixin.test_serve',false);
  147. if ($order_info->{'pay_money'} != $pay_money && !$is_test) {
  148. Order::where('id', $order_info->{'id'})->update(['pay_code' => $pay_code]);
  149. ErrorRecord::create(['msg' => $order_info->{'order_sn'} . '支付金额不匹配', 'data' => serialize($notify_info)]);
  150. return false;
  151. }
  152. $date = date('Y-m-d H:i:s');
  153. $shop_id = $order_info->{'shop_id'};
  154. //店铺订单序号生成
  155. $key = $shop_id . '_number';
  156. $total_count = RedisDataServer::creatServer()->getData($key);
  157. if (empty($total_count)){
  158. $total_count = '1';
  159. // 获取当前时间戳
  160. $now = time();
  161. // 获取今天结束的时间戳
  162. $endOfDay = strtotime("tomorrow") - 1;
  163. // 计算剩余时间(秒)
  164. $secondsLeft = bcsub($endOfDay,$now,1);
  165. RedisDataServer::creatServer()->setData($key,$total_count,'str',$secondsLeft);
  166. }
  167. RedisDataServer::creatServer()->setIncr($key);
  168. //订单更新信息
  169. $update['pay_type'] = $pay_type;
  170. $update['pay_time'] = $date;
  171. $update['pay_code'] = $pay_code;
  172. $update['number'] = $total_count;
  173. $update['order_status'] = 2;
  174. //更新订单信息
  175. Order::where('id', $order_info->{'id'})->update($update);
  176. // 投递打印消息
  177. JobServer::creatServer()->shopOrderPrintJob($order_info->{'id'},$order_info->{'shop_id'});
  178. return true;
  179. }
  180. }