Register.php 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730
  1. <?php
  2. /**
  3. * api注册控制器
  4. */
  5. namespace app\api\controller\v1;
  6. use app\api\controller\Api;
  7. use app\api\library\MemberDevice;
  8. use app\common\library\IpLimit;
  9. use app\common\model\Members;
  10. use app\common\model\Channel;
  11. use app\common\model\ChannelFrozen;
  12. use app\common\model\Logininfo;
  13. use app\common\model\Subaccount;
  14. use app\common\library\JwtToken;
  15. use app\common\library\Sms;
  16. use app\common\logic\Member as MemberLogic;
  17. use app\common\service\FkStrategiesService;
  18. use app\service\TiktokService;
  19. use think\Db;
  20. use think\Env;
  21. use think\Exception;
  22. use app\common\logic\Coin;
  23. use think\Cache;
  24. use app\common\model\Setting;
  25. use think\Request;
  26. class Register extends Api
  27. {
  28. /**
  29. * 用户注册处理
  30. * return array
  31. */
  32. public function index()
  33. {
  34. // if(temporary()){
  35. // $this->jsonResult('', 0, '禁止登录');
  36. // }
  37. $ip = $_SERVER['REMOTE_ADDR'];
  38. $imeil = trim($this->input('imeil'));
  39. $memberModel = new Members;
  40. $frozenModel = new ChannelFrozen;
  41. $channelModel = new Channel;
  42. $settingModel = new Setting();
  43. $type = $this->input('type'); //注册类型,为mobile时表示手机号注册
  44. $code = $this->input('sms_code'); //短信验证码
  45. $password = trim($this->input('password','')); //明文密码
  46. $gameid = $this->input('gameid');
  47. $dy_channel_id = $this->input('dy_channel_id',0);
  48. $channel_id = $this->input('channel_id');
  49. $oaid = $this->input('oaid','');
  50. $androidid = $this->input('androidid','');
  51. $imei = $this->input('imei','');
  52. //海外游戏ip限制
  53. if(in_array($gameid,config('haiwai_game_ids'))){
  54. $res = (new IpLimit())->validateIp(request()->ip(),strtolower(trim($this->input('username',''))));
  55. if($res != 1){
  56. $this->jsonResult('', -110, '国内用户禁止登录');
  57. }
  58. }
  59. $data = [
  60. 'username' => strtolower(trim($this->input('username',''))),
  61. 'password' => $password,
  62. 'device' => $this->input('device'),
  63. 'gameid' => $gameid,
  64. 'imeil' => $imeil,
  65. 'channel_id' => $channel_id,
  66. 'deviceinfo' => $this->input('deviceinfo'),
  67. 'mobile' => '',
  68. ];
  69. // file_put_contents(ROOT_PATH.'3.txt',var_export($data,true)."\n",FILE_APPEND);
  70. log_message(var_export($data,true)."\n",'log',LOG_PATH . 'register/');
  71. $result = $this->validate($data,
  72. [
  73. ['username', 'require|length:6,11|alphaNum', '请输入用户名| 用户名长度为 6 - 11|用户名只能是字母或者数字'],
  74. ['password', 'require|length:6,15', '请输入密码|密码长度为 6 - 15'],
  75. ['device', 'require|integer', '获取不到设置信息|设备信息必须为整型'],
  76. ['gameid', 'require|integer|gt:0', '游戏ID不能为空|游戏ID必须为整型|游戏ID必须大于0'],
  77. ['channel_id', 'require|integer', '渠道不能为空|渠道错误'],
  78. ['imeil', 'require', '设备imeil不能为空']
  79. ]);
  80. if (true !== $result) {
  81. $this->jsonResult('', -100, $result);
  82. }
  83. $channelInfo = $channelModel->where(['status'=>1,'id'=>$channel_id])->find();
  84. if(!$channelInfo && intval($channel_id)<>config('EMPTY_CHANNEL_ID'))
  85. {
  86. $this->jsonResult('',-120,'渠道信息不存在');
  87. }
  88. else if($channelInfo['level'] <> 3){
  89. $this->jsonResult('', -120, '非推广员渠道,不能进行推广,请联系客服');
  90. }
  91. if (!$game = model('Common/Game')->where(['id' => $gameid])->find()) {
  92. $this->jsonResult('', -120, '游戏信息不存在');
  93. }
  94. if ($game['cooperation_status'] == 3) {
  95. $this->jsonResult('', -120, '游戏已下架不存在');
  96. }
  97. if ($game['is_register'] == 1) {
  98. $gameInfo = Db::table('cy_gameinfo')->where(['game_id' => $gameid])->field('ban_register_msg, ban_channel_ids')->find();
  99. // 判断当前渠道是否在封禁渠道列表中
  100. $banChannelIds = $gameInfo['ban_channel_ids'] ?? '';
  101. if (!empty($banChannelIds)) {
  102. $isBanChannel = false;
  103. if ($banChannelIds === 'all') {
  104. // 所有渠道都封禁
  105. $isBanChannel = true;
  106. } else {
  107. $banIds = explode(',', $banChannelIds);
  108. $banIds = array_filter(array_map('intval', $banIds));
  109. // 判断当前渠道是否直接在封禁列表中
  110. if (in_array(intval($channel_id), $banIds)) {
  111. $isBanChannel = true;
  112. } else {
  113. // 判断当前渠道的上级渠道是否在封禁列表中
  114. $channelInfo = Db::name('nw_channel')->where(['id' => $channel_id])->field('parent_id, level')->find();
  115. if (!empty($channelInfo)) {
  116. // 获取所有上级渠道ID
  117. $parentIds = [];
  118. $parentId = $channelInfo['parent_id'];
  119. while ($parentId > 0) {
  120. $parentIds[] = $parentId;
  121. $parent = Db::name('nw_channel')->where(['id' => $parentId])->field('parent_id')->find();
  122. $parentId = $parent ? $parent['parent_id'] : 0;
  123. }
  124. // 判断上级渠道是否在封禁列表中
  125. if (!empty(array_intersect($parentIds, $banIds))) {
  126. $isBanChannel = true;
  127. }
  128. }
  129. }
  130. }
  131. // 如果当前渠道在封禁列表中,返回封禁提示
  132. if ($isBanChannel) {
  133. $ban_register_msg = '目前游戏禁止注册!';
  134. if (!empty($gameInfo['ban_register_msg'])) {
  135. $ban_register_msg = $gameInfo['ban_register_msg'];
  136. }
  137. $this->jsonResultUnescape('', -120, $ban_register_msg);
  138. }
  139. } else {
  140. // 没有设置封禁渠道,走原来的逻辑(全部封禁)
  141. $ban_register_msg = '目前游戏禁止注册!';
  142. if (!empty($gameInfo['ban_register_msg'])) {
  143. $ban_register_msg = $gameInfo['ban_register_msg'];
  144. }
  145. $this->jsonResultUnescape('', -120, $ban_register_msg);
  146. }
  147. }
  148. // ## 指定游戏限制只能手机号注册 ##
  149. if(in_array($data['gameid'], ['344', '345']) && 'mobile' != $type){
  150. $this->jsonResultUnescape('', -120, '当前注册方式已关闭,请使用手机号注册!');
  151. }
  152. // 游客注册时
  153. if ('visitor' == $type) {
  154. $this->jsonResult('', -120, '已关闭游客模式,请注册账号!客服QQ:' . CUSTOMER_SERVICE_QQ);
  155. // 判断是否已有注册游客(imeil为限制条件)
  156. $memberInfo = Db::table('cy_memberstwo a,cy_members b')
  157. ->field('a.userid, b.username')
  158. ->where('a.userid=b.id')
  159. ->where([
  160. 'b.imeil' => $imeil,
  161. 'a.realname'=> '-1',
  162. 'a.idcard' => '-1'
  163. ])
  164. ->find();
  165. // 游客账号已存在,直接登录
  166. if ($memberInfo) {
  167. //判断游戏是否冻结IP或者IMEI
  168. $LoginIp = request()->ip();
  169. $BannedInfo = model('GameBanned')->where(['game_id'=>array('in',[0,$gameid]), 'banned_type'=>'ip','banned_device'=> $LoginIp])->find();
  170. if(!empty($BannedInfo)){
  171. $template = '【封禁提示】IP禁止注册:' .' ip:'.$LoginIp;
  172. curlDD($template, Env::get('notice_weelfar_url'), true);
  173. $this->jsonResult('',-120,'您的IP已被禁止登录此游戏! ');
  174. }
  175. if($imeil){
  176. $BannedInfo = model('GameBanned')->where(['game_id'=>array('in',[0,$gameid]), 'banned_type'=>'imeil','banned_device'=> $imeil])->find();
  177. if(!empty($BannedInfo)){
  178. $template = '【封禁提示】设备禁止注册:' .' imeil:'.$imeil;
  179. curlDD($template, Env::get('notice_weelfar_url'), true);
  180. $this->jsonResult('',-120,'该设备已被禁止登录此游戏! ');
  181. }
  182. }
  183. // 渠道禁止判断
  184. if (isFrozenOption($data['channel_id'],$gameid,'member_login')) {
  185. $this->jsonResult('',-120,'您所在渠道已经被禁止登录此游戏! ');
  186. }
  187. //密码加密,用于生成旧SDK的memkey
  188. $data['password'] = auth_code($data['password'],"ENCODE", Env::get($this->aesKey));
  189. // 登录处理
  190. $returnData = $this->loginProcess(array_merge($data, [
  191. 'userid' => $memberInfo['userid'],
  192. 'username' => $memberInfo['username'],
  193. 'gameid' => $gameid])
  194. );
  195. $this->jsonResultUnescape($returnData, 200, '注册成功!');
  196. }
  197. }
  198. //手机注册时,短信验证
  199. if('mobile' == $type)
  200. {
  201. $sms = new Sms;
  202. $codeResult = $sms->checkCode($data['username'], $code);
  203. if(!$codeResult['status']) {
  204. $this->jsonResult('', -120, $codeResult['msg']);
  205. }
  206. $data['mobile'] = $data['username'];
  207. }
  208. if(!empty($memberModel->field('id')->where(['username' => $data['username']])->find())) {
  209. $this->jsonResult('', -120, '用户已经存在');
  210. }
  211. //空渠道游戏不可注册开关开启,渠道ID=100做为默认渠道(空渠道)
  212. if($data['channel_id']==config('EMPTY_CHANNEL_ID')){
  213. $empty_register_switch = $settingModel::getSetting('EMPTY_REGISTER_SWITCH');
  214. if($empty_register_switch){
  215. $this->jsonResult('', -120, '渠道号为空,无法注册');
  216. }
  217. }
  218. else {
  219. //未分包渠道的游戏不可注册开关开启
  220. $channel_register_switch = $settingModel::getSetting('CHANNEL_REGISTER_SWITCH');
  221. if($channel_register_switch){
  222. $conditions = array();
  223. $conditions['gameid'] = $gameid;
  224. $conditions['channel_id'] = $data['channel_id'];
  225. // $conditions['status'] = 1;
  226. $conditions['upload_status'] = 1;
  227. $conditions['filename'] = array("neq","");
  228. $subPackageCnt = model('SdkGameList')->where($conditions)->count();
  229. if(!$subPackageCnt){
  230. $this->jsonResult('', -120, '渠道暂未分包,无法注册用户');
  231. }
  232. }
  233. }
  234. //判断游戏是否冻结IP或者IMEI
  235. $LoginIp = request()->ip();
  236. $BannedInfo = model('GameBanned')->where(['game_id'=>array('in',[0,$gameid]), 'banned_type'=>'ip','banned_device'=> $LoginIp])->find();
  237. if(!empty($BannedInfo)){
  238. $template = '【封禁提示】IP禁止注册:' .' ip:'.$LoginIp;
  239. curlDD($template, Env::get('notice_weelfar_url'), true);
  240. $this->jsonResult('',-120,'您的IP已被禁止注册此游戏! ');
  241. }
  242. if($imeil){
  243. $BannedInfo = model('GameBanned')->where(['game_id'=>array('in',[0,$gameid]), 'banned_type'=>'imeil','banned_device'=> $imeil])->find();
  244. if(!empty($BannedInfo)){
  245. $template = '【封禁提示】设备禁止注册:' .' imeil:'.$imeil;
  246. curlDD($template, Env::get('notice_weelfar_url'), true);
  247. $this->jsonResult('',-120,'该设备已被禁止注册此游戏! ');
  248. }
  249. }
  250. //是否禁止注册
  251. if (isFrozenOption($data['channel_id'],$data['gameid'],'register')) {
  252. $this->jsonResult('', -120, '您所在渠道已经被禁止注册此游戏');
  253. }
  254. //渠道注册限制检查
  255. $this->chkChannelConfig($data['channel_id'],$data['gameid']);
  256. //当前时间
  257. $now_time = NOW_TIMESTAMP;
  258. //密码加密
  259. $data['password'] = auth_code($data['password'],"ENCODE", Env::get($this->authKey));
  260. $data['reg_time'] = $now_time;
  261. $data['login_time'] = $now_time;
  262. $data['ip'] = request()->ip();
  263. $data['dy_channel_id'] = $dy_channel_id;
  264. // ## 注册管控 ##
  265. if($ip && regidterHandle($ip, $imeil) == false){
  266. $this->jsonResult('', -120, '当前注册已达上限!');
  267. }
  268. // 启动事务
  269. Db::startTrans();
  270. try{
  271. $member_id = $memberModel->insertGetId($data);
  272. if ($member_id) {
  273. // 插入玩家历史记录
  274. Db::table('cy_member_history')->insert([
  275. 'userid' => $member_id,
  276. 'password' => $data['password'],
  277. 'mobile' => $data['mobile'],
  278. 'ip' => request()->ip(),
  279. 'create_time' => $now_time
  280. ]);
  281. $realname = '';
  282. $idcard = '';
  283. // 游客注册 增加组合标识 认证字段双-1
  284. if ( 'visitor' == $type ) {
  285. $realname = -1;
  286. $idcard = -1;
  287. }
  288. //插入用户扩展记录
  289. Db::table('cy_memberstwo')->insert([
  290. 'userid' => $member_id,
  291. 'username' => $data['username'],
  292. 'realname' => $realname,
  293. 'idcard' => $idcard,
  294. 'create_time' => $now_time
  295. ]);
  296. //绑定抖音channel 和 平台内的channel
  297. $dy_channel_info = Db::table("mw_dy_channel_rel")
  298. ->where("channel_id",$data['channel_id'])
  299. ->where("dy_channel_id",$data['dy_channel_id'])->find();
  300. if(empty($dy_channel_info)){
  301. $dy_channel_rel = [
  302. 'channel_id'=>$data['channel_id'],
  303. 'dy_channel_id'=>$data['dy_channel_id'],
  304. 'create_time'=>NOW_TIMESTAMP,
  305. 'update_time'=>NOW_TIMESTAMP,
  306. ];
  307. Db::table("mw_dy_channel_rel")->insert($dy_channel_rel);
  308. }
  309. // 登录处理
  310. $returnData = $this->loginProcess(array_merge($data, ['userid' => $member_id, 'gameid' => $gameid,'oaid'=>$oaid]));
  311. }
  312. else{
  313. throw new Exception("注册失败!");
  314. }
  315. // 提交事务
  316. Db::commit();
  317. } catch (\Exception $e) {
  318. // 回滚事务
  319. Db::rollback();
  320. $this->jsonResult('', -130, '注册失败!' . $e->getMessage());
  321. }
  322. if ($game['is_login'] == 1) {
  323. $this->jsonResultUnescape('', -120, '注册成功,目前禁止登录!');
  324. }
  325. // ## 风控
  326. $fkData = [
  327. 'user_name' => $data['username'], // username
  328. 'ip' => request()->ip(), // ip
  329. 'imei' => $imeil, // imei
  330. ];
  331. $fkResult = (new FkStrategiesService())->handleBlackList($fkData); // 注册
  332. if ($fkResult['status']) {
  333. $this->jsonResult('', -120, "异常注册!当前账户已被禁用!请联系客服处理!客服QQ: " . CUSTOMER_SERVICE_QQ);
  334. }
  335. //return数据时,不能放在事物里面
  336. $this->jsonResultUnescape($returnData, 200, '注册成功!');
  337. }
  338. /**
  339. * 随机生成唯一用户名
  340. *
  341. */
  342. public function createUsername()
  343. {
  344. $memberModel = new Members();
  345. $username = strtolower(random(11));
  346. while ($memberModel->field('id')->where(['username' => $username])->find()) {
  347. $username = strtolower(random(11));
  348. }
  349. $this->jsonResult(['username' => $username], 1, '用户名生成成功');
  350. }
  351. /**
  352. * 根据类型生成不同格式的用户名
  353. *
  354. * @return void
  355. * @throws \think\db\exception\DataNotFoundException
  356. * @throws \think\db\exception\ModelNotFoundException
  357. * @throws \think\exception\DbException
  358. */
  359. public function createChexkUsername()
  360. {
  361. $memberModel = new Members();
  362. $type = input('type', 1); // 获取类型参数,默认为1
  363. $username = '';
  364. // 根据类型生成不同格式的用户名
  365. switch ($type) {
  366. case 1:
  367. // 三个字母(不含i、o) + 五个数字
  368. $username = $this->generateUsername(3, 5);
  369. break;
  370. case 2:
  371. // 四个字母(不含i、o) + 三个数字
  372. $username = $this->generateUsername(4, 3);
  373. break;
  374. default:
  375. // 默认使用类型1的规则
  376. $username = $this->generateUsername(3, 5);
  377. }
  378. // 如果不是空字符串,检查数据库唯一性
  379. if ($username !== '') {
  380. while ($memberModel->field('id')->where(['username' => $username])->find()) {
  381. // 重新生成用户名
  382. if ($type == 2) {
  383. $username = $this->generateUsername(4, 3);
  384. } else {
  385. $username = $this->generateUsername(3, 5);
  386. }
  387. }
  388. }
  389. $this->jsonResult(['username' => $username], 1, '用户名生成成功');
  390. }
  391. /**
  392. * 生成指定格式的用户名
  393. * @param int $letterCount 字母数量
  394. * @param int $numberCount 数字数量
  395. * @return string
  396. */
  397. private function generateUsername($letterCount, $numberCount)
  398. {
  399. // 可用字母(排除i和o)
  400. $letters = 'abcdefghjklmnpqrstuvwxyz';
  401. $numbers = '0123456789';
  402. $username = '';
  403. // 生成字母部分
  404. for ($i = 0; $i < $letterCount; $i++) {
  405. $username .= $letters[rand(0, strlen($letters) - 1)];
  406. }
  407. // 生成数字部分
  408. for ($i = 0; $i < $numberCount; $i++) {
  409. $username .= $numbers[rand(0, strlen($numbers) - 1)];
  410. }
  411. return $username;
  412. }
  413. /**
  414. * 登录处理
  415. *
  416. * @param $data array 玩家信息
  417. *
  418. */
  419. private function loginProcess($data)
  420. {
  421. $logininfoModel = new Logininfo;
  422. $memberModel = new Members();
  423. $subaccountModel = new Subaccount();
  424. $cy_member_channel_game_rel = Db::name('cy_member_channel_game_rel');
  425. // 登录时 绑定该游戏的归属渠道
  426. $info = $cy_member_channel_game_rel->where(['member_id' => $data['userid'], 'game_id' => $data['gameid']])->find();
  427. //子账号用户名
  428. $gameAccountInfo = $subaccountModel->where(['game_id' => $data['gameid'], 'member_id' => $data['userid']])->find();
  429. $sub_username = $gameAccountInfo['sub_username'] ?? '';
  430. // 首次登录
  431. if (empty($info)) {
  432. $userId = $data['userid'];
  433. $channelId = $data['channel_id'];
  434. $gameId = $data['gameid'];
  435. $cy_member_channel_game_rel->insert([
  436. 'member_id' => $userId,
  437. 'channel_id' => $channelId,
  438. 'game_id' => $gameId,
  439. 'mcgr_createtime' => time(),
  440. 'update_time' => time(),
  441. 'mcgr_imeil' => $data['imeil'],
  442. 'mcgr_ip' => request()->ip()
  443. ]);
  444. // 插入玩家游戏渠道绑定记录
  445. $channelName = model('Channel')->where(['id'=>$channelId])->value('name');
  446. $gameName = model('Common/Game')->where(['id'=>$gameId])->value('name');
  447. Db::table('cy_member_history')->insert([
  448. 'userid' => $userId,
  449. 'channel' => $gameName.",".$channelName,
  450. 'ip' => request()->ip(),
  451. 'create_time' => time()
  452. ]);
  453. // 用于首充发放 (用于首次登录)
  454. // (new Coin())->autoSend($gameId, $channelId, $userId);
  455. }
  456. else{ //更新游戏最后登录时间
  457. $userId = $data['userid'];
  458. $channelId = $data['channel_id'];
  459. $gameId = $data['gameid'];
  460. if($userId && $channelId && $gameId){
  461. $cy_member_channel_game_rel->where(['member_id'=>$userId,'game_id'=>$gameId])->update(['update_time'=> time()]);
  462. }
  463. }
  464. //为了兼容旧SDK保存memkey,新SDK没有用到这个值,旧SDK关闭后可以删除该代码
  465. $userNickName = random(3).$data['userid'];
  466. $memberModel->where(['id'=>$data['userid']])->update(['memkey'=>md5($data['username'].$data['password'].rand(0,1000)),'nickname'=>$userNickName]);
  467. //子账号信息没有时
  468. if(empty($sub_username)){
  469. // 指定的几款游戏 不需要注册,账号从cy_members 取
  470. // $settingModel = new Setting();
  471. // $accountArr = explode(',',$settingModel->getSetting('ANDROID_IOS_ACCOUNT'));
  472. //
  473. // if (in_array($data['gameid'],$accountArr)){
  474. // $sub_username = $data['username'];
  475. // }elseif( $data['gameid'] > 220 ){
  476. // $sub_username = $data['userid'];
  477. // } else{
  478. // $sub_username = strtolower(random(20));
  479. //
  480. // //保证子账号名唯一性
  481. // while ($subaccountModel->field('id')->where(['sub_username' => $sub_username])->find()) {
  482. // $sub_username = strtolower(random(20));
  483. // }
  484. // }
  485. $sub_username = $data['userid'].'_'.APP_STATUS;
  486. if(in_array($data['gameid'], [652, 653, 654, 655])){
  487. $sub_username = $data['userid'];
  488. }
  489. $gameAccountInfo = $subaccountModel->create([
  490. 'member_id' => $data['userid'],
  491. 'game_id' => $data['gameid'],
  492. 'channel_id' => $data['channel_id'],
  493. 'sub_username' => $sub_username,
  494. 'create_time' => time(),
  495. 'update_time' => time(),
  496. 'last_imeil' => $data['imeil'],
  497. ]);
  498. }
  499. //插入登录记录
  500. $logininfoModel->limitInsert([
  501. "sub_id"=> $gameAccountInfo['id'],
  502. "userid" => $data['userid'],
  503. "gameid" => $data['gameid'],
  504. "imeil"=> $data['imeil'],
  505. "device" => $data['device'],
  506. "reg_time" => NOW_TIMESTAMP,
  507. "fromflag" => 1,
  508. "channel_id" => $data['channel_id'],
  509. "login_time" => NOW_TIMESTAMP,
  510. "ip" => request()->ip(),
  511. ]);
  512. // $memberLogic = new MemberLogic;
  513. //同步用户信息到账户中心
  514. // $openid = $memberLogic->syncMember($data['username'], $password, $data['mobile'], $now_time);
  515. // $signStr = "username=".$openid."&appkey=".$this->appInfo['appkey']."&logintime=".$now_time;
  516. // $returnData['sign'] = md5($signStr);
  517. // $returnData['memkey'] = md5($openid.$password.rand(0,1000)); //登录生成用户key
  518. // $returnData['login_time'] = $logData['login_time'];
  519. // $returnData['openid'] = $openid;
  520. // $memberModel->update(['memkey' => $returnData['memkey']], ['id' => $member_id]);
  521. // 更新常用设备列表
  522. try {
  523. $memberDevice = new MemberDevice();
  524. $memberDevice->addDevice($data['userid'], $data['gameid'], $data['imeil'], $data['device'], true);
  525. } catch (\Exception $e) {
  526. // 设备记录更新失败不影响登录流程
  527. trace('设备记录更新失败:' . $e->getMessage(), 'error');
  528. }
  529. $platform = ($data['device']==3 ? 1 : 0);
  530. //收集设备信息
  531. $this->saveDevices($data['gameid'],$data['imeil'],$platform);
  532. //token最后的随机码
  533. $token_random = random(8);
  534. $token = auth_code($data['userid'] . '|' . $data['username'] . '|' . $data['gameid'].'|' .$sub_username.'|'.$token_random.'|sdk|v3',"ENCODE", Env::get($this->authKey));
  535. \think\Cache::store('redis')->set($token, $data['imeil'], 60 * 60 * 24 * 30);
  536. \think\Cache::store('redis')->set('token|sdk|'.$data['userid'].'|'.$data['gameid'], $token_random, 60 * 60 * 24 * 30);
  537. // 用户推广信息保存
  538. // setChannelId($data['userid'],$channelId);
  539. // if(isset($data['oaid'])){
  540. // //2022-10-13 抖音推送
  541. // $extend = [
  542. // 'Oaid' => $data['oaid'],
  543. // 'Idfa' => '',
  544. // 'Androidid' => '',
  545. // 'Imei' => $data['imeil'],
  546. // 'PayAmount' => 0,
  547. // 'Ip'=>request()->ip()
  548. // ];
  549. // $tiktokService = new TiktokService();
  550. // $tiktokService->push('tiktok.active_register', $userId, $gameId, $channelId, $extend);
  551. // }
  552. // 风控: 记录注册时间(记录60s)
  553. \think\Cache::store('redis')->set('fk_register_time:'.$data['username'], time(), 60);
  554. $returnData['token'] = $token;
  555. $returnData['username'] = $data['username']; //主账号名
  556. $returnData['sub_username'] = $sub_username; //子账号名
  557. // ## JWT:仅版本号大于 v3.6.6 的客户端返回 ##
  558. if (!empty($this->version) && version_compare($this->version, '3.6.8', '>')) {
  559. $jwtKey = trim((string) Env::get('jwt.jwt_key', ''));
  560. $jwtExpTime = (int) Env::get('jwt.exp_time', 0);
  561. $returnData['jwt_token'] = '';
  562. if ($jwtKey === '' || $jwtExpTime <= 0) {
  563. trace('JWT配置缺失或错误,请检查jwt.jwt_key和jwt.exp_time', 'error');
  564. } else {
  565. $jwtIssuedAt = time();
  566. $jwtUserData = [
  567. 'member_id' => $data['userid'],
  568. 'username' => $data['username'],
  569. 'game_id' => $data['gameid'],
  570. 'sub_id' => $gameAccountInfo['id'],
  571. 'channel_id' => $gameAccountInfo['channel_id'],
  572. 'iat' => $jwtIssuedAt,
  573. 'exp' => $jwtIssuedAt + $jwtExpTime,
  574. ];
  575. $returnData['jwt_token'] = JwtToken::encode($jwtUserData, $jwtKey);
  576. }
  577. }
  578. //$demo_token['productdesc'] = $token;
  579. // Db::name('cy_demo')->insertGetId($demo_token);
  580. return $returnData;
  581. }
  582. /**
  583. * 检查渠道登录注册限制
  584. */
  585. public function chkChannelConfig($channel_id,$gameid)
  586. {
  587. //该配置表暂时默认只有一笔记录,直接写定
  588. $id = 1;
  589. $ChannelConfig = model('channelConfig')->where(['id' => $id])->find();
  590. if($channel_id && $ChannelConfig && intval($ChannelConfig['status'])){ //存在且开启验证
  591. if(trim($ChannelConfig['free_channel'])){ //白名单渠道不做验证
  592. $FreeChannelArr = explode(',',trim($ChannelConfig['free_channel']));
  593. if(in_array($channel_id,$FreeChannelArr)){
  594. return true;
  595. }
  596. }
  597. // 判断渠道注册是否超过阈值,有配置值时验证
  598. $register_most = intval($ChannelConfig['register_most']);
  599. $time_warning_registered = intval($ChannelConfig['register_period']);
  600. if($register_most && $time_warning_registered){
  601. $key = 'aoyousdk_register_most:gameid:'. $gameid. 'channel_id:'. $channel_id;
  602. $is_register = $this->register_times_limited($key,$register_most,$time_warning_registered*60);
  603. if(false === $is_register){
  604. $mobiles = str_replace('|',',',trim($ChannelConfig['mobile']));
  605. $WarningContent = 'SMS_199793630';
  606. // $WarningContent = '游戏:[%s],渠道:[%s],当前注册量已上限,请及时跟进。';
  607. $GameName = model("Game")->where(array('id'=>$gameid))->value('name');
  608. $ChannelName = model("Channel")->where(array('id'=>$channel_id))->value('name');
  609. // $WarningContent = sprintf($WarningContent, $GameName, $ChannelName);
  610. $params = array('name'=>$GameName,'channel'=>$ChannelName);
  611. $sms = new Sms();
  612. $send = @$sms->sendNotify($mobiles, $WarningContent,$params);
  613. /*
  614. if ( $send['status'] ) {
  615. } else {
  616. }
  617. */
  618. $template = '游戏:'.$GameName.',渠道:'.$ChannelName.',当前注册量已上限,请及时跟进,时间:'.date('Y-m-d H:i:s');
  619. $ddurl = Env::get('dingtalk.warning_url');
  620. $result = curlDD($template, $ddurl,true);
  621. return false;
  622. }
  623. }
  624. }
  625. return true;
  626. }
  627. /**
  628. * 渠道注册次数控制
  629. *
  630. * @param string $key 键值
  631. * @param int $times 个数上限
  632. * @param int $expire 过期时间
  633. * @return string
  634. */
  635. private function register_times_limited($key,$times=60,$expire=60) {
  636. if(!empty($key)){
  637. $times = is_numeric($times) ? (int)$times : 60;
  638. $expire = is_numeric($expire) ? (int)$expire : 60;
  639. $redis = Cache::store('redis');
  640. $handler = $redis->handler();
  641. $value = $handler->incr($key);
  642. if ($times < $value) {
  643. $handler->del($key);
  644. return false;
  645. } else if ( '1' == $value) {
  646. $handler->expire($key, $expire);
  647. }
  648. }
  649. return true;
  650. }
  651. }