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; $provideAmount += $order['amount']; } } 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; $gameIds = $bindRole['share_game_ids']; $spendMap = [ 'game_id' => ['in', $gameIds], '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) ->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(); $permissionPromote = $promoteService->getTSPermPromote($promote); $strCondition .= ' and promote_id in (' . $promoteService->subInSql($permissionPromote) . ')'; } $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(); $permissionPromote = $promoteService->getTSPermPromote($promote); $testPromote = M('promote', 'tab_')->field(['id', 'chain'])->where(['id' => $testingRole['promote_id']])->find(); if (is_null($testPromote) || ($permissionPromote && !$promoteService->isSubOrSelf($testPromote, $permissionPromote))) { throw new \Exception('测试角色所属推广员异常'); } $game = M('game', 'tab_')->where(['id' => $gameId])->find(); if (is_null($game)) { throw new \Exception('游戏不存在'); } $gameIds = [$gameId]; if ($game['data_share'] == 1) { $gameRepository = new GameRepository(); $baseGames = $gameRepository->getBaseGames(); $baseGame = $gameRepository->getBaseGameByGameId($gameId, $baseGames); if (is_null($baseGame)) { throw new \Exception('游戏不存在'); } $gameIds = $gameRepository->getGameIdsByBaseGame($baseGame); } $bindRole = M('user_play_info', 'tab_') ->field(['id', 'role_id', 'user_id', 'promote_id']) ->where(['role_id' => $bindRoleId, 'game_id' => ['in', $gameIds]]) ->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) || ($permissionPromote && !$promoteService->isSubOrSelf($bindPromote, $permissionPromote))) { 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('该玩家账号为测试账号,无法绑定'); } $existBindCount = M('testing_binding', 'tab_')->where(['game_id' => ['in', $gameIds], 'bind_role_id' => $bindRoleId])->count(); if ($existBindCount >= 2) { throw new \Exception('同一角色最多只能被绑定两次'); } $testExistBind = M('testing_binding', 'tab_')->field(['id'])->where(['game_id' => ['in', $gameIds], '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'] ?? []; $promoteService = new PromoteService(); $permissionPromote = $promoteService->getTSPermPromote($promote); if ($permissionPromote && $permissionPromote['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('区服不存在'); } $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) || ($permissionPromote && !$promoteService->isSubOrSelf($testPromote, $permissionPromote))) { throw new \Exception('测试角色所属推广员异常'); } $bindingRole = null; if ($binding) { $gameRepository = new GameRepository(); $baseGames = $gameRepository->getBaseGames(); $gameIds = [$gameId]; if ($game['data_share'] == 1) { $baseGame = $gameRepository->getBaseGameByGameId($gameId, $baseGames); $gameIds = $gameRepository->getGameIdsByBaseGame($baseGame); } $bindingRole = M('user_play_info', 'tab_') ->field(['id', 'role_id', 'user_id', 'promote_id', 'game_id']) ->where(['game_id' => ['in', $gameIds], 'role_id' => $binding['bind_role_id']]) ->find(); if (is_null($bindingRole)) { throw new \Exception('绑定玩家角色不存在'); } $bindingRole['share_game_ids'] = $gameIds; $bindingRole['binding_time'] = $binding['create_time']; $bindPromote = M('promote', 'tab_')->field(['id', 'chain'])->where(['id' => $bindingRole['promote_id']])->find(); if (is_null($bindPromote) || ($permissionPromote && !$promoteService->isSubOrSelf($bindPromote, $permissionPromote))) { 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(); } }