Identify.php 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778
  1. <?php
  2. /**
  3. * Identify.php UTF-8
  4. * 玩家实名认证
  5. *
  6. * @date : 2020/6/20 11:53
  7. *
  8. * @license 这不是一个自由软件,未经授权不许任何使用和传播。
  9. * @author : chenbingling <cbl@huosdk.com>
  10. * @version : HUOUNION 8.5
  11. */
  12. namespace huoIdentify\controller;
  13. use huo\controller\common\Base;
  14. use huo\controller\common\CommonFunc;
  15. use huo\controller\integral\MemIa;
  16. use huo\model\game\GameModel;
  17. use huo\model\member\MemberModel;
  18. use huo\model\member\MemGameModel;
  19. use huoIdentify\lib\queue\controller\IdentifyQueue;
  20. use huoIdentify\lib\queue\controller\ReportQueue;
  21. use huoIdentify\model\IdentifyGameModel;
  22. use huoIdentify\model\IdentifyMemModel;
  23. use huoIdentify\model\IdentifyOrderModel;
  24. use huoIdentify\model\IdentifyPiModel;
  25. use huoIdentify\model\IdentifyPlatformLogModel;
  26. use huolib\constant\CommonConst;
  27. use huolib\constant\DeviceTypeConst;
  28. use huolib\constant\GameConst;
  29. use huolib\constant\IaConst;
  30. use huolib\constant\IdentifyConst;
  31. use huolib\constant\MemConst;
  32. use huolib\status\CommonStatus;
  33. use huolib\status\IdentifyStatus;
  34. use huolib\status\MemberStatus;
  35. use huolib\tool\RateLimit;
  36. use huolib\tool\StrUtils;
  37. use huolib\utils\IdentifyUtils;
  38. use think\Config;
  39. use think\Exception;
  40. class Identify extends Base {
  41. protected $app_id = 0;
  42. public function __construct($app_id = 0) {
  43. $this->__initConfig($app_id);
  44. }
  45. private function __initConfig($app_id) {
  46. $_app_id = $app_id;
  47. if (empty($_app_id)) {
  48. $_app_id = (int)request()->param('game_id/d', 0);
  49. if (empty($_app_id)) {
  50. $_app_id = (int)request()->param('app_id/d', 0);
  51. }
  52. }
  53. $this->app_id = $_app_id;
  54. if (!empty($_app_id)) {
  55. $_identify_game_model = new IdentifyGameModel();
  56. $_identify_game_info = (array)$_identify_game_model->getInfoByAppId($_app_id);
  57. if (!empty($_identify_game_info['driver_key'])) {
  58. Config::set('identify_conf.default', $_identify_game_info['driver_key']);
  59. }
  60. }
  61. }
  62. /**
  63. * 获取会员认证信息
  64. *
  65. * @param int $mem_id 玩家id
  66. * @param bool $encrypt 是否加密
  67. * @param int $app_id 当前游戏id
  68. *
  69. * @return mixed : array
  70. */
  71. public function getIdentifyByMemId($mem_id, $encrypt = false, $app_id = 0) {
  72. $_mem_data = (new IdentifyMemModel())->getInfoByMemId($mem_id);
  73. if (empty($_mem_data) && !empty($app_id)) {
  74. /* 未获取到实名信息,则查看是否有认证中的数据 */
  75. $this->checkMemIdentify($mem_id, $app_id);
  76. $_mem_data = (new IdentifyMemModel())->getInfoByMemId($mem_id);
  77. }
  78. $_data['id_card'] = get_val($_mem_data, 'id_card');
  79. $_data['real_name'] = get_val($_mem_data, 'real_name');
  80. $_data['pi'] = get_val($_mem_data, 'identify_pi');
  81. $_data['birthday'] = IdentifyUtils::getBirthday($_data['id_card']);
  82. $_data['age'] = IdentifyUtils::getAge($_data['birthday']);
  83. $_data['is_auth'] = IdentifyConst::IS_AUTH_NO;
  84. if (!empty($_data['id_card'])) {
  85. $_data['is_auth'] = IdentifyConst::IS_AUTH_YES;
  86. }
  87. if (true == $encrypt) {
  88. if (!empty($_data['real_name'])) {
  89. $_data['real_name'] = StrUtils::encryptName($_data['real_name']);
  90. }
  91. if (!empty($_data['id_card'])) {
  92. $_data['id_card'] = StrUtils::encryptName($_data['id_card']);
  93. }
  94. }
  95. return $_data;
  96. }
  97. /**
  98. * 根据app_id获取游戏实名认证状态
  99. *
  100. * @param int $app_id
  101. *
  102. * @return:int
  103. */
  104. public function getGameAuthByAppId($app_id) {
  105. $_is_auth = (new GameModel())->getIsAuthById($app_id);
  106. return $_is_auth;
  107. }
  108. /**
  109. * 获取用户实名信息状况
  110. *
  111. * @param int $app_id 游戏id
  112. * @param int $mem_id 会员id
  113. * @param string $device_id 设备号 用于未实名玩家时长统计
  114. *
  115. * @return array
  116. */
  117. public function getMemIdentifyInfo($app_id, $mem_id, $device_id = '', $token = '') {
  118. /*定义返回数组*/
  119. $_rdata = [
  120. 'auth_info' => [
  121. 'id_card' => '',
  122. 'real_name' => '',
  123. 'birthday' => '',
  124. 'age' => '',
  125. 'is_auth' => IdentifyConst::IS_AUTH_NO
  126. ],
  127. 'url' => '',
  128. ];
  129. $_app_ids = CommonFunc::getAppAppId();
  130. $_game_auth = $this->getGameAuthByAppId($app_id);
  131. if (!in_array($app_id, $_app_ids)) {
  132. /* 不需要实名不做任何处理 */
  133. if (GameConst::GAME_IDENTIFY_IS_NO == $_game_auth) {
  134. return $_rdata;
  135. }
  136. }
  137. $_token = session_id();
  138. if (!empty($token)) {
  139. $_token = $token;
  140. }
  141. $_param = [
  142. 'app_id' => $app_id,
  143. 'device_id' => $device_id,
  144. 'token' => $_token
  145. ];
  146. $_identify_url = IdentifyConst::getIdentifyUrl($_param);
  147. $_mem_auth_info = $this->getIdentifyByMemId($mem_id, false, $app_id);
  148. $_mem_auth_info['is_auth'] = $_game_auth;
  149. $_rdata['auth_info'] = $_mem_auth_info;
  150. /* 获取玩家是否已绑定手机 */
  151. $_mem_model = new MemberModel();
  152. $_mobile = $_mem_model->getMobileById($mem_id);
  153. $_status = $_mem_model->getStatus($mem_id);
  154. if (empty($_mobile) && MemConst::STATUS_TRY == $_status) {
  155. $_rdata['url'] = IdentifyConst::getBindMobileUrl($_param);
  156. return $_rdata;
  157. }
  158. $_rdata['url'] = $_identify_url;
  159. /* 玩家未实名返回实名认证地址 */
  160. if (empty($_mem_auth_info['id_card'])) {
  161. return $_rdata;
  162. }
  163. /* 玩家已实名校验未成年限制 */
  164. $_rdata['url'] = (new Online($app_id, $mem_id, $device_id))->checkLimit();
  165. return $_rdata;
  166. }
  167. /**
  168. * 更新实名认证信息
  169. *
  170. * @param $mem_id
  171. * @param int $type
  172. * @param $real_name
  173. * @param $id_card
  174. * @param int $app_id
  175. *
  176. * @return mixed
  177. */
  178. public function updateIdentify($mem_id, $type = 1, $real_name, $id_card, $app_id = 0) {
  179. $_id_card = strtoupper($id_card); /* 防止输入小写字符 x*/
  180. $_real_name = $real_name;
  181. $_mem_model = new MemberModel();
  182. $_mem_data = $_mem_model->getInfoById($mem_id);
  183. if (empty($_mem_data)) {
  184. $_code = MemberStatus::LOGIN_IS_OUT;
  185. return $this->huoError($_code, MemberStatus::getMsg($_code));
  186. }
  187. $_app_id = $app_id;
  188. if (empty($_app_id)) {
  189. $_app_id = request()->param('app_id/d', 0);
  190. }
  191. if (empty($_app_id)) {
  192. $_app_id = $_mem_data['app_id'];
  193. }
  194. \think\Log::error('↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓');
  195. \think\Log::error('================= 实名认证开始 =====================');
  196. \think\Log::error([$mem_id, $type, $real_name, $id_card, $_app_id]);
  197. /* 1、本地正则校验 */
  198. $_chk_rs = IdentifyUtils::checkIdentify($type, $_real_name, $_id_card);
  199. if (IdentifyStatus::NO_ERROR != $_chk_rs) {
  200. \think\Log::error('================= 正则校验失败 =====================');
  201. return $this->huoError($_chk_rs, IdentifyStatus::getMsg($_chk_rs));
  202. }
  203. \think\Log::error('================= 正则校验通过 =====================');
  204. /* 2、获取游戏配置 */
  205. $_identify_conf = (new \huoIdentify\controller\IdentifyDriverConf())->getIdentityCheckType($_app_id);
  206. $_driver_key = get_val($_identify_conf, 'driver_key', Config::get('identify_conf.default'));
  207. $_rs_data = [];
  208. if (empty($_identify_conf['pre_check'])
  209. || IdentifyConst::IDENTITY_PRE_CHECK_AT_CLOUD == $_identify_conf['pre_check']
  210. || in_array($_driver_key, [IdentifyConst::DRIVER_KEY_ALIPAY, IdentifyConst::DRIVER_KEY_WXPAY])) {
  211. \think\Log::error('================= 前置阿里/腾讯云校验 =====================');
  212. /* 未配置实名参数,或前置校验需要使用阿里腾讯云 */
  213. $_rs_data = $this->identifyByThirdParty($mem_id, $type, $_real_name, $_id_card, $_app_id);
  214. if (CommonStatus::NO_ERROR != $_rs_data['code']) {
  215. \think\Log::error('================= 前置阿里/腾讯云返回结果 =====================');
  216. \think\Log::error($_rs_data);
  217. return $this->huoReturn($_rs_data);
  218. }
  219. $_id_card = strtoupper(get_val($_rs_data['data'], 'id_card', ''));
  220. $_real_name = get_val($_rs_data['data'], 'real_name', '');
  221. }
  222. switch ($_driver_key) {
  223. case IdentifyConst::DRIVER_KEY_ALIPAY:
  224. case IdentifyConst::DRIVER_KEY_WXPAY:
  225. \think\Log::error('================= 阿里/腾讯云实名直接返回认证成功,允许进入游戏 =====================');
  226. /* 阿里/腾讯云实名直接返回认证成功,允许进入游戏 */
  227. $_code = IdentifyStatus::NO_ERROR;
  228. return $this->huoSuccess($_code, IdentifyStatus::getMsg($_code), $_rs_data);
  229. default:
  230. return $this->getReportIdentity($mem_id, $type, $_real_name, $_id_card, $_app_id);
  231. }
  232. }
  233. /**
  234. * 上报实名信息
  235. *
  236. * @param $mem_id
  237. * @param int $type
  238. * @param $real_name
  239. * @param $id_card
  240. * @param int $app_id
  241. * @param bool $from_queue 是否来自队列
  242. *
  243. * @return mixed
  244. */
  245. public function getReportIdentity($mem_id, $type = 1, $real_name, $id_card, $app_id = 0, $from_queue = false) {
  246. $_im_model = new IdentifyMemModel();
  247. $_app_id = $app_id;
  248. $_identify_from = Config::get('identify_conf.default'); //实名认证api
  249. $_pi_info = $this->getPiInfoByIdCard($id_card);
  250. $_identify_pi = get_val($_pi_info, 'identify_pi', '');
  251. $_pi_real_name = get_val($_pi_info, 'real_name', '');
  252. if (!empty($_identify_pi) && $_pi_real_name == $real_name) {
  253. /* 产品经理和技术负责人明确:库中实名信息与输入信息一致才不需重新上报 */
  254. \think\Log::error('================= PI值存在无需上报 =====================');
  255. $_identify_from = get_val($_pi_info, 'identify_from', '');
  256. $id_card = get_val($_pi_info, 'id_card', $id_card);
  257. $real_name = get_val($_pi_info, 'real_name', $real_name);
  258. return $this->afterIdentify($mem_id, $id_card, $real_name, $type, $_identify_from, $_identify_pi, $_app_id);
  259. }
  260. try {
  261. /* Modified by chenbingling BEGIN 2021/5/6 ISSUES:#-1 不是队列来的入队列处理 */
  262. if (false === $from_queue) {
  263. /* 判断当前信息认证状态 */
  264. $_report_status = $_im_model->getReportStatusByMemIdIdCard($mem_id, $id_card);
  265. if (IdentifyConst::IDENTITY_STATUS_NO == $_report_status) {
  266. $_code = IdentifyStatus::IDENTITY_FAIL;
  267. return $this->huoError($_code, IdentifyStatus::getMsg($_code));
  268. }
  269. $_rs = (new IdentifyQueue())->addInQueueData($mem_id, $id_card, $real_name, $_app_id, $_identify_pi);
  270. if (true === $_rs) {
  271. \think\Log::error('================= 数据入队列 =====================');
  272. if (IdentifyConst::DRIVER_KEY_FCMGAME == $_identify_from) {
  273. \think\Log::error('================= 国家防沉迷上报结果等待 =====================');
  274. $_code = IdentifyStatus::IDENTITY_WAIT;
  275. } else {
  276. \think\Log::error('================= CP上报后允许进入游戏 =====================');
  277. $_code = IdentifyStatus::IDENTITY_IN_PROGRESS;
  278. }
  279. return $this->huoSuccess($_code, IdentifyStatus::getMsg($_code));
  280. }
  281. }
  282. /* END 2021/5/6 ISSUES:#-1 */
  283. $_identify_conf = \huoIdentify\controller\IdentifyDriverConf::getConfig($_identify_from, $_app_id);
  284. $_identify_class = \huoIdentify\identifyDriver\Identify::ins()->get($_identify_from, $_identify_conf);
  285. $_identify_class->setRealName($real_name);
  286. $_identify_class->setIdCard($id_card);
  287. $_identify_class->setMemId($mem_id);
  288. $_identify_class->setIdentifyFrom($_identify_from);
  289. $_mg_mem_id = (new MemGameModel())->getDefaultMgIdByMemAppId($mem_id, $_app_id);
  290. $_identify_class->setMgMemId($_mg_mem_id);
  291. $_classify = (new \huoIdentify\model\GameModel())->getClassifyById($_app_id);
  292. $_pf = GameConst::GAME_IOS == $_classify ? 2 : 1; /* 1 安卓 2 ios*/
  293. $_identify_class->setPf($_pf);
  294. $_identify_rs = $_identify_class->identify();
  295. /* 玩家实名认证中可放行 */
  296. if (CommonStatus::MEM_IDENTIFY_IN_PROGRESS == $_identify_rs['code']) {
  297. if (true === $from_queue) {
  298. /* 来源队列的原样返回 */
  299. return $this->huoReturn($_identify_rs);
  300. }
  301. if (IdentifyConst::DRIVER_KEY_FCMGAME == $_identify_from) {
  302. $_code = IdentifyStatus::IDENTITY_WAIT;
  303. } else {
  304. $_code = IdentifyStatus::IDENTITY_IN_PROGRESS;
  305. }
  306. return $this->huoSuccess($_code, $_identify_rs['msg']);
  307. }
  308. /* 认证失败的清理实名信息 */
  309. if (IdentifyStatus::IDENTITY_FAIL == $_identify_rs['code']) {
  310. $_im_model = new IdentifyMemModel();
  311. \think\Log::error('================= 认证失败实名信息清理 =====================');
  312. \think\Log::error([$mem_id, $type, $real_name, $id_card, $app_id]);
  313. $_id = $_im_model->getIdByMemId($mem_id);
  314. if (!empty($_id)) {
  315. $_im_model->deleteData($_id);
  316. }
  317. }
  318. if (CommonStatus::NO_ERROR != $_identify_rs['code']) {
  319. /* 设置认证失败 */
  320. $_im_model->setReportFailByMemIdIdCard($mem_id, $id_card);
  321. $_identify_rs['msg'] = lang('IDENTITY_FAIL_CONFIRM_INFO');
  322. return $this->huoReturn($_identify_rs);
  323. }
  324. $_identify_pi = isset($_identify_rs['data']['pi']) ? $_identify_rs['data']['pi'] : '';
  325. } catch (Exception $e) {
  326. /* 设置认证失败 */
  327. $_im_model->setReportFailByMemIdIdCard($mem_id, $id_card);
  328. return $this->huoError($e->getCode(), $e->getMessage());
  329. }
  330. \think\Log::error('================= 认证成功结束 =====================');
  331. \think\Log::error([$mem_id, $type, $real_name, $id_card, $app_id]);
  332. return $this->afterIdentify($mem_id, $id_card, $real_name, $type, $_identify_from, $_identify_pi, $_app_id);
  333. }
  334. /**
  335. * 直接使用腾讯或阿里云实名认证
  336. *
  337. * @param $mem_id
  338. * @param $type
  339. * @param $real_name
  340. * @param $id_card
  341. * @param $app_id
  342. *
  343. * @return array
  344. */
  345. public function identifyByThirdParty($mem_id, $type, $real_name, $id_card, $app_id) {
  346. $_im_model = new IdentifyMemModel();
  347. $_cnt = $_im_model->getCntByIdCard($id_card);
  348. $_id_bind_limit = (new IdentifyConf())->getIdCardBindCnt();
  349. $_im_info = $_im_model->getInfoByIdCard($id_card);
  350. $_im_real_name = get_val($_im_info, 'real_name', '');
  351. if ($_cnt >= $_id_bind_limit) {
  352. $_code = IdentifyStatus::IDCARD_BIND_LIMIT;
  353. return $this->huoError($_code, IdentifyStatus::getMsg($_code));
  354. } elseif (empty($_cnt) || $_im_real_name != $real_name) {
  355. /*产品经理和技术负责人明确:库中已有信息,但是真实姓名不一致则需要重新实名 */
  356. try {
  357. list($_identify_from, $_identify_conf) = (new \huoIdentify\controller\IdentifyDriverConf(
  358. ))->getATCloudConf();
  359. $_identify_class = \huoIdentify\identifyDriver\Identify::ins()->get($_identify_from, $_identify_conf);
  360. $_identify_class->setRealName($real_name);
  361. $_identify_class->setIdCard($id_card);
  362. $_identify_class->setMemId($mem_id);
  363. $_identify_class->setIdentifyFrom($_identify_from);
  364. $_identify_rs = $_identify_class->identify();
  365. if (CommonStatus::NO_ERROR != $_identify_rs['code']) {
  366. $_identify_rs['msg'] = '认证失败,请确认身份信息是否正确';
  367. return $this->huoReturn($_identify_rs);
  368. }
  369. $_identify_pi = isset($_identify_rs['data']['pi']) ? $_identify_rs['data']['pi'] : '';
  370. } catch (Exception $e) {
  371. return $this->huoError($e->getCode(), $e->getMessage());
  372. }
  373. } else {
  374. $_identify_from = get_val($_im_info, 'identify_from', '');
  375. $_identify_pi = get_val($_im_info, 'identify_pi', '');
  376. }
  377. return $this->afterIdentify($mem_id, $id_card, $real_name, $type, $_identify_from, $_identify_pi, $app_id);
  378. }
  379. /**
  380. * 实名后操作
  381. *
  382. * @param $mem_id
  383. * @param $id_card
  384. * @param $real_name
  385. * @param $type
  386. * @param $identify_from
  387. * @param $identify_pi
  388. * @param $app_id
  389. *
  390. * @return array
  391. */
  392. public function afterIdentify($mem_id, $id_card, $real_name, $type, $identify_from, $identify_pi, $app_id) {
  393. $_im_model = new IdentifyMemModel();
  394. $_old_id_data = $_im_model->getInfoByMemId($mem_id);
  395. $_old_id_card = get_val($_old_id_data, 'id_card', '');
  396. $_old_real_name = get_val($_old_id_data, 'real_name', '');
  397. $_old_identify_pi = get_val($_old_id_data, 'identify_pi', '');
  398. if ($_old_id_card != $id_card || $_old_real_name != $real_name || $_old_identify_pi != $identify_pi) {
  399. /* 有变化 */
  400. $_data = [
  401. 'identify_from' => $identify_from,
  402. 'mem_id' => $mem_id,
  403. 'real_name' => $real_name,
  404. 'id_card' => $id_card,
  405. 'identify_type' => $type,
  406. ];
  407. if (!empty($identify_pi)) {
  408. $_data['identify_pi'] = $identify_pi;
  409. }
  410. if (empty($_old_id_data)) {
  411. $_rs = $_im_model->addData($_data);
  412. } else {
  413. $_rs = $_im_model->updateData($_data, $_old_id_data['id']);
  414. }
  415. if (false === $_rs) {
  416. return $this->huoSuccess(MemberStatus::INNER_ERROR, MemberStatus::getMsg(MemberStatus::INNER_ERROR));
  417. }
  418. if (!empty($identify_pi)) {
  419. $this->updatePiInfo($id_card, $real_name, $identify_pi, $identify_from);
  420. }
  421. $_mem_data = [
  422. 'status' => MemConst::STATUS_NORMAL
  423. ];
  424. $_mem_data['real_name'] = $real_name;
  425. $_mem_data['id_card'] = $id_card;
  426. $_mem_data['identify_type'] = $type;
  427. (new MemberModel())->updateData($_mem_data, $mem_id);
  428. /* 实名认证成功获取积分 */
  429. if (empty($_old_id_card)) {
  430. (new MemIa($mem_id))->doItgAct(IaConst::IA_IDENTIFY);
  431. }
  432. }
  433. $_data = $this->getIdentifyByMemId($mem_id);
  434. $_age = IdentifyUtils::getAgeById($id_card);
  435. if ($_age < 18) {
  436. /* 小于18岁校验是否可以玩游戏 */
  437. $_url = (new Online($app_id, $mem_id, ''))->checkUnderageLimitOnTheHour();
  438. if (!empty($_url)) {
  439. $_code = IdentifyStatus::IDENTITY_NOT_ALLOW_LOGIN;
  440. $_data['url'] = $_url;
  441. return $this->huoSuccess($_code, IdentifyStatus::getMsg($_code), $_data);
  442. }
  443. }
  444. return $this->retSucMsg(IdentifyStatus::NO_ERROR, $_data);
  445. }
  446. /**
  447. * 获取游戏实名认证信息
  448. *
  449. * @param int $app_id 游戏id
  450. * @param int $mem_id 会员id
  451. * @param string $device_type 设备类型
  452. *
  453. * @return array
  454. */
  455. public function getAuthInfo($app_id, $mem_id, $device_type = DeviceTypeConst::DEVICE_TYPE_MP) {
  456. /*定义返回数组*/
  457. $_data = [];
  458. $_is_auth = $this->getGameAuthByAppId($app_id);
  459. if (GameConst::GAME_IDENTIFY_IS_NO == $_is_auth) {
  460. return $_data;
  461. }
  462. $_data['auth_info'] = $this->getIdentifyByMemId($mem_id);
  463. $_data['url'] = '';
  464. if (IdentifyConst::IS_AUTH_NO == $_data['auth_info']['is_auth']) {
  465. $_param = [
  466. 'token' => session_id(),
  467. 'app_id' => $app_id,
  468. 'device_type' => $device_type,
  469. ];
  470. $_data['url'] = MemConst::getIdentifyUrl($_param);
  471. }
  472. return $_data;
  473. }
  474. /**
  475. * 上报登录行为
  476. *
  477. * @param $app_id
  478. * @param $mem_id
  479. *
  480. * @return array|bool
  481. */
  482. public function reportLoginBehavior($app_id, $mem_id) {
  483. return $this->reportCommon($app_id, $mem_id, CommonConst::STATUS_YES);
  484. }
  485. /**
  486. * 上报退出登录行为
  487. *
  488. * @param $app_id
  489. * @param $mem_id
  490. *
  491. * @return array|bool
  492. */
  493. public function reportLogoutBehavior($app_id, $mem_id) {
  494. return $this->reportCommon($app_id, $mem_id, CommonConst::STATUS_NO);
  495. }
  496. public function reportCommon($app_id, $mem_id, $is_login = CommonConst::STATUS_YES, $from_queue = false) {
  497. if (false === $from_queue) {
  498. $_rs = (new ReportQueue())->push($app_id, $mem_id, $is_login);
  499. if (true === $_rs) {
  500. $_code = IdentifyStatus::NO_ERROR;
  501. return $this->huoSuccess($_code, CommonStatus::getMsg($_code));
  502. }
  503. }
  504. $_identify_mem_info = (new IdentifyMemModel())->getInfoByMemId($mem_id);
  505. if (!empty($_identify_mem_info['id_card'])) {
  506. $_identify_from = Config::get('identify_conf.default');
  507. if (!empty($app_id)) {
  508. $_identify_game_model = new IdentifyGameModel();
  509. $_identify_game_info = (array)$_identify_game_model->getInfoByAppId($app_id);
  510. if (!empty($_identify_game_info['driver_key'])) {
  511. $_identify_from = $_identify_game_info['driver_key'];
  512. Config::set('identify_conf.default', $_identify_game_info['driver_key']);
  513. }
  514. }
  515. /* 需要pi的类型 */
  516. $_need_pi_type = IdentifyConst::getNeedPiTypes();
  517. try {
  518. $_identify_conf = \huoIdentify\controller\IdentifyDriverConf::getConfig($_identify_from, $app_id);
  519. $_id_card = isset($_identify_mem_info['id_card']) ? $_identify_mem_info['id_card'] : '';
  520. $_real_name = isset($_identify_mem_info['real_name']) ? $_identify_mem_info['real_name'] : '';
  521. $_identify_pi = isset($_identify_mem_info['identify_pi']) ? $_identify_mem_info['identify_pi'] : '';
  522. if (empty($_identify_pi) && !empty($_id_card) && !empty($_real_name)
  523. && in_array($_identify_from, $_need_pi_type)
  524. ) {
  525. /* 游戏开启国家防沉迷认证但是玩家没有在国家防沉迷系统认证的需要前往认证 */
  526. $_rs = $this->updateIdentify($mem_id, 1, $_real_name, $_id_card, $app_id);
  527. if (IdentifyStatus::NO_ERROR == $_rs['code']) {
  528. $_identify_pi = get_val($_rs['data'], 'identify_pi', '');
  529. }
  530. }
  531. $_identify_class = \huoIdentify\identifyDriver\Identify::ins()->get($_identify_from, $_identify_conf);
  532. $_identify_class->setRealName($_real_name);
  533. $_identify_class->setIdCard($_id_card);
  534. $_identify_class->setMemId($mem_id);
  535. $_identify_class->setIdentifyFrom($_identify_from);
  536. $_mg_mem_id = (new MemGameModel())->getDefaultMgIdByMemAppId($mem_id, $app_id);
  537. $_identify_class->setMgMemId($_mg_mem_id);
  538. $_classify = (new \huoIdentify\model\GameModel())->getClassifyById($app_id);
  539. $_pf = GameConst::GAME_IOS == $_classify ? 2 : 1; /* 1 安卓 2 ios*/
  540. $_identify_class->setPf($_pf);
  541. $_identify_class->setPi($_identify_pi);
  542. if ($is_login == CommonConst::STATUS_YES) {
  543. $_identify_rs = $_identify_class->loginBehavior($_identify_pi);
  544. } else {
  545. $_identify_rs = $_identify_class->logoutBehavior($_identify_pi);
  546. }
  547. if (CommonStatus::NO_ERROR != $_identify_rs['code']) {
  548. $_identify_rs['msg'] = '上报失败';
  549. return $this->huoReturn($_identify_rs);
  550. }
  551. } catch (exception $e) {
  552. return $this->huoError($e->getCode(), $e->getMessage());
  553. }
  554. }
  555. $_code = IdentifyStatus::NO_ERROR;
  556. return $this->huoSuccess($_code, CommonStatus::getMsg($_code));
  557. }
  558. /**
  559. * 查询是否有认证中数据
  560. *
  561. * @param $mem_id
  562. * @param $app_id
  563. */
  564. protected function checkMemIdentify($mem_id, $app_id) {
  565. /* 限制速率 */
  566. $_rs = (new RateLimit())->rateLimit($mem_id, true, true, 1, 3);
  567. if (false == $_rs) {
  568. return false;
  569. }
  570. $_identify_from = Config::get('identify_conf.default');
  571. switch ($_identify_from) {
  572. case IdentifyConst::DRIVER_KEY_ALIPAY:
  573. case IdentifyConst::DRIVER_KEY_WXPAY:
  574. return false;
  575. case IdentifyConst::DRIVER_KEY_FCMGAME:
  576. try {
  577. $_identify_conf = \huoIdentify\controller\IdentifyDriverConf::getConfig($_identify_from, $app_id);
  578. } catch (exception $e) {
  579. return false;
  580. }
  581. $_in_progress_data = $this->getFcmGameInProgressData($mem_id, $_identify_conf['bizId']);
  582. break;
  583. default:
  584. $_in_progress_data = [];
  585. $_class_name = '\\huoIdentify\\identifyDriver\\driver\\'.ucfirst(strtolower($_identify_from));
  586. if (class_exists($_class_name)) {
  587. $_status_in_progress = $_class_name::STATUS_IN_PROGRESS; /* 获取各实名驱动类的认证中状态值 */
  588. $_in_progress_data = $this->getInProgressDataByMemAppFrom(
  589. $mem_id, $app_id, $_identify_from, $_status_in_progress
  590. );
  591. }
  592. }
  593. if (empty($_in_progress_data)) {
  594. return false;
  595. }
  596. $_real_name = get_val($_in_progress_data, 'real_name', '');
  597. $_id_card = get_val($_in_progress_data, 'id_card', '');
  598. $_rs = $this->updateIdentify($mem_id, 1, $_real_name, $_id_card, $app_id);
  599. if (IdentifyStatus::NO_ERROR == $_rs['code']) {
  600. return true;
  601. }
  602. return false;
  603. }
  604. /**
  605. * 获取国家防沉迷系统认证中数据
  606. *
  607. * @param $mem_id
  608. * @param $biz_id
  609. *
  610. * @return array
  611. */
  612. public function getFcmGameInProgressData($mem_id, $biz_id) {
  613. $_io_data = (new IdentifyOrderModel())->getLastInfoByBizIdMem($biz_id, $mem_id);
  614. if (empty($_io_data)) {
  615. return [];
  616. }
  617. $_status = get_val($_io_data, 'status', 2);
  618. if (\huoIdentify\identifyDriver\driver\Fcmgame::STATUS_IN_PROGRESS != $_status) {
  619. /* 非认证中不处理 */
  620. return [];
  621. }
  622. return $_io_data;
  623. }
  624. /**
  625. * 根据玩家id和游戏id获取实名认证中数据
  626. *
  627. * @param $mem_id
  628. * @param $app_id
  629. *
  630. * @return array|bool
  631. */
  632. public function getInProgressDataByMemApp($mem_id, $app_id) {
  633. $_identify_from = Config::get('identify_conf.default');
  634. switch ($_identify_from) {
  635. case IdentifyConst::DRIVER_KEY_ALIPAY:
  636. case IdentifyConst::DRIVER_KEY_WXPAY:
  637. return false;
  638. case IdentifyConst::DRIVER_KEY_FCMGAME:
  639. try {
  640. $_identify_conf = \huoIdentify\controller\IdentifyDriverConf::getConfig($_identify_from, $app_id);
  641. } catch (exception $e) {
  642. return false;
  643. }
  644. $_in_progress_data = $this->getFcmGameInProgressData($mem_id, $_identify_conf['bizId']);
  645. break;
  646. default:
  647. $_in_progress_data = [];
  648. $_class_name = '\\huoIdentify\\identifyDriver\\driver\\'.ucfirst(strtolower($_identify_from));
  649. if (class_exists($_class_name)) {
  650. $_status_in_progress = $_class_name::STATUS_IN_PROGRESS; /* 获取各实名驱动类的认证中状态值 */
  651. $_in_progress_data = $this->getInProgressDataByMemAppFrom(
  652. $mem_id, $app_id, $_identify_from, $_status_in_progress
  653. );
  654. }
  655. }
  656. return $_in_progress_data;
  657. }
  658. /**
  659. * 获取实名认证中的数据
  660. *
  661. * @param int $mem_id 玩家id
  662. * @param int $app_id 游戏id
  663. * @param string $identify_from 认证平台
  664. * @param int $status_in_progress 认证中状态
  665. *
  666. * @return array
  667. */
  668. private function getInProgressDataByMemAppFrom($mem_id, $app_id, $identify_from, $status_in_progress) {
  669. $_mg_mem_id = (new MemGameModel())->getDefaultMgIdByMemAppId($mem_id, $app_id);
  670. if (empty($_mg_mem_id)) {
  671. return [];
  672. }
  673. $_ipl_data = (new IdentifyPlatformLogModel())->getInfoByMgFrom($_mg_mem_id, $identify_from);
  674. if (empty($_ipl_data)) {
  675. return [];
  676. }
  677. $_status = get_val($_ipl_data, 'status', 0);
  678. if ($status_in_progress != $_status) {
  679. /* 非认证中不处理 */
  680. return [];
  681. }
  682. return $_ipl_data;
  683. }
  684. /**
  685. * 根据身份证号获取pi信息
  686. *
  687. * @param string $id_card 身份证号
  688. *
  689. * @return array
  690. */
  691. public function getPiInfoByIdCard($id_card) {
  692. $_pi_info = (new IdentifyPiModel())->getInfoByIdCard($id_card);
  693. // if (empty($_pi_info)) {
  694. // /* 此处兼容旧数据查找的一种方案可注释,也可将旧数据查找后写入信数据表中后注释 */
  695. // $_pi_info = (new IdentifyMemModel())->getInfoByIdCard($id_card);
  696. // }
  697. return $_pi_info;
  698. }
  699. /**
  700. * 更新PI信息
  701. *
  702. * @param string $id_card 身份证号
  703. * @param string $real_name 真实姓名
  704. * @param string $identify_pi 中宣部PI
  705. * @param string $identify_from 认证来源
  706. *
  707. * @return bool|false|int
  708. */
  709. public function updatePiInfo($id_card, $real_name, $identify_pi, $identify_from) {
  710. if (empty($id_card) || empty($real_name) || empty($identify_pi)) {
  711. return false;
  712. }
  713. $_ip_model = new IdentifyPiModel();
  714. $_pi_info = $_ip_model->getInfoByIdCard($id_card);
  715. $_rs = true;
  716. if (empty($_pi_info)) {
  717. $_data = [
  718. 'id_card' => $id_card,
  719. 'real_name' => $real_name,
  720. 'identify_pi' => $identify_pi,
  721. 'identify_from' => $identify_from,
  722. ];
  723. $_rs = $_ip_model->addData($_data);
  724. }
  725. return $_rs;
  726. }
  727. }