first(); ThrowException::isTrue($od->type != OrderType::FADAN, '请在跟单大厅中跟单'); ThrowException::isTrue(!$od->canCopy(), '已无法跟单,请选择大厅中的其他跟单'); $jingcaiService = LotteryService::getJingcaiServiceByOrder($od); return $jingcaiService->copyOrder($customer, $od, $data); } /** * 创建订单 * @param $data * @param \App\Model\Customer\Customer $customer * @return Order * @throws \Throwable */ public function create($data, Customer $customer) { $lotteryTypeId = Arr::get($data, 'lottery_type_id'); $lotteryType = LotteryType::find($lotteryTypeId); ThrowException::isTrue(!$lotteryType, '暂不支持该彩种'); $jingcaiService = LotteryService::getJingcaiService($lotteryType->type); return $jingcaiService->createOrder($customer, $data); } /** * 设置订单为支付成功状态 * @param Order $order * @throws \Throwable */ public function setOrderPaySuccess(Order $order) { // 参与合买的订单支付 if ($order->type == OrderType::UNION && $order->pid != $order->id) { $this->setUnionOrderPaySuccess($order); return; } try { DB::beginTransaction(); /** @var Order $order */ $order = Order::lockForUpdate()->find($order->id); if ($order->pay_state != PayState::UNPAID) { JingCaiException::throwJingcai('订单错误,请重新下单'); } CustomerWalletService::buyLottery($order); // 修改订单支付状态 $order->setSuccess(); DB::commit(); } catch (JingCaiException $exception) { DB::rollBack(); throw $exception; } catch (\Exception $exception) { DB::rollBack(); throw $exception; } } /** * 参与合买的流程 * 设置订单为支付成功状态 * @param Order $order * @throws \Throwable */ public function setUnionOrderPaySuccess(Order $order) { try { DB::beginTransaction(); /** @var Order $unionOrder */ $unionOrder = Order::lockForUpdate()->find($order->pid); if (date('Y-m-d H:i:s') > $unionOrder->odds_early_close_time) { ThrowException::run('订单已截止!'); } /** @var Order $order */ $order = Order::lockForUpdate()->find($order->id); if ($order->pay_state != PayState::UNPAID) { JingCaiException::throwJingcai('订单错误,请重新下单'); } // ThrowException::isTrue($order->customer_id == $unionOrder->customer_id, '发起者不能参与合买'); $remainPiece = $unionOrder->union_piece_total - $unionOrder->union_piece_buy - $order->union_piece_self; ThrowException::isTrue($remainPiece < 0, '剩余份数不总,无法支付'); // 更新订单的购买份数 $unionOrder->union_piece_buy += $order->union_piece_self; // 如果合买已完成,则更新合买完成状态 if ($unionOrder->union_piece_total == $unionOrder->union_piece_buy) { $unionOrder->union_pay_success = BoolEnum::YES; } $unionOrder->save(); CustomerWalletService::buyLottery($order); // 修改订单支付状态 $order->setSuccess(); DB::commit(); } catch (JingCaiException $exception) { DB::rollBack(); throw $exception; } catch (\Exception $exception) { DB::rollBack(); throw $exception; } } public function sellerThrowCooperate(Seller $seller, $orderSn) { /** @var Order $order */ $order = Order::sn($orderSn)->first(); ThrowException::isTrue(!$order, '订单不存在'); ThrowException::isTrue($order->shop_id != $seller->shop_id, '无法跨店甩单'); ThrowException::isTrue($order->lottery_state != LottState::PENDING, '订单状态不对,无法接单'); ThrowException::isTrue($order->type == OrderType::UNION, '合作模式不支持合买'); ThrowException::isTrue($order->cooperate_id <= 0 || $order->cooperate_id == $seller->shop_id, '该订单不是合作店铺模式产生的'); /** @var Lottery $lottery */ $lottery = $order->lottery; $scl = $lottery->shopCooperateLottery; ThrowException::isTrue(!$scl, '该订单对应的彩种没有开启合作店铺'); $order->cooperate_throw_seller_id = $seller->id; $order->cooperate_show = BoolEnum::YES; $order->save(); } protected function cooperateOrderValid(Seller $seller, Order $order) { /** @var Lottery $lottery */ $lottery = $order->lottery; // 本店铺操作 if ($order->shop_id == $seller->shop_id) { ThrowException::isTrue($lottery->owned == BoolEnum::NO, '本店无此彩种,无法操作'); } else { // 合作店铺操作 ThrowException::isTrue($lottery->cooperate_id <= 0, '不是合作订单,无法操作'); $scl = $lottery->shopCooperateLottery; ThrowException::isTrue(!$scl || $scl->cooperate_id != $seller->shop_id, '该订单未与本店铺合作,无法操作'); } } public function sellerReceive(Seller $seller, $orderSn) { $order = Order::sn($orderSn)->first(); ThrowException::isTrue(!$order, '订单不存在'); ThrowException::isTrue($order->lottery_state != LottState::PENDING, '订单状态不对,无法接单'); $this->cooperateOrderValid($seller, $order); if ($order->type == OrderType::UNION) { ThrowException::isTrue($order->id != $order->pid, '订单有误,无法接单'); ThrowException::isTrue($order->union_piece_total > $order->union_piece_buy + $order->union_piece_keep, '合买未完成,无法接单'); } // 刷新彩票信息,更新订单状态 $jingcaiService = LotteryService::getJingcaiServiceByOrder($order); if ($jingcaiService instanceof JclqService) { $oddsInfo = $jingcaiService->refreshOdds($order->odds); $odds = $oddsInfo['odds']; $oddsRaw = $oddsInfo['odds_raw']; } else { $odds = $jingcaiService->refreshOdds($order->odds); $oddsRaw = null; } $order->odds = $odds; $order->odds_raw = $oddsRaw; $order->receive_user_id = $seller->id; $order->receive_at = date('Y-m-d H:i:s'); $order->receive_date = date('Ymd'); $order->lottery_state = LottState::DRAFT; $order->save(); $order->updateUnionOrderState(LottState::DRAFT); } public function sellerRevoke(Seller $seller, $orderSn,$revokeMessage = '') { $order = Order::sn($orderSn)->first(); ThrowException::isTrue(!$order, '订单不存在'); ThrowException::isTrue($order->lottery_state != LottState::DRAFT, '订单状态不对,无法撤单'); // ThrowException::isTrue($order->shop_id != $seller->shop_id, '无法跨店撤单'); $this->cooperateOrderValid($seller, $order); if ($order->type == OrderType::UNION && $order->id != $order->pid) { ThrowException::run('订单有误,无法撤单'); } DB::beginTransaction(); try { $order->revoke_user_id = $seller->id; $order->revoke_at = date('Y-m-d H:i:s'); $order->revoke_message = $revokeMessage; $order->lottery_state = LottState::REVOKE; $order->save(); $order->updateUnionOrderState(LottState::REVOKE); CustomerWalletService::refundForRevokeOrder($order, $seller); DB::commit(); } catch (\Exception $exception) { DB::rollBack(); throw $exception; } } public function sellerUploadPiao(Seller $seller, $orderSn, $materialIds) { ThrowException::isTrue(!$materialIds, '请上传图片'); $order = Order::sn($orderSn)->first(); ThrowException::isTrue(!$order, '订单不存在'); $this->cooperateOrderValid($seller, $order); Material::where('order_id', $order->id)->delete(); Material::whereIn('id', $materialIds) ->where('scene', MaterialScene::LOTTERY) ->where('order_id', 0) ->update(['order_id' => $order->id]); } public function sellerDraw(Seller $seller, $orderSn, $materialIds, $oddses) { ThrowException::isTrue(!$materialIds, '请上传图片'); $order = Order::sn($orderSn)->first(); ThrowException::isTrue(!$order, '订单不存在'); ThrowException::isTrue($order->lottery_state != LottState::DRAFT, '订单状态不对,无法出票'); ThrowException::isTrue(!$order->sameToReceiver($seller->id), '无出票权限'); $this->cooperateOrderValid($seller, $order); DB::beginTransaction(); try { // 出票相关账单 SellerWalletService::ticket($order, $seller); // 刷新彩票信息,更新订单状态 $jingcaiService = LotteryService::getJingcaiServiceByOrder($order); $order = Order::lockForUpdate()->find($order->id); $orderOdds = $order->odds; if ($oddses) { // 更新赔率 foreach ($oddses as $id => $oddItem) { foreach ($oddItem as $oddPlay => $playData) { foreach ($playData as $play => $oddval) { if (Arr::get($orderOdds, $id. '.'. $oddPlay. '.' . $play) !== null) { $orderOdds[$id][$oddPlay][$play] = $oddval; } } } } $order->odds = $orderOdds; } $computeInfo = $jingcaiService->computePrizeInfo($order->odds, $order->bets_num, $order->pass_mode); if ($computeInfo && Arr::get($computeInfo, 'prize_min') !== null) { $order->prize_min = Arr::get($computeInfo, 'prize_min'); } if ($computeInfo && Arr::get($computeInfo, 'prize_max') !== null) { $order->prize_max = Arr::get($computeInfo, 'prize_max'); } $order->lottery_state = LottState::WAIT; $order->draft_at = date('Y-m-d H:i:s'); $order->draft_date = date('Ymd'); $order->draft_user_id = $seller->id; $order->draft_shop_id = $seller->shop_id; $order->save(); $order->updateUnionOrderState(LottState::WAIT); DB::commit(); // 发送出票事件 OrderTicketedEvent::dispatch($order->id); } catch (JingCaiException $exception) { DB::rollBack(); throw $exception; } catch (\Exception $exception) { DB::rollBack(); throw $exception; } Material::whereIn('id', $materialIds) ->where('scene', MaterialScene::LOTTERY) ->where('order_id', 0) ->update(['order_id' => $order->id]); } public function sellerSendPrize(Seller $seller, $orderSn, $sendPrize) { $order = Order::sn($orderSn)->first(); ThrowException::isTrue(!$order, '订单不存在'); ThrowException::isTrue($order->lottery_state != LottState::WIN, '订单状态不对,无法派奖'); $this->cooperateOrderValid($seller, $order); ThrowException::isTrue($sendPrize <= 0, '奖金有误'); if ($order->type == OrderType::UNION) { return $this->sellerSendUnionPrize($seller, $order, $sendPrize); } if ($order->type == OrderType::GENDAN) { return $this->sellerSendGendanPrize($seller, $order, $sendPrize);; } return $this->sellerSendNormalPrize($seller, $order, $sendPrize); } public function sellerTakeTicket(Seller $seller, $orderSn) { $order = Order::sn($orderSn)->first(); ThrowException::isTrue(!$order, '订单不存在'); ThrowException::isTrue($order->lottery_take_ticket != BoolEnum::NO, '不可重复取票'); ThrowException::isTrue($order->lottery->shop_id != $seller->shop_id, '无法跨店取票'); $this->cooperateOrderValid($seller, $order); $order->lottery_take_ticket = BoolEnum::YES; $order->save(); } /** * 派奖:合买 * @param $seller * @param $order * @param $sendPrize * @throws \Exception */ private function sellerSendUnionPrize($seller, $order, $sendPrize) { if ($order->type == OrderType::UNION && $order->id != $order->pid) { ThrowException::run('该合买参与订单不可派奖!'); } DB::beginTransaction(); try { $unionBrokerageLv = 0; // 如果设置了合买佣金 if ($order->union_brokerage) { $unionBrokerageLv = $order->union_brokerage / 100; } $unionBrokerage = $order->lottery_should_send_prize * $unionBrokerageLv; // 合买主单的数据 $order->lottery_state = LottState::SEND; $order->lottery_send_prize = $sendPrize; $order->send_user_id = $seller->id; $order->send_at = date('Y-m-d H:i:s'); $order->send_date = date('Ymd'); $order->union_brokerage_money = $unionBrokerage; $order->save(); if ($order->union_brokerage && $unionBrokerage > 0) { // 合买佣金 CustomerWalletService::unionBrokerage($order, $unionBrokerage); } $perShouldPrize = ($order->lottery_should_send_prize - $unionBrokerage) / $order->union_piece_total; $perPrize = ($sendPrize - $unionBrokerage) / $order->union_piece_total; // 合买参与人的数据 $unionOrders = Order::where('type', OrderType::UNION) ->where('pay_state', PayState::SUCCESS) ->where('pid', $order->id)->get(); foreach ($unionOrders as $unionOrder) { $buyPiece = $unionOrder->union_piece_self; if ($unionOrder->id == $unionOrder->pid) { $buyPiece = $unionOrder->union_piece_self + $unionOrder->union_piece_keep; } $unionOrder->union_send_prize = $perPrize * $buyPiece; $unionOrder->union_should_send_prize = $perShouldPrize * $buyPiece; $unionOrder->lottery_state = LottState::SEND; $unionOrder->save(); // 中奖 CustomerWalletService::winPrize($unionOrder, $unionOrder->union_send_prize); } DB::commit(); } catch (JingCaiException $exception) { DB::rollBack(); throw $exception; } catch (\Exception $exception) { DB::rollBack(); throw $exception; } return; } /** * 跟单中奖100元后,各个环节账单流水: * * 跟单人: * +100 奖金 * -10 跟单佣金 * * 跟单人店铺: * -10 平台扣除佣金 * * 跟单人店铺: * +2 平台派发佣金 * * 发单人店铺: * +6 发单佣金 * * 发单人账户余额: * +6 * 派奖:跟单 * @param $seller * @param $order * @param $sendPrize 奖金扣除跟单佣金后的金额 * @throws \Exception */ private function sellerSendGendanPrize($seller, $order, $sendPrize) { DB::beginTransaction(); try { $order = Order::lockForUpdate()->find($order->id); $winPrize = $sendPrize; $allBrokerage = $winPrize * Config::fadanAllFeeLv(); $userBroerage = $allBrokerage * Config::fadanUserFeeLv(); // 跟单中奖 $order->send_user_id = $seller->id; $order->send_at = date('Y-m-d H:i:s'); $order->send_date = date('Ymd'); $order->lottery_state = LottState::SEND; $order->lottery_send_prize = $winPrize; $order->lottery_gendan_brokerage = $userBroerage; $order->lottery_gendan_brokerage_all = $allBrokerage; $order->save(); // if (!$order->isTakeTicket()) { SellerWalletService::cooperateOrderWined($seller, $order); // -------跟单用户 start // 跟单中奖 CustomerWalletService::winPrize($order, $sendPrize); // 扣除跟单佣金 CustomerWalletService::gendanReduceBrokerage($order); // -------跟单用户 end // } // -------跟单店铺 start // 跟单人店铺扣除所有发单佣金 SellerWalletService::gendanShopReduceAllBrokerage($seller, $order, $sendPrize); // 跟单人店铺增加部分佣金 SellerWalletService::gendanShopIncrBrokerage($seller, $order, $sendPrize); // -------跟单店铺 end // 发单人店铺增加佣金 $pOrder = $order->pOrder; SellerWalletService::fadanShopIncrBrokerage($order, $pOrder->shop_id, $sendPrize); // 发单人余额增加佣金 CustomerWalletService::fadanBrokerage($order, $pOrder->customer_id, $sendPrize); DB::commit(); } catch (JingCaiException $exception) { DB::rollBack(); throw $exception; } catch (\Exception $exception) { DB::rollBack(); throw $exception; } } /** * 派奖:下注 * @param $seller * @param $order * @param $sendPrize * @throws \Exception */ private function sellerSendNormalPrize($seller, $order, $sendPrize) { DB::beginTransaction(); try { $order->send_user_id = $seller->id; $order->send_at = date('Y-m-d H:i:s'); $order->send_date = date('Ymd'); $order->lottery_state = LottState::SEND; $order->lottery_send_prize = $sendPrize; $order->save(); // if (!$order->isTakeTicket()) { SellerWalletService::cooperateOrderWined($seller, $order); CustomerWalletService::winPrize($order, $sendPrize); // } DB::commit(); } catch (JingCaiException $exception) { DB::rollBack(); throw $exception; } catch (\Exception $exception) { DB::rollBack(); throw $exception; } } }