Index.php 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248
  1. <?php
  2. namespace app\index\controller;
  3. use think\facade\Db;
  4. use app\middleware\Log;
  5. use think\facade\Cache;
  6. use ReflectionException;
  7. use app\middleware\Safe;
  8. use think\file\UploadedFile;
  9. use \think\response\Json;
  10. use think\facade\Request;
  11. use think\admin\Controller;
  12. use InvalidArgumentException;
  13. use app\service\WeiboService;
  14. use app\admin\model\SystemNotice;
  15. use think\facade\Log as FacadeLog;
  16. use think\db\exception\DbException;
  17. use think\admin\service\SystemService;
  18. use think\exception\FuncNotFoundException;
  19. use think\exception\ClassNotFoundException;
  20. use think\db\exception\DataNotFoundException;
  21. use think\db\exception\ModelNotFoundException;
  22. /**
  23. * Class Index
  24. * @package app\index\controller
  25. */
  26. class Index extends Controller
  27. {
  28. /**
  29. * 获取品牌任务相关配置
  30. *
  31. * @throws FuncNotFoundException
  32. * @throws ClassNotFoundException
  33. * @throws ReflectionException
  34. * @throws DbException
  35. * @throws ModelNotFoundException
  36. * @throws DataNotFoundException
  37. * @return mixed
  38. */
  39. public function brand()
  40. {
  41. $conf = $this->getBrandConfigAndState();
  42. if ($conf instanceof Json) {
  43. return $conf;
  44. }
  45. return $this->successResponse($conf);
  46. }
  47. /**
  48. * 检测登录 通过cookie中的SUB字段的内容,调用用户接口检测登录状态
  49. * @throws ClassNotFoundException
  50. * @throws ReflectionException
  51. * @return mixed
  52. */
  53. public function checkLogin()
  54. {
  55. FacadeLog::info("checkLogin cookies:" . json_encode(Request::post()));
  56. $sub = Request::post('cookie');
  57. $uid = 0;
  58. $userInfoRes = (new WeiboService($uid))->userinfo($sub);
  59. if (empty($userInfoRes) || $userInfoRes['ok'] != 1) {
  60. return $this->response(403, $userInfoRes['msg'] ?? '没有登录');
  61. }
  62. // 使用客户端信息生成token
  63. $token = md5($_SERVER['HTTP_USER_AGENT'] . $_SERVER['HTTP_ACCEPT_ENCODING'] . $_SERVER['HTTP_ACCEPT_LANGUAGE'] . get_client_ip(0) . $userInfoRes['data']['uid']);
  64. $user = $userInfoRes['data'];
  65. $userInfo = Db::table('awards_user_info')->where('uid', $user['uid'])->find();
  66. $count = 0;
  67. $isShare = 0;
  68. if (empty($userInfo)) {
  69. $userAttr = [
  70. 'uid' => $user['uid'],
  71. 'portrait' => $user['profile_image_url'],
  72. 'nickname' => $user['name'],
  73. 'is_share' => 0,
  74. 'count' => 1,
  75. 'create_at' => time()
  76. ];
  77. if (0 == Db::table('awards_user_info')->insert($userAttr)) {
  78. return $this->response(5001, '系统错误,请稍后再试~');
  79. }
  80. } else {
  81. $count = Db::table('awards_user_task_log')->where('uid', $user['uid'])->count('id');
  82. $isShare = $userInfo['is_share'];
  83. }
  84. // 生成加密用的密钥和向量
  85. $cipher = "aes-256-gcm";
  86. $ivlen = openssl_cipher_iv_length($cipher);
  87. $iv = bin2hex(openssl_random_pseudo_bytes($ivlen));
  88. $aesKey = bin2hex(openssl_random_pseudo_bytes(32));
  89. // $user = array_merge($user, [
  90. // 'aes_key' => $aesKey,
  91. // 'ase_iv' => $iv,
  92. // ]);
  93. $cacheUser = [
  94. 'aes_key' => $aesKey,
  95. 'ase_iv' => $iv,
  96. 'uid' => $user['uid'],
  97. ];
  98. $activity = Db::table('awards_activity')->where('begin_at', '<=', time())
  99. ->where('end_at', '>=', time())->find();
  100. $isBeginActivity = 1;
  101. if (empty($activity)) {
  102. $isBeginActivity = 0;
  103. }
  104. $userInfo = [];
  105. if ($count > 0) {
  106. $userInfo = Db::table('awards_user_task_log')->alias('l')
  107. ->leftJoin('awards_user_info u', 'l.uid = u.uid')
  108. ->field(['u.nickname', 'u.portrait', 'u.uid', 'l.duration', 'l.number'])
  109. ->order('l.number', 'desc')
  110. ->order('l.duration', 'asc')
  111. ->find();
  112. }
  113. // 缓存用户信息1天
  114. Cache::set('u:' . $token, json_encode($cacheUser), 86400);
  115. return $this->successResponse([
  116. 'user' => $user,
  117. 'token' => $token,
  118. 'isShare' => $isShare,
  119. 'count' => $count,
  120. 'isBeginActivity' => $isBeginActivity,
  121. 'task' => $userInfo
  122. ]);
  123. }
  124. /**
  125. * 是否可以参与游戏
  126. * @throws ClassNotFoundException
  127. * @throws ReflectionException
  128. * @return mixed
  129. */
  130. public function checkRole()
  131. {
  132. $activity = Db::table('awards_activity')->where('begin_at', '<=', time())
  133. ->where('end_at', '>=', time())->find();
  134. if (empty($activity)) {
  135. return $this->response(5002, '活动末开始');
  136. }
  137. $userInfo = Db::table('awards_user_info')->where('uid', Safe::$user['uid'])->find();
  138. $count = Db::table('awards_user_task_log')->where('uid', Safe::$user['uid'])->count('id');
  139. return $this->successResponse([
  140. 'isShare' => $userInfo['is_share'],
  141. 'count' => $count
  142. ]);
  143. }
  144. /**
  145. * 提交任务接口
  146. * @throws FuncNotFoundException
  147. * @throws ClassNotFoundException
  148. * @throws DbException
  149. * @throws ModelNotFoundException
  150. * @throws DataNotFoundException
  151. * @return mixed
  152. */
  153. public function submitTask()
  154. {
  155. $activity = Db::table('awards_activity')->where('begin_at', '<=', time())
  156. ->where('end_at', '>=', time())->find();
  157. if (empty($activity)) {
  158. return $this->response(5002, '活动末开始');
  159. }
  160. if (empty(Safe::$body)) {
  161. return $this->response(5003, '参数有误');
  162. }
  163. if (!isset(Safe::$body['duration']) || Safe::$body['duration'] < 1 || Safe::$body['duration'] > 1000) {
  164. return $this->response(5003, '时长参数有误');
  165. }
  166. if (!isset(Safe::$body['number']) || Safe::$body['number'] < 0 || Safe::$body['number'] > 1000) {
  167. return $this->response(5003, '时长参数有误');
  168. }
  169. $duration = Safe::$body['duration'];
  170. $number = Safe::$body['number'];
  171. $duration = Request::post("duration");
  172. $number = Request::post("number");
  173. $date = date('Y-m-d');
  174. $userInfo = Db::table('awards_user_info')->where('uid', Safe::$user['uid'])->find();
  175. if (empty($userInfo)) {
  176. return $this->response(403, '没有登录');
  177. }
  178. $count = Db::table('awards_user_task_log')->where('uid', Safe::$user['uid'])->count('id');
  179. if ($count >= $userInfo['count']) {
  180. return $this->response(5002, '没有参与次数');
  181. }
  182. $log = [
  183. 'uid' => Safe::$user['uid'],
  184. 'date' => $date,
  185. 'duration' => $duration,
  186. 'number' => $number,
  187. 'create_at' => time()
  188. ];
  189. if (0 == Db::table('awards_user_task_log')->insert($log)) {
  190. return $this->response(5001, '系统错误,请稍后再试~');
  191. }
  192. return $this->successResponse(null, '提交成功');
  193. }
  194. /**
  195. * 提交发布微博接口
  196. * @throws FuncNotFoundException
  197. * @throws ClassNotFoundException
  198. * @throws DbException
  199. * @throws ModelNotFoundException
  200. * @throws DataNotFoundException
  201. * @return mixed
  202. */
  203. public function submitShare()
  204. {
  205. $activity = Db::table('awards_activity')->where('begin_at', '<=', time())
  206. ->where('end_at', '>=', time())->find();
  207. if (empty($activity)) {
  208. return $this->response(5002, '活动末开始');
  209. }
  210. $userInfo = Db::table('awards_user_info')->where('uid', Safe::$user['uid'])->find();
  211. if (empty($userInfo)) {
  212. return $this->response(403, '没有登录');
  213. }
  214. if ($userInfo['is_share'] > 0) {
  215. return $this->response(601, '已发布');
  216. }
  217. // 更新任务状态
  218. $nums = Db::table('awards_user_info')->where('uid', Safe::$user['uid'])->update([
  219. 'is_share' => 1,
  220. 'count' => 2,
  221. 'share_at' => time()
  222. ]);
  223. if ($nums) {
  224. return $this->successResponse(null, '提交成功');
  225. } else {
  226. return $this->response(601, '发布失败');
  227. }
  228. }
  229. /**
  230. * 开始游戏
  231. * @return mixed|Json
  232. * @throws DataNotFoundException
  233. * @throws DbException
  234. * @throws ModelNotFoundException
  235. */
  236. public function startGame()
  237. {
  238. $activity = Db::table('awards_activity')->where('begin_at', '<=', time())
  239. ->where('end_at', '>=', time())->find();
  240. if (empty($activity)) {
  241. return $this->response(5002, '活动末开始');
  242. }
  243. $userInfo = Db::table('awards_user_info')->where('uid', Safe::$user['uid'])->find();
  244. if (empty($userInfo)) {
  245. return $this->response(403, '没有登录');
  246. }
  247. $count = Db::table('awards_user_task_log')->where('uid', Safe::$user['uid'])->count('id');
  248. if ($count >= $userInfo['count']) {
  249. return $this->response(5002, '没有参与次数');
  250. }
  251. $game = Db::table('awards_user_game')
  252. ->where('uid', '=', Safe::$user['uid'])
  253. ->where('state', '=', 1)
  254. ->find();
  255. if (!empty($game)) {
  256. Db::table('awards_user_game')->where('id', '=', $game['id'])->delete(true);
  257. }
  258. $gameId = $this->uuid();
  259. $attr = [
  260. 'game_id' => $gameId,
  261. 'uid' => Safe::$user['uid'],
  262. 'begin_at' => time(),
  263. 'end_at' => 0,
  264. 'state' => 1,
  265. 'create_at' => time()
  266. ];
  267. Db::table('awards_user_game')->insert($attr);
  268. return $this->successResponse(['gameId' => $gameId], '开始游戏成功');
  269. }
  270. /**
  271. * 结束游戏
  272. * @return mixed|Json
  273. * @throws DataNotFoundException
  274. * @throws DbException
  275. * @throws ModelNotFoundException
  276. */
  277. public function endGame()
  278. {
  279. $activity = Db::table('awards_activity')->where('begin_at', '<=', time())
  280. ->where('end_at', '>=', time())->find();
  281. if (empty($activity)) {
  282. return $this->response(5002, '活动末开始');
  283. }
  284. $userInfo = Db::table('awards_user_info')->where('uid', Safe::$user['uid'])->find();
  285. if (empty($userInfo)) {
  286. return $this->response(403, '没有登录');
  287. }
  288. $gameId = Request::post("gameId");
  289. $game = Db::table('awards_user_game')
  290. ->where('uid', '=', Safe::$user['uid'])
  291. ->where('game_id', '=', $gameId)
  292. ->where('state', '=', 1)
  293. ->find();
  294. if (empty($game)) {
  295. return $this->response(6001, '游戏不存在');
  296. }
  297. $endAt = time();
  298. Db::table('awards_user_game')->where('game_id', '=', $gameId)->update([
  299. 'end_at' => $endAt,
  300. 'state' => 2,
  301. 'update_at' => time()
  302. ]);
  303. $count = Db::table('awards_user_task_log')->where('uid', Safe::$user['uid'])->count('id');
  304. if ($count >= $userInfo['count']) {
  305. return $this->response(5002, '没有参与次数');
  306. }
  307. return $this->successResponse(null, '提交成功');
  308. }
  309. /**
  310. * 提交彩蛋
  311. * @return mixed|Json
  312. * @throws DataNotFoundException
  313. * @throws DbException
  314. * @throws ModelNotFoundException
  315. */
  316. public function submitEasterEgg()
  317. {
  318. $easterEgg = Request::post("easterEgg");
  319. if (!in_array($easterEgg, [1, 2, 3,4 ,5 ,6,7, 8, 9, 10, 11, 12, 13, 14, 15])) {
  320. return $this->response(6003, '游戏参数有误');
  321. }
  322. $activity = Db::table('awards_activity')->where('begin_at', '<=', time())
  323. ->where('end_at', '>=', time())->find();
  324. if (empty($activity)) {
  325. return $this->response(5002, '活动末开始');
  326. }
  327. $userInfo = Db::table('awards_user_info')->where('uid', Safe::$user['uid'])->find();
  328. if (empty($userInfo)) {
  329. return $this->response(403, '没有登录');
  330. }
  331. $gameId = Request::post("gameId");
  332. $game = Db::table('awards_user_game')
  333. ->where('uid', '=', Safe::$user['uid'])
  334. ->where('game_id', '=', $gameId)
  335. ->where('state', '=', 1)
  336. ->find();
  337. if (empty($game)) {
  338. return $this->response(6001, '游戏不存在');
  339. }
  340. $log = Db::table('awards_user_game_log')
  341. ->where('uid', '=', Safe::$user['uid'])
  342. ->where('game_id', '=', $gameId)
  343. ->where('draw', '=', $easterEgg)
  344. ->find();
  345. if (!empty($log)) {
  346. return $this->successResponse(null, '提交成功');
  347. }
  348. $log = Db::table('awards_user_game_log')
  349. ->where('uid', '=', Safe::$user['uid'])
  350. ->where('game_id', '=', $gameId)
  351. ->order('create_at', 'desc')
  352. ->find();
  353. if (empty($log)) {
  354. $startTime = $game['begin_at'];
  355. } else {
  356. $startTime = $log['create_at'];
  357. }
  358. $duration = time() - $startTime;
  359. if ($duration < 0) {
  360. return $this->response(6002, '游戏参数有误');
  361. }
  362. $attr = [
  363. 'uid' => Safe::$user['uid'],
  364. 'game_id' => $gameId,
  365. 'draw' => $easterEgg,
  366. 'duration' => $duration,
  367. 'create_at' => time()
  368. ];
  369. Db::table('awards_user_game_log')->insert($attr);
  370. return $this->successResponse(null, '提交成功');
  371. }
  372. function uuid()
  373. {
  374. $chars = md5(uniqid(mt_rand(), true));
  375. $uuid = substr ( $chars, 0, 8 )
  376. . substr ( $chars, 8, 4 )
  377. . substr ( $chars, 12, 4 )
  378. . substr ( $chars, 16, 4 )
  379. . substr ( $chars, 20, 12 );
  380. return $uuid ;
  381. }
  382. /**
  383. * 头号排行接口
  384. * @throws FuncNotFoundException
  385. * @throws ClassNotFoundException
  386. * @throws DbException
  387. * @throws ModelNotFoundException
  388. * @throws DataNotFoundException
  389. * @return mixed
  390. */
  391. public function topRanking()
  392. {
  393. $ranking = Db::query("select u.nickname, u.portrait, l.uid, l.duration, l.number from awards_user_task_log as l left join awards_user_info as u on l.uid = u.uid
  394. where u.portrait != '' and u.portrait is not null group by l.uid order by l.number desc, l.duration asc limit 50");
  395. $userInfo = Db::table('awards_user_task_log')->alias('l')
  396. ->leftJoin('awards_user_info u', 'l.uid = u.uid')
  397. ->field(['u.nickname', 'u.portrait', 'l.uid', 'l.duration', 'l.number'])
  398. ->where('l.uid', '=', Safe::$user['uid'])
  399. ->order('l.number', 'desc')
  400. ->order('l.duration', 'asc')
  401. ->find();
  402. $res = [
  403. 'self' => $userInfo,
  404. 'ranking' => $ranking
  405. ];
  406. return $this->successResponse($res);
  407. }
  408. /**
  409. * 最新排行接口
  410. * @throws FuncNotFoundException
  411. * @throws ClassNotFoundException
  412. * @throws DbException
  413. * @throws ModelNotFoundException
  414. * @throws DataNotFoundException
  415. * @return mixed
  416. */
  417. public function newRanking()
  418. {
  419. $ranking = Db::query("select u.nickname, u.portrait, l.uid, l.duration, l.number from awards_user_task_log as l left join awards_user_info as u on l.uid = u.uid
  420. where u.portrait != '' and u.portrait is not null group by l.uid order by l.create_at desc, l.number desc, l.duration asc limit 50");
  421. $userInfo = Db::table('awards_user_task_log')->alias('l')
  422. ->leftJoin('awards_user_info u', 'l.uid = u.uid')
  423. ->field(['u.nickname', 'u.portrait', 'l.uid', 'l.duration', 'l.number'])
  424. ->where('l.uid', '=', Safe::$user['uid'])
  425. ->order('l.number', 'desc')
  426. ->order('l.duration', 'asc')
  427. ->find();
  428. $res = [
  429. 'self' => $userInfo,
  430. 'ranking' => $ranking
  431. ];
  432. return $this->successResponse($res);
  433. }
  434. /**
  435. * 提交领取信息接口
  436. * @throws FuncNotFoundException
  437. * @throws ClassNotFoundException
  438. * @throws DbException
  439. * @throws ModelNotFoundException
  440. * @throws DataNotFoundException
  441. * @return mixed
  442. */
  443. public function submitReceive()
  444. {
  445. $name = trim(Request::post("name"));
  446. $mobile = trim(Request::post("mobile"));
  447. $address = trim(Request::post("address"));
  448. $giftId = trim(Request::post("giftId"));
  449. $type = trim(Request::post("type"));
  450. $orders = Db::table('awards_order')->where('uid', Safe::$user['uid'])->where('type', $type)->find();
  451. if (empty($orders)) {
  452. return $this->response(5001, '参数有误');
  453. }
  454. $userInfo = Db::table('awards_user_info')->where('uid', Safe::$user['uid'])->find();
  455. if (empty($userInfo)) {
  456. return $this->response(403, '没有登录');
  457. }
  458. if (strlen($name) < 1 || strlen($name) > 50) {
  459. return $this->response(5001, '姓名有误');
  460. }
  461. if (strlen($mobile) != 11) {
  462. return $this->response(5001, '手机号有误');
  463. }
  464. if (strlen($address) < 1 || strlen($address) > 1000) {
  465. return $this->response(5001, '地址有误');
  466. }
  467. // 更新任务状态
  468. $nums = Db::table('awards_order')->where('uid', Safe::$user['uid'])->where('type', $type)->update([
  469. 'name' => $name,
  470. 'mobile' => $mobile,
  471. 'address' => $address,
  472. ]);
  473. if ($nums < 1) {
  474. return $this->response(5001, '系统错误,请稍后再试~');
  475. }
  476. return $this->successResponse(null, '提交成功');
  477. }
  478. /**
  479. * 获取轮播中奖接口
  480. * @throws FuncNotFoundException
  481. * @throws ClassNotFoundException
  482. * @throws DbException
  483. * @throws ModelNotFoundException
  484. * @throws DataNotFoundException
  485. * @return mixed
  486. */
  487. public function getRotationAward() {
  488. $activity = Db::table('awards_activity')->where('begin_at', '<=', time())
  489. ->where('end_at', '>=', time())->find();
  490. if (empty($activity)) {
  491. return $this->response(5002, '活动末开始');
  492. }
  493. $orders = Db::table('awards_order')->alias('o')
  494. ->leftJoin('awards_user_info u', 'o.uid = u.uid')
  495. ->leftJoin('awards_gift g', 'o.gift_id = g.id')
  496. ->field(['u.nickname', 'u.portrait', 'u.uid', 'g.name as giftName'])
  497. ->order('o.id', 'desc')
  498. ->select();
  499. return $this->successResponse($orders);
  500. }
  501. /**
  502. * 排行中奖接口
  503. * @throws FuncNotFoundException
  504. * @throws ClassNotFoundException
  505. * @throws DbException
  506. * @throws ModelNotFoundException
  507. * @throws DataNotFoundException
  508. * @return mixed
  509. */
  510. public function getRankingWinAward() {
  511. $activity = Db::table('awards_activity')->where('begin_at', '<=', time())
  512. ->where('end_at', '>=', time())->find();
  513. if (!empty($activity)) {
  514. return $this->response(5002, '活动末结束');
  515. }
  516. $ranking = Db::table('awards_user_task_log')->alias("l")
  517. ->leftJoin('awards_user_info u', 'l.uid = u.uid')
  518. ->field(['u.nickname', 'u.portrait', 'u.uid', 'l.duration', 'l.number'])
  519. ->distinct('l.uid')
  520. ->order('l.number', 'desc')
  521. ->order('l.duration', 'asc')
  522. ->limit(50)
  523. ->select();
  524. $isWinAward = 0;
  525. $rank = 0;
  526. foreach ($ranking as $key => $val) {
  527. if ($val['uid'] == Safe::$user['uid']) {
  528. $isWinAward = 1;
  529. $rank = $key +1;
  530. break;
  531. }
  532. }
  533. $giftId = 0;
  534. // 如果中奖 插入用户中奖信息
  535. if ($isWinAward == 1) {
  536. $gifts = Db::table('awards_gift')->where('type', 2)->select();
  537. foreach ($gifts as $val) {
  538. if ($rank >= $val['min_rank'] && $rank <= $val['max_rank']) {
  539. $giftId = $val['id'];
  540. $orders = Db::table('awards_order')->where('uid', Safe::$user['uid'])->where('type', 2)->find();
  541. if (empty($orders)) {
  542. $order = [
  543. 'uid' => Safe::$user['uid'],
  544. 'gift_id' => $giftId,
  545. 'type' => 2,
  546. 'create_at' => time(),
  547. ];
  548. Db::table('awards_order')->insert($order);
  549. }
  550. break;
  551. }
  552. }
  553. }
  554. return $this->successResponse([
  555. 'isWinAward' => $isWinAward,
  556. 'giftId' => $giftId
  557. ]);
  558. }
  559. /**
  560. * 抽奖接口
  561. * @throws FuncNotFoundException
  562. * @throws ClassNotFoundException
  563. * @throws DbException
  564. * @throws ModelNotFoundException
  565. * @throws DataNotFoundException
  566. * @return mixed
  567. */
  568. public function getLuckDraw()
  569. {
  570. $userInfo = Db::table('awards_user_info')->where('uid', Safe::$user['uid'])->find();
  571. if ($userInfo['draw_count'] >= 30) {
  572. return $this->response(5002, '抽奖次数已达上线~');
  573. }
  574. Db::table('awards_user_info')->where('uid', Safe::$user['uid'])->update([
  575. 'draw_count' => $userInfo['draw_count'] + 1
  576. ]);
  577. $orders = Db::table('awards_order')->where('uid', Safe::$user['uid'])->where('type', 1)->find();
  578. $isWinAward = 0;
  579. if ($orders) {
  580. return $this->successResponse([
  581. 'isWinAward' => $isWinAward,
  582. 'giftId' => 0
  583. ]);
  584. }
  585. $gifts = Db::table('awards_gift')->where('type', 1)->select();
  586. $logCount = Db::table('awards_user_task_log')->distinct('uid')->count('id');
  587. $limit = 5000;
  588. $userRate = rand(0, $limit);
  589. $giftId = 0;
  590. foreach ($gifts as $gift) {
  591. $orderCount = Db::table('awards_order')->where('type', 1)->where('gift_id', $gift['id'])->count('id');
  592. if ($orderCount >= $gift['count']) {
  593. continue;
  594. }
  595. // 如果参与活动人数 5000人内 有人中奖过,那么不在计算。
  596. $total = $logCount + 1;
  597. if ($orderCount == floor($total/$limit)) {
  598. $isWinAward = 0;
  599. $giftId = 0;
  600. break;
  601. }
  602. for ($i=0;$i<$gift['count'];$i++) {
  603. $giftRage = rand(0, $limit);
  604. if ($userRate == $giftRage) {
  605. $isWinAward = 1;
  606. $giftId = $gift['id'];
  607. break;
  608. }
  609. }
  610. // 如果参与活动人数 5000人内 还没有人中奖那最后一人必中。
  611. if ($orderCount < floor($total/$limit) && $isWinAward ==0 && ($total%$limit) == 0) {
  612. $isWinAward = 1;
  613. $giftId = $gift['id'];
  614. break;
  615. }
  616. }
  617. // 如果中奖 插入用户中奖信息
  618. if ($isWinAward == 1) {
  619. $order = [
  620. 'uid' => Safe::$user['uid'],
  621. 'gift_id' => $giftId,
  622. 'type' => 1,
  623. 'create_at' => time(),
  624. ];
  625. if (0 == Db::table('awards_order')->insert($order)) {
  626. return $this->response(5001, '系统错误,请稍后再试~');
  627. }
  628. }
  629. return $this->successResponse([
  630. 'isWinAward' => $isWinAward,
  631. 'giftId' => $giftId
  632. ]);
  633. }
  634. /**
  635. * 奖品记录接口
  636. * @throws FuncNotFoundException
  637. * @throws ClassNotFoundException
  638. * @throws DbException
  639. * @throws ModelNotFoundException
  640. * @throws DataNotFoundException
  641. * @return mixed
  642. */
  643. public function getAwardLog()
  644. {
  645. $awards = Db::table('awards_order')->alias('o')
  646. ->leftJoin('awards_gift g', 'o.gift_id = g.id')
  647. ->field(['g.name as giftName', 'o.*'])
  648. ->where('o.uid', Safe::$user['uid'])
  649. ->select();
  650. $res = [];
  651. foreach ($awards as $val) {
  652. $type = '抽奖';
  653. if ($val['type'] == 2) {
  654. $type = '排名奖';
  655. }
  656. $isReceive = 1;
  657. if (empty($val['name']) && empty($val['address']) && empty($val['mobile'])) {
  658. $isReceive = 0;
  659. }
  660. $res[] = [
  661. 'giftId' => $val['gift_id'],
  662. 'giftName' => $val['giftName'],
  663. 'typeLabel' => $type,
  664. 'type' => $val['type'],
  665. 'createAt' => date('y-m-d h:i:s', $val['create_at']),
  666. 'address' => $val['address'],
  667. 'name' => $val['name'],
  668. 'mobile' => $val['mobile'],
  669. 'isReceive' => $isReceive
  670. ];
  671. }
  672. return $this->successResponse($res);
  673. }
  674. public function clearGameData()
  675. {
  676. // 更新用户参与状态
  677. Db::table('awards_user_info')->where('uid', Safe::$user['uid'])->update([
  678. 'is_share' => 0,
  679. 'share_at' => 0,
  680. 'count' => 1,
  681. ]);
  682. Db::table('awards_user_task_log')->where('uid', Safe::$user['uid'])->delete();
  683. Db::table('awards_order')->where('uid', Safe::$user['uid'])->delete();
  684. return $this->successResponse(null, '清除成功');
  685. }
  686. /**
  687. * 品牌任务关注接口
  688. * @throws FuncNotFoundException
  689. * @throws ClassNotFoundException
  690. * @throws ReflectionException
  691. * @throws DbException
  692. * @throws ModelNotFoundException
  693. * @throws DataNotFoundException
  694. * @return mixed
  695. */
  696. public function follow()
  697. {
  698. // 先获取品牌任务配置及状态
  699. $conf = $this->getBrandConfigAndState();
  700. if ($conf instanceof Json) {
  701. return $conf;
  702. }
  703. // 已经关注过了
  704. if ($conf['state']['follow_state'] == 1) {
  705. return $this->successResponse([
  706. 'result' => 2,
  707. 'brand' => $conf,
  708. ], '您已经关注过了');
  709. }
  710. // 调用接口关注
  711. $weiboRes = (new WeiboService(Safe::$user['uid']))->add($conf['config']['follow']['id']);
  712. if (empty($weiboRes) || $weiboRes['code'] != 10000) {
  713. return $this->response(600, $weiboRes['msg'] ?? '关注失败~');
  714. }
  715. $date = date('Y-m-d');
  716. $redisKey = $this->getTaskStateRedisKey(intval(Safe::$user['uid']));
  717. // 如果已经完成了另外两项,则标记品牌任务已经完成
  718. $finishState = $conf['state']['finish_state'];
  719. if ($conf['state']['view_state'] == 1 && $conf['state']['forward_state'] == 1) {
  720. $finishState = 1;
  721. }
  722. // 更新任务状态
  723. $nums = Db::table('awards_user_task')->where('uid', Safe::$user['uid'])->where('date', $date)->update([
  724. 'follow_state' => 1,
  725. 'finish_state' => $finishState,
  726. ]);
  727. if ($nums) {
  728. $conf['state']['follow_state'] = 1;
  729. $conf['state']['finish_state'] = $finishState;
  730. Cache::set($redisKey, json_encode($conf['state']), 86400);
  731. return $this->successResponse([
  732. 'result' => 1,
  733. 'brand' => $conf,
  734. ], '关注成功');
  735. } else {
  736. return $this->response(601, '更新任务状态失败');
  737. }
  738. }
  739. /**
  740. * 品牌任务转发博文接口
  741. * @throws FuncNotFoundException
  742. * @throws ClassNotFoundException
  743. * @throws ReflectionException
  744. * @throws DbException
  745. * @throws ModelNotFoundException
  746. * @throws DataNotFoundException
  747. * @return mixed
  748. */
  749. public function forward()
  750. {
  751. // 先获取品牌任务配置及状态
  752. $conf = $this->getBrandConfigAndState();
  753. if ($conf instanceof Json) {
  754. return $conf;
  755. }
  756. // 已经转发过了
  757. if ($conf['state']['forward_state'] == 1) {
  758. return $this->successResponse([
  759. 'result' => 2,
  760. 'brand' => $conf,
  761. ], '您已经转发过了');
  762. }
  763. // 调用微博接口转发
  764. $weiboRes = (new WeiboService(Safe::$user['uid']))->repost($conf['config']['forward']['id'], $conf['config']['forward']['content'] ?? '');
  765. if (empty($weiboRes) || $weiboRes['code'] != 10000) {
  766. return $this->response(600, $weiboRes['msg'] ?? '转发失败~');
  767. }
  768. $date = date('Y-m-d');
  769. $redisKey = $this->getTaskStateRedisKey(intval(Safe::$user['uid']));
  770. // 如果已经完成了另外两项,则标记品牌任务已经完成
  771. $finishState = $conf['state']['finish_state'];
  772. if ($conf['state']['view_state'] == 1 && $conf['state']['follow_state'] == 1) {
  773. $finishState = 1;
  774. }
  775. // 更新任务状态
  776. $nums = Db::table('awards_user_task')->where('uid', Safe::$user['uid'])->where('date', $date)->update([
  777. 'forward_state' => 1,
  778. 'finish_state' => $finishState,
  779. ]);
  780. if ($nums) {
  781. $conf['state']['forward_state'] = 1;
  782. $conf['state']['finish_state'] = $finishState;
  783. Cache::set($redisKey, json_encode($conf['state']), 86400);
  784. return $this->successResponse([
  785. 'result' => 1,
  786. 'brand' => $conf,
  787. ], '转发成功');
  788. } else {
  789. return $this->response(601, '更新任务状态失败');
  790. }
  791. }
  792. /**
  793. * 获取活动规则
  794. * @throws FuncNotFoundException
  795. * @throws ReflectionException
  796. * @throws InvalidArgumentException
  797. * @throws ClassNotFoundException
  798. * @return mixed
  799. */
  800. public function getRule()
  801. {
  802. $config = SystemService::instance()->getData('activity:rule');
  803. return $this->successResponse($config);
  804. }
  805. /**
  806. * 聚合页配置信息
  807. * @throws FuncNotFoundException
  808. * @throws ReflectionException
  809. * @throws InvalidArgumentException
  810. * @throws ClassNotFoundException
  811. * @return mixed
  812. */
  813. public function groupPageConfig()
  814. {
  815. return $this->successResponse(['config' => SystemService::instance()->getData('group:page:config')]);
  816. }
  817. // public function index()
  818. // {
  819. // $this->redirect('video');
  820. // }
  821. /**
  822. * 聚合页通知获取
  823. * 查询最近20条通知
  824. * @throws DbException
  825. * @throws ModelNotFoundException
  826. * @throws DataNotFoundException
  827. * @return mixed
  828. */
  829. public function notices()
  830. {
  831. $rows = SystemNotice::limit(20)->order('id', 'desc')->select();
  832. return $this->successResponse([
  833. "lists" => $rows,
  834. ]);
  835. }
  836. /**
  837. * 首次弹窗
  838. * 发放邀请函微博
  839. * @return Json
  840. */
  841. public function sendInviteWeibo()
  842. {
  843. $config = SystemService::instance()->getData('group:page:config');
  844. $sendRes = (new WeiboService(Safe::$user['uid']))->status($config['firstDialog']['content']);
  845. if (empty($sendRes) || $sendRes['code'] != 10000) {
  846. return $this->response(403, $sendRes['msg'] ?? '发布失败');
  847. }
  848. Cache::set('u:f:' . Safe::$user['uid'], 1, 15552000);
  849. return $this->successResponse(null, '发布成功!');
  850. }
  851. /**
  852. * 首次弹窗用户未选择发送邀请函
  853. * 标记已经首次弹窗过了
  854. * @return mixed
  855. */
  856. public function setFirst()
  857. {
  858. Cache::set('u:f:' . Safe::$user['uid'], 1, 15552000);
  859. return $this->successResponse(null, '操作成功!');
  860. }
  861. /**
  862. * 标记用户已经浏览过主页了,用户点了去浏览时调用
  863. * @throws FuncNotFoundException
  864. * @throws ClassNotFoundException
  865. * @throws ReflectionException
  866. * @throws DbException
  867. * @throws ModelNotFoundException
  868. * @throws DataNotFoundException
  869. * @return mixed
  870. */
  871. public function setViewed()
  872. {
  873. // 先获取品牌任务配置及状态
  874. $conf = $this->getBrandConfigAndState();
  875. if ($conf instanceof Json) {
  876. return $conf;
  877. }
  878. if ($conf['state']['view_state'] == 1) {
  879. return $this->successResponse([
  880. 'result' => 2,
  881. 'brand' => $conf,
  882. ], '您已经浏览过了');
  883. }
  884. $date = date('Y-m-d');
  885. $redisKey = $this->getTaskStateRedisKey(intval(Safe::$user['uid']));
  886. // 如果已经完成了另外两项,则标记品牌任务已经完成
  887. $finishState = $conf['state']['finish_state'];
  888. if ($conf['state']['forward_state'] == 1 && $conf['state']['follow_state'] == 1) {
  889. $finishState = 1;
  890. }
  891. $nums = Db::table('awards_user_task')->where('uid', Safe::$user['uid'])->where('date', $date)->update([
  892. 'view_state' => 1,
  893. 'finish_state' => $finishState,
  894. ]);
  895. if ($nums) {
  896. $conf['state']['view_state'] = 1;
  897. $conf['state']['finish_state'] = $finishState;
  898. Cache::set($redisKey, json_encode($conf['state']), 86400);
  899. return $this->successResponse([
  900. 'result' => 1,
  901. 'brand' => $conf,
  902. ], '浏览成功');
  903. } else {
  904. return $this->response(601, '更新任务状态失败');
  905. }
  906. }
  907. /**
  908. * 用户完成端外分享时调用接口加票
  909. * @throws FuncNotFoundException
  910. * @throws ClassNotFoundException
  911. * @throws ReflectionException
  912. * @throws DbException
  913. * @throws ModelNotFoundException
  914. * @throws DataNotFoundException
  915. * @return mixed
  916. */
  917. public function shareFinishAddVotes()
  918. {
  919. // 先获取品牌任务配置及状态
  920. $conf = $this->getBrandConfigAndState();
  921. if ($conf instanceof Json) {
  922. return $conf;
  923. }
  924. if ($conf['state']['share_add_votes'] == 1) {
  925. return $this->successResponse([
  926. 'result' => 2,
  927. 'brand' => $conf,
  928. ], '您今日已经领取过投票机会了~');
  929. }
  930. // 调用接口给用户发券(加票)
  931. $weiboRes = (new WeiboService(Safe::$user['uid']))->setcoupons($conf['config']['share']['votes']);
  932. if (empty($weiboRes) || $weiboRes['code'] != 10000) {
  933. return $this->response(600, $weiboRes['msg'] ?? '加票失败~');
  934. }
  935. // 标记状态
  936. $date = date('Y-m-d');
  937. $redisKey = $this->getTaskStateRedisKey(intval(Safe::$user['uid']));
  938. $nums = Db::table('awards_user_task')->where('uid', Safe::$user['uid'])->where('date', $date)->update([
  939. 'share_add_votes' => 1,
  940. ]);
  941. if ($nums) {
  942. $conf['state']['share_add_votes'] = 1;
  943. Cache::set($redisKey, json_encode($conf['state']), 86400);
  944. return $this->successResponse([
  945. 'result' => 1,
  946. 'brand' => $conf,
  947. ], '加票成功');
  948. } else {
  949. return $this->response(601, '更新任务状态失败');
  950. }
  951. }
  952. /**
  953. * 完成品牌任务后领取加票机会接口
  954. * @throws FuncNotFoundException
  955. * @throws ClassNotFoundException
  956. * @throws ReflectionException
  957. * @throws DbException
  958. * @throws ModelNotFoundException
  959. * @throws DataNotFoundException
  960. * @return mixed
  961. */
  962. public function taskFinishAddVotes()
  963. {
  964. // 先获取品牌任务配置及状态
  965. $conf = $this->getBrandConfigAndState();
  966. if ($conf instanceof Json) {
  967. return $conf;
  968. }
  969. if ($conf['state']['finish_add_votes'] == 1) {
  970. return $this->successResponse([
  971. 'result' => 2,
  972. 'brand' => $conf,
  973. ], '您今日已经领取过投票机会了~');
  974. }
  975. // 未完成品牌任务 领取失败
  976. if ($conf['state']['finish_state'] == 0) {
  977. return $this->response(603, '请先完成品牌任务,再来领取加票', [
  978. 'result' => 0,
  979. 'brand' => $conf,
  980. ]);
  981. }
  982. // 调用微博接口 给用户发券(加票)
  983. $weiboRes = (new WeiboService(Safe::$user['uid']))->setcoupons($conf['config']['task']['votes']);
  984. if (empty($weiboRes) || $weiboRes['code'] != 10000) {
  985. return $this->response(600, $weiboRes['msg'] ?? '加票失败~');
  986. }
  987. // 标记加票成功
  988. $date = date('Y-m-d');
  989. $redisKey = $this->getTaskStateRedisKey(intval(Safe::$user['uid']));
  990. $nums = Db::table('awards_user_task')->where('uid', Safe::$user['uid'])->where('date', $date)->update([
  991. 'finish_add_votes' => 1,
  992. ]);
  993. if ($nums) {
  994. $conf['state']['finish_add_votes'] = 1;
  995. Cache::set($redisKey, json_encode($conf['state']), 86400);
  996. return $this->successResponse([
  997. 'result' => 1,
  998. 'brand' => $conf,
  999. ], '加票成功');
  1000. } else {
  1001. return $this->response(601, '更新任务状态失败');
  1002. }
  1003. }
  1004. /**
  1005. * 获取品牌任务配置及状态
  1006. * @throws FuncNotFoundException
  1007. * @throws ReflectionException
  1008. * @throws InvalidArgumentException
  1009. * @throws ClassNotFoundException
  1010. * @throws DbException
  1011. * @throws ModelNotFoundException
  1012. * @throws DataNotFoundException
  1013. * @return \think\response\Json|array
  1014. */
  1015. protected function getBrandConfigAndState()
  1016. {
  1017. $config = SystemService::instance()->getData('brand:task:config');
  1018. $date = date('Y-m-d');
  1019. $dateForRedis = date('Ymd');
  1020. if (empty(Safe::$user['uid'])) {
  1021. $state = [
  1022. // 品牌任务完成状态
  1023. 'finish_state' => 0,
  1024. // 关注子任务状态
  1025. 'follow_state' => 0,
  1026. // 转发子任务状态
  1027. 'forward_state' => 0,
  1028. // 查看浏览主页任务状态
  1029. 'view_state' => 0,
  1030. // 品牌任务完成后是否加票
  1031. 'finish_add_votes' => 0,
  1032. // 分享完成后是否加票
  1033. 'share_add_votes' => 0,
  1034. 'uid' => 0,
  1035. 'date' => $date,
  1036. ];
  1037. } else {
  1038. $redisKey = "t:{$dateForRedis}:" . Safe::$user['uid'];
  1039. $state = Cache::get($redisKey);
  1040. if (empty($state)) {
  1041. // 缓存失败 查数据库
  1042. $state = Db::table('awards_user_task')->where('uid', Safe::$user['uid'])->where('date', $date)->find();
  1043. if (empty($state)) {
  1044. // 当天第一次,初始化数据
  1045. $state = [
  1046. // 品牌任务完成状态
  1047. 'finish_state' => 0,
  1048. // 关注子任务状态
  1049. 'follow_state' => 0,
  1050. // 转发子任务状态
  1051. 'forward_state' => 0,
  1052. // 查看浏览主页任务状态
  1053. 'view_state' => 0,
  1054. // 品牌任务完成后是否加票
  1055. 'finish_add_votes' => 0,
  1056. // 分享完成后是否加票
  1057. 'share_add_votes' => 0,
  1058. 'uid' => Safe::$user['uid'],
  1059. 'date' => $date,
  1060. ];
  1061. if (0 == Db::table('awards_user_task')->insert($state)) {
  1062. return $this->response(5001, '系统错误,请稍后再试~');
  1063. }
  1064. }
  1065. Cache::set($redisKey, json_encode($state), 86400);
  1066. } else {
  1067. $state = json_decode($state, true);
  1068. }
  1069. // 如果未关注状态,查询下已经实际已经关注了
  1070. if ($state['follow_state'] == 0) {
  1071. $weiboRes = (new WeiboService(Safe::$user['uid']))->friends($config['follow']['id']);
  1072. if (isset($weiboRes['data'][$config['follow']['id']]) && $weiboRes['data'][$config['follow']['id']] == 1) {
  1073. $nums = Db::table('awards_user_task')->where('uid', Safe::$user['uid'])->where('date', $date)->update(['follow_state' => 1]);
  1074. if ($nums) {
  1075. $state['follow_state'] = 1;
  1076. Cache::set($redisKey, json_encode($state), 86400);
  1077. }
  1078. }
  1079. }
  1080. }
  1081. // 校准状态,可能存在异常情况关注,转发,浏览都完成了,但是总的品牌任务状态没标记成已完成
  1082. if ($state['follow_state'] == 1 && $state['forward_state'] == 1 && $state['view_state'] == 1 && $state['finish_state'] != 1) {
  1083. $nums = Db::table('awards_user_task')->where('uid', Safe::$user['uid'])->where('date', $date)->update(['finish_state' => 1]);
  1084. if ($nums) {
  1085. $state['finish_state'] = 1;
  1086. Cache::set($redisKey, json_encode($state), 86400);
  1087. }
  1088. }
  1089. return [
  1090. 'config' => $config,
  1091. 'state' => $state,
  1092. ];
  1093. }
  1094. /**
  1095. * 获取品牌任务redis 缓存键
  1096. * @param int $uid
  1097. * @return string
  1098. */
  1099. protected function getTaskStateRedisKey(int $uid): string
  1100. {
  1101. $dateForRedis = date('Ymd');
  1102. return "t:{$dateForRedis}:" . $uid;
  1103. }
  1104. /**
  1105. * @param $code
  1106. * @param $msg
  1107. * @param $data
  1108. * @return Json
  1109. */
  1110. protected function response($code, $msg, $data = null)
  1111. {
  1112. return json(
  1113. [
  1114. 'code' => $code,
  1115. 'message' => $msg,
  1116. 'data' => $data,
  1117. 'trackID' => Log::$logID,
  1118. ],
  1119. 200
  1120. );
  1121. }
  1122. /**
  1123. * @param $data
  1124. * @param $msg
  1125. * @return mixed
  1126. */
  1127. protected function successResponse($data, $msg = '操作成功')
  1128. {
  1129. return $this->response(0, $msg, $data);
  1130. }
  1131. }