优化玩家迁移

master
ELF 3 years ago
parent 06df47b713
commit 55a14f9d46

@ -71,10 +71,22 @@ class ConsoleController extends Think {
public function runShiftTask()
{
$promoteService = new PromoteService();
$tasks = M('shift_task', 'sys_')->where(['status' => 0, 'order_time' => ['elt', time()]])->select();
if (count($tasks) == 0) {
Printer::export('无可执行任务', true);
$replenishTasks = M('shift_task', 'sys_')
->where(['status' => 1, 'order_time' => ['elt', time()], 'handle_time' => ['egt', time() - 3600], 'is_replenished' => 0, 'type' => 2])
->select();
foreach ($replenishTasks as $replenishTask) {
$message = '玩家补充迁移[' . $replenishTask['id'] . ']';
$result = $promoteService->replenishShift($replenishTask);
if ($result['status']) {
$message = 'SUCCESS ----- ' . $message . $result['msg'];
} else {
$message = 'ERROR ----- ' . $message . $result['msg'];
}
Printer::export($message);
}
$tasks = M('shift_task', 'sys_')->where(['status' => 0, 'order_time' => ['elt', time()]])->select();
foreach ($tasks as $task) {
if ($task['type'] == 1) {
$message = '推广员迁移[' . $task['id'] . ']';

@ -0,0 +1,293 @@
<?php
namespace Base\Business;
use Base\Service\PromoteCompanyService;
use Base\Service\PromoteService;
use Exception;
use Think\Model;
class ShiftPlayer
{
private $task;
private $fromPromote;
private $toPromote;
private $fromWord;
private $toWord;
private $orderTime;
private $userIds;
private $users;
private $payAmountItems = [];
private $notices = [];
public function __construct($task)
{
$this->task = $task;
$this->orderTime = $task['order_time'];
$this->userIds = json_decode($task['shift_ids'], true) ?? [];
$this->getPromotes();
$this->getShiftUsers();
$this->statShiftPayAmount();
}
public function handle()
{
if ($this->fromPromote['id'] == 0 && count($this->shiftIds) == 0) {
throw new Exception('官方渠道玩家不能全部迁移');
}
$this->getNoticeCommonWords();
$model = new Model();
$model->startTrans();
$hasError = false;
foreach ($this->users as $user) {
$amount = $this->payAmountItems[$user['id']] ?? 0;
$status = $this->updateMend($user['id'], $amount);
if (!$status) {
$hasError = true;
break;
}
$this->generateNotice($user, $amount);
}
if ($hasError) {
$model->rollback();
throw new Exception('系统异常,修改补链记录失败');
}
$this->saveNotices();
$status = $this->shiftUser();
if (!$status) {
$model->rollback();
throw new Exception('系统异常,修改用户推广员失败');
}
try {
$this->shiftPlayer();
$this->shiftSpend();
$this->shiftDeposit();
$this->shiftBindSpend();
$this->shiftUserDataCount();
$model->commit();
} catch (\Exception $e) {
$model->rollback();
throw new \Exception('系统异常: ' . $e->getMessage());
}
}
public function handleReplenish()
{
$model = new Model();
$model->startTrans();
$hasError = false;
foreach ($this->payAmountItems as $userId => $amount) {
$status = $this->updateMend($userId, $amount);
if (!$status) {
$hasError = true;
break;
}
}
if ($hasError) {
$model->rollback();
throw new Exception('系统异常,修改补链记录失败');
}
try {
$this->shiftSpend();
$this->shiftDeposit();
$this->shiftBindSpend();
$model->commit();
} catch (\Exception $e) {
$model->rollback();
throw new \Exception('系统异常: ' . $e->getMessage());
}
}
private function getPromotes()
{
$toPromoteId = $this->task['to_promote_id'];
$fromPromoteId = $this->task['from_promote_id'];
$toPromote = M('promote', 'tab_')->where(['id' => $toPromoteId])->find();
$fromPromote = M('promote', 'tab_')->where(['id' => $fromPromoteId])->find();
$this->toPromote = $toPromote ?? ['id' => 0, 'account' => C('OFFICIEL_CHANNEL'), 'company_id' => 0];
$this->fromPromote = $fromPromote ?? ['id' => 0, 'account' => C('OFFICIEL_CHANNEL'), 'company_id' => 0];
}
private function getNoticeCommonWords()
{
$belongs = PromoteCompanyService::$belongs;
$formConpany = M('promote_company', 'tab_')->field(['company_name', 'company_belong'])->where(['id' => $this->fromPromote['company_id']])->find();
$toConpany = M('promote_company', 'tab_')->field(['company_name', 'company_belong'])->where(['id' => $this->toPromote['company_id']])->find();
$this->fromWord = $this->fromPromote['account'] . ($formConpany ? '(' . $belongs[$formConpany['company_belong']] . '-' . $formConpany['company_name'] . ')' : '');
$this->toWord = $this->toPromote['account'] . ($toConpany ? '(' . $belongs[$toConpany['company_belong']] . '-' . $toConpany['company_name'] . ')' : '');
}
private function getShiftUsers()
{
$map = $this->getShiftCommonMap(true);
$this->users = M('user', 'tab_')->field(['id', 'account', 'nickname'])->where($map)->select();
}
private function getSpendMap()
{
$map = $this->getShiftCommonMap();
$map['pay_time'] = ['egt', $this->orderTime];
// $map['is_check'] = ['in','1,2'];
$map['settle_check'] = 0;
$map['selle_status'] = 0;
$map['pay_status'] = 1;
return $map;
}
private function statShiftPayAmount()
{
$spendMap = $this->getSpendMap();
$payAmountRows = M('spend', 'tab_')
->field(['user_id', 'sum(pay_amount) pay_amount'])
->where($spendMap)
->group('user_id')
->select();
foreach ($payAmountRows as $row) {
$this->payAmountItems[$row['user_id']] = round(floatval($row['pay_amount']), 2);
}
}
private function updateMend($userId, $amount)
{
return M('mend', 'tab_')
->where(['task_id' => $this->task['id'], 'user_id' => $userId])
->save(['status' => 1, 'pay_amount' => ['exp', 'pay_amount+' . $amount], 'update_time' => time()]);
}
private function generateNotice($user, $amount)
{
if ($amount > 500) {
$userWord = '玩家账号' . $user['account'];
$content = $userWord . ', 从' . $this->fromWord . '换绑到' . $this->toWord . '换绑金额超过500达到' . $amount . '元';
$this->notices[] = [
'type' => 'shift-player',
'title' => '换绑额度超500',
'content' => $content,
'admin_ids' => '31',
'create_time' => time(),
'target' => $user['account'],
'start_time' => time(),
'end_time' => time() + 7*24*3600,
];
}
}
private function saveNotices()
{
if (count($this->notices) > 0) {
M('admin_notice', 'tab_')->addAll($this->notices);
}
}
private function shiftUser()
{
$map = $this->getShiftCommonMap(true);
return M('user', 'tab_')->where($map)->save([
'promote_id' => $this->toPromote['id'],
'promote_account' => $this->toPromote['account']
]);
}
private function shiftPlayer()
{
$map = $this->getShiftCommonMap();
$updateData = [
'promote_id' => $this->toPromote['id'],
'promote_account' => $this->toPromote['account']
];
M('user_play', 'tab_')->where($map)->save($updateData);
M('user_play_info', 'tab_')->where($map)->save($updateData);
}
private function shiftSpend()
{
$toPromote = $this->toPromote;
$spendMap = $this->getSpendMap();
[$hasGameIds, $hasNotGameIds] = $this->getPromoteGameIds($toPromote);
unset($spendMap['pay_status']);
$updateData = [
'promote_id' => $toPromote['id'],
'promote_account' => $toPromote['account'],
'market_admin_id' => $toPromote['admin_id'],
];
if (count($hasGameIds) > 0) {
$spendMap['game_id'] = ['in', $hasGameIds];
M('spend', 'tab_')->where($spendMap)->save(array_merge($updateData, ['is_check' => 1]));
}
if (count($hasNotGameIds) > 0) {
$spendMap['game_id'] = ['in', $hasNotGameIds];
M('spend', 'tab_')->where($spendMap)->save(array_merge($updateData, ['is_check' => 2]));
}
}
private function getPromoteGameIds($promote)
{
$service = new PromoteService();
$toTopPromote = $service->getTopPromote($promote);
$hasGameIds = $toTopPromote['game_ids'] == '' ? [] : explode(',', $toTopPromote['game_ids']);
$hasNotGameIds = M('game', 'tab_')->where(['game_id' => ['not in', $hasGameIds]])->getField('id', true);
$hasNotGameIds = $hasNotGameIds ?? [];
return [$hasGameIds, $hasNotGameIds];
}
private function getShiftCommonMap($isUserTable = false)
{
$map = ['promote_id' => $this->fromPromote['id']];
if (count($this->userIds) > 0) {
$userColumn = $isUserTable ? 'id' : 'user_id';
$map[$userColumn] = ['in', $this->userIds];
}
return $map;
}
private function shiftDeposit()
{
$map = $this->getShiftCommonMap();
$map['create_time'] = ['egt', $this->orderTime];
$toPromote = $this->toPromote;
M('deposit', 'tab_')->where($map)->save([
'promote_id' => $toPromote['id'],
'promote_account' => $toPromote['account'],
'market_admin_id' => $toPromote['admin_id'],
]);
}
private function shiftBindSpend()
{
$map = $this->getShiftCommonMap();
$map['pay_time'] = ['egt', $this->orderTime];
$toPromote = $this->toPromote;
M('bind_spend', 'tab_')->where($map)->save([
'promote_id' => $toPromote['id'],
'promote_account' => $toPromote['account']
]);
}
private function shiftUserDataCount()
{
$map = $this->getShiftCommonMap();
$map['create_time'] = ['egt', $this->orderTime];
M('user_play_data_count', 'tab_')->where($map)->save(['promote_id' => $this->toPromote['id']]);
}
}

@ -1,6 +1,7 @@
<?php
namespace Base\Service;
use Base\Business\ShiftPlayer;
use Base\Model\PromoteModel;
use Base\Model\UserPlayInfoModel;
use Base\Model\UserPlayModel;
@ -344,140 +345,12 @@ class PromoteService {
public function shiftPlayer($task)
{
$toPromoteId = $task['to_promote_id'];
$fromPromoteId = $task['from_promote_id'];
$orderTime = $task['order_time'];
$shiftIds = json_decode($task['shift_ids'], true) ?? [];
$toPromote = M('promote', 'tab_')->where(['id' => $toPromoteId])->find();
$fromPromote = M('promote', 'tab_')->where(['id' => $fromPromoteId])->find();
$toPromote = $toPromote ?? ['id' => 0, 'account' => C('OFFICIEL_CHANNEL'), 'company_id' => 0];
$fromPromote = $fromPromote ?? ['id' => 0, 'account' => C('OFFICIEL_CHANNEL'), 'company_id' => 0];
if ($fromPromote['id'] == 0 && count($shiftIds) == 0) {
return ['status' => false, 'msg' => '官方渠道玩家不能全部迁移'];
}
$map = [];
$map['promote_id'] = $fromPromote['id'];
$spendMap = $map;
if (count($shiftIds) > 0) {
$spendMap['user_id'] = $map['id'] = ['in', $shiftIds];
}
$users = M('user', 'tab_')->field(['id', 'account', 'nickname'])->where($map)->select();
$spendMap['pay_time'] = ['egt', $orderTime];
// $spendMap['is_check'] = ['in','1,2'];
$spendMap['settle_check'] = 0;
$spendMap['selle_status'] = 0;
$spendMap['pay_status'] = 1;
$payAmountRows = M('spend', 'tab_')
->field(['user_id', 'sum(pay_amount) pay_amount'])
->where($spendMap)
->group('user_id')
->select();
$payAmountRows = index_by_column('user_id', $payAmountRows);
$users = index_by_column('id', $users);
$notices = [];
$formConpany = M('promote_company', 'tab_')->field(['company_name', 'company_belong'])->where(['id' => $fromPromote['company_id']])->find();
$toConpany = M('promote_company', 'tab_')->field(['company_name', 'company_belong'])->where(['id' => $toPromote['company_id']])->find();
$belongs = PromoteCompanyService::$belongs;
$model = new Model();
$model->startTrans();
$hasError = false;
foreach ($users as $item) {
$amount = isset($payAmountRows[$item['id']]) ? round(floatval($payAmountRows[$item['id']]['pay_amount']), 2) : 0;
$status = M('mend', 'tab_')->where(['task_id' => $task['id'], 'user_id' => $item['id']])->save(['status' => 1, 'pay_amount' => $amount, 'update_time' => time()]);
if (!$status) {
$hasError = true;
}
if ($amount > 500) {
$userWord = '玩家账号' . $item['account'];
$fromWord = $fromPromote['account'] . ($formConpany ? '(' . $belongs[$formConpany['company_belong']] . '-' . $formConpany['company_name'] : '');
$toWord = $toPromote['account'] . ($toConpany ? '(' . $belongs[$toConpany['company_belong']] . '-' . $toConpany['company_name'] : '');
$content = $userWord . ', 从' . $fromWord . '换绑到' . $toWord . '换绑金额超过500达到' . $amount . '元';
$notices[] = [
'type' => 'shift-player',
'title' => '换绑额度超500',
'content' => $content,
'admin_ids' => '31',
'create_time' => time(),
'target' => $item['account'],
'start_time' => time(),
'end_time' => time() + 7*24*3600,
];
}
}
if ($hasError) {
$model->rollback();
return ['status' => false, 'msg' => '系统异常,修改补链记录失败'];
}
$toTopPromote = $this->getTopPromote($toPromote);
$hasGameIds = $toTopPromote['game_ids'] == '' ? [] : explode(',', $toTopPromote['game_ids']);
$hasNotGameIds = M('game', 'tab_')->where(['game_id' => ['not in', $hasGameIds]])->getField('id', true);
$hasNotGameIds = $hasNotGameIds ?? [];
if (count($notices) > 0) {
M('admin_notice', 'tab_')->addAll($notices);
}
$updateData = [
'promote_id' => $toPromote['id'],
'promote_account' => $toPromote['account']
];
$updateMarket = [
'market_admin_id' => $toPromote['admin_id'],
];
$map = $otherMap = ['promote_id' => $fromPromote['id']];
if (count($shiftIds) > 0) {
$map['id'] = ['in', $shiftIds];
$otherMap['user_id'] = ['in', $shiftIds];
}
$status = M('user', 'tab_')->where($map)->save($updateData);
if (!$status) {
$model->rollback();
return ['status' => false, 'msg' => '系统异常,修改用户推广员失败'];
}
try {
M('user_play', 'tab_')->where($otherMap)->save($updateData);
M('user_play_info', 'tab_')->where($otherMap)->save($updateData);
unset($spendMap['pay_status']);
if (count($hasGameIds) > 0) {
$spendMap['game_id'] = ['in', $hasGameIds];
M('spend', 'tab_')->where($spendMap)->save(array_merge($updateData, $updateMarket, ['is_check' => 1]));
}
if (count($hasNotGameIds) > 0) {
$spendMap['game_id'] = ['in', $hasNotGameIds];
M('spend', 'tab_')->where($spendMap)->save(array_merge($updateData, $updateMarket, ['is_check' => 2]));
}
$bindMap = $otherMap;
$bindMap['pay_time'] = ['egt', $orderTime];
M('bind_spend', 'tab_')->where($bindMap)->save($updateData);
$orderMap = $otherMap;
$orderMap['create_time'] = ['egt', $orderTime];
M('deposit', 'tab_')->where($orderMap)->save(array_merge($updateData, $updateMarket));
M('user_play_data_count', 'tab_')->where($orderMap)->save(['promote_id' => $toPromote['id']]);
$model->commit();
$shiftPlayer = new ShiftPlayer($task);
$shiftPlayer->handle();
return ['status' => true, 'msg' => '玩家迁移成功'];
} catch (\Exception $e) {
$model->rollback();
return ['status' => true, 'msg' => '系统异常: ' . $e->getMessage()];
return ['status' => false, 'msg' => $e->getMessage()];
}
}
@ -492,6 +365,21 @@ class PromoteService {
M('shift_task', 'sys_')->where('id=' . $task['id'])->save($data);
}
/**
* 玩家补充迁移(处理在迁移过程中玩家正在充值的订单无法迁移的问题)
*/
public function replenishShift($task)
{
try {
$shiftPlayer = new ShiftPlayer($task);
$shiftPlayer->handleReplenish();
M('shift_task', 'sys_')->where('id=' . $task['id'])->save(['is_replenished' => 1]);
return ['status' => true, 'msg' => '玩家补充迁移完成'];
} catch (\Exception $e) {
return ['status' => false, 'msg' => $e->getMessage()];
}
}
public function shift($task)
{
$result = null;

@ -2906,4 +2906,8 @@ CREATE TABLE `tab_rebate_orders` (
`send_result` varchar(255) not null DEFAULT '' COMMENT '发送结果',
`create_time` int(11) NOT NULL DEFAULT 0 COMMENT '生成时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='游戏返利订单表';
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='游戏返利订单表';
ALTER TABLE `sys_shift_task`
ADD COLUMN `is_replenished` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否已处理玩家补充迁移' AFTER `status`;
update sys_shift_task set is_replenished = 1;
Loading…
Cancel
Save