ScratchOrderLogic.php 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. <?php
  2. namespace addons\Scratch\common\logic;
  3. use addons\Coupon\common\models\AddonsCouponUserRelate;
  4. use addons\Scratch\common\enums\ScratchEnum;
  5. use addons\Scratch\common\models\ScratchLogModel;
  6. use addons\Scratch\common\models\ScratchOrderModel;
  7. use common\enums\OrderStatusEnum;
  8. use common\enums\RedisKeyEnum;
  9. use common\events\order\OrderCreateEvent;
  10. use common\helpers\LockHelper;
  11. use common\models\cart\Cart;
  12. use common\models\goods\GoodsAttr;
  13. use common\models\order\Order;
  14. use common\models\order\OrderDetail;
  15. use common\models\order\OrderMarketing;
  16. use Yii;
  17. use Exception;
  18. /**
  19. * Class ScratchOrderLogic
  20. * @package addons\Scratch\common\logic
  21. */
  22. class ScratchOrderLogic
  23. {
  24. /**
  25. * @param $form
  26. * @param $scratchLog
  27. * @return array|false
  28. * @throws \yii\db\Exception
  29. */
  30. public static function createOrder($form, $scratchLog){
  31. $stock_locks = [];
  32. try{
  33. $group_order_goods = $form['group_order_goods'];
  34. $trans = Yii::$app->db->beginTransaction();
  35. $attr = [];
  36. $order_trade_info = [];
  37. $order_ids = [];
  38. foreach($group_order_goods as $mch_order){
  39. $mch_order_info = $mch_order['mch_order_info'];
  40. $mch_order_info['goods_price'] = 0;
  41. $mch_order_info['pay_money'] = $mch_order_info['shipping_money'];
  42. $mch_order_info['marketing_type'] = ScratchEnum::ADDONS_NAME;
  43. $order = new Order();
  44. $order->loadDefaultValues();
  45. $order->load($mch_order_info,'');
  46. $order->order_status = OrderStatusEnum::NOT_PAY;
  47. empty($order->order_no) && $order->order_no = Order::generateOrderNo('s');
  48. /**
  49. * 创建中奖兑换订单日志
  50. */
  51. $scratchOrder = ScratchOrderModel::setData([
  52. 'mall_id' => $order->mall_id,
  53. 'scratch_log_id' => $scratchLog->id,
  54. 'order_id' => 0
  55. ]);
  56. $order->marketing_id = $scratchOrder->id;
  57. $res = $order->save();
  58. if($res === false) throw new Exception($order->getErrorMessage());
  59. $scratchOrder->order_id = $order->id;
  60. if(!$scratchOrder->save()) throw new Exception($scratchOrder->getErrorMessage());
  61. $order_id = $order->id;
  62. $order_ids[] = $order->id;
  63. // 总商品库存维护
  64. $goods_stock_arr = [];
  65. // 遍历商户商品
  66. $goods_ids = array_keys($mch_order['goods']);
  67. foreach($mch_order['goods'] as $goods_id =>$goods){
  68. $goods['goods_price'] = 0;
  69. !isset($goods_name) && $goods_name = $goods['goods_name'];
  70. foreach($goods['goods_details'] as $goods_detail){
  71. // $goods_detail['goods_price'] = 0;
  72. $lock_key = RedisKeyEnum::suffix(RedisKeyEnum::LOCK_GOODS_ATTR , $goods_detail['goods_attr_id']);
  73. $identification = uniqid();
  74. if (!LockHelper::lock($lock_key, $identification, 30, 60)) throw new Exception('当前访问人数过多');
  75. $stock_locks[$lock_key] = $identification;
  76. //操作商品库存-减
  77. GoodsAttr::handleStock($goods_detail['goods_attr_id'],$goods_detail['num']*-1);
  78. if(!isset($goods_stock_arr[$goods_id])){
  79. $goods_stock_arr[$goods_id] = $goods_detail['num'];
  80. }else{
  81. $goods_stock_arr[$goods_id] += $goods_detail['num'];
  82. }
  83. // 订单详情
  84. $order_detail = new OrderDetail();
  85. $order_detail->loadDefaultValues();
  86. $order_detail->load($goods_detail,'');
  87. $order_detail->order_id = $order_id;
  88. // $goods_statistics[] = ['goods_id' => $goods_detail['goods_id'], 'order_num' => 1, 'sales_num' => $goods_detail['num']];
  89. $res = $order_detail->save();
  90. if($res === false) throw new Exception($order_detail->getErrorMessage());
  91. $attr[$goods_detail['goods_attr_id']] = $goods_detail['num'];
  92. // 订单营销
  93. if (!empty($goods_detail['marketing'])) {
  94. $order_marketing = new OrderMarketing();
  95. $order_marketing->loadDefaultValues();
  96. $order_marketing->load($goods_detail['marketing'],'');
  97. $order_marketing->order_detail_id = $order_detail->id;
  98. $res = $order_marketing->save();
  99. if($res === false) throw new Exception($order_marketing->getErrorMessage());
  100. }
  101. }
  102. }
  103. $data = is_array($form->data)?$form->data:Json::decode($form->data,true);
  104. if(!empty($data['user_coupon_ids'])){
  105. $user_coupon_id = $data['user_coupon_ids'];
  106. $res = AddonsCouponUserRelate::updateAll(['is_use'=>1], ['id' => $user_coupon_id]);
  107. if($res === false) throw new Exception($order->getErrorMessage());
  108. }
  109. $order_trade_info[]=[
  110. 'order_no'=>$order->order_no,
  111. 'amount'=>$order->pay_money,
  112. 'title'=> Order::getOrderTitle($order),
  113. 'notify_class'=>'common\logic\notify\Notify',
  114. 'order_type'=>'order',
  115. ];
  116. }
  117. /**
  118. * 更新中奖日志状态
  119. */
  120. $scratchLog->status = ScratchLogModel::STATUS_RECEIVED;
  121. if(!$scratchLog->save()) throw new Exception($scratchLog->getErrorMessage());
  122. $trans->commit();
  123. LockHelper::batchUlock($stock_locks);
  124. //生成支付流水
  125. $res = \Yii::$app->services->pay->createTrade($form['mall_id'],$form['user_id'],$order_trade_info);
  126. if($res==false) throw new Exception('生成支付流水失败');
  127. Order::updateAll(['out_trade_no'=>$res['trade_no']],['id'=>$order_ids]);
  128. // 触发订单添加事件,事务提交完成后触发
  129. $event = new OrderCreateEvent($form['mall_id']);
  130. Yii::$app->services->events->dispatch($event, ['order_ids' => $order_ids], $event->listeners);
  131. //删除购物车
  132. if ($form->type == 'cart') Cart::decreaseNumb(['user_id' => $form->user_id, 'list' => $attr]);
  133. $res['order_ids'] = implode(',', $order_ids);
  134. $arr['transaction'] = $res;
  135. $arr['pay_success_page'] = Yii::$app->services->setting->mall->get($form['mall_id'], 'order.pay_after_link');// 支付成功后跳转的地址
  136. return $arr;
  137. }catch(Exception $e){
  138. LockHelper::batchUlock($stock_locks);
  139. if(isset($trans)) $trans->rollback();
  140. self::$static_error = $e->getMessage();
  141. return false;
  142. }
  143. }
  144. }