GamePromotion.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547
  1. <?php
  2. /**
  3. * 游戏推广落地页控制器
  4. *
  5. */
  6. namespace app\api\controller;
  7. use app\common\model\Game;
  8. use app\common\model\SdkGameList;
  9. use app\common\model\GameBand;
  10. use app\common\model\PromotionShortLink;
  11. use app\common\library\jssdk;
  12. use think\Controller;
  13. use think\Db;
  14. use think\Config;
  15. class GamePromotion extends Controller
  16. {
  17. public function _initialize()
  18. {
  19. }
  20. // 双端推广页
  21. public function index($mark = ''){
  22. $shortLinkModel = new PromotionShortLink;
  23. $short_link = pathinfo($_SERVER['REQUEST_URI'])['filename'];
  24. if (strpos($short_link, '?')) {
  25. $short_link = substr($short_link, 0, strpos($short_link, '?'));
  26. }
  27. if (mb_strlen($short_link, 'UTF-8') == 8 || isset($mark)) {
  28. $shortLinkInfo = $shortLinkModel->where(['short_link' => $short_link])->find();
  29. if (empty($shortLinkInfo)) $this->error('短链接记录不存在');
  30. $game_id = $shortLinkInfo['game_id'];
  31. $channel_id = $shortLinkInfo['channel_id'];
  32. $package_type = $shortLinkInfo['package_type'];
  33. } else {
  34. $game_id = input('game_id', 0, 'intval');
  35. $channel_id = input('channel_id', 0, 'intval');
  36. $package_type = input('package_type', 0, 'intval');
  37. }
  38. if (empty($game_id)) {
  39. $this->error('游戏参数错误');
  40. }
  41. if (empty($channel_id)) {
  42. $this->error('渠道参数错误');
  43. }
  44. // 游戏详情
  45. $gameInfo = Db::table('cy_game')->alias('g')
  46. ->join('cy_gameinfo info', 'g.id=info.game_id', 'left')
  47. ->join('nw_android_sdk_config nasc', 'g.android_sdk_id=nasc.id', 'left')
  48. ->field('g.id as game_id, g.type, g.name, g.cooperation_status, g.pinyin, info.mobileicon as logo_img, info.landing_img, info.landing_page_status, nasc.version')
  49. ->where(['g.id' => $game_id])->find();
  50. if (empty($gameInfo)) {
  51. $this->error('游戏信息不存在!');
  52. }
  53. if (!empty($gameInfo['cooperation_status']) && $gameInfo['cooperation_status'] != 1) {
  54. if($gameInfo['cooperation_status'] == 3){
  55. $this->error('当前游戏已下架!');
  56. }
  57. if($gameInfo['cooperation_status'] != 1){
  58. $this->error('当前游戏未上线!');
  59. }
  60. }
  61. $gameName = cleanGameName($gameInfo['name'])??'';
  62. $landing_page_msg = "{$gameName} · {$gameInfo['version']} · 杭州祈点信息技术有限公司";
  63. // 游戏推广数据
  64. $gameData = [
  65. 'game_id' => $game_id, // 游戏ID
  66. 'channel_id' => $channel_id, // 渠道ID
  67. 'game_name' => $gameName, // 游戏名称
  68. 'game_type' => $gameInfo['type'], // 游戏类型:1=ios、2=安卓、3=h5
  69. // 'logo_img' => STATIC_DOMAIN . "/favicon.ico", // 游戏图标
  70. 'landing_page_status' => $gameInfo['landing_page_status'], // 落地页状态开关:1=开启、2=关闭
  71. 'landing_page_msg' => $landing_page_msg, // 落地页状态内容
  72. 'user_agreement' => T_DOMAIN."/user_agreement.html", // 用户协议
  73. 'game_privacy' => T_DOMAIN."/game_privacy.html", // 隐私协议
  74. 'landing_img' => 'https://t.qmgames.cn/static/images/test_bg.png', // 落地页背景图
  75. // 'landing_img' => 'http://static.qmgames.cn//image/game/landing/20250723162068809b3725435.png', // 落地页背景图
  76. // 'landing_img' => 'http://sdkapi.newsdk.com/static/game_img.jpg', // 落地页背景图
  77. // 安卓下载地址
  78. 'android_info' => [
  79. 'down_url' => '', // 包下载地址
  80. 'result_status' => 3, // 状态:1=正常,2=游戏问题,3=分包问题、4=程序异常
  81. 'result_msg' => '没有当前 安卓游戏 分包!', // 说明
  82. ],
  83. // IOS下载地址
  84. 'ios_info' => [
  85. 'down_url' => '', // 包下载地址
  86. 'result_status' => 3, // 状态:1=正常,2=游戏问题,3=分包问题、4=程序异常
  87. 'result_msg' => '没有当前 IOS游戏 分包!', // 说明
  88. ],
  89. // H5下载地址
  90. 'h5_info' => [
  91. 'down_url' => '', // 包下载地址
  92. 'result_status' => 3, // 状态:1=正常,2=游戏问题,3=分包问题、4=程序异常
  93. 'result_msg' => '没有当前 H5游戏 分包!', // 说明
  94. ],
  95. ];
  96. if(!empty($gameInfo['logo_img'])){
  97. $gameData['logo_img'] = STATIC_DOMAIN . '/' . $gameInfo['logo_img'];
  98. }
  99. if(!empty($gameInfo['landing_img'])){
  100. $gameData['landing_img'] = STATIC_DOMAIN . $gameInfo['landing_img'];
  101. }
  102. // 根据游戏ID 和类型,查询双端推广页
  103. $bandWhere = [];
  104. if($gameInfo['type'] == 1){
  105. $bandWhere['ios_game_id'] = $gameInfo['game_id'];
  106. } else if ($gameInfo['type'] == 2) {
  107. $bandWhere['android_game_id'] = $gameInfo['game_id'];
  108. } else if ($gameInfo['type'] == 3) {
  109. $bandWhere['h5_game_id'] = $gameInfo['game_id'];
  110. }
  111. $gameBandInfo = Db::table('nw_game_band')->where($bandWhere)->field('id,android_game_id,ios_game_id,h5_game_id')->find();
  112. // 判断游戏是否是H5,不是H5则查询双端
  113. $gameIds = [];
  114. if($gameInfo['type'] == 3){
  115. $gameIds[] = $gameInfo['game_id'];
  116. }else{
  117. if(!empty($gameBandInfo['android_game_id'])){
  118. $gameIds[] = $gameBandInfo['android_game_id'];
  119. }
  120. if(!empty($gameBandInfo['ios_game_id'])){
  121. $gameIds[] = $gameBandInfo['ios_game_id'];
  122. }
  123. // if(!empty($gameBandInfo['h5_game_id'])){
  124. // $gameIds[] = $gameBandInfo['h5_game_id'];
  125. // }
  126. }
  127. $appInfo = Db::table('cy_sdkgamelist')->alias('cs')
  128. ->join('cy_game cg', "cs.gameid = cg.id", 'left')
  129. ->where(['cs.gameid' => ['in', $gameIds], 'cs.channel_id' => $channel_id])->field('cs.gameid,cs.filename,cs.upload_status,cs.status, cg.type,cg.pinyin,cg.cooperation_status')->select();
  130. if(!$appInfo){
  131. $gameData['result_status'] = 2;
  132. $gameData['result_msg'] = '当前游戏没有包数据,请联系上级确认!';
  133. }
  134. foreach($appInfo as $v){
  135. if($v['type'] == 1){
  136. $gamePageInfo = $this->getGamePackInfo($v);
  137. if($gamePageInfo['result_status'] === 1){
  138. $gamePageInfo['down_url'] = getHandleCdnGamesByIds($v['gameid']) . '/sygame/' . $v['pinyin'] . '/' . str_replace(".ipa", ".plist", $v['filename']);
  139. }
  140. $gameData['ios_info'] = $gamePageInfo;
  141. } else if($v['type'] == 2){
  142. $gamePageInfo = $this->getGamePackInfo($v);
  143. if($gamePageInfo['result_status'] === 1){
  144. $gamePageInfo['down_url'] = getHandleCdnGamesByIds($v['gameid']) . '/sygame/' . $v['pinyin'] . '/' . $v['filename'];
  145. }
  146. $gameData['android_info'] = $gamePageInfo;
  147. } else if($v['type'] == 3){
  148. $gamePageInfo = $this->getGamePackInfo($v);
  149. if($gamePageInfo['result_status'] === 1){
  150. $gamePageInfo['down_url'] = getChannelH5Url($v['filename'], $v['gameid']);
  151. }
  152. $gameData['h5_info'] = $gamePageInfo;
  153. }
  154. }
  155. $this->assign('gameData', $gameData);
  156. return $this->fetch();
  157. }
  158. // 游戏&游戏包 状态判断
  159. private function getGamePackInfo($info){
  160. $result = [
  161. 'result_status' => 1, // 状态:1=正常,2=游戏问题,3=分包问题、4=程序异常
  162. 'result_msg' => '', // 说明
  163. 'down_url' => '', // 包下载地址
  164. ];
  165. // ## 判断游戏是否正常
  166. // if(empty($info['cooperation_status'])){
  167. // $result['result_status'] = 2;
  168. // $result['result_msg'] = '当前游戏没有相关包,请联系上级确认!';
  169. // } else
  170. if ($info['cooperation_status'] == 3) {
  171. $result['result_status'] = 2;
  172. $result['result_msg'] = '当前游戏已下架!';
  173. } else
  174. // if ($info['cooperation_status'] != 1) {
  175. // $result['result_status'] = 2;
  176. // $result['result_msg'] = '当前游戏未开放,请联系商务确认!';
  177. // }
  178. // ## 判断游戏包是否正常
  179. if($info['status'] != 1){
  180. $result['result_status'] = 3;
  181. $result['result_msg'] = '当前 游戏包已禁用,请联系商务!';
  182. }
  183. switch ($info['upload_status']){
  184. case 1:
  185. // 游戏包正常
  186. break;
  187. case 4:
  188. $result['result_status'] = 3;
  189. $result['result_msg'] = '游戏正在打包中,请稍后重试...';
  190. break;
  191. case 5:
  192. $result['result_status'] = 3;
  193. $result['result_msg'] = '游戏包 打包失败,请联系商务!';
  194. break;
  195. case 9:
  196. $result['result_status'] = 3;
  197. $result['result_msg'] = '当前 游戏包已禁用,请联系商务!';
  198. break;
  199. default:
  200. $result['result_status'] = 3;
  201. $result['result_msg'] = '游戏包 异常,请联系商务!';
  202. }
  203. // ## 游戏包下载地址
  204. if(!$info['filename']){
  205. $result['result_status'] = 3;
  206. $result['result_msg'] = '当前游戏 未打包 或 打包异常,请联系商务确认!';
  207. }
  208. return $result;
  209. }
  210. /**
  211. * 推广落地页
  212. */
  213. public function indexOld($mark = '')
  214. {
  215. $sdkGameListModel = new SdkGameList;
  216. $shortLinkModel = new PromotionShortLink;
  217. $short_link = pathinfo($_SERVER['REQUEST_URI'])['filename'];
  218. if (strpos($short_link, '?')) {
  219. $short_link = substr($short_link, 0, strpos($short_link, '?'));
  220. }
  221. if (mb_strlen($short_link, 'UTF-8') == 8 || isset($mark)) {
  222. $shortLinkInfo = $shortLinkModel->where(['short_link' => $short_link])->find();
  223. if (empty($shortLinkInfo)) $this->error('短链接记录不存在');
  224. $game_id = $shortLinkInfo['game_id'];
  225. $channel_id = $shortLinkInfo['channel_id'];
  226. $package_type = $shortLinkInfo['package_type'];
  227. } else {
  228. $game_id = input('game_id', 0, 'intval');
  229. $channel_id = input('channel_id', 0, 'intval');
  230. $package_type = input('package_type', 0, 'intval');
  231. }
  232. if (empty($game_id)) {
  233. $this->error('游戏参数错误');
  234. }
  235. if (empty($channel_id)) {
  236. $this->error('渠道参数错误');
  237. }
  238. // 游戏详情
  239. $gameInfo = (new Game)->alias('g')->join('cy_gameinfo info', 'g.id=info.game_id', 'left')
  240. ->field('g.id as game_id, g.type, g.name, g.cooperation_status, g.pinyin, info.mobileicon as logo_img, info.title_img, info.landing_img')
  241. ->where(['g.id' => $game_id])->find();
  242. if (empty($gameInfo)) {
  243. $this->error('游戏信息不存在!');
  244. }
  245. if (!empty($gameInfo['cooperation_status']) && $gameInfo['cooperation_status'] != 1) {
  246. if($gameInfo['cooperation_status'] == 3){
  247. $this->error('当前游戏已下架!');
  248. }
  249. if($gameInfo['cooperation_status'] != 1){
  250. $this->error('当前游戏未上线!');
  251. }
  252. }
  253. if(!empty($gameInfo['logo_img'])){
  254. $gameInfo['logo_img'] = STATIC_DOMAIN . '/' . $gameInfo['logo_img'];
  255. }else{
  256. $gameInfo['logo_img'] = STATIC_DOMAIN . "/favicon.ico";
  257. }
  258. if(!empty($gameInfo['title_img'])){
  259. $gameInfo['title_img'] = $gameInfo['title_img'];
  260. }
  261. if(!empty($gameInfo['landing_img'])){
  262. $gameInfo['landing_img'] = STATIC_DOMAIN . '/' . $gameInfo['landing_img'];
  263. }
  264. // 分包详情
  265. $appInfo = $sdkGameListModel->where(['gameid' => $game_id, 'channel_id' => $channel_id, 'package_type' => $package_type])->field('filename,upload_status,status')->find();
  266. if (empty($appInfo)) {
  267. $this->error('当前 游戏包不存在!');
  268. }
  269. if($appInfo['status'] != 1){
  270. $this->error('当前 游戏包已禁用,请联系商务!');
  271. }
  272. switch ($appInfo['upload_status']){
  273. case 1:
  274. // 游戏包正常
  275. break;
  276. case 4:
  277. $this->error('游戏包 正在打包中,请稍后重试!');
  278. break;
  279. case 5:
  280. $this->error('游戏包 打包失败,请联系商务!');
  281. break;
  282. case 9:
  283. $this->error('游戏包 已禁用!');
  284. break;
  285. default:
  286. $this->error('游戏包 异常,请联系商务!');
  287. }
  288. // 下载地址
  289. $downUrl = getHandleCdnGamesByIds($game_id) . '/sygame/' . $gameInfo['pinyin'] . '/' . $appInfo['filename'];
  290. if($gameInfo['type'] == 1){
  291. $downUrl = "itms-services://?action=download-manifest&url=" . str_replace(".ipa", ".plist", $downUrl);
  292. }else if($gameInfo['type'] == 2){
  293. $downUrl = getHandleCdnGamesByIds($game_id) . '/sygame/' . $gameInfo['pinyin'] . '/' . $appInfo['filename'];
  294. }else if($gameInfo['type'] == 3){
  295. $downUrl = getChannelH5Url($appInfo['filename'], $game_id);
  296. }
  297. if(!$downUrl){
  298. $this->error('游戏打包异常,请确认相关配置以及分包情况!');
  299. }
  300. $gameInfo['down_url'] = $downUrl;
  301. $this->assign('gameInfo', $gameInfo);
  302. return $this->fetch();
  303. }
  304. /**
  305. * IOS
  306. *
  307. * @return mixed
  308. */
  309. public function ios()
  310. {
  311. $sdkGameListModel = new SdkGameList;
  312. $shortLinkModel = new PromotionShortLink;
  313. $short_link = pathinfo($_SERVER['REQUEST_URI'])['filename'];
  314. if (strpos($short_link, '?')) {
  315. $short_link = substr($short_link, 0, strpos($short_link, '?'));
  316. }
  317. if (mb_strlen($short_link, 'UTF-8') == 8) {
  318. $shortLinkInfo = $shortLinkModel->where(['short_link' => $short_link])->find();
  319. if (empty($shortLinkInfo)) $this->error('短链接记录不存在');
  320. $game_id = $shortLinkInfo['game_id'];
  321. $channel_id = $shortLinkInfo['channel_id'];
  322. $package_type = $shortLinkInfo['package_type'];
  323. } else {
  324. $game_id = input('game_id', 0, 'intval');
  325. $channel_id = input('channel_id', 0, 'intval');
  326. $package_type = input('package_type', 0, 'intval');
  327. }
  328. if (empty($game_id)) {
  329. $this->error('游戏参数错误');
  330. }
  331. if (empty($channel_id)) {
  332. $this->error('渠道参数错误');
  333. }
  334. $isWeixin = $this->isWeixin();
  335. $signPackage = false;
  336. if ($isWeixin) {
  337. $jssdk = new jssdk(Config::get('wx_jssdk')['appid'], Config::get('wx_jssdk')['appsecret']);
  338. $signPackage = $jssdk->getSignPackage();
  339. if (empty($signPackage)) {
  340. $this->error($jssdk->getError());
  341. }
  342. }
  343. //$gamePromotionModel = Db::name('nw_game_promotion');
  344. $gameModel = new Game;
  345. $gameBandModel = new GameBand;
  346. //$promotionInfo = $gamePromotionModel->field('background_image,background_color_image,title_image,specific_show,specific_title_image,specific_image')->where(['game_id'=>$game_id])->find();
  347. /*if(empty($promotionInfo)){
  348. $this->error('推广信息还未配置');
  349. }*/
  350. $gameInfo = $gameModel->table('cy_game g,cy_gameinfo info')
  351. ->field('g.id as game_id,g.name,g.nickname,g.image,g.pinyin,g.publicity,info.mobileicon,info.bigimage,info.video,info.video_image,info.platform,info.drawingImg,info.landing_img,info.title_img,info.new_back_img')->where('g.id = info.game_id')->where(['g.id' => $game_id])->find();
  352. if (empty($gameInfo)) {
  353. $this->error('游戏信息不存在');
  354. }
  355. //当前游戏的包名
  356. $filename = $sdkGameListModel->where(['gameid' => $game_id, 'channel_id' => $channel_id, 'upload_status' => 1, 'package_type' => $package_type])->value('filename');
  357. $out_img = [];
  358. if ($gameInfo['bigimage']) {
  359. $bigimage_list = explode(';', $gameInfo['bigimage']);
  360. if ($gameInfo['drawingImg']) {
  361. $draw_list = json_decode($gameInfo['drawingImg'], 1);
  362. unset($gameInfo['drawingImg']);
  363. }
  364. foreach ($bigimage_list as $key => $value) {
  365. $out_img[$key]['backimg'] = $bigimage_list[$key];
  366. $out_img[$key]['drawimg'] = isset($draw_list[$key]) ? $draw_list[$key] : '';
  367. }
  368. } else {
  369. $bigimage_list = '';
  370. }
  371. //默认
  372. if (!$gameInfo['video_image']) {
  373. $gameInfo['video_image'] = 'image/game/videoImg/2020091114135f5b159963833.png';
  374. }
  375. //$this->assign('promotionInfo', $promotionInfo);
  376. $this->assign('gameInfo', $gameInfo);
  377. $this->assign('bigimage_list', $out_img); //游戏截图
  378. //安卓游戏
  379. if ($gameInfo['platform'] == 0) {
  380. $ios_down_url = '';
  381. $gameBandInfo = $gameBandModel->table('nw_game_band b,cy_game g')->field('b.ios_game_id,g.id,g.pinyin')
  382. ->where('b.ios_game_id = g.id')
  383. ->where(['b.android_game_id' => $game_id])->find();
  384. if (!empty($gameBandInfo)) {
  385. //绑定的游戏包名
  386. $bandFilename = $sdkGameListModel->where(['gameid' => $gameBandInfo['id'], 'channel_id' => $channel_id, 'upload_status' => 1, 'package_type' => 0])->value('filename');
  387. if (!empty($bandFilename)) {
  388. $ios_down_url = APK_DOWN_DOMAIN . '/sygame/' . $gameBandInfo['pinyin'] . '/' . str_replace(".ipa", ".plist", $bandFilename);
  389. }
  390. }
  391. $this->assign('android_down_url', (!empty($filename) ? APK_DOWN_DOMAIN . '/sygame/' . $gameInfo['pinyin'] . '/' . $filename : ''));
  392. $this->assign('ios_down_url', $ios_down_url);
  393. // 获取当前游戏的title_image 落地页背景图片 back_img 游戏图标
  394. $this->assign("title_image", $gameInfo['title_image'] ?: null);
  395. $this->assign("back_img", $gameInfo['new_back_img'] ?: null);
  396. } //IOS游戏
  397. else {
  398. $android_down_url = '';
  399. $gameBandInfo = $gameBandModel->table('nw_game_band b,cy_game g')->field('b.android_game_id,g.id,g.pinyin')
  400. ->where('b.android_game_id = g.id')
  401. ->where(['b.ios_game_id' => $game_id])->find();
  402. if (!empty($gameBandInfo)) {
  403. //绑定的游戏包名
  404. $bandFilename = $sdkGameListModel->where(['gameid' => $gameBandInfo['id'], 'channel_id' => $channel_id, 'upload_status' => 1, 'package_type' => 0])->value('filename');
  405. if (!empty($bandFilename)) {
  406. $android_down_url = APK_DOWN_DOMAIN . '/sygame/' . $gameBandInfo['pinyin'] . '/' . $bandFilename;
  407. }
  408. }
  409. $this->assign('android_down_url', $android_down_url);
  410. $this->assign('ios_down_url', (!empty($filename) ? APK_DOWN_DOMAIN . '/sygame/' . $gameInfo['pinyin'] . '/' . str_replace(".ipa", ".plist", $filename) : ''));
  411. // 获取当前游戏的title_image 落地页背景图片 back_img 游戏图标
  412. $this->assign("title_image", $gameInfo['title_image'] ?: null);
  413. $this->assign("back_img", $gameInfo['new_back_img'] ?: null);
  414. }
  415. return $this->fetch();
  416. }
  417. /**
  418. * 是否是通过微信访问
  419. *
  420. * @return boolean
  421. */
  422. function isWeixin()
  423. {
  424. if (strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') !== false) {
  425. return true;
  426. }
  427. return false;
  428. }
  429. public function abc()
  430. {
  431. return $this->fetch();
  432. }
  433. public function wlxx()
  434. {
  435. return $this->fetch();
  436. }
  437. /**
  438. * 微信中安卓游戏包下载
  439. *
  440. *//*
  441. public function download() {
  442. $android_down_url = input('android_down_url');
  443. if ( empty($android_down_url) ) {
  444. exit('参数不正确');
  445. }
  446. $header = get_headers($android_down_url, true);
  447. if ( strpos($header[0], '200') === false ) {
  448. $android_down_url = '';
  449. }
  450. if ( empty($android_down_url) ) {
  451. exit('下载文件不存在');
  452. }
  453. $name = basename($android_down_url);
  454. header("Content-Type: application/zip");
  455. header("Content-Length: " . $header['Content-Length']);
  456. header("Content-Disposition: attachment; filename=\"{$name}\"");
  457. header('Content-Transfer-Encoding: binary');
  458. header("Expires: 0");
  459. header("Cache-control: private");
  460. header("Pragma: no-cache");
  461. readfile($android_down_url);
  462. exit;
  463. }*/
  464. }