jingcai-php/app/Service/CtzqSfc14Service.php

453 lines
15 KiB
PHP
Executable File

<?php
/**
* @createtime 2023/6/29
* @author wild
* @copyright PhpStorm
*/
namespace App\Service;
use App\Enums\BoolEnum;
use App\Enums\LottType;
use App\Enums\OrderType;
use App\Enums\PayState;
use App\Enums\SaleState;
use App\Exceptions\JingCaiException;
use App\Model\Config;
use App\Model\Customer\Customer;
use App\Model\Lottery;
use App\Model\LotteryType;
use App\Model\Order;
use App\Model\OrderCtzqSfcResult;
use App\Model\Seller\Seller;
use App\Model\Zq\CtzqSfc;
use App\Model\Zq\CtzqSfcMatch;
use App\Utils\Helps;
use App\Utils\ThrowException;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
class CtzqSfc14Service implements IJingcai
{
use JingCaiTrait;
public function getOddsFromRequestData($odds) {
$result = [];
foreach ($odds as $k => $oddItems) {
$result[$k] = array_keys($oddItems['odds']);
}
return $result;
}
/**
* 可销售的彩票赔率
* @param Customer $customer
* @return mixed
*/
public function saleLotteries(Customer $customer, $lotteryTypeId)
{
$lotteryType = LotteryType::where('type', LottType::CTZQ_SFC14)
->where('status', BoolEnum::YES)
->find($lotteryTypeId);
ThrowException::isTrue(!$lotteryType, '不支持此彩种');
/** @var Lottery $lottery */
$lottery = Lottery::active()
->shopAndType($customer->shop_id, $lotteryTypeId)
->first();
ThrowException::isTrue(!$lottery, '店铺不支持此彩种');
$ctzqs = CtzqSfc::with('matches')
->where('state', SaleState::Selling)
->orderBy('issue_num', 'asc')
->get();
$result = [
'play_types' => [],
'odds' => []
];
$odds = [];
/** @var $ctzqs $ctzq */
foreach ($ctzqs as $ctzq) {
if (!$ctzq->matches || count($ctzq->matches) < 1) {
continue;
}
foreach ($ctzq->matches as $mat) {
$mat->match_time_date = date('Y-m-d', strtotime($mat->match->start_time));
$mat->match_time_hour = date('H:i', strtotime($mat->match->start_time)) . '开赛';
}
unset($ctzq->matchs);
$ctzq->close_time = $ctzq->getCloseTime($lottery->earlySecond());
$odds[] = $ctzq;
}
$result['odds'] = $odds;
return $result;
}
public function valid(Lottery $lottery, $data)
{
$oddsData = Arr::get($data, 'odds');
$ctzqMatchId = array_key_first($oddsData);
$ctzqMatch = CtzqSfcMatch::find($ctzqMatchId);
ThrowException::isTrue(!$ctzqMatch, '无对应的比赛数据,无法投注');
$ctzq = CtzqSfc::where('id', $ctzqMatch->ctzq_sfc_id)->first();
ThrowException::isTrue(!$ctzq, '无此期投注');
ThrowException::isTrue($ctzq->state != SaleState::Selling, '不在销售中');
if (date('Y-m-d H:i:s') > $ctzq->getCloseTime($lottery->earlySecond())) {
ThrowException::run( '已截止投注');
}
$oddsData = Arr::get($data, 'odds');
ThrowException::isTrue(count($oddsData) != 14, '请选择全部14场比赛主队和客队总进球数进行投注');
$ids = array_keys($oddsData);
$countIds = CtzqSfcMatch::where('ctzq_sfc_id', $ctzq->id)
->whereIn('id', $ids)->count();
ThrowException::isTrue($countIds != count($ids), '选择的比赛数据有误');
foreach ($oddsData as $id => $odd) {
if (count($odd) <= 0 ) {
ThrowException::run('请选择全部14场比赛主队和客队总进球数进行投注');
}
}
}
/**
* 计算价格
* @param $data 数据
* @param $betsNum 倍数
* @return mixed
*/
public function computePrizeInfo($data, $betsNum = 1, $mnKeys = [])
{
$input = $this->getCombinationInput($data);
$combinationData = Helps::getCombinationData($input, count($data));
$zhuNum = count($combinationData);
return [
'money' => $zhuNum * $betsNum * Config::lotteryUnitPrice(),
'zhu_num' => $zhuNum,
];
}
/**
* 获取二维数组组合的入参
* @param $data {1=>[1,2], ..}
*/
public function getCombinationInput($data)
{
$result = [];
foreach ($data as $id => $odds) {
$item = [];
foreach ($odds as $odd) {
$item[] = $this->generateSfcCombinationItem($id, $odd);
}
$result[] = $item;
}
return $result;
}
public function generateSfcCombinationItem($id, $odd)
{
return sprintf('%d-%s', $id, $odd);
}
public function parserSfcCombinationItem($item)
{
$arr = explode('-', $item);
return [
'ctzq_match_id' => $arr[0],
'odd' => $arr[1],
];
}
/**
* 刷新数据的赔率
* @param $data
* @return mixed
*/
public function refreshOdds($data)
{
return $data;
}
public function createPiaos($oddsData, $betsNum)
{
$input = $this->getCombinationInput($oddsData);
$combinationData = Helps::getCombinationData($input, count($oddsData));
$data = [];
foreach ($combinationData as $comBitem) {
$dataItem = [];
foreach ($comBitem as $item) {
$itemInfo = $this->parserSfcCombinationItem($item);
$dataItem[] = $itemInfo['odd'] ;
}
$itemKey = implode('|',$dataItem);
$data[$itemKey] = $betsNum;
}
$piaos = [];
$this->addPiaos($piaos, $data);
return $piaos;
}
public function addPiaos(&$piaos, $arr)
{
$remainArr = [];
$num = 0;
$piao = [];
$ok = false;
$maxNum = Config::piaoMaxBetsNum();
foreach ($arr as $k => $val) {
$tempNum = $num + $val;
if (!$ok) {
if ($tempNum >= $maxNum) {
$ying = $maxNum - $num;
$num += $ying;
$piao[$k] = $ying;
$ok = true;
if ($val - $ying > 0) {
$remainArr[$k] = $val - $ying;
}
continue;
}
$num += $val;
$piao[$k] = $val;
} else {
$remainArr[$k] = $val;
}
}
$piaos[] = $piao;
if ($remainArr) {
$this->addPiaos($piaos, $remainArr);
}
}
/**
* 创建订单
* @param Customer $customer
* @param $data
* @return Order
*/
public function createOrder(Customer $customer, $data)
{
$lotteryTypeId = Arr::get($data, 'lottery_type_id');
$type = Arr::get($data, 'type', OrderType::NORMAL);
$fadanSecret = Arr::get($data, 'type_mode', 1);
$fadanDesc = Arr::get($data, 'type_desc', '');
$betsNum = Arr::get($data, 'bets_num');
$oddsData = Arr::get($data, 'odds'); // 购买的场次或投注信息
$union_piece_total = intval(Arr::get($data, 'union_piece_total', 0));
$union_piece_buy = intval(Arr::get($data, 'union_piece_buy', 0));
$union_piece_keep = intval(Arr::get($data, 'union_piece_keep', 0));
$union_keep = Arr::get($data, 'union_keep', BoolEnum::NO);
$union_brokerage = intval(Arr::get($data, 'union_brokerage', 0));
ThrowException::isTrue($type == OrderType::FADAN, '该彩种不支持发单');
ThrowException::isTrue($type == OrderType::GENDAN, '该彩种不支持跟单');
/** @var Lottery $lott */
$lott = LotteryService::getLottery($customer->shop->id, $lotteryTypeId);
ThrowException::isTrue(!$lott, '店铺未开通该彩种');
$this->valid($lott, $data);
$computeInfo = $this->computePrizeInfo($oddsData, $betsNum);
$lott->validMixMoney($computeInfo['money']);
if ($type == OrderType::UNION) {
$lott->validEnableHemai();
throw_if(!$fadanDesc, JingCaiException::create('请填写合买宣言!'));
ThrowException::isTrue($union_piece_total <= 0, '总份数不能小于0');
$piecePrice = $computeInfo['money'] / $union_piece_total;
ThrowException::isTrue($piecePrice <= 1, '每份金额必须大于1');
ThrowException::isTrue($union_piece_buy > $union_piece_total, '超过方案总金额');
if ($union_keep == BoolEnum::YES) {
$union_piece_keep = $union_piece_total - $union_piece_buy;
}
$this->canCreateUnionOrder($customer->id);
}
$ctzqMatchId = array_key_first($oddsData);
$ctzqMatch = CtzqSfcMatch::find($ctzqMatchId);
ThrowException::isTrue(!$ctzqMatch, '无对应的比赛数据,无法投注');
/** @var \App\Model\Zq\CtzqSfc $ctzq */
$ctzq = CtzqSfc::where('id', $ctzqMatch->ctzq_sfc_id)->where('state', SaleState::Selling)->first();
DB::beginTransaction();
try {
$earlyTime = $ctzq->getCloseTime($lott->earlySecond());
$lateTime =$ctzq->getCloseTime($lott->earlySecond());
$this->checkCloseTimeOver($earlyTime);
$piaos = $this->createPiaos($oddsData, $betsNum);
$order = new Order();
$order->pid = 0;
$order->customer_id = $customer->id;
$order->lottery_id = $lott->id;
$order->shop_id = $customer->shop_id;
$order->lottery_type_id = $lott->lottery_type_id;
$order->order_sn = Order::makeOrderSn();
$order->play_type = '';
$order->bets_num = $betsNum;
$order->zhu_num = $computeInfo['zhu_num'];
$order->piao_num = count($piaos);
$order->money = $computeInfo['money'];
$order->prize_min = 0;
$order->prize_max = 0;
$order->pay_state = PayState::UNPAID;
$order->pass_mode = [];
$order->odds_close_time = $ctzq->getCloseTime(0);
$order->odds_early_close_time = $earlyTime;
$order->odds_late_close_time = $lateTime;
$order->type = $type;
$order->type_mode = $fadanSecret;
$order->type_desc = $fadanDesc;
$order->odds = $oddsData;
if ($type == OrderType::UNION) {
$pieceMoney = $order->money / $union_piece_total;
$order->union_piece_total = $union_piece_total;
$order->union_piece_buy = $union_piece_buy;
$order->union_piece_self = $union_piece_buy;
$order->union_piece_keep = $union_piece_keep;
$order->union_keep = $union_keep;
$order->union_brokerage = $union_brokerage;
$order->union_piece_money = $pieceMoney;
$order->union_money = $pieceMoney * ($union_piece_buy + $union_piece_keep);
}
$order->created_date = date('Ymd');
// 设置合作相关的数据
$order->setCooperateInfo($lott);
$order->save();
// 如果是合买,更新自己的pid
if ($order->type == OrderType::UNION) {
$order->pid = $order->id;
$order->save();
}
$ids = array_keys($oddsData);
$matches = CtzqSfcMatch::where('ctzq_sfc_id', $ctzq->id)
->whereIn('id', $ids)->get()->keyBy('id');
$orderOdds = [];
foreach ($oddsData as $ctzqMatchId => $info) {
$match = Arr::get($matches, $ctzqMatchId);
$orderOdds[] = [
'order_id' => $order->id,
'ctzq_sfc_id' => $ctzq->id,
'ctzq_sfc_match_id' => $ctzqMatchId,
'lottery_type' => LottType::CTZQ_SFC14,
'match_id' => $match->match_id,
'odds' => json_encode($info, JSON_UNESCAPED_UNICODE),
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
];
}
OrderCtzqSfcResult::insert($orderOdds);
DB::commit();
return $order;
} catch (JingCaiException $e) {
DB::rollBack();
Log::error('ctzq_sfc14::order::create ValidateException: ' . $e);
throw $e;
} catch (\Exception $e) {
DB::rollBack();
Log::error('ctzq_sfc14::order::create Exception: ' . $e);
throw $e;
}
}
/**
* 跟单
* @param Customer $customer
* @param Order $order
* @param $data
* @return Order
*/
public function copyOrder(Customer $customer, Order $order, $data)
{
}
/**
* 展示订单详情
* @param Customer $customer 查看订单的人
* @param Order $order
* @return mixed
*/
public function showOrder(Customer $customer, Order $order)
{
$order->sellings = [];
// 自购的
if ($order->customerCanSeeSellings($customer)) {
$this->setOrderOdds($order);
}
$order->chang_num = count($order->sellings);
$order->play_name = $order->lottery->name;
unset($order->lottery);
return $order;
}
private function setOrderOdds(Order $order) {
$oddsData = $order->odds;
$ctzqMatchs = CtzqSfcMatch::whereIn('id', array_keys($oddsData))->get();
$ctzqMatch = Arr::get($ctzqMatchs, 0);
$ctzq = CtzqSfc::find($ctzqMatch->ctzq_sfc_id);
$matchs = $ctzq->matches->whereIn('id', array_keys($oddsData));
$sellings = [];
foreach ($matchs as $match) {
$match->buy_odds = Arr::get($oddsData, $match->id);
$sellings[] = $match;
}
$order->sellings = $sellings;
$order->issue_num = $ctzq->issue_num;
return $order;
}
/**
* 店主-展示订单详情
* @param Seller $seller 查看订单的人
* @param Order $order
* @return mixed
*/
public function sellerShowOrder(Seller $seller, Order $order)
{
$order->sellings = [];
if ($order->sellerCanSeeSellings($seller)) {
$this->setOrderOdds($order);
}
$order->chang_num = count($order->sellings);
$order->play_name = $order->lottery->name;
unset($order->lottery);
return $order;
}
public function chaiPiao(Order $order)
{
$piaoList = [];
return $piaoList;
}
}