You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1007 lines
38 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Service;
use App\Exception\BusinessException;
use App\Helper\RebateGiftItem\Manager;
use App\Model\BaseGame;
use App\Model\PlayerRole;
use App\Model\RebateGift;
use App\Model\RebateOrder;
use App\Model\RebateTimesSetting;
use App\Model\Server;
use App\Model\SimulateSpend;
use App\Model\Spend;
use Hyperf\DbConnection\Db as DB;
class RebateService extends Service
{
const AUTO_REVIEW = false;
public function getBaseGameConfig($baseGame)
{
$commonConfig = [
'is_daily_repeat' => true,
];
$configs = [
11 => ['is_daily_repeat' => false],
];
$configs = [
21 => ['is_daily_repeat' => false],
];
return $configs[$baseGame->id] ?? $commonConfig;
}
public function getProps($baseGameId)
{
$props = [];
return $props[$baseGameId] ?? null;
}
private function getOrders(BaseGame $baseGame, array $timeRange, array $serverIds = null)
{
$gameIds = [$baseGame->android_game_id, $baseGame->ios_game_id];
$orderQuery = Spend::where('pay_status', 1)->whereIn('game_id', $gameIds)->whereBetween('pay_time', $timeRange);
if (!is_null($serverIds)) {
$orderQuery->whereIn('server_id', $serverIds);
}
$orders = $orderQuery->get(['pay_order_number', 'game_player_id', 'pay_amount', 'server_id', 'pay_time'])->toArray();
$simulateOrderQuery = SimulateSpend::where('base_game_id', $baseGame->id)->whereBetween('review_time', $timeRange)->where('status', 1);
if (!is_null($serverIds)) {
$simulateOrderQuery->whereIn('server_id', $serverIds);
}
$simulateOrders = $simulateOrderQuery->get([
DB::raw('role_id as game_player_id'),
DB::raw('amount as pay_amount'),
DB::raw('order_no as pay_order_number'),
DB::raw('create_time as pay_time'),
'server_id'
])
->toArray();
return array_merge($orders, $simulateOrders);
}
/**
* 单笔充值福利生成
*/
public function generateSingle($baseGame, $timeRange)
{
$gifts = RebateGift::where('type', 'A')->where('base_game_id', $baseGame->id)->orderBy('amount', 'asc')->get();
if (count($gifts) == 0) {
return;
}
$orders = $this->getOrders($baseGame, $timeRange);
$orderNumbers = array_column($orders, 'pay_order_number');
$existItems = RebateOrder::whereIn('order_number', $orderNumbers)
->where('type', 'A')
->where('base_game_id', $baseGame->id)
->get(['order_number'])
->keyBy(function($item) {
return $item->order_number;
});
$roles = $this->getRolesByRoleIds($baseGame, array_column($orders, 'game_player_id'));
$records = [];
foreach ($orders as $order) {
$maxGift = null;
foreach ($gifts as $gift) {
if ($order['pay_amount'] >= $gift->amount) {
$maxGift = $gift;
}
}
if ($maxGift && empty($existItems[$order['pay_order_number']])) {
$role = $roles[$order['game_player_id']] ?? null;
$record = $this->getCommonRecord($baseGame, $role, $maxGift);
$record = array_merge($record, [
'pay_amount' => $order['pay_amount'],
'order_number' => $order['pay_order_number'],
]);
$records[] = $record;
}
}
RebateOrder::insert($records);
}
/**
* 单笔充值福利生成(暂时只是用玄灵契约)
*/
public function generateSingleTimes($baseGame, $timeRange)
{
$gifts = RebateGift::where('type', 'I')->where('base_game_id', $baseGame->id)->orderBy('amount', 'asc')->get();
if (count($gifts) == 0) {
return;
}
$defaultTimes = 0;
$setting = RebateTimesSetting::where('base_game_id', $baseGame->id)->where('type', 'I')->first();
if ($setting) {
$defaultTimes = $setting->default_times;
}
$orders = $this->getOrders($baseGame, $timeRange);
$orderNumbers = array_column($orders, 'pay_order_number');
$existItems = RebateOrder::whereIn('order_number', $orderNumbers)
->where('type', 'I')
->where('base_game_id', $baseGame->id)
->get(['order_number'])
->keyBy(function($item) {
return $item->order_number;
});
$roles = $this->getRolesByRoleIds($baseGame, array_column($orders, 'game_player_id'));
$records = [];
foreach ($orders as $order) {
$maxGift = null;
foreach ($gifts as $gift) {
if ($order['pay_amount'] >= $gift->amount) {
$maxGift = $gift;
}
}
if ($maxGift && empty($existItems[$order['pay_order_number']])) {
[$giftProps, $giftContents] = $this->getOrderProps($maxGift, $defaultTimes);
$role = $roles[$order['game_player_id']] ?? null;
$record = $this->getCommonRecord($baseGame, $role, $maxGift);
$record = array_merge($record, [
'pay_amount' => $order['pay_amount'],
'order_number' => $order['pay_order_number'],
'times' => $defaultTimes,
'props' => json_encode($giftProps, JSON_UNESCAPED_UNICODE),
'gift_content' => implode('|', $giftContents),
]);
$records[] = $record;
}
}
RebateOrder::insert($records);
}
private function getOrderProps($gift, $defaultTimes)
{
$props = $this->getProps($gift->base_game_id);
$giftProps = $props[$gift->gift_key];
$giftContents = [];
foreach ($giftProps as $key => $prop) {
$prop['num'] = $defaultTimes;
$giftProps[$key] = $prop;
$giftContents[] = $prop['name'] . '*' . $defaultTimes;
}
return [$giftProps, $giftContents];
}
private function getPayAmountGroupByRole($baseGame, $timeRange, $roleIds = null)
{
$gameIds = [$baseGame->android_game_id, $baseGame->ios_game_id];
$spendQuery = Spend::where('pay_status', 1)
->whereIn('game_id', $gameIds)
->whereBetween('pay_time', $timeRange);
if (is_array($roleIds)) {
$spendQuery->whereIn('game_player_id', $roleIds);
}
$items = $spendQuery->groupBy('game_player_id')
->get(['game_player_id', DB::raw('sum(pay_amount) amount')])
->pluck('amount', 'game_player_id')
->toArray();
$simulateQuery = SimulateSpend::where('base_game_id', $baseGame->id)
->whereBetween('review_time', $timeRange)
->where('status', 1);
if (is_array($roleIds)) {
$simulateQuery->whereIn('role_id', $roleIds);
}
$simulateItems = $simulateQuery->groupBy('role_id') ->get(['role_id', DB::raw('sum(amount) amount')]);
foreach ($simulateItems as $simulateItem) {
if (isset($items[$simulateItem->role_id])) {
$items[$simulateItem->role_id] += $simulateItem->amount;
} else {
$items[$simulateItem->role_id] = $simulateItem->amount;
}
}
return $items;
}
/**
* 月卡福利
*/
public function generateDaily($baseGame, $date)
{
$gifts = RebateGift::where('type', 'B')->where('base_game_id', $baseGame->id)->orderBy('amount', 'asc')->get();
if (count($gifts) == 0) {
return;
}
$gameIds = [$baseGame->android_game_id, $baseGame->ios_game_id];
$timeRange = [strtotime($date . ' 00:00:00'), strtotime($date . ' 23:59:59')];
$items = Spend::where('pay_status', 1)
->whereIn('game_id', $gameIds)
->whereBetween('pay_time', $timeRange)
->groupBy('game_player_id')
->get(['game_player_id', DB::raw('sum(pay_amount) amount')])
->pluck('amount', 'game_player_id')
->toArray();
$simulateItems = SimulateSpend::where('base_game_id', $baseGame->id)
->whereBetween('review_time', $timeRange)
->where('status', 1)
->groupBy('role_id')
->get(['role_id', DB::raw('sum(amount) amount')]);
foreach ($simulateItems as $simulateItem) {
if (isset($items[$simulateItem->role_id])) {
$items[$simulateItem->role_id] += $simulateItem->amount;
} else {
$items[$simulateItem->role_id] = $simulateItem->amount;
}
}
$roleIds = array_keys($items);
$existQuery = RebateOrder::where('type', 'B')->where('base_game_id', $baseGame->id)->whereIn('role_id', $roleIds);
$config = $this->getBaseGameConfig($baseGame);
if ($config['is_daily_repeat']) {
$existQuery->where('award_date', $date);
} else {
$tomorrow = date('Y-m-d', strtotime($date) + 24 * 3600);
$existQuery->where('award_started_at', '<=', $tomorrow)->where('award_ended_at', '>=', $tomorrow);
}
$existItems = $existQuery->get(['role_id', 'gift_key'])->keyBy(function($item) {
return $item->role_id . '-' . $item->gift_key;
});
$roles = $this->getRolesByRoleIds($baseGame, $roleIds);
$awardStartedAt = date('Y-m-d', strtotime($date) + 1 * 24 * 3600);
$awardEndedAt = date('Y-m-d', strtotime($date) + 30 * 24 * 3600);
$records = [];
foreach ($items as $roleId => $amount) {
$maxGift = null;
foreach ($gifts as $gift) {
if ($amount >= $gift->amount) {
$maxGift = $gift;
}
}
if (is_null($maxGift)) {
continue;
}
$orderKey = $roleId . '-' . $maxGift->gift_key;
if (empty($existItems[$orderKey])) {
$role = $roles[$roleId] ?? null;
$record = $this->getCommonRecord($baseGame, $role, $maxGift);
$record = array_merge($record, [
'pay_amount' => $amount,
'award_date' => $date,
'award_started_at' => $awardStartedAt,
'award_ended_at' => $awardEndedAt,
'order_number' => uniqid('total_').rand(100000, 999999)
]);
$records[] = $record;
}
}
RebateOrder::insert($records);
}
/**
* 累充福利生成
*/
public function generateAccumulative($baseGame, $timeRange)
{
$gifts = RebateGift::where('type', 'C')
->where('base_game_id', $baseGame->id)
->orderBy('amount', 'asc')
->get();
if (count($gifts) == 0) {
return;
}
$gameIds = [$baseGame->android_game_id, $baseGame->ios_game_id];
$roleIds = Spend::where('pay_status', 1)
->whereIn('game_id', $gameIds)
->whereBetween('pay_time', $timeRange)
->get([DB::raw('DISTINCT game_player_id')])
->pluck('game_player_id')
->toArray();
$simulateRoleIds = SimulateSpend::where('base_game_id', $baseGame->id)
->whereBetween('review_time', $timeRange)
->where('status', 1)
->get([DB::raw('DISTINCT role_id')])
->pluck('role_id')
->toArray();
$roleIds = array_unique(array_merge($roleIds, $simulateRoleIds));
$existItems = RebateOrder::whereIn('role_id', $roleIds)
->where('type', 'C')
->where('base_game_id', $baseGame->id)
->get(['gift_key', 'role_id'])
->keyBy(function($item) {
return $item->role_id . '-' . $item->gift_key;
});
$items = Spend::where('pay_status', 1)
->whereIn('game_id', $gameIds)
->whereIn('game_player_id', $roleIds)
->groupBy('game_player_id')
->get(['game_player_id', DB::raw('sum(pay_amount) amount')])
->pluck('amount', 'game_player_id')
->toArray();
$simulateItems = SimulateSpend::where('base_game_id', $baseGame->id)
->where('status', 1)
->whereIn('role_id', $roleIds)
->groupBy('role_id')
->get(['role_id', DB::raw('sum(amount) amount')]);
foreach ($simulateItems as $simulateItem) {
if (isset($items[$simulateItem->role_id])) {
$items[$simulateItem->role_id] += $simulateItem->amount;
} else {
$items[$simulateItem->role_id] = $simulateItem->amount;
}
}
$roles = $this->getRolesByRoleIds($baseGame, array_keys($items));
$records = [];
foreach ($items as $roleId => $amount) {
foreach ($gifts as $gift) {
if ($amount >= $gift->amount) {
$orderKey = $roleId . '-' . $gift->gift_key;
if (empty($existItems[$orderKey])) {
$role = $roles[$roleId] ?? null;
$record = $this->getCommonRecord($baseGame, $role, $gift);
$record = array_merge($record, [
'pay_amount' => $amount,
'order_number' => uniqid('total_').rand(100000, 999999)
]);
$records[] = $record;
}
}
}
}
RebateOrder::insert($records);
}
/**
* 首充福利生成
* (注意:优化处理,没领过首充礼包的都算首充)
*/
public function generateFirstPay($baseGame, $timeRange)
{
$gifts = RebateGift::where('type', 'D')->where('base_game_id', $baseGame->id)->get();
if (count($gifts) == 0) {
return;
}
$gameIds = [$baseGame->android_game_id, $baseGame->ios_game_id];
$items = Spend::where('pay_status', 1)
->whereIn('game_id', $gameIds)
->whereBetween('pay_time', $timeRange)
->orderBy('pay_time', 'asc')
->get(['game_player_id', 'pay_amount', 'pay_order_number'])
->toArray();
$simulateItems = SimulateSpend::where('base_game_id', $baseGame->id)
->whereBetween('review_time', $timeRange)
->where('status', 1)
->get([
DB::raw('role_id as game_player_id'),
DB::raw('amount as pay_amount'),
DB::raw('order_no as pay_order_number')
])
->toArray();
$items = array_merge($items, $simulateItems);
$roleIds = array_column($items, 'game_player_id');
$existItems = RebateOrder::whereIn('role_id', $roleIds)
->where('type', 'D')
->where('base_game_id', $baseGame->id)
->get(['gift_key', 'role_id'])
->keyBy(function($item) {
return $item->role_id . '-' . $item->gift_key;
});
$roles = $this->getRolesByRoleIds($baseGame, $roleIds);
$records = [];
$newOrderKeys = [];
foreach ($items as $item) {
foreach ($gifts as $gift) {
if ($item['pay_amount'] >= $gift->amount) {
$orderKey = $item['game_player_id'] . '-' . $gift->gift_key;
if (empty($existItems[$orderKey]) && empty($newOrderKeys[$orderKey])) {
$role = $roles[$item['game_player_id']] ?? null;
$newOrderKeys[$orderKey] = 1;
$record = $this->getCommonRecord($baseGame, $role, $gift);
$record = array_merge($record, [
'pay_amount' => $item['pay_amount'],
'order_number' => $item['pay_order_number'],
]);
$records[] = $record;
}
}
}
}
RebateOrder::insert($records);
}
/**
* 单日累充福利生成
*/
public function generateDayAccumulative($baseGame, $date)
{
$gifts = RebateGift::where('type', 'E')->where('base_game_id', $baseGame->id)->orderBy('amount', 'asc')->get();
if (count($gifts) == 0) {
return;
}
$gameIds = [$baseGame->android_game_id, $baseGame->ios_game_id];
$timeRange = [strtotime($date . ' 00:00:00'), strtotime($date . ' 23:59:59')];
$items = Spend::where('pay_status', 1)
->whereIn('game_id', $gameIds)
->whereBetween('pay_time', $timeRange)
->groupBy('game_player_id')
->get(['game_player_id', DB::raw('sum(pay_amount) amount')])
->pluck('amount', 'game_player_id')
->toArray();
$simulateItems = SimulateSpend::where('base_game_id', $baseGame->id)
->whereBetween('review_time', $timeRange)
->where('status', 1)
->groupBy('role_id')
->get(['role_id', DB::raw('sum(amount) amount')]);
foreach ($simulateItems as $simulateItem) {
if (isset($items[$simulateItem->role_id])) {
$items[$simulateItem->role_id] += $simulateItem->amount;
} else {
$items[$simulateItem->role_id] = $simulateItem->amount;
}
}
$roleIds = array_keys($items);
$existItems = RebateOrder::whereIn('role_id', $roleIds)
->where('type', 'E')
->where('base_game_id', $baseGame->id)
->where('award_date', $date)
->get(['gift_key', 'role_id'])
->keyBy(function($item) {
return $item->role_id . '-' . $item->gift_key;
});
$mode = $baseGame->id == 17 ? 'max' : 'all';
$roles = $this->getRolesByRoleIds($baseGame, $roleIds);
$roleGiftGroupMap = $this->getDayAccumulativeRoleGiftGropMap($baseGame, $gifts, $roles);
$records = [];
foreach ($items as $roleId => $amount) {
$groupGifts = $gifts->where('group', $roleGiftGroupMap[$roleId] ?? 0);
$maxGift = null;
foreach ($groupGifts as $gift) {
if ($amount >= $gift->amount) {
if ($mode == 'max') {
$maxGift = $gift;
continue;
}
$orderKey = $roleId . '-' . $gift->gift_key;
if (empty($existItems[$orderKey])) {
$role = $roles[$roleId] ?? null;
$record = $this->getCommonRecord($baseGame, $role, $gift);
$record = array_merge($record, [
'award_date' => $date,
'pay_amount' => $amount,
'order_number' => uniqid('total_').rand(100000, 999999)
]);
$records[] = $record;
}
}
}
if ($mode == 'max' && $maxGift) {
$orderKey = $roleId . '-' . $maxGift->gift_key;
if (empty($existItems[$orderKey])) {
$role = $roles[$roleId] ?? null;
$record = $this->getCommonRecord($baseGame, $role, $maxGift);
$record = array_merge($record, [
'award_date' => $date,
'pay_amount' => $amount,
'order_number' => uniqid('total_').rand(100000, 999999)
]);
$records[] = $record;
}
}
}
RebateOrder::insert($records);
}
public function getDayAccumulativeRoleGiftGropMap($baseGame, $gifts, $roles) {
if ($baseGame->id == 17) {
$roleGiftGroupMap = [];
$serverIds = array_unique($roles->pluck('server_id')->toArray());
$gameIds = [$baseGame->android_game_id, $baseGame->ios_game_id];
$servers = Server::whereIn('game_id', $gameIds)->whereIn('server_id', $serverIds)->get(['server_id', 'create_time'])->keyBy('server_id');
foreach ($roles as $role) {
$serverCreateTime = $servers[$role->server_id] ? $servers[$role->server_id]->create_time : time();
$serverCreateTime = strtotime(date('Y-m-d 00:00:00', $serverCreateTime));
$openDayCount = (strtotime(date('Y-m-d 23:59:59')) + 1 - $serverCreateTime) / (24*60*60);
if ($openDayCount >=1 && $openDayCount <= 7) {
$roleGiftGroupMap[$role->role_id] = 1;
} elseif ($openDayCount >=8 && $openDayCount <= 15) {
$roleGiftGroupMap[$role->role_id] = 2;
} elseif ($openDayCount >=16 && $openDayCount <= 30) {
$roleGiftGroupMap[$role->role_id] = 3;
} elseif ($openDayCount >=31 && $openDayCount <= 45) {
$roleGiftGroupMap[$role->role_id] = 4;
} elseif ($openDayCount >=46 && $openDayCount <= 60) {
$roleGiftGroupMap[$role->role_id] = 5;
} elseif ($openDayCount >=61 && $openDayCount <= 90) {
$roleGiftGroupMap[$role->role_id] = 6;
} elseif ($openDayCount >=91 && $openDayCount <= 999) {
$roleGiftGroupMap[$role->role_id] = 7;
}
}
return $roleGiftGroupMap;
} else {
return [];
}
}
/**
* 周卡福利(聚宝周卡)
* 目前仅适用于玄灵契约(无普遍适用性)
*/
public function generateWeekly($baseGame, $timeRange)
{
$gifts = RebateGift::where('type', 'F')->where('base_game_id', $baseGame->id)->orderBy('amount', 'asc')->get();
if (count($gifts) == 0) {
return;
}
$gameIds = [$baseGame->android_game_id, $baseGame->ios_game_id];
$date = date('Y-m-d', $timeRange[0]);
$dateRange = [strtotime($date . ' 00:00:00'), strtotime($date . ' 23:59:59')];
$items = [];
$roleIds = [];
if (in_array($baseGame->id, [75, 79, 81])) {
$roleIds = Spend::where('pay_status', 1)
->whereIn('game_id', $gameIds)
->whereBetween('pay_time', $timeRange)
->where('extend', 'like', '%|123|%') // 玄灵契约聚宝盆活动标识
->get([DB::raw('DISTINCT game_player_id')])
->pluck('game_player_id')
->toArray();
$items = Spend::where('pay_status', 1)
->whereIn('game_id', $gameIds)
->whereIn('game_player_id', $roleIds)
->whereBetween('pay_time', $dateRange)
->where('extend', 'like', '%|123|%') // 玄灵契约聚宝盆活动标识
->groupBy('game_player_id')
->get(['game_player_id', DB::raw('sum(pay_amount) amount')])
->pluck('amount', 'game_player_id')
->toArray();
} else {
$roleIds = Spend::where('pay_status', 1)
->whereIn('game_id', $gameIds)
->whereBetween('pay_time', $timeRange)
->get([DB::raw('DISTINCT game_player_id')])
->pluck('game_player_id')
->toArray();
$items = $this->getPayAmountGroupByRole($baseGame, $dateRange, $roleIds);
}
if (false) {
$giftExistItems = RebateOrder::where('type', 'F')
->where('base_game_id', $baseGame->id)
->whereIn('role_id', $roleIds)
->get(['role_id'])
->keyBy('role_id');
}
$existItems = RebateOrder::where('type', 'F')
->where('base_game_id', $baseGame->id)
->whereIn('role_id', $roleIds)
->where('award_started_at', '<=', $date)
->where('award_ended_at', '>=', $date)
->get(['role_id'])
->keyBy('role_id');
$roles = $this->getRolesByRoleIds($baseGame, $roleIds);
// 当天开始发放
$awardStartedAt = date('Y-m-d', strtotime($date) + 0 * 24 * 3600);
$awardEndedAt = date('Y-m-d', strtotime($date) + 6 * 24 * 3600);
$records = [];
foreach ($items as $roleId => $amount) {
$maxGift = null;
foreach ($gifts as $gift) {
if ($amount >= $gift->amount) {
$maxGift = $gift;
}
}
if ($maxGift && empty($existItems[$roleId])) {
$role = $roles[$roleId] ?? null;
$record = $this->getCommonRecord($baseGame, $role, $maxGift);
$record = array_merge($record, [
'pay_amount' => $amount,
'award_date' => $date,
'award_started_at' => $awardStartedAt,
'award_ended_at' => $awardEndedAt,
'order_number' => uniqid('total_').rand(100000, 999999)
]);
$records[] = $record;
}
}
RebateOrder::insert($records);
}
/**
* 首次进游(每个角色一次)
*/
public function generateNewRole($baseGame, $timeRange)
{
$gifts = RebateGift::where('type', 'G')->where('base_game_id', $baseGame->id)->get();
if (count($gifts) == 0) {
return;
}
$gameIds = [$baseGame->android_game_id, $baseGame->ios_game_id];
$roles = PlayerRole::whereIn('game_id', $gameIds)
->whereBetween('create_time', $timeRange)
->get(['user_id', 'role_name', 'role_id', 'server_id', 'server_name', 'user_account']);
$roleIds = $roles->pluck('role_id')->toArray();
$existItems = RebateOrder::whereIn('role_id', $roleIds)
->where('type', 'G')
->where('base_game_id', $baseGame->id)
->get(['role_id'])
->keyBy('role_id');
$gift = $gifts->first();
$records = [];
foreach ($roles as $role) {
if ($gift && empty($existItems[$role->role_id])) {
$record = $this->getCommonRecord($baseGame, $role, $gift);
$records[] = $record;
}
}
RebateOrder::insert($records);
}
/**
* 签到福利发放(每个角色如果当天有登录发放)
*/
public function generateDailySign($baseGame, $timeRange)
{
$gifts = RebateGift::where('type', 'H')->where('base_game_id', $baseGame->id)->get();
if (count($gifts) == 0) {
return;
}
$date = date('Y-m-d', $timeRange[0]);
$gameIds = [$baseGame->android_game_id, $baseGame->ios_game_id];
$roles = PlayerRole::whereIn('game_id', $gameIds)
->whereBetween('play_time', $timeRange)
->get(['user_id', 'role_name', 'role_id', 'server_id', 'server_name', 'user_account', 'play_time', 'create_time']);
$roleIds = $roles->pluck('role_id')->toArray();
$maxItems = [];
if (!in_array($baseGame->id, [84])) {
$maxItems = RebateOrder::whereIn('role_id', $roleIds)
->where('type', 'H')
->where('base_game_id', $baseGame->id)
->groupBy('role_id')
->havingRaw('count(*) >= ?', [3])
->get(['role_id'])
->keyBy('role_id');
}
$existItems = RebateOrder::whereIn('role_id', $roleIds)
->where('type', 'H')
->where('award_date', $date)
->where('base_game_id', $baseGame->id)
->get(['role_id'])
->keyBy('role_id');
$gift = $gifts->first();
$records = [];
foreach ($roles as $role) {
if (date('Ymd', $role['play_time']) <= date('Ymd', $role['create_time'])) {
continue;
}
if ($gift && empty($existItems[$role->role_id]) && empty($maxItems[$role->role_id])) {
$record = $this->getCommonRecord($baseGame, $role, $gift);
$record = array_merge($record, [
'award_date' => $date,
]);
$records[] = $record;
}
}
RebateOrder::insert($records);
}
/**
* 开服七天活动
*/
public function generateOpenSevenDay($baseGame, $timeRange)
{
$gifts = RebateGift::where('type', 'K')->where('base_game_id', $baseGame->id)->get()->keyBy('gift_key');
if (count($gifts) == 0) {
return;
}
$gameIds = [$baseGame->android_game_id, $baseGame->ios_game_id];
$serverStartedAt = strtotime(date('Y-m-d 00:00:00', $timeRange[0] - 7*24*3600));
$serverEndedAt = strtotime(date('Y-m-d 23:59:59', $timeRange[0]));
$servers = Server::whereIn('game_id', $gameIds)->whereBetween('start_time', [$serverStartedAt, $serverEndedAt])->get(['id', 'server_id', 'start_time']);
$servers = $servers->keyBy('server_id');
$serverIds = $servers->pluck('server_id')->toArray();
$orders = $this->getOrders($baseGame, $timeRange, $serverIds);
$orderNumbers = array_column($orders, 'pay_order_number');
$existItems = RebateOrder::whereIn('order_number', $orderNumbers)
->where('type', 'K')
->where('base_game_id', $baseGame->id)
->get(['order_number'])
->keyBy(function($item) {
return $item->order_number;
});
$roles = $this->getRolesByRoleIds($baseGame, array_column($orders, 'game_player_id'));
$records = [];
foreach ($orders as $order) {
$amount = intval($order['pay_amount']);
$server = $servers[$order['server_id']];
if (is_null($server)) {
continue;
}
$num = 0;
if ($amount == 328) {
$num = 1;
} elseif ($amount == 648) {
$num = 2;
} elseif ($amount == 1000) {
$num = 3;
}
$day = (
strtotime(date('Y-m-d 00:00:00', $order['pay_time'])) -
strtotime(date('Y-m-d 00:00:00', $server->start_time))
)/(24*3600) + 1;
$giftKey = 'K-'.$day;
$gift = $gifts[$giftKey] ?? null;
if ($gift && empty($existItems[$order['pay_order_number']])) {
$role = $roles[$order['game_player_id']] ?? null;
$record = $this->getCommonRecord($baseGame, $role, $gift);
$record = array_merge($record, [
'pay_amount' => $order['pay_amount'],
'order_number' => $order['pay_order_number'],
]);
for ($i=0; $i<$num; $i++) {
$records[] = $record;
}
}
}
RebateOrder::insert($records);
}
/**
* 等级福利生成
*/
public function generateRoleLevel($baseGame, $timeRange)
{
$gifts = RebateGift::where('type', 'L')
->where('base_game_id', $baseGame->id)
->orderBy('amount', 'asc')
->get();
if (count($gifts) == 0) {
return;
}
$gameIds = [$baseGame->android_game_id, $baseGame->ios_game_id];
$roleIds = PlayerRole::whereIn('game_id', $gameIds)
->whereBetween('play_time', $timeRange)
->get([DB::raw('DISTINCT role_id')])
->pluck('role_id')
->toArray();
$existItems = RebateOrder::whereIn('role_id', $roleIds)
->where('type', 'L')
->where('base_game_id', $baseGame->id)
->get(['gift_key', 'role_id'])
->keyBy(function($item) {
return $item->role_id . '-' . $item->gift_key;
});
$roles = $this->getRolesByRoleIds($baseGame, $roleIds);
$records = [];
foreach ($roleIds as $roleId) {
$role = $roles[$roleId] ?? null;
if (is_null($role)) {
continue;
}
foreach ($gifts as $gift) {
if ($role->role_level >= $gift->amount) {
$orderKey = $roleId . '-' . $gift->gift_key;
if (empty($existItems[$orderKey])) {
$record = $this->getCommonRecord($baseGame, $role, $gift);
$record = array_merge($record, [
'pay_amount' => $role->role_level,
'order_number' => uniqid('total_').rand(100000, 999999)
]);
$records[] = $record;
}
}
}
}
RebateOrder::insert($records);
}
private function getRolesByRoleIds($baseGame, $roleIds)
{
$gameIds = [$baseGame->android_game_id, $baseGame->ios_game_id];
return PlayerRole::whereIn('game_id', $gameIds)
->whereIn('role_id', $roleIds)
->orderBy('role_level', 'desc')
->get(['user_id', 'role_name', 'role_id', 'server_id', 'server_name', 'user_account', 'role_level'])
->keyBy('role_id');
}
/* private function getGameRolesPayAmount($baseGame, $roleIds)
{
$gameIds = [$baseGame->android_game_id, $baseGame->ios_game_id];
return Spend::where('pay_status', 1)
->whereIn('game_id', $gameIds)
->whereIn('game_player_id', $roleIds)
->groupBy('game_player_id')
->get(['game_player_id', DB::raw('sum(pay_amount) amount')]);
} */
private function getCommonRecord($baseGame, $role, $gift)
{
$record = [
'base_game_id' => $baseGame->id,
'base_game_name' => $baseGame->name,
'user_id' => $role ? $role->user_id : '',
'user_account' => $role ? $role->user_account : '',
'server_id' => $role ? $role->server_id : '',
'server_name' => $role ? $role->server_name : '',
'role_name' => $role ? $role->role_name : '',
'role_id' => $role ? $role->role_id : '',
'type' => $gift->type,
'amount' => $gift->amount,
'gift_key' => $gift->gift_key,
'gift_content' => $gift->gift_content,
'gift_group' => $gift->group,
'create_time' => time(),
'creator_username' => '系统',
];
if (self::AUTO_REVIEW) {
$record = $this->addReviewParams($record);
}
return $record;
}
private function addReviewParams($record)
{
$record['review_type'] = 0;
$record['reviewer_id'] = 0;
$record['reviewer_username'] = '系统';
$record['review_status'] = 1;
$record['review_time'] = time();
return $record;
}
public function saveRebateGifts($baseGameId, $isReset = false)
{
if ($isReset) {
RebateGift::where('base_game_id', $baseGameId)->delete();
} else {
$rebateGift = RebateGift::query()->where('base_game_id', $baseGameId)->first();
if ($rebateGift) {
throw new BusinessException('返利配置已存在');
}
}
$manager = new Manager();
$typeItemsMap = $manager->getTypeItemsMap($baseGameId);
foreach ($typeItemsMap as $type => $items) {
$this->saveRebateGiftsByItems($items, $baseGameId, $type);
}
}
private function saveRebateGiftsByItems($items, $baseGameId, $type)
{
$records = [];
foreach ($items as $item) {
$item['type'] = $type;
$item['group'] = $item['group'] ?? 0;
$item['base_game_id'] = $baseGameId;
$item['gifts'] = json_encode($item['gifts']);
$records[] = $item;
}
RebateGift::insert($records);
}
public function getListColumnMap($type)
{
$columns = [
'base_game_name' => '游戏名称',
'server_name' => '区服',
'user_account' => '账号',
'role_id' => '角色ID',
'role_name' => '角色名称',
'promote_account' => '所属推广员',
];
if ($type == 'A') {
$columns['pay_amount'] = '充值金额';
} elseif ($type == 'B') {
$columns['pay_amount'] = '当日累计充值金额';
$columns['award_date_range'] = '可领取福利日期';
} elseif ($type == 'C') {
$columns['amount'] = '达到档位金额';
} elseif ($type == 'D') {
$columns['pay_amount'] = '首充金额';
} elseif($type == 'E') {
$columns['pay_amount'] = '当日累计充值金额';
$columns['award_date'] = '达成日期';
} elseif($type == 'F') {
$columns['award_date_range'] = '可领取福利日期';
} elseif($type == 'H') {
$columns['award_date'] = '签到日期';
} elseif ($type == 'I') {
$columns['pay_amount'] = '充值金额';
$columns['times'] = '返利倍数';
} elseif($type == 'J') {
$columns['award_date'] = '达成日期';
$columns['pay_amount'] = '当日累充总额';
$columns['times'] = '返利倍数';
$columns['amount'] = '申请总价值';
}
if ($type == 'J') {
$columns['gift_content'] = '申请道具';
} elseif($type == 'I') {
} else {
$columns['gift_content'] = '奖励内容';
}
$columns = array_merge($columns, [
'create_time' => '订单生成时间',
'review_status_text' => '审核状态',
'review_time' => '审核时间',
'send_status_text' => '发放状态',
'send_time' => '发放时间',
'reviewer_username' => '审核人',
]);
return $columns;
}
public function getListColumns($type)
{
$columns = [];
foreach ($this->getListColumnMap($type) as $key => $name) {
$columns[] = ['key' => $key, 'name' => $name];
}
return $columns;
}
}