SubPackage.php 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697
  1. <?php
  2. /**
  3. * 渠道包打包和删包公共业务逻辑类
  4. */
  5. namespace app\common\logic;
  6. use app\common\model\Game;
  7. use app\common\model\GameInfo;
  8. use app\common\model\SdkGameList;
  9. use app\common\model\Logininfo;
  10. use app\common\model\PromotionShortLink;
  11. use think\Cache;
  12. use think\Db;
  13. use think\Env;
  14. use think\Exception;
  15. use app\common\library\AliyunOSS;
  16. use app\common\library\HuaweiObs;
  17. use app\service\HuaWeiCloudService;
  18. class SubPackage{
  19. /**
  20. * 接收渠道游戏打包请求,并处理
  21. *
  22. * @param $game_id integer 游戏ID
  23. * @param $admin_id integer 后台及推广平台用户ID
  24. * @param $platform integer 游戏平台 1=ios、2=安卓、3=h5
  25. * @param $apktype integer 游戏包类型 0:普通包,1:光环包
  26. * @param $pack_type integer 分包方式 0:异步,1:同步
  27. */
  28. public function index($channel_id, $game_id, $admin_id = '0', $platform = 0, $apktype = 0, $pack_type = 0)
  29. {
  30. $gameInfoModel = new GameInfo;
  31. $gameaidModel = Db::name('cy_gameaid');
  32. $runnable = true;
  33. $msg = false;
  34. $extend = []; //扩展参数
  35. if (empty($game_id)) {
  36. $runnable = false;
  37. $msg = 'game_id 参数缺失';
  38. }
  39. if (empty($channel_id) && $runnable) {
  40. $runnable = false;
  41. $msg = 'channel_id 参数缺失';
  42. }
  43. //判断光环游戏记录是否存在
  44. if ($apktype == 1 && !$gameaidModel->where(['gameid' => $game_id])->find()) {
  45. $runnable = false;
  46. $msg = '光环游戏记录不存在';
  47. }
  48. if ($runnable) {
  49. $game_info = Game::get($game_id);
  50. $mobileicon = $gameInfoModel->where(['game_id'=>$game_id])->value('mobileicon');
  51. if(empty($game_info)) {
  52. $runnable = false;
  53. $msg = 'game_id不存在';
  54. } elseif($platform==1 && (empty($mobileicon) || empty($game_info['package_name']))){ // ios游戏时
  55. $runnable = false;
  56. $msg = '游戏参数不全,请前往游戏内容编辑页面配置(请添加游戏图标、落地背景页)';
  57. } else{
  58. $pinyin = $game_info['pinyin'];
  59. $extend['channel_version'] = $game_info['channel_version'];
  60. $extend['pinyin'] = $game_info['pinyin'];
  61. $extend['channel_id'] = (string)$channel_id;
  62. $extend['admin_id'] = $admin_id;
  63. $extend['512pngUrl'] = STATIC_DOMAIN.$mobileicon; //游戏图标
  64. $extend['bundleID'] = $game_info['package_name']; //游戏包名
  65. $extend['gameChineseName'] = $game_info['name']; //游戏名称
  66. }
  67. }
  68. if($runnable) {
  69. $channel_info = \app\common\model\Channel::get($channel_id);
  70. if(empty($channel_info)) {
  71. $runnable = false;
  72. $msg = '渠道信息不存在';
  73. }
  74. else if($channel_info['level'] <> 3){
  75. $runnable = false;
  76. $msg = '非推广员渠道,不能进行打包';
  77. }
  78. }
  79. // 渠道 + 游戏 是否被禁止打包
  80. if($runnable) { // todo 此处 数据库运行很慢 需要看下是什么原因 暂时先屏蔽了
  81. $isFrozen = isFrozenOption($channel_id, $game_id);
  82. if($isFrozen) {
  83. $runnable = false;
  84. $msg = '您已经被禁止打包此游戏';
  85. }
  86. }
  87. // 判断游戏母包是否存在
  88. if($runnable && $platform != 3) { // h5游戏不需要母包
  89. $apk_is_exists = isRawGameApkExist($pinyin,$platform,$apktype);
  90. if($apk_is_exists == false || $apk_is_exists == 'False') {
  91. $runnable = false;
  92. $msg = '游戏母包不存在';
  93. }
  94. }
  95. // 判断 channel_id 与 game_id 是否在sdkgamelist表 无则新建 有则跳过
  96. if($runnable) {
  97. $result = (new SdkGameList())->where(['gameid' => $game_id, 'channel_id' => $channel_id, 'package_type'=> $apktype])->find();
  98. // 没有分包记录 则生成记录
  99. if (empty($result)) {
  100. $data = [
  101. 'gameid' => $game_id,
  102. 'channel_id' => $channel_id,
  103. 'update_time' => time(),
  104. 'create_time' => time(),
  105. 'channel_version' => $game_info['channel_version'],
  106. 'package_type' => $apktype,
  107. 'upload_status' => 4,
  108. ];
  109. $resultAdd = (new SdkGameList())->save($data);
  110. // ## 双端推广链接合并 ##
  111. // 判断双端对应链接是否存在,存在则使用另一端的推广地址
  112. $shortLinkModel = new PromotionShortLink();
  113. if(in_array($game_info['type'], [1,2])){
  114. if($game_info['type'] == 1){
  115. $bandId = Db::table('nw_game_band')->where(['ios_game_id' => $game_id])->value('android_game_id');
  116. } else if ($game_info['type'] == 2){
  117. $bandId = Db::table('nw_game_band')->where(['android_game_id' => $game_id])->value('ios_game_id');
  118. }
  119. if($bandShortLink = $shortLinkModel->where(['game_id'=>$bandId, 'channel_id'=>$channel_id, 'package_type'=>$apktype, 'type' => 1])->value('short_link')) {
  120. $shortLinkModel->insert(['game_id'=> $game_id, 'channel_id'=> $channel_id, 'package_type'=>$apktype, 'create_time'=>time(), 'short_link'=> $bandShortLink, 'type' => 1]);
  121. }else{
  122. $shortLinkModel->insertData($game_id,$channel_id,$apktype, 1);
  123. }
  124. }else{
  125. $shortLinkModel->insertData($game_id,$channel_id,$apktype, 1);
  126. // $shortLinkModel->insertData($game_id,$channel_id,$apktype, 2);
  127. }
  128. if($resultAdd == 0 || $resultAdd == false) {
  129. $runnable = false;
  130. $msg = '生成分包记录存储失败';
  131. }
  132. } elseif(!empty($result['filename'])){ // 文件名记录不为空时,删除包体
  133. // log_message('filename:' . $result['filename'], 'log', LOG_PATH . 'package/');
  134. // // 路径先依照老平台的来,如果要修改,需要和 python 上传时使用的路径保持一致
  135. // $file_path = "sygame/{$game_info['pinyin']}/{$result['filename']}";
  136. // $pathinfo = pathinfo($result['filename']);
  137. //
  138. // //IOS包时,需要同步删除plist文件
  139. // if($pathinfo['extension']=='ipa'){
  140. // if(UPLOAD_SAVE_PLACE=='ali'){
  141. // AliyunOSS::deleteObject("sygame/{$game_info['pinyin']}/{$pathinfo['filename']}.plist",PACKAGE_BUCKET);
  142. // } elseif(UPLOAD_SAVE_PLACE=='huawei') {
  143. // $obs = new HuaweiObs();
  144. // $obs->DeleteObject("sygame/{$game_info['pinyin']}/{$pathinfo['filename']}.plist",PACKAGE_BUCKET);
  145. // }
  146. // }
  147. // // log_message('file_path:' . $file_path, 'log', LOG_PATH . 'package/');
  148. // if(UPLOAD_SAVE_PLACE=='ali'){
  149. // // 无需传递文件的绝对路径,传递 URI 部分即可,这个方法的返回值,并不能表示删除结果。所以不做判断
  150. // AliyunOSS::deleteObject($file_path,PACKAGE_BUCKET);
  151. // } elseif(UPLOAD_SAVE_PLACE=='huawei'){
  152. // $obs->DeleteObject($file_path,PACKAGE_BUCKET);
  153. // }
  154. }
  155. }
  156. // 防止频繁提交任务 [python那边没有处理,该段代码先注释]
  157. if($runnable) {
  158. $cache_key = "subpackage_channel_{$game_id}_{$channel_id}".date('Y-m-d');
  159. if(cache($cache_key)) {
  160. $runnable = false;
  161. $msg = '打包任务已提交,请稍候';
  162. }else{
  163. cache($cache_key, time(), 10);
  164. }
  165. }
  166. // 产生一个随机的文件名,避免文件分发过程中,被各种云给缓存掉,导致渠道串包
  167. $apk_filename = uniqid(); // H5
  168. if($platform == 1){
  169. $apk_filename .= '.ipa';
  170. }else if ($platform == 2){
  171. $apk_filename .= '.apk';
  172. }
  173. if($platform == 3){
  174. // $game_url = Db::name('nw_game_package_upload')->where(['game_id' => $game_id])->value('path');
  175. $update_result = (new SdkGameList())->where(['gameid' => $game_id, 'channel_id' => $channel_id, 'package_type' => $apktype])
  176. ->update(['filename' => $apk_filename, 'channel_version' => $game_info['channel_version'], 'upload_status' => 1, 'update_time' => time()]);
  177. if ($update_result == 0 || $update_result == false) {
  178. return ["code" => 0, "msg" => $game_info['name']." - 分包失败:更新失败!", "data" => ['filename' => $apk_filename]];
  179. }
  180. return ["code" => 1, "msg" => "分包成功!", "data" => ['filename' => $apk_filename]];
  181. }
  182. // ## 同步分包处理
  183. if ($runnable && $pack_type == 1) {
  184. $task_data = [
  185. 'filename' => $pinyin, // 用于打包程序定位apk目录
  186. 'channel_id' => (string)$channel_id,
  187. 'apktype' => $apktype, //游戏包类型
  188. 'extend' => json_encode($extend),
  189. 'ext' => ($platform == 1) ? 'ipa' : 'apk',
  190. 'target_filename' => $apk_filename, // 指定要生成的渠道包文件名称
  191. 'sign_ver' => $game_info['sign_ver'] ?? 0, // 指定要生成的渠道包文件名称
  192. ];
  193. $res1 = gameApkPack($task_data);
  194. $res = json_decode($res1, true);
  195. if (!$res && $res['status'] != 'success' || $res1 == false) {
  196. Db::name('cy_sdkgamelist')->where(['gameid' => $game_id, 'channel_id' => $channel_id])->update(['upload_status' => 5]);
  197. return ["code" => 0, "msg" => "分包失败:" . $res['message'], "data" => []];
  198. }
  199. $update_result = (new SdkGameList())->where(['gameid' => $game_id, 'channel_id' => $channel_id, 'package_type' => $apktype])
  200. ->update(['filename' => $apk_filename, 'channel_version' => $game_info['channel_version'], 'upload_status' => 4, 'update_time' => time()]);
  201. if ($update_result == 0 || $update_result == false) {
  202. return ["code" => 0, "msg" => "分包失败:包名存储更新失败!", "data" => ['filename' => $apk_filename]];
  203. }
  204. Db::name('cy_sdkgamelist')->where(['gameid' => $game_id, 'channel_id' => $channel_id])->update(['upload_status' => 1]);
  205. return ["code" => 1, "msg" => "分包成功!", "data" => ['filename' => $apk_filename]];
  206. }
  207. // ## 异步分包处理
  208. if ($runnable) {
  209. // 更新到数据表中
  210. $update_result = (new SdkGameList())->where(['gameid' => $game_id, 'channel_id' => $channel_id, 'package_type' => $apktype])
  211. ->update(['filename' => $apk_filename, 'channel_version' => $game_info['channel_version'], 'upload_status' => 4, 'update_time' => time()]);
  212. if ($update_result == 0 || $update_result == false) {
  213. $runnable = false;
  214. $msg = '打包记录存储失败';
  215. }
  216. }
  217. // 投递任务至异步队列
  218. if ($runnable && $pack_type == 0) {
  219. $redis = Cache::init()->handler(); // 获取redis句柄
  220. // 异步打包完成后,回调通知回来的数据
  221. // todo 新得回调地址 http://admin.7dgames.cn/upload_notify/index/game_id/249/channel_id/5217/adminid/cps5190/apktype/0.html
  222. $callback_url = SUBPACK_DOMAIN . '/upload_notify/index/game_id/' . $game_id . '/channel_id/' . $channel_id . '/adminid/' . $admin_id . '/apktype/' . $apktype . '.html';
  223. // TODO: 本地测试专用:
  224. // $encrypt = md5($game_id.$channel_id.$admin_id.$apktype.'aoyou88!!!');
  225. // $callback_url = SUBPACK_DOMAIN.'/upload_notify/index/game_id/'.$game_id.'/channel_id/'.$channel_id.'/encrypt/'.$encrypt.'/adminid/'.$admin_id.'/apktype/'.$apktype.'.html';
  226. $task_key = ($platform==1) ? 'aoyou:ios:subpackage:task' : 'aoyou:apk:subpackage:task';
  227. $task_data = [
  228. 'filename' => $pinyin, // 用于打包程序定位apk目录
  229. 'channel_id' => (string)$channel_id,
  230. 'apktype' => $apktype, //游戏包类型
  231. 'extend' => $extend,
  232. 'target_filename' => $apk_filename, // 指定要生成的渠道包文件名称
  233. 'finish_notice_url' => $callback_url, // 打包完成后,回调通知该地址
  234. 'sign_ver' => $game_info['sign_ver'] ?? 0, // 签名版本
  235. ];
  236. // json_encode($task_data) = "{"filename":"mubaoANDROID","channel_id":"5215","apktype":0,"extend":{"channel_version":18,"pinyin":"mubaoANDROID","channel_id":"5215","admin_id":1,"512pngUrl":"http:\/\/cdn.7dgame.cn\/image\/game\/icons\/2023091416266502c3cc46898.png","bundleID":"com.qimeng.mubao","gameChineseName":"\u6bcd\u5305ANDROID"},"target_filename":"66c5ac2f14326.apk","finish_notice_url":"http:\/\/admin.7dgames.cn\/upload_notify\/index\/game_id\/10\/channel_id\/5215\/adminid\/1\/apktype\/0.html","sign_ver":0}"
  237. $redis->lpush($task_key, json_encode($task_data));
  238. }
  239. // 响应
  240. if($runnable) {
  241. return ['msg' => '打包任务发送成功', 'code' => 0];
  242. }else{
  243. return ['msg' => $msg, 'code' => 400];
  244. }
  245. }
  246. /**
  247. * 打包任务完成后,通知该方法
  248. */
  249. public function uploadPackageNotify() {
  250. $runnable = true;
  251. $channel_id = input('channel_id/d');
  252. $game_id = input('game_id/d');
  253. $adminid = input('adminid','','trim');
  254. $apktype = input('apktype/d'); //0 普通包,1 光环包
  255. $token = input('encrypt');
  256. $checkToken = md5($game_id.$channel_id.$adminid.$apktype.'aoyou88!!!');
  257. // token 校验 md5(game_id+channel_id+adminid+'aoyou88!!!') md5(234354aoyou88!!!)
  258. // if ($checkToken != $token) {
  259. // $runnable = false;
  260. // $msg = 'token校验失败!';
  261. // }
  262. if(empty($channel_id)) {
  263. $runnable = false;
  264. $msg = '参数缺失!';
  265. }
  266. if(empty($adminid)) {
  267. $runnable = false;
  268. $msg = '用户id缺失!';
  269. }
  270. if($runnable && empty($game_id)) {
  271. $runnable = false;
  272. $msg = '参数缺失!';
  273. }
  274. // TODO 验证adminid,
  275. try {
  276. if($runnable) { // 修改包的上传状态
  277. $update_result = (new SdkGameList)
  278. ->where(['gameid' => $game_id, 'channel_id' => $channel_id,'package_type'=>$apktype])
  279. ->update(['upload_status' => 1]);
  280. if(!$update_result) {
  281. $runnable = false;
  282. $msg = '修改apk状态失败!';
  283. }
  284. }
  285. // 调用消息系统接口,websocket告知用户打包完成
  286. if($runnable && $adminid != 'ydd_fb') { // 这块代码 是给前端 websocket 通知得
  287. $ws = new Websocket();
  288. $gameInfo = model('Game')->where(['id' => $game_id])->find();
  289. if (!$gameInfo) {
  290. $runnable = false;
  291. $msg = '游戏id不存在!';
  292. } else {
  293. // 没有华为云,先注释
  294. // try {
  295. // // $sdkGameList = (new SdkGameList)->where(['gameid' => $game_id, 'channel_id' => $channel_id,'package_type'=>$apktype])->find();
  296. // // $down_url = APK_DOWN_DOMAIN.'/sygame/'.$gameInfo['pinyin'].'/'.$sdkGameList['filename'];
  297. // // (new HuaWeiCloudService())->createPreheatingTasks([$down_url]);
  298. // }catch(\Exception $e){
  299. // $template = 'cdn创建缓存异常,'.$e->getMessage().'时间:'.date('Y-m-d H:i:s');
  300. // $ddurl = Env::get('warning_url');
  301. // curlDD($template, $ddurl,true);
  302. // }
  303. $gamename = $gameInfo['name'].'-'.$channel_id;
  304. $str = '{"error_code":0,"data":{"action":"subpackageFinish","data":{"code":0,"gamename":"'.$gamename.'", "message":"分包完成!"}}}';
  305. $ws->sayToUid($adminid, $str);
  306. }
  307. }
  308. }catch (\Exception $e){
  309. $runnable = false;
  310. }
  311. if($runnable) {
  312. return 'success';
  313. }else{
  314. return $msg;
  315. }
  316. }
  317. /**
  318. * 更新游戏分包表的记录、 删除OSS的渠道包文件
  319. *
  320. * @param $package_type integer 游戏包类型 0:普通包,1:光环包
  321. */
  322. public function deletePackage($channel_id, $game_id,$package_type){
  323. $runnable = true;
  324. $msg = '';
  325. // 查询一下是否存在打包记录
  326. $apk_info = (new SdkGameList())->where(['gameid' => (int)$game_id, 'channel_id' => (int)$channel_id,'package_type'=>$package_type])->find();
  327. if(empty($apk_info) || empty($apk_info['filename'])) {
  328. $runnable = false;
  329. $msg = '无分包记录';
  330. }
  331. /*
  332. if($runnable && empty($apk_info['upload_status'])) {
  333. $runnable = false;
  334. $msg = '无打包或未上传完成';
  335. }*/
  336. if($runnable) {
  337. //删除包体文件
  338. $this->removePackageFile($game_id, $apk_info['filename']);
  339. (new SdkGameList())->save(['filename' => '', 'upload_status' => 0],['id' => $apk_info['id']]);
  340. }
  341. if($runnable) {
  342. return ['msg' => 'success'];
  343. }else{
  344. return ['msg' => $msg];
  345. }
  346. }
  347. /**
  348. * 删除渠道包文件
  349. *
  350. * @param $game_id 游戏ID
  351. * @param $filename string 包体文件名
  352. */
  353. public function removePackageFile($game_id,$filename)
  354. {
  355. $runnable = true;
  356. $msg = '';
  357. if(empty($filename)){
  358. $runnable = false;
  359. $msg = '包体文件名不能为空';
  360. }
  361. if($runnable){
  362. $game_info = Game::get($game_id);
  363. if(empty($game_info)) {
  364. $runnable = false;
  365. $msg = 'game_id不存在';
  366. }else{
  367. $pinyin = $game_info['pinyin'];
  368. }
  369. }
  370. if($runnable) {
  371. // 路径先依照老平台的来,如果要修改,需要和 python 上传时使用的路径保持一致
  372. $file_path = "sygame/{$pinyin}/{$filename}";
  373. $pathinfo = pathinfo($filename);
  374. if(isset($pathinfo['extension'])){
  375. //IOS包时,需要同步删除plist文件
  376. if($pathinfo['extension']=='ipa'){
  377. if(UPLOAD_SAVE_PLACE=='ali'){
  378. AliyunOSS::deleteObject("sygame/{$pinyin}/{$pathinfo['filename']}.plist",PACKAGE_BUCKET);
  379. } elseif(UPLOAD_SAVE_PLACE=='huawei'){
  380. $obs = new HuaweiObs();
  381. $obs->DeleteObject("sygame/{$pinyin}/{$pathinfo['filename']}.plist",PACKAGE_BUCKET);
  382. }
  383. }
  384. if(UPLOAD_SAVE_PLACE=='ali'){
  385. // 无需传递文件的绝对路径,传递 URI 部分即可,这个方法的返回值,并不能表示删除结果。所以不做判断
  386. AliyunOSS::deleteObject($file_path,PACKAGE_BUCKET);
  387. } elseif(UPLOAD_SAVE_PLACE=='huawei'){
  388. $obs = new HuaweiObs();
  389. $obs->DeleteObject($file_path,PACKAGE_BUCKET);
  390. }
  391. }
  392. }
  393. return ['code' => $runnable,'msg' => $msg];
  394. }
  395. /**
  396. * 删除游戏分包表的记录、 删除OSS的渠道包文件
  397. *
  398. * @param $package_type integer 游戏包类型 0:普通包,1:光环包
  399. */
  400. public function removePackage($channel_id, $game_id,$package_type){
  401. $runnable = true;
  402. $msg = '';
  403. // 查询一下是否存在打包记录
  404. $apk_info = (new SdkGameList())->where(['gameid' => (int)$game_id, 'channel_id' => (int)$channel_id,'package_type'=>$package_type])->find();
  405. if(empty($apk_info)) {
  406. $runnable = false;
  407. $msg = '无分包记录';
  408. }
  409. if($runnable) {
  410. //删除包体文件
  411. $this->removePackageFile($game_id, $apk_info['filename']);
  412. (new SdkGameList())->where(['id' => $apk_info['id']])->delete();
  413. }
  414. if($runnable) {
  415. return ['msg' => 'success'];
  416. }else{
  417. return ['msg' => $msg];
  418. }
  419. }
  420. /**
  421. * 根据活跃天数进行批量分包
  422. *
  423. * @param $gameId int 游戏ID
  424. * @param $day_limit int 活跃天数
  425. * @param $package_type int 游戏包类型
  426. * @param $admin_id int 操作者ID
  427. *
  428. */
  429. public function batchSubpackageByActiveDay($gameId,$day_limit,$package_type,$admin_id)
  430. {
  431. $gameModel = new Game;
  432. $gameInfoModel = new GameInfo;
  433. $runnable = true;
  434. $msg = '';
  435. $reply = [];
  436. if (!$gameId) {
  437. $msg = '游戏id参数错误!';
  438. $runnable = false;
  439. }
  440. if (!$day_limit) {
  441. $msg = '活跃天数参数错误!';
  442. $runnable = false;
  443. }
  444. if(!in_array($package_type,[0,1])){
  445. $msg = '游戏包类型参数错误';
  446. $runnable = false;
  447. }
  448. $condition['cy_sdkgamelist.gameid'] = $gameId;
  449. $condition['cy_sdkgamelist.package_type'] = $package_type;
  450. $condition['channel.level'] = 3;
  451. $gameInfo = $gameModel->where(['id' => $gameId])->field('channel_version')->find();
  452. if (!$gameInfo) {
  453. $msg = '游戏无信息!';
  454. $runnable = false;
  455. }
  456. //游戏平台
  457. $platform = $gameInfoModel->where(['game_id'=>$gameId])->value('platform');
  458. $platform = ($platform==false) ? 0 : $platform;
  459. $list = (new SdkGameList())->join('nw_channel channel', 'cy_sdkgamelist.channel_id = channel.id')->where($condition)->select();
  460. if(!empty($list) && $runnable) {
  461. $loginInfo = new Logininfo();
  462. foreach ($list as $val) {
  463. // todo 非活跃渠道,不做分包, 联运部门除外
  464. if($val['channel_id'] != 50) {
  465. $is_active_channel = $loginInfo->isActiveChannel($val['channel_id'], $gameId, $day_limit);
  466. if (false == $is_active_channel) continue;
  467. }
  468. $this->deletePackage($val['channel_id'], $gameId,$package_type); // 删包
  469. $subPath = $this->index($val['channel_id'], $gameId, $admin_id,$platform,$package_type); // 分包
  470. $reply[] = array(
  471. 'channel_name' => get_channel_name($val['channel_id']),
  472. 'msg' => $subPath['code'] == 0 ? ' 分包成功请等待后端消息推送': ' 分包失败,'.$subPath['msg'],
  473. 'code' => $subPath['code']
  474. );
  475. }
  476. }
  477. if($runnable) {
  478. if(!empty($reply)){
  479. $res = $reply;
  480. }else{
  481. $res = [
  482. 'code' => 400,
  483. 'msg' => '无可分包渠道'
  484. ];
  485. }
  486. } else {
  487. $res = [
  488. 'code' => 400,
  489. 'msg' => $msg
  490. ];
  491. }
  492. return $res;
  493. }
  494. /**
  495. * 批量分包
  496. *
  497. * @param $gameId int 游戏ID
  498. * @param $day_limit int 活跃天数
  499. * @param $package_type int 游戏包类型
  500. * @param $admin_id int 操作者ID
  501. *
  502. */
  503. public function batchBySubpackage($gameId,$admin_id)
  504. {
  505. $gameModel = new Game;
  506. $gameInfoModel = new GameInfo;
  507. $runnable = true;
  508. $msg = '';
  509. $reply = [];
  510. if (!$gameId) {
  511. $msg = '游戏id参数错误!';
  512. $runnable = false;
  513. }
  514. $condition['cy_sdkgamelist.gameid'] = $gameId;
  515. $condition['channel.level'] = 3;
  516. $gameInfo = $gameModel->where(['id' => $gameId])->field('channel_version')->find();
  517. if (!$gameInfo) {
  518. $msg = '游戏无信息!';
  519. $runnable = false;
  520. }
  521. //游戏平台
  522. $platform = $gameInfoModel->where(['game_id'=>$gameId])->value('platform');
  523. $platform = ($platform==false) ? 0 : $platform;
  524. $list = (new SdkGameList())->join('nw_channel channel', 'cy_sdkgamelist.channel_id = channel.id')->where($condition)->select();
  525. if(!empty($list) && $runnable) {
  526. foreach ($list as $val) {
  527. $this->deletePackage($val['channel_id'], $gameId,$val['package_type']); // 删包
  528. $subPath = $this->index($val['channel_id'], $gameId, $admin_id,$platform,$val['package_type']); // 分包
  529. $reply[] = array(
  530. 'channel_name' => get_channel_name($val['channel_id']),
  531. 'msg' => $subPath['code'] == 0 ? ' 分包成功请等待后端消息推送': ' 分包失败,'.$subPath['msg'],
  532. 'code' => $subPath['code']
  533. );
  534. }
  535. }
  536. if($runnable) {
  537. if(!empty($reply)){
  538. $res = $reply;
  539. }else{
  540. $res = [
  541. 'code' => 400,
  542. 'msg' => '无可分包渠道'
  543. ];
  544. }
  545. } else {
  546. $res = [
  547. 'code' => 400,
  548. 'msg' => $msg
  549. ];
  550. }
  551. return $res;
  552. }
  553. /**
  554. * 渠道包下载,下载地址为永久,不随着渠道apk文件名变化而失效
  555. * 访问地址: /index.php/downapp/游戏ID/渠道ID
  556. */
  557. public function down($channel_id, $game_id){
  558. $runnable = true;
  559. $msg = '';
  560. if(empty($channel_id) || empty($game_id)) {
  561. $runnable = false;
  562. $msg = '参数有误';
  563. }
  564. if($runnable) {
  565. // 查出包的信息
  566. $apk_info = (new SdkGameList())
  567. ->where(['gameid' => $game_id, 'channel_id' => $channel_id])
  568. ->find();
  569. if(empty($apk_info)) {
  570. $runnable = false;
  571. $msg = '未找到分包信息';
  572. }
  573. }
  574. if($runnable && empty($apk_info['upload_status'])) {
  575. $runnable = false;
  576. $msg = '游戏包暂未生成';
  577. }
  578. if($runnable) {
  579. try{
  580. // 查询出游戏的拼音名称
  581. $pinyin = Game::get($game_id)->pinyin;
  582. }catch (Exception $e){
  583. exit("<script>alert('游戏参数错误')</script>");
  584. }
  585. // 跳转到CDN下载地址
  586. header("Location:".APK_DOWN_DOMAIN."/sygame/{$pinyin}/{$apk_info['filename']}");
  587. }
  588. !$runnable && exit("<script>alert('{$msg}');location.href='http://www.weilongwl.com'</script>");
  589. }
  590. /**
  591. * @param int $platform
  592. *
  593. * @return bool
  594. */
  595. public function isB (int $platform): bool
  596. {
  597. return $platform == 1;
  598. }
  599. }