repository = new TestingResourceRepository(); } public function verify($batch) { if ($batch['verify_status'] != 0) { throw new \Exception('审核状态异常'); } $batchData = []; $batchData['verify_time'] = time(); $batchData['update_time'] = time(); if (!in_array($batch['game_id'], [229, 230])) { $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'] = '审核成功'; M('testing_resource_batch', 'tab_')->where(['id' => $batch['id']])->save($batchData); } public function provide($batch) { if ($batch['verify_status'] != 1) { throw new \Exception('该申请未审核通过'); } if ($batch['provide_status'] != 0) { throw new \Exception('发放状态异常'); } $role = M('user_play_info', 'tab_') ->field(['id', 'role_id', 'user_id', 'promote_id', 'user_account', 'sdk_version']) ->where(['game_id' => $batch['game_id'], 'role_id' => $batch['role_id']]) ->find(); $orders = M('testing_resource_order', 'tab_') ->where(['batch_id' => $batch['id']]) ->select(); $hasError = false; $provideAmount = 0; foreach ($orders as $order) { $result = $this->provideFromGameCat($order, $role); $orderData = [ 'result' => json_encode(['code' => $result['code'], 'message' => $result['message']]), ]; if (!$result['status']) { $hasError = true; $orderData['provide_status'] = 2; } else { $orderData['provide_status'] = 1; } $provideAmount += round($order['ref_amount'] * $order['num'], 2); $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 provideFromGameCat($order, $role) { $gameCatClient = new GameCatClient(); $result = $gameCatClient->api('provide', [ 'roleId' => $role['role_id'], 'amount' => intval($order['ref_amount']), 'supportItem' => $order['ref_id'], 'supportType' => '0', 'channelUid' => $role['user_account'], 'applyRemark' => $order['remark'] == '' ? '测试资源申请' : $order['remark'], 'applyId' => $order['order_no'], 'device_type' => $role['sdk_version'] == 1 ? 'andriod' : 'ios', ]); if ($result['state'] == 1 && $result['data']) { return [ 'status' => true, 'message' => $result['msg'], 'code' => 1, ]; } else { return [ 'status' => false, 'msg' => $result['msg'], 'code' => $result['state'], ]; } } 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)) { $totalQuota += M('spend', 'tab_') ->where(['game_id' => $role['game_id'], 'game_player_id' => $bindRole['role_id'], 'pay_status' => 1]) ->group('game_id,game_player_id') ->sum('pay_amount'); } $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) { $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, '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) { $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('测试账号不存在'); } $promoteService = new PromoteService(); $testPromote = M('promote', 'tab_')->field(['id', 'chain'])->where(['id' => $testingRole['promote_id']])->find(); if (is_null($testPromote) || !$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) || !$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 apply($params, $promote = null) { $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('权限不足'); } $resources = []; if ($gameId == 229) { $resources = $this->getGameCatResources('android'); } elseif ($gameId == 230) { $resources = $this->getGameCatResources('ios'); } else { 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('测试账号不存在'); } $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('绑定玩家角色不存在'); } $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 = false; $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']; } } $testingResourceService = new TestingResourceService(); $remainQuota = $testingResourceService->getRemainQuota($role, $bindingRole); if ($amount > $remainQuota) { throw new \Exception('额度不足'); } $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_amount' => $amount, 'provide_status' => 0, 'verify_status' => 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()); } } private function getGameCatResources($deviceType) { $resources = []; $gameCatClient = new GameCatClient(); $result = $gameCatClient->api('get-pay-type', ['device_type' => $deviceType]); if ($result['state'] == 1) { $items = $result['data']; foreach ($items as $item) { $resources[$item['supportItem']] = [ 'ref_id' => $item['supportItem'], 'name' => $item['content'], 'amount' => $item['amount'], ]; } } return $resources; } }