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.

622 lines
24 KiB
PHP

<?php
namespace Base\Service;
use Base\Facade\Request;
use Base\Tool\GameResource;
use Base\Repository\TestingResourceRepository;
use Base\Repository\SpendRepository;
use Think\Model;
class TestingResourceService
{
public $repository;
public function __construct()
{
$this->repository = new TestingResourceRepository();
}
public function verify($batch, $verifyAdminId = 0)
{
if ($batch['verify_status'] != 0) {
throw new \Exception('审核状态异常');
}
$batchData = [];
$batchData['verify_time'] = time();
$batchData['update_time'] = time();
$gameIds = $this->repository->getHadSettingGameIds();
if (!in_array($batch['game_id'], $gameIds)) {
$batchData['verify_status'] = 2;
$batchData['verify_remark'] = '该游戏暂不支持资源申请!';
M('testing_resource_batch', 'tab_')->where(['id' => $batch['id']])->save($batchData);
throw new \Exception('该游戏发放功能暂未实现');
}
$batchData['verify_status'] = 1;
$batchData['verify_remark'] = '审核成功';
$batchData['verify_admin_id'] = $verifyAdminId;
M('testing_resource_batch', 'tab_')->where(['id' => $batch['id']])->save($batchData);
}
public function verifyRefuse($batch, $remark = '审核拒绝', $verifyAdminId = 0)
{
if ($batch['verify_status'] != 0) {
throw new \Exception('审核状态异常');
}
$batchData = [];
$batchData['verify_time'] = time();
$batchData['update_time'] = time();
$batchData['verify_status'] = 2;
$batchData['verify_remark'] = $remark;
$batchData['verify_admin_id'] = $verifyAdminId;
M('testing_resource_batch', 'tab_')->where(['id' => $batch['id']])->save($batchData);
}
public function provideRefuse($batch, $remark = '发放失败')
{
if ($batch['verify_status'] != 1) {
throw new \Exception('该申请未审核通过');
}
if ($batch['provide_status'] != 0) {
throw new \Exception('发放状态异常');
}
M('testing_resource_order', 'tab_')
->where(['batch_id' => $batch['id']])
->save([
'provide_status' => 2,
'provide_time' => time(),
]);
M('testing_resource_batch', 'tab_')
->where(['id' => $batch['id']])
->save([
'provide_status' => 2,
'provide_time' => time(),
'update_time' => time()
]);
}
public function provide($batch)
{
if ($batch['verify_status'] != 1) {
throw new \Exception('该申请未审核通过');
}
if ($batch['provide_status'] != 0) {
throw new \Exception('发放状态异常');
}
$gameSetting = $this->repository->getGameSettingByGameId($batch['game_id']);
if (is_null($gameSetting)) {
throw new \Exception('该游戏不支持发放测试资源');
}
$role = M('user_play_info', 'tab_')
->field(['id', 'role_id', 'user_id', 'promote_id', 'user_account', 'sdk_version', 'server_id'])
->where(['game_id' => $batch['game_id'], 'role_id' => $batch['role_id']])
->find();
$orders = M('testing_resource_order', 'tab_')
->where(['batch_id' => $batch['id']])
->select();
$game = M('game', 'tab_')->field(['id', 'sdk_version'])->where(['id' => $batch['game_id']])->find();
$hasError = false;
$provideAmount = 0;
foreach ($orders as $order) {
$orderData = [];
if ($gameSetting['has_itf'] == 1) {
$gameResource = new GameResource($game);
$result = $gameResource->apply($order, $role);
$orderData = [
'result' => json_encode($result),
];
if (!$result['status']) {
$hasError = true;
$orderData['provide_status'] = 2;
} else {
$orderData['provide_status'] = 1;
}
} else {
$orderData['provide_status'] = 1;
}
$provideAmount += $order['amount'];
$orderData['provide_time'] = time();
M('testing_resource_order', 'tab_')
->where(['id' => $order['id']])
->save($orderData);
}
$batchData = [];
if ($hasError) {
$batchData['provide_status'] = 2;
} else {
$batchData['provide_status'] = 1;
}
$batchData['provide_time'] = time();
$batchData['provide_amount'] = $provideAmount;
$batchData['update_time'] = time();
M('testing_resource_batch', 'tab_')
->where(['id' => $batch['id']])
->save($batchData);
}
public function getRemainQuota($role, $bindRole = null, $gameSetting = null)
{
if (is_null($gameSetting)) {
$gameSetting = $this->repository->getGameSettingByGameId($role['game_id']);
}
if (is_null($gameSetting)) {
throw new \Exception('游戏未设置测试资源');
}
$totalQuota = $role['testing_other_quota'] + ($gameSetting['base_quota'] ?? 0);
if (!is_null($bindRole)) {
$bindTime = $bindRole['binding_time'] ?? 0;
$spendMap = [
'game_id' => $role['game_id'],
'game_player_id' => $bindRole['role_id'],
'pay_status' => 1,
'pay_time' => ['egt', strtotime(date('Y-m-d 00:00:00', $bindTime))]
];
$spendRepository = new SpendRepository();
$spendMap = $spendRepository->withIsCheck($spendMap);
$spendQuota += M('spend', 'tab_')
->where($spendMap)
->group('game_id,game_player_id')
->sum('pay_amount');
$totalQuota += round($gameSetting['rate'] / 100 * $spendQuota, 2);
}
$providedQuota = M('testing_resource_batch', 'tab_')
->where(['provide_status' => [in, [1, 2]], 'game_id' => $role['game_id'], 'role_id' => $role['role_id']])
->sum('provide_amount');
$providingQuota = M('testing_resource_batch', 'tab_')
->where(['verify_status' => [in, [0, 1]], 'provide_status' => 0, 'game_id' => $role['game_id'], 'role_id' => $role['role_id']])
->sum('apply_amount');
return round(floatval($totalQuota) - floatval($providedQuota) - floatval($providingQuota), 2);
}
public function addTestingUsers($accounts, $promote = null)
{
// 测试账号是否自动审核
$isAutoVerify = true;
$verifyStatus = 0;
$verifyTime = 0;
if ($isAutoVerify) {
$verifyStatus = 1;
$verifyTime = time();
}
$accounts = array_unique($accounts);
$existAccounts = M('testing_user', 'tab_')->where(['user_account' => ['in', $accounts]])->getField('user_account', true);
$existAccounts = $existAccounts ?? [];
$existCount = count($existAccounts);
$newAccounts = array_diff($accounts, $existAccounts);
$errorCount = 0;
$successCount = 0;
if (count($newAccounts)) {
$strCondition = '1=1';
if ($promote) {
$promoteService = new PromoteService();
$strCondition .= ' and promote_id in (' . $promoteService->subInSql($promote) . ')';
}
$users = M('user', 'tab_')->field(['id', 'account'])->where(['account' => ['in', $newAccounts], '_string' => $strCondition])->select();
$errorAccounts = array_diff($newAccounts, array_column($users, 'account'));
$errorCount = count($errorAccounts);
foreach ($users as $user) {
if (in_array($user['account'], $errorAccounts)) {
continue;
}
$data = [
'user_id' => $user['id'],
'user_account' => $user['account'],
'status' => 1,
'verify_status' => $verifyStatus,
'verify_time' => $verifyTime,
'create_time' => time(),
'update_time' => time(),
];
M('testing_user', 'tab_')->add($data);
$successCount ++;
}
}
return [
'errorCount' => $errorCount,
'successCount' => $successCount,
'existCount' => $existCount,
];
}
public function saveGameSetting($params)
{
$gameId = $params['base_game_id'] ?? 0;
$baseQuota = $params['base_quota'] ?? 0;
$rate = $params['rate'] ?? 0;
if ($gameId == 0) {
throw new \Exception('请选择游戏');
}
$data = [
'base_game_id' => $gameId,
'base_quota' => $baseQuota,
'rate' => $rate,
];
$setting = M('testing_game_setting', 'tab_')->where(['base_game_id' => $gameId])->find();
if ($setting) {
$data['update_time'] = time();
M('testing_game_setting', 'tab_')->where(['base_game_id' => $gameId])->save($data);
} else {
$data['create_time'] = time();
$data['update_time'] = time();
M('testing_game_setting', 'tab_')->add($data);
}
}
public function bindRole($params, $promote = null)
{
$gameId = $params['game_id'] ?? 0;
$testingRoleId = $params['testing_role_id'] ?? '';
$bindRoleId = $params['bind_role_id'] ?? '';
$testingGameRoleId = $this->repository->getGameRoleId($gameId, $testingRoleId);
$bindGameRoleId = $this->repository->getGameRoleId($gameId, $bindRoleId);
$testingRole = M('user_play_info', 'tab_')
->field(['id', 'role_id', 'user_id', 'game_id', 'promote_id'])
->where(['game_role_id' => $testingGameRoleId])
->find();
if (is_null($testingRole)) {
throw new \Exception('测试账号角色不存在');
}
$testingUser = M('testing_user', 'tab_')->where(['user_id' => $testingRole['user_id']])->find();
if (is_null($testingUser)) {
throw new \Exception('测试账号不存在');
}
if ($testingUser['verify_status'] != 1) {
throw new \Exception('测试账号未审核通过');
}
if (!in_array($testingUser['status'], [1, 2])) {
throw new \Exception('测试账号已禁用');
}
$promoteService = new PromoteService();
$testPromote = M('promote', 'tab_')->field(['id', 'chain'])->where(['id' => $testingRole['promote_id']])->find();
if (is_null($testPromote) || ($promote && !$promoteService->isSubOrSelf($testPromote, $promote))) {
throw new \Exception('测试角色所属推广员异常');
}
$bindRole = M('user_play_info', 'tab_')
->field(['id', 'role_id', 'user_id', 'promote_id'])
->where(['game_role_id' => $bindGameRoleId])
->find();
if (is_null($bindRole)) {
throw new \Exception('玩家角色不存在');
}
$bindPromote = M('promote', 'tab_')->field(['id', 'chain'])->where(['id' => $bindRole['promote_id']])->find();
if (is_null($bindPromote) || ($promote && !$promoteService->isSubOrSelf($bindPromote, $promote))) {
throw new \Exception('玩家账号所属推广员异常');
}
/* if ($testPromote['id'] != $bindPromote['id']) {
throw new \Exception('玩家账号与测试账号非同一推广员');
} */
$bindIsTesting = M('testing_user', 'tab_')->where(['user_id' => $bindRole['user_id']])->find();
if ($bindIsTesting) {
throw new \Exception('该玩家账号为测试账号,无法绑定');
}
$existBind = M('testing_binding', 'tab_')->field(['id'])->where(['game_id' => $gameId, 'bind_role_id' => $bindRoleId])->find();
if ($existBind) {
throw new \Exception('该玩家角色已被绑定');
}
$testExistBind = M('testing_binding', 'tab_')->field(['id'])->where(['game_id' => $gameId, 'role_id' => $testingRoleId])->find();
if ($testExistBind) {
throw new \Exception('该测试账号角色已绑定有角色');
}
$status = M('testing_binding', 'tab_')->add([
'game_id' => $testingRole['game_id'],
'user_id' => $testingRole['user_id'],
'role_id' => $testingRole['role_id'],
'bind_user_id' => $bindRole['user_id'],
'bind_role_id' => $bindRole['role_id'],
'create_time' => time(),
'update_time' => time()
]);
if (!$status) {
throw new \Exception('绑定角色异常');
}
}
public function unbindRole($bindingId)
{
return M('testing_binding', 'tab_')->where(['id' => $bindingId])->delete();
}
public function apply($params, $promote = null, $adminId = 0)
{
$gameId = $params['game_id'] ?? 0;
$roleId = $params['role_id'] ?? '';
$serverId = $params['server_id'] ?? 0;
$userAccount = $params['user_account'] ?? '';
$records = $params['records'] ?? [];
if ($promote && $promote['level'] > 2) {
throw new \Exception('权限不足');
}
$game = M('game', 'tab_')->where(['id' => $gameId])->find();
$resources = $this->getResources($game);
$gameSetting = $this->repository->getGameSettingByGameId($gameId);
if (is_null($gameSetting)) {
throw new \Exception('该游戏不支持发放测试资源');
}
$binding = M('testing_binding', 'tab_')->where(['game_id' => $gameId, 'role_id' => $roleId])->find();
/* if (is_null($binding)) {
throw new \Exception('该角色未绑定玩家角色');
} */
$user = M('user', 'tab_')->field(['id', 'promote_id'])->where(['account' => $userAccount])->find();
if (is_null($user)) {
throw new \Exception('玩家账号不存在');
}
$testingUser = M('testing_user', 'tab_')->where(['user_id' => $user['id']])->find();
if (is_null($testingUser)) {
throw new \Exception('测试账号不存在');
}
if ($testingUser['verify_status'] != 1) {
throw new \Exception('测试账号未审核通过');
}
if (!in_array($testingUser['status'], [1, 2])) {
throw new \Exception('测试账号已禁用');
}
$server = M('server', 'tab_')->field(['id', 'server_name', 'server_id'])->where(['id' => $serverId])->find();
if (is_null($server)) {
throw new \Exception('区服不存在');
}
$promoteService = new PromoteService();
$role = M('user_play_info', 'tab_')
->field(['id', 'role_id', 'promote_id', 'game_id', 'testing_other_quota'])
->where(['user_id' => $user['id'], 'game_id' => $gameId, 'server_id' => $server['server_id'], 'role_id' => $roleId])
->find();
if (is_null($role)) {
throw new \Exception('角色不存在');
}
$otherRoleBatch = M('testing_resource_batch', 'tab_')
->where([
'user_id' => $user['id'],
'game_id' => $gameId,
'server_id' => $server['server_id'],
'role_id' => ['neq', $roleId],
'verify_status' => ['in', [0, 1]],
])
->find();
if ($otherRoleBatch) {
throw new \Exception('每个账号同区服只能申请一个角色');
}
$testPromote = M('promote', 'tab_')->field(['id', 'chain'])->where(['id' => $role['promote_id']])->find();
if (is_null($testPromote) || ($promote && !$promoteService->isSubOrSelf($testPromote, $promote))) {
throw new \Exception('测试角色所属推广员异常');
}
$bindingRole = null;
if ($binding) {
$bindingRole = M('user_play_info', 'tab_')
->field(['id', 'role_id', 'user_id', 'promote_id', 'game_id'])
->where(['game_id' => $gameId, 'role_id' => $binding['bind_role_id']])
->find();
if (is_null($bindingRole)) {
throw new \Exception('绑定玩家角色不存在');
}
$bindingRole['binding_time'] = $binding['create_time'];
$bindPromote = M('promote', 'tab_')->field(['id', 'chain'])->where(['id' => $bindingRole['promote_id']])->find();
if (is_null($bindPromote) || ($promote && !$promoteService->isSubOrSelf($bindPromote, $promote))) {
throw new \Exception('绑定角色所属推广员异常');
}
/* if ($testPromote['id'] != $bindPromote['id']) {
throw new \Exception('测试账号与玩家账号所属推广员不同');
} */
}
$hasItf = ($gameSetting['has_itf'] == 1);
$amount = 0;
if ($hasItf) {
foreach ($records as $key => $record) {
if (isset($resources[$record['resource_id']])) {
$value = $resources[$record['resource_id']]['amount'];
$records[$key]['value'] = $value;
$records[$key]['resource_name'] = $resources[$record['resource_id']]['name'];
$amount += $record['num'] * $value;
} else {
throw new \Exception('含有资源内容不存在');
}
/**
* @todo 游戏猫只能每个资源数量只能为1
*/
if ($record['num'] != 1) {
throw new \Exception('该游戏每次申请单项资源数量只能为1');
}
}
} else {
foreach ($records as $key => $record) {
if (empty($record['amount'])) {
throw new \Exception('请输入资源价值');
}
if (empty($record['remark'])) {
throw new \Exception('请输入资源备注');
}
$amount += $record['amount'];
}
}
$remainQuota = $this->getRemainQuota($role, $bindingRole, $gameSetting);
if ($amount > $remainQuota) {
throw new \Exception('额度不足');
}
$olderBatch = M('testing_resource_batch', 'tab_')
->field(['id'])
->where(['user_id' => $testingUser['user_id'], 'game_id' => $gameId, 'verify_status' => 1])
->find();
$batchNo = date('YmdHis') . substr(md5($roleId . strval(microtime(true)) . rand(0, 9999)), 8, 16);
try {
$model = new Model();
$model->startTrans();
$batch = [
'batch_no' => $batchNo,
'user_id' => $testingUser['user_id'],
'game_id' => $gameId,
'role_id' => $roleId,
'server_id' => $serverId,
'apply_promote_id' => $promote ? $promote['id'] : 0,
'apply_admin_id' => $adminId,
'apply_amount' => $amount,
'provide_status' => 0,
'verify_status' => 0,
'auto_verify' => $gameSetting['has_itf'] == 1 && $olderBatch ? 1 : 0,
'create_time' => time(),
'update_time' => time(),
];
$batchId = M('testing_resource_batch', 'tab_')->add($batch);
$i = 1;
foreach ($records as $record) {
$orderNo = $batchNo . '_' . $i;
$order = [
'batch_id' => $batchId,
'order_no' => $orderNo,
'ref_id' => $record['resource_id'] ?? '',
'ref_name' => isset($record['resource_name']) ? $record['resource_name'] : ($record['remark'] ?? ''),
'ref_amount' => isset($record['amount']) ? $record['amount'] : $record['value'],
'num' => $record['num'] ?? 1,
'amount' => isset($record['amount']) ? $record['amount'] : ($record['num'] * $record['value']),
'remark' => $record['remark'],
];
M('testing_resource_order', 'tab_')->add($order);
}
$model->commit();
} catch (\Exception $e) {
$model->rollback();
throw new \Exception('系统异常' . $e->getMessage());
}
}
public function getResourceTypes($game)
{
$gameSetting = $this->repository->getGameSettingByGameId($game['id']);
if ($gameSetting['has_itf'] == 0) {
return [];
}
$gameResource = new GameResource($game);
return $gameResource->getResourceTypes();
}
public function getResources($game, $typeId = null)
{
$gameSetting = $this->repository->getGameSettingByGameId($game['id']);
if ($gameSetting['has_itf'] == 0) {
return [];
}
$gameResource = new GameResource($game);
return $gameResource->getResources($typeId);
}
public function getHasItfGameIds()
{
$gameSettings = $this->repository->getGameSettings();
$baseGameIds = [];
foreach ($gameSettings as $gameSetting) {
if ($gameSetting['has_itf'] == 1) {
$baseGameIds[] = $gameSetting['base_game_id'];
}
}
$baseGames = [];
if (count($baseGameIds) > 0) {
$baseGames = M('base_game', 'tab_')->where(['id' => ['in', $baseGameIds]])->select();
}
if (empty($baseGames)) {
return [];
} else {
return array_merge(array_column($baseGames, 'android_game_id'), array_column($baseGames, 'ios_game_id'));
}
}
public function verifyTestingUser($userIds, $verifyStatus)
{
if (count($userIds) == 0) {
throw new \Exception('请选择要审核的测试账号');
}
if (!in_array($verifyStatus, [1, 2])) {
throw new \Exception('状态值异常');
}
$testingUsers = M('testing_user', 'tab_')->where(['verify_status' => 0, 'user_id' => ['in', $userIds]])->get();
if (count($testingUsers) == 0) {
throw new \Exception('含有非待审核的测试账号');
}
M('testing_user', 'tab_')->where(['user_id' => ['in', $userIds]])->save([
'status' => $verifyStatus
]);
}
public function freezeTestingUser($userId)
{
$testingUser = M('testing_user', 'tab_')->where(['user_id' => $userId])->find();
if (is_null($testingUser)) {
throw new \Exception('测试账号不存在');
}
M('testing_user', 'tab_')->where(['user_id' => $userId])->save([
'status' => 3
]);
}
public function unfreezeTestingUser($userId)
{
$testingUser = M('testing_user', 'tab_')->where(['user_id' => $userId])->find();
if (is_null($testingUser)) {
throw new \Exception('测试账号不存在');
}
M('testing_user', 'tab_')->where(['user_id' => $userId])->save([
'status' => 1
]);
}
public function deleteTestingUser($userId)
{
$testingUser = M('testing_user', 'tab_')->where(['user_id' => $userId])->find();
if (is_null($testingUser)) {
throw new \Exception('测试账号不存在');
}
if ($testingUser['verify_status'] != 2) {
throw new \Exception('只有审核拒绝的测试账号才能删除');
}
M('testing_user', 'tab_')->where(['user_id' => $userId])->delete();
}
}