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.

752 lines
31 KiB
PHP

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
/**
* 定时自动完成
*/
namespace Admin\Controller;
use Admin\Model\SpendModel;
use Think\Think;
use Base\Tool\Printer;
use Base\Tool\TaskClient;
use Base\Service\PromoteService;
use GuzzleHttp\Client;
use think\Db;
use Base\Task\Task;
use Base\Service\MarketService;
use Base\Tool\AggregateClient;
use Base\Repository\GameRepository;
use Base\Tool\Redis;
use Think\Model;
class ConsoleController extends Think {
protected function _initialize()
{
C(api('Config/lists'));
}
public function modifyPromote()
{
$promotes = M('promote', 'tab_')->where(['parent_id' => 0])->select();
foreach ($promotes as $promote) {
$promote['chain'] = '/';
$promote['level'] = 1;
M('promote', 'tab_')->where(['id' => $promote['id']])->save(['chain' => '/', 'level' => 1]);
$subPromote = $promote;
unset($subPromote['id']);
$subPromote['parent_id'] = $promote['id'];
$subPromote['parent_name'] = $promote['account'];
$subPromote['chain'] = $promote['chain'] . $promote['id'] . '/';
$subPromote['level'] = $promote['level'] + 1;
$subPromote['account'] = 'second_' . $promote['account'];
$subPromote['nickname'] = '二级_' . $promote['nickname'];
$subPromote['mobile_phone'] = '';
$subPromote['email'] = '';
$subPromote['real_name'] = '';
$subPromote['money'] = 0;
$subPromote['total_money'] = 0;
$subPromote['balance_coin'] = 0;
$subPromote['create_time'] = time();
$subPromote['last_login_time'] = 0;
$subPromote['idcard'] = '';
M('promote', 'tab_')->add($subPromote);
$subId = M()->getLastInsID();
$subChain = $subPromote['chain'] . $subId . '/';
M('promote', 'tab_')->where(['parent_id' => $promote['id'], 'id' => ['neq', $subId]])->save([
'parent_id' => $subId,
'parent_name' => $subPromote['account'],
'chain' => $subChain,
'level' => 3,
]);
// echo M()->getLastSql() . "\n";
M('promote', 'tab_')->where(['grand_id' => $promote['id']])->save([
'chain' => ['exp', 'concat("' . $subChain. '",parent_id,"/")'],
'level' => 4,
]);
// echo M()->getLastSql() . "\n";
}
}
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);
}
foreach ($tasks as $task) {
if ($task['type'] == 1) {
$message = '推广员迁移[' . $task['id'] . ']';
$result = $promoteService->shiftPromote($task);
if ($result['status']) {
$message = 'SUCCESS ----- ' . $message . $result['msg'];
} else {
$message = 'ERROR ----- ' . $message . $result['msg'];
}
Printer::export($message);
} elseif ($task['type'] == 2) {
$message = '玩家迁移[' . $task['id'] . ']';
$result = $promoteService->shiftPlayer($task);
if ($result['status']) {
$message = 'SUCCESS ----- ' . $message . $result['msg'];
} else {
$message = 'ERROR ----- ' . $message . $result['msg'];
}
Printer::export($message);
}
}
}
public function runTask($queue = 'common', $count = 10)
{
Printer::export($queue);
Printer::export($count);
try {
$task = new Task($queue);
$task->run($count);
Printer::export('运行完成');
} catch (\Exception $e) {
Printer::export($e->getMessage());
}
}
public function addTask()
{
/* $id = M('market_shift', 'tab_')->add([
'from_id' => 1,
'to_id' => 2,
'split_time' => 0,
'created_time' => time()
]);
$params = [
'market_shift_id' => $id
]; */
for ($i=0; $i<50; $i++) {
Task::add('test', ['value' => $i]);
}
}
public function testAggregate()
{
/* $client = new AggregateClient();
$result = $client->api('game-data', ['unique_codes' => ['w123'], 'started_at' => '2019-06-27', 'ended_at' => '2020-07-27']);
var_dump($result); */
echo M('game', 'tab_')->where('id>2')->field(['id', 'game_name'])->where('sdk_version=1')->select(false);
}
public function initMarketAdmin()
{
$marketService = new MarketService();
$promoteService = new PromoteService();
$promotes = M('promote', 'tab_')->field(['id', 'admin_id', 'account', 'chain', 'level'])
->where(['level' => 1, 'admin_id' => ['gt', 0], 'company_belong' => ['in', [1, 2]]])
->select();
foreach ($promotes as $promote) {
Printer::export('处理会长: ' . $promote['account']);
$subPromotes = $promoteService->getAllChildren($promote, 0, ['id']);
$promoteIds = [$promote['id']];
$promoteIds = array_merge(array_column($subPromotes, 'id'), $promoteIds);
$marketService->shiftSpend($promoteIds, 0, $promote['admin_id']);
$marketService->shiftDeposit($promoteIds, 0, $promote['admin_id']);
}
}
public function initPromoteAdmin()
{
$promotes = M('promote', 'tab_')->field(['id', 'chain', 'level', 'admin_id'])->where(['level' => 1, 'admin_id' => ['gt', 0]])->select();
foreach ($promotes as $promote) {
M('promote', 'tab_')->where(['chain' => ['like', $promote['chain'] . $promote['id'] . '/%']])->save(['admin_id' => $promote['admin_id']]);
}
}
public function modifyLoginRepair()
{
$this->modifyLogin(1569686400);
}
public function modifyLoginGenerate($start_time=0)
{
$start_time = $start_time ? $start_time : date('Y-m-d', strtotime('-1 day'));
$this->modifyLogin(strtotime($start_time));
}
public function modifyLoginCheck($start_time=0, $end_time=0)
{
$start_time = $start_time ? strtotime($start_time) : strtotime(date("Y-m-d"));
$end_time = $end_time ? strtotime($end_time) : $start_time;
$this->modifyLogin($start_time, $end_time);
}
/**
* 登录校验
*/
private function modifyLogin($start_time=0, $end_time=0)
{
$current_time = $end_time?: strtotime(date("Y-m-d"))-86400;
for ($i=$start_time; $i<=$current_time; $i+=86400) {
$end_time = $i+86400;
$result = M()->query("SELECT
game_id,
UNIX_TIMESTAMP(FROM_UNIXTIME(login_time, '%Y-%m-%d')) create_time,
user_id,
promote_id
FROM
tab_user_login_record ulr
WHERE
login_time >= {$i} and login_time < {$end_time}
AND NOT EXISTS (
SELECT
id
FROM
tab_login_daily_record ldr
where ldr.create_time >= {$i} and ldr.create_time < {$end_time} and ldr.game_id = ulr.game_id and ldr.user_id = ulr.user_id and ldr.promote_id = ulr.promote_id
)
GROUP BY
create_time,
game_id,
user_id,
promote_id");
if ($result) {
foreach ($result as $index => $item) {
if (is_null($result[$index]['promote_id']))
{
unset($result[$index]);
}
}
$step = 500;
for ($j=0;;$j+=$step) {
$insData = array_slice($result, $j, $step);
if ($insData) {
$res = M("login_daily_record", 'tab_')->addAll($insData);
echo "写入 $res \n";
} else {
break;
}
}
} else {
echo "写入{$item['create_time']}\n";
}
}
}
public function deleteRepeatUserPlayInfo()
{
$gameIds = [157, 155, 153, 150, 151, 148, 175, 142, 143, 172, 173, 155, 154, 180];
foreach($gameIds as $gameId) {
$this->doDeleteRepeatUserPlayInfo($gameId);
}
}
public function doDeleteRepeatUserPlayInfo($gameId)
{
$sql = 'select id from tab_user_play_info a left join (
select role_id, server_id, game_id, count(1) from tab_user_play_info where server_id="' . $serverId . '" and game_id = ' . $gameId . ' GROUP BY role_id, server_id, game_id, server_name having count(1) > 1
) b on a.role_id=b.role_id where a.server_id=b.server_id and a.game_id=b.game_id and a.server_id="' . $serverId . '" and a.game_id = ' . $gameId . ' order by a.role_id, a.server_id, a.game_id';
$model = new \Think\Model();
$servers = M('server', 'tab_')->field('server_id')->where(['game_id' => $gameId])->group('server_id')->select();
foreach ($servers as $server) {
$serverId = $server['server_id'];
$sql = 'select a.id, a.role_id, a.server_id, a.game_id, a.role_level from tab_user_play_info a left join (
select role_id, server_id, game_id, count(1) from tab_user_play_info where server_id="' . $serverId . '" and game_id = ' . $gameId . ' GROUP BY role_id, server_id, game_id, server_name having count(1) > 1
) b on a.role_id=b.role_id where a.server_id=b.server_id and a.game_id=b.game_id and a.server_id="' . $serverId . '" and a.game_id = ' . $gameId . ' order by a.role_id, a.server_id, a.game_id';
// var_dump($sql);
$result = $model->query($sql);
$uniqueRole = null;
$items = [];
foreach ($result as $item) {
$items[$item['role_id']][] = $item;
}
$maxRoleIds = [];
$repeatIds = [];
foreach ($items as $roles) {
$maxRole = null;
foreach ($roles as $role) {
if ($maxRole == null) {
$maxRole = $role;
} elseif ($role['role_level'] > $maxRole['role_level']) {
$repeatIds[] = $maxRole['id'];
$maxRole = $role;
} else {
$repeatIds[] = $role['id'];
}
}
$maxRoleIds[] = $maxRole['id'];
}
if (count($repeatIds) > 0) {
M('user_play_info', 'tab_')->where(['id' => ['in', $repeatIds], 'game_id' => $gameId, 'server_id' => $serverId])->delete();
echo M()->getLastSql();
echo PHP_EOL;
}
}
}
public function deleteRepeatUserPlayInfo2()
{
$gameIds = [157, 148, 150, 151, 158, 175, 142, 143, 172, 173, 154, 155, 176, 165, 164, 179, 156, 153, 180];
foreach ($gameIds as $gameId) {
$this->doDeleteRepeatUserPlayInfo2($gameId);
}
}
public function doDeleteRepeatUserPlayInfo2($gameId)
{
$sql = 'select id from tab_user_play_info a left join (
select role_id, server_id, game_id, count(1) from tab_user_play_info where server_id="' . $serverId . '" and game_id = ' . $gameId . ' GROUP BY role_id, server_id, game_id, server_name having count(1) > 1
) b on a.role_id=b.role_id where a.server_id=b.server_id and a.game_id=b.game_id and a.server_id="' . $serverId . '" and a.game_id = ' . $gameId . ' order by a.role_id, a.server_id, a.game_id';
$model = new \Think\Model();
$servers = M('server', 'tab_')->field('server_id')->where(['game_id' => $gameId])->group('server_id')->select();
foreach ($servers as $server) {
$serverId = $server['server_id'];
$sql = 'select a.id, a.role_id, a.server_id, a.game_id, a.role_level from tab_user_play_info a left join (
select role_id, server_id, game_id, count(1) from tab_user_play_info where server_id="' . $serverId . '" and game_id = ' . $gameId . ' GROUP BY role_id, server_id, game_id having count(1) > 1
) b on a.role_id=b.role_id where a.server_id=b.server_id and a.game_id=b.game_id and a.server_id="' . $serverId . '" and a.game_id = ' . $gameId . ' order by a.role_id, a.server_id, a.game_id';
// var_dump($sql);
$result = $model->query($sql);
$uniqueRole = null;
$items = [];
foreach ($result as $item) {
$items[$item['role_id']][] = $item;
}
$maxRoleIds = [];
$repeatIds = [];
foreach ($items as $roles) {
$maxRole = null;
foreach ($roles as $role) {
if ($maxRole == null) {
$maxRole = $role;
} elseif ($role['role_level'] >= $maxRole['role_level']) {
$repeatIds[] = $maxRole['id'];
$maxRole = $role;
} else {
$repeatIds[] = $role['id'];
}
}
$maxRoleIds[] = $maxRole['id'];
}
if (count($repeatIds) > 0) {
M('user_play_info', 'tab_')->where(['id' => ['in', $repeatIds], 'game_id' => $gameId, 'server_id' => $serverId])->delete();
echo M()->getLastSql();
echo PHP_EOL;
}
}
}
public function resetIndexChart()
{
for ($i=1; $i<100; $i++) {
$item = M('index_chart', 'tab_')->where(['id' => $i])->find();
if ($item) {
$item['new_user_hours'] = json_encode(unserialize($item['new_user_hours']));
$item['active_user_hours'] = json_encode(unserialize($item['active_user_hours']));
$item['active_user_list'] = json_encode(unserialize($item['active_user_list']));
$item['pay_user_hours'] = json_encode(unserialize($item['pay_user_hours']));
$item['pay_user_list'] = json_encode(unserialize($item['pay_user_list']));
$item['pay_money_hours'] = json_encode(unserialize($item['pay_money_hours']));
$item['promote_new_hours'] = json_encode(unserialize($item['promote_new_hours']));
$item['all_count'] = json_encode(unserialize($item['all_count']));
M("index_chart_1", "tab_")->add($item);
}
}
}
public function testLogin()
{
/* $client = new Client([
'base_uri' => 'http://47.111.118.107:9501',
'timeout' => 10.0,
]);
$response = $client->post('/game-event/login', [
'form_params' => [
'user_id' => 28747,
'game_id' => 153,
'login_time' => 1577361998
]
]);
$result = (string)$response->getBody();
echo $result; */
$data = [
'user_id' => 28747,
'game_id' => 153,
'login_time' => 1577361998
];
$client = new Client([
'base_uri' => 'http://47.111.118.107:9501',
'timeout' => 5.0,
]);
$promise = $client->requestAsync('POST', '/game-event/login', [
'form_params' => $data
]);
$promise->then(
function (ResponseInterface $res) {
echo $res->getStatusCode() . PHP_EOL;
},
function (RequestException $e) {
echo $e->getMessage() . PHP_EOL;
echo $e->getRequest()->getMethod();
}
);
}
public function divideWarnCheck()
{
$redis = new \Org\RedisSDK\Redis(['host'=>'127.0.0.1','port'=>6379],[]);
$warns = M('partner_divide_warn', 'tab_')->alias('pdw')
->field('pdw.*, cgr.ratio, sum(s.pay_amount) as total_amount, p.partner')
->join('tab_partner p on pdw.partner_id = p.id')
->join('tab_game g on pdw.partner_id = g.partner_id')
->join('tab_cp_game_ratio cgr on cgr.game_id = g.id and begin_total_amount = 0 and is_del = 0')
->join('tab_game_data s on s.game_id = g.id')
->where(['pdw.status'=>1])
->group('pdw.id')
->select();
if (!$warns) return;
$taskClient = new TaskClient();
$current_time = date('Y-m-d H:i:s');
foreach ($warns as $info) {
if (!$info['ratio']) return;
$total_amount = ceil(($info['ratio'] / 100) * $info['total_amount']);
$cacheKey = "divide:warn:check:{$info['partner_id']}";
if (!($lastStep = $redis->get($cacheKey))) {
$lastStep = 0;
}
if ((intval($info['advance_amount']) - intval($total_amount)) <= $info['warming_amount']) {
if ($total_amount - $lastStep >= $info['warn_frequency']) { // 达到预警
// 发送预警短信
$content = "{$info['partner']}的预付分成款已于{$current_time}余额不足{$info['warming_amount']}元,请尽快进行充值。";
$sendRes = $taskClient->sendSmsBatch(json_decode($info['phones'], true), $content);
if ($sendRes['code'] != TaskClient::SUCCESS) {
continue;
}
// 变换缓存值如果为0需要设置过期时间
if ($lastStep) {
$redis->set($cacheKey, $total_amount);
} else {
$redis->setex($cacheKey, 86400 * 30, $total_amount);
}
}
}
}
}
public function coinRecords() {
$deposit = M('deposit', 'tab_')->field('pay_order_number,user_id,user_account,pay_status,pay_way,pay_amount,create_time as pay_time,2 as record_type')->where(['pay_status'=>1])->select(false);
// $agent = M('agent', 'tab_')->field('pay_order_number,user_id,user_account,pay_status,pay_way,real_amount as pay_amount,create_time as pay_time,3 as record_type')->where(['pay_status'=>1])->select(false);
// $spend = M('spend', 'tab_')->field('pay_order_number,user_id,user_account,pay_status,pay_way,pay_amount,pay_time,1 as record_type')->where(['pay_status' => 1,'pay_way'=>0])->select(false);
$query = M('spend', 'tab_')->field('pay_order_number,user_id,user_account,pay_status,pay_way,pay_amount,pay_time,1 as record_type')->where(['pay_status' => 1,'pay_way'=>0])->union($deposit,'pay_time')->select(false);
$model = new \Think\Model();
$datas = $model->table('(' . $query . ') a ')->order('pay_time asc')->select();
foreach ($datas as $key => $data) {
if(empty($data['pay_order_number'])) {
$order = 0;
}else {
$order = $data['pay_order_number'];
}
$data['order_number'] = $order;
$data['user_id'] = $data['user_id'];
$data['value'] = $data['pay_amount'];
$data['before_value'] = 0;
$data['after_value'] = 0;
$data['create_time'] = $data['pay_time'];
if ($data['record_type'] == 1) {
$data['type'] = 'spend';
$data['remark'] ='历史消费spend';
$data['pay_type'] = 1;
$data['value'] = -$data['pay_amount'];
}
if ($data['record_type'] == 2) {
$data['type'] = 'deposit';
$data['remark'] ='历史充值deposit';
$data['pay_type'] = 2;
$data['value'] = $data['pay_amount'];
}
M('value_detail_log', 'tab_')->add($data);
}
echo "success";
}
public function updateValue() {
//$map['type'] = ['neq', '2'];
$valueDetails = M('value_detail_log', 'tab_')->field('user_id')->where($map)->group('user_id')->select();
foreach ($valueDetails as $key => $valueDetail) {
$user_id = $valueDetail['user_id'];
$map['user_id'] = $user_id;
$userValues = M('value_detail_log', 'tab_')->where($map)->select();
$currentValue = 0;
foreach ($userValues as $userValue) {
$id = $userValue['id'];
$userValue['before_value'] = $currentValue;
$userValue['after_value'] = $currentValue + $userValue['value'];
M('value_detail_log', 'tab_')->where(['id' => $id])->save($userValue);
$after_update = M('value_detail_log', 'tab_')->where(['id'=>$id])->find();
$currentValue = $after_update['after_value'];
}
}
}
public function arpu()
{
$start = I('start', date('Y-m-d'));
$end = I('end', date('Y-m-d'));
$gameIds = I('game_ids', '');
$startTime = strtotime($start . ' 00:00:00');
$endTime = strtotime($end . ' 23:59:59');
$gameIdRows = explode(',', $gameIds);
// 新增用户
/* M('user', 'tab_')
->field('count(*) count, FROM_UNIXTIME(register_time, "%Y-%m-%d") date')
->where([
'game_id' => ['in', $gameIdRows],
'register_time' => ['between', [$startTime, $endTime]]
])
->group('date')
->select(); */
$newUsers = M('user_play', 'tab_')
->field('count(DISTINCT user_id) count, FROM_UNIXTIME(create_time, "%Y-%m-%d") date')
->where([
'game_id' => ['in', $gameIdRows],
'create_time' => ['between', [$startTime, $endTime]]
])
->group('date')
->select();
$newUsers = index_by_column('date', $newUsers);
// 活跃用户
$loginUsers = M('login_daily_record', 'tab_')
->field('count(DISTINCT user_id) count, FROM_UNIXTIME(create_time, "%Y-%m-%d") date')
->where([
'game_id' => ['in', $gameIdRows],
'create_time' => ['between', [$startTime, $endTime]]
])
->group('date')
->select();
$loginUsers = index_by_column('date', $loginUsers);
// 付费玩家,付费金额
$payLogs = M('spend', 'tab_')
->field('count(DISTINCT user_id) count, sum(pay_amount) amount, FROM_UNIXTIME(pay_time, "%Y-%m-%d") date')
->where([
'game_id' => ['in', $gameIdRows],
'pay_time' => ['between', [$startTime, $endTime]],
'pay_status' => 1,
])
->group('date')
->select();
$payLogs = index_by_column('date', $payLogs);
// 起始时间前的总充值金额
/* $beforePayAmount =M('spend', 'tab_')
->where([
'game_id' => ['in', $gameIdRows],
'pay_time' => ['lt', $startTime],
'pay_status' => 1,
])
->sum('pay_amount'); */
$rows = [];
for ($time = $startTime; $time < $endTime; $time = $time + 24*3600) {
$date = date('Y-m-d', $time);
$newUser = isset($newUsers[$date]) ? $newUsers[$date]['count'] : 0;
$loginUser = isset($loginUsers[$date]) ? $loginUsers[$date]['count'] : 0;
$payAmount = isset($payLogs[$date]) ? $payLogs[$date]['amount'] : 0;
$payUser = isset($payLogs[$date]) ? $payLogs[$date]['count'] : 0;
$rows[] = [
'date' => $date,
'new_user' => $newUser,
'login_user' => $loginUser,
'pay_amount' => $payAmount,
'pay_user' => $payUser,
'pay_rate' => $loginUser > 0 ? (round($payUser / $loginUser * 100, 2) . '%') : '--',
'arpu' => $loginUser > 0 ? (round($payAmount / $loginUser, 2)) : '0.00',
'arppu' => $payUser > 0 ? (round($payAmount / $payUser, 2)) : '0.00',
];
}
$thml = '';
$html .= '<table>' . PHP_EOL;
$html .= '<tr>' . PHP_EOL;
$html .= '<th>日期</th><th>新增用户</th><th>活跃玩家</th><th>充值金额</th><th>付费玩家</th><th>付费率</th><th>ARPU</th><th>ARPPU</th>' . PHP_EOL;
$html .= '</tr>' . PHP_EOL;
foreach ($rows as $row) {
$html .= '<tr>' . PHP_EOL;
$html .= '<td>' . $row['date'] . '</td>' . PHP_EOL;
$html .= '<td>' . $row['new_user'] . '</td>' . PHP_EOL;
$html .= '<td>' . $row['login_user'] . '</td>' . PHP_EOL;
$html .= '<td>' . $row['pay_amount'] . '</td>' . PHP_EOL;
$html .= '<td>' . $row['pay_user'] . '</td>' . PHP_EOL;
$html .= '<td>' . $row['pay_rate'] . '</td>' . PHP_EOL;
$html .= '<td>' . $row['arpu'] . '</td>' . PHP_EOL;
$html .= '<td>' . $row['arppu'] . '</td>' . PHP_EOL;
$html .= '</tr>' . PHP_EOL;
}
$html .= '<table>' . PHP_EOL;
echo $html;
// 付费率 (当日充值用户数/当日活跃用户数)
// ARPU (当日充值金额/当日活跃用户数)
// ARRPU (当日充值金额/当日充值用户数)
}
public function checkAndfreezeTestingUser()
{
$pageCount = 100;
$hasNext = true;
$lastId = 0;
do {
$testingUsers = M('testing_user', 'tab_')
->where(['status' => ['in', [1, 2]], 'id' => ['gt', $lastId]])
->order('id asc')
->limit($pageCount)
->select();
if (count($testingUser) < $pageCount) {
$hasNext = false;
}
$userIds = array_column($testingUsers, 'user_id');
$users = M('user', 'tab_')->field(['id', 'account', 'login_time'])->where(['id' => ['in', $userIds]])->select();
$users = index_by_column('id', $users);
$unloginLimitTime = 7 * 24 * 3600;
$unloginUserIds = [];
foreach ($testingUsers as $testingUser) {
$user = $users[$testingUser['user_id']] ?? null;
if ($user && (time() - $user['login_time']) > $unloginLimitTime) {
$unloginUserIds[] = $user['id'];
}
$lastId = $testingUser['id'];
}
if (count($unloginUserIds) > 0) {
M('testing_user', 'tab_')->where(['user_id' => ['in', $unloginUserIds]])->save([
'status' => 3
]);
}
} while($hasNext);
}
public function statUserRetention()
{
$begin = I('begin', date('Y-m-d'));
$end = I('end', date('Y-m-d'));
$baseGameId = I('base_game_id', 0);
$repository = new GameRepository();
$baseGame = M('base_game', 'tab_')->where(['id' => $baseGameId])->find();
$beginDate = strtotime($begin);
$endDate = strtotime($end);
$dayTime = 24 * 3600;
$trs = '';
for ($date = $beginDate; $date <= $endDate; $date = $date + $dayTime) {
$dateStr = date('Y-m-d', $date);
$userRegisterCount = $repository->getUserRegisterCount($baseGame, $dateStr);
$userRetentionCount60 = $repository->getUserRetentionCount($baseGame, $dateStr, 60);
$userRetentionCount90 = $repository->getUserRetentionCount($baseGame, $dateStr, 90);
$trs .= '<tr>' . PHP_EOL;
$trs .= '<td>' . $dateStr . '</td>' . PHP_EOL;
$trs .= '<td>' . $userRegisterCount . '</td>' . PHP_EOL;
$trs .= '<td>' . $userRetentionCount60 . '</td>' . PHP_EOL;
$trs .= '<td>' . $userRetentionCount90 . '</td>' . PHP_EOL;
$trs .= '<td>' . round($userRetentionCount60 / $userRegisterCount * 100, 2) . '%' . '</td>' . PHP_EOL;
$trs .= '<td>' . round($userRetentionCount90 / $userRegisterCount * 100, 2) . '%' . '</td>' . PHP_EOL;
$trs .= '</tr>'. PHP_EOL;
}
echo '<table>' . PHP_EOL . $trs . '</table>';
}
public function generateHistoryGame()
{
$items = M('spend', 'tab_')
->field(['tab_promote.level1_id', 'group_concat(distinct tab_spend.game_id) game_ids'])
->join('left join tab_promote on tab_spend.promote_id=tab_promote.id')
->where('tab_spend.is_check=1 and tab_spend.pay_status=1')
->group('tab_promote.level1_id')
->select();
foreach ($items as $item) {
if ($item['level1_id']) {
$key = Redis::getKey('promote_history_games', ['promote_id' => $item['level1_id']]);
Redis::set($key, $item['game_ids']);
}
}
}
public function updateHistoryGame()
{
$items = M('spend', 'tab_')
->field(['tab_promote.level1_id', 'group_concat(distinct tab_spend.game_id) game_ids'])
->join('left join tab_promote on tab_spend.promote_id=tab_promote.id')
->where('tab_spend.is_check=1 and tab_spend.pay_status=1 and tab_spend.pay_time>' . strtotime(date('Y-m-d 00:00:00')))
->group('tab_promote.level1_id')
->select();
foreach ($items as $item) {
if ($item['level1_id']) {
$key = Redis::getKey('promote_history_games', ['promote_id' => $item['level1_id']]);
$value = Redis::get($key);
$gameIds = $value ? explode(',', $value) : [];
$nowGameIds = explode(',', $item['game_ids']);
$gameIds = array_unique(array_merge($gameIds, $nowGameIds));
Redis::set($key, implode(',', $gameIds));
}
}
}
public function generatePromotesLevelId()
{
$promotes = M('promote', 'tab_')->field(['chain', 'id'])->select();
foreach ($promotes as $promote) {
$fullChain = explode('/', $promote['chain'] . $promote['id']);
M('promote', 'tab_')->where(['id' => $promote['id']])->save([
'level1_id' => $fullChain[1] ?? 0,
'level2_id' => $fullChain[2] ?? 0,
'level3_id' => $fullChain[3] ?? 0,
'level4_id' => $fullChain[4] ?? 0,
]);
}
}
public function setUserFirstPayTime()
{
$hasNext = true;
$limit = 500;
$lastId = 0;
do {
$items = M('spend', 'tab_')
->field(['user_id', 'min(pay_time) first_pay_time'])
->where(['pay_status' => 1, 'user_id' => ['gt', $lastId]])
->group('user_id')
->order('user_id asc')
->limit($limit)
->select();
$model = new Model();
$model->startTrans();
foreach ($items as $item) {
M('user', 'tab_')->where(['id' => $item['user_id']])->save([
'first_pay_time' => $item['first_pay_time']
]);
$lastId = $item['user_id'];
}
$model->commit();
if (count($items) < $limit) {
$hasNext = false;
}
} while($hasNext);
}
}