TaskController.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474
  1. <?php
  2. namespace app\api\controller;
  3. use app\portal\model\UserModel;
  4. use app\user\model\PoolModel;
  5. use app\weixin\model\AccountLog;
  6. use app\weixin\model\Books;
  7. use app\weixin\model\Devices;
  8. use app\weixin\model\Member;
  9. use app\weixin\model\UserBalanceLog;
  10. use app\weixin\model\UserContactLog;
  11. use app\weixin\service\Award;
  12. use app\weixin\service\Export;
  13. use app\weixin\service\PRedis;
  14. use think\Controller;
  15. use think\Db;
  16. class TaskController extends Controller
  17. {
  18. /**
  19. * 订单超时处理
  20. * @throws \think\Exception
  21. * @throws \think\exception\PDOException
  22. */
  23. public function catchBook()
  24. {
  25. try {
  26. $key = input('key', '');
  27. $checkKey = config('task.key');
  28. if ($key != $checkKey) {
  29. showJson(1004, 2009, '', "\n");
  30. }
  31. $cancelTime = config('task.orderCancelTime');
  32. $cancelTime = $cancelTime ? $cancelTime * 60 : 30 * 60;
  33. // 未支付
  34. $cancelTime = date('Y-m-d H:i:s', time() - $cancelTime);
  35. $cancelCount = Books::where(['status' => 1])
  36. ->where('created_at', '<=', $cancelTime)
  37. ->count('id');
  38. Books::where(['status' => 1])
  39. ->where('created_at', '<=', $cancelTime)
  40. ->update(['status' => 4, 'remark' => '超时自动取消']);
  41. // 已取消的删除
  42. $deleteTime = date('Y-m-d H:i:s', time() - 3 * 24 * 3600);
  43. $deleteCount = Books::where(['status' => 4])
  44. ->where('created_at', '<=', $deleteTime)
  45. ->count('id');
  46. Books::where(['status' => 4])
  47. ->where('created_at', '<=', $deleteTime)
  48. ->delete();
  49. $msg = "报名订单自动取消已处理成功,累计取消{$cancelCount}个,删除{$deleteCount}个";
  50. return showJson(1005, $msg, '', "\n");
  51. } catch (\Exception $exception) {
  52. return showJson(1004, $exception->getMessage(), '', "\n");
  53. }
  54. }
  55. /**
  56. * 认识申请超时处理
  57. */
  58. public function cancelContact()
  59. {
  60. $key = input('key', '');
  61. $checkKey = config('task.contactKey');
  62. if ($key != $checkKey) {
  63. showJson(1004, 2009, '', "\n");
  64. }
  65. try {
  66. // 申请失效时间
  67. $siteInfo = cmf_get_site_info();
  68. $expire = isset($siteInfo['contact_time']) ? intval($siteInfo['contact_time']) : 0;
  69. $expire = $expire ? $expire : 1;
  70. $dataList = UserContactLog::where(['status' => 1])
  71. ->where('created_at', '<', date('Y-m-d H:i:s', time() - $expire * 24 * 3600))
  72. ->field('id,contact_uid')
  73. ->select();
  74. if (empty($dataList)) {
  75. showJson(1004, 1003, '', "\n");
  76. }
  77. $results = [];
  78. foreach ($dataList as $val) {
  79. $cid = isset($val['id']) ? intval($val['id']) : 0;
  80. $userId = isset($val['contact_uid']) ? intval($val['contact_uid']) : 0;
  81. if ($cid && $userId) {
  82. $res = Member::contactConfirm($userId, $cid, 4);
  83. if (is_array($res)) {
  84. $results[] = $res;
  85. }
  86. }
  87. }
  88. PRedis::set('tasks:contact:' . date('Ymd'), ['datalist' => $dataList, 'result' => $results], 3600);
  89. $msg = "认识申请记录超时处理结果,累计处理" . count($results) . "个";
  90. return showJson(1005, $msg, "\n");
  91. } catch (\Exception $exception) {
  92. return showJson(1004, $exception->getMessage(), '', "\n");
  93. }
  94. }
  95. /**
  96. * 批量推荐队列处理
  97. */
  98. public function catchMakeHearts()
  99. {
  100. set_time_limit(0);
  101. $key = input('key', '');
  102. $checkKey = config('task.heartKey');
  103. if ($key != $checkKey) {
  104. showJson(1004, 2009, '', "\n");
  105. }
  106. try {
  107. $userIds = [];
  108. $queenKey = "queens:hearts:" . date('Ymd');
  109. //echo $queenKey."<br>\n";
  110. for ($i = 0; $i < 500; $i++) {
  111. $userId = PRedis::lpop($queenKey);
  112. //echo $userId."\n";
  113. if ($userId) {
  114. $userIds[] = $userId;
  115. $url = url('/api/task/catchUserHeart', '', '', true);
  116. httpRequest($url, ['uid' => $userId], 'post', '', 2);
  117. }
  118. }
  119. $msg = "更新推荐数据结果,累计处理" . count($userIds) . "个会员数据更新";
  120. return showJson(1005, $msg, "\n");
  121. } catch (\Exception $exception) {
  122. return showJson(1004, $exception->getMessage(), '', "\n");
  123. }
  124. }
  125. /**
  126. * 清除过期签到爱心
  127. */
  128. public function clearSignHeart()
  129. {
  130. set_time_limit(0);
  131. $key = input('key', '');
  132. $checkKey = config('task.clearHeartKey');
  133. if ($key != $checkKey) {
  134. showJson(1004, 2009, '', "\n");
  135. }
  136. try {
  137. $month = date('Y-m-01', time() - 2 * 86400);
  138. $users = AccountLog::where(['type' => 12, 'status' => 2])
  139. ->where('created_at', '>=', $month)
  140. ->order('created_at', 'asc')
  141. ->column('user_id');
  142. $userIds = [];
  143. if ($users) {
  144. foreach ($users as $userId) {
  145. // 清除签到爱心
  146. if ($userId && \app\weixin\service\Member::clearSignRedHeart($userId)) {
  147. $userIds[] = $userId;
  148. }
  149. }
  150. }
  151. $msg = "清除签到爱心数据结果,共" . count($users) . "个,累计处理" . count($userIds) . "个会员数据更新";
  152. return showJson(1005, $msg, "\n");
  153. } catch (\Exception $exception) {
  154. return showJson(1004, $exception->getMessage(), '', "\n");
  155. }
  156. }
  157. /**
  158. * 处理怦然心动
  159. */
  160. public function catchUserHeart()
  161. {
  162. $uid = input('uid', 0);
  163. $dataList = Member::getHeartList($uid, '', true);
  164. showJson(1005, 1001, $dataList);
  165. }
  166. /**
  167. * 更新怦然心动推荐数据入队处理
  168. */
  169. public function makeHearts()
  170. {
  171. set_time_limit(0);
  172. $key = input('key', '');
  173. $checkKey = config('task.heartKey');
  174. if ($key != $checkKey) {
  175. showJson(1004, 2009, '', "\n");
  176. }
  177. try {
  178. // 查询需要推荐的用户
  179. $dataList = Member::alias('m')
  180. ->join('user_profile up', 'up.userid=m.id', 'left')
  181. ->field('m.openid,m.user_nickname,m.id,up.idcard_check,m.is_reg_profile')
  182. ->where(['m.user_status' => 1, 'm.user_type' => 2, 'up.idcard_check' => 2, 'm.is_reg_profile' => 1])
  183. ->where(function ($query) {
  184. return $query->where('m.heart_recommend_at', '<', date('Y-m-d 19:00:00'))
  185. ->whereOr('m.heart_recommend_at', 'exp', 'is null');
  186. })
  187. ->order('m.id')
  188. ->column('m.id');
  189. if (empty($dataList)) {
  190. showJson(1004, 1003, '', "\n");
  191. }
  192. $sql = Member::getLastSql();
  193. //echo $sql;
  194. // 处理数据更新
  195. $userids = [];
  196. $queenKey = "queens:hearts:" . date('Ymd');
  197. foreach ($dataList as $userId) {
  198. if ($userId && PRedis::rpush($queenKey, $userId)) {
  199. $userids[] = $userId;
  200. }
  201. }
  202. PRedis::expire($queenKey, 2 * 3600);
  203. PRedis::set('tasks:hearts:' . date('Ymd'), ['datalist' => $dataList, 'results' => $userids, 'time' => date('Y-m-d H:i:s'), 'sql' => $sql], 3600);
  204. $msg = "更新推荐数据入队结果,累计处理" . count($userids) . "个会员数据更新";
  205. return showJson(1005, $msg, "\n");
  206. } catch (\Exception $exception) {
  207. return showJson(1004, $exception->getMessage(), '', "\n");
  208. }
  209. }
  210. /**
  211. * 更新隐身
  212. * @throws \think\Exception
  213. * @throws \think\db\exception\DataNotFoundException
  214. * @throws \think\db\exception\ModelNotFoundException
  215. * @throws \think\exception\DbException
  216. * @throws \think\exception\PDOException
  217. */
  218. public function updateHeartStatus()
  219. {
  220. set_time_limit(0);
  221. $key = input('key', '');
  222. $checkKey = config('task.upHeartKey');
  223. if ($key != $checkKey) {
  224. showJson(1004, 2009, '', "\n");
  225. }
  226. $where = ['m.is_heart' => 1, 'm.is_reg_profile' => 1, 'm.user_status' => 1, 'm.user_type' => 2];
  227. $dataList = Member::alias('m')
  228. ->join('user_profile up', 'up.userid=m.id', 'left')
  229. ->where($where)
  230. ->where(function ($query) {
  231. $query->where(db()->raw("up.introduce is NULL or up.introduce = ''"))
  232. ->whereOr(db()->raw("up.family is NULL or up.family = ''"))
  233. ->whereOr(db()->raw("up.hobby is NULL or up.hobby = ''"))
  234. ->whereOr(db()->raw("up.purpose is NULL or up.purpose = ''"))
  235. ->whereOr(db()->raw("up.cause is NULL or up.cause = ''"))
  236. ->whereOr(db()->raw("up.expect is NULL or up.expect = ''"));
  237. })
  238. ->field('m.id,up.introduce,up.family,up.hobby,up.purpose,up.cause,up.expect')
  239. ->select()
  240. ->each(function ($profile, $k) {
  241. if (empty($profile) || (empty($profile['photolist']) || empty($profile['introduce']) || empty($profile['family']) || empty($profile['hobby']) || empty($profile['purpose']) || empty($profile['cause']) || empty($profile['expect']))) {
  242. Member::where(['id' => $profile['id']])->update(['is_heart' => 2, 'remark' => '系统检测自动设置隐身']);
  243. }
  244. });
  245. showJson(1005, 1001, $dataList);
  246. }
  247. /**
  248. * 活动报名分销收益结算
  249. * @throws \think\Exception
  250. * @throws \think\Exception\DbException
  251. * @throws \think\db\exception\DataNotFoundException
  252. * @throws \think\db\exception\ModelNotFoundException
  253. */
  254. public function catchBookMarket()
  255. {
  256. set_time_limit(0);
  257. $key = input('key', '');
  258. $checkKey = config('task.catchBookMarket');
  259. if ($key != $checkKey) {
  260. showJson(1004, 2009, '', "\n");
  261. }
  262. $catchIds = [];
  263. $catchList = [];
  264. $bookList = Books::alias('b')
  265. ->leftJoin('activity a', 'a.id=b.aid')
  266. ->leftJoin('user u', 'u.id=b.uid')
  267. ->where('a.endtime', '<=', time())
  268. // ->where('a.endtime', '>', time()-24*3600*3)
  269. ->where('u.parent_id', '>', 0)
  270. ->where(['a.is_top' => 0, 'a.status' => 1, 'b.status' => 3, 'b.is_market' => 2])
  271. ->field('b.id,b.uid,b.aid,b.money,u.parent_id,b.status')
  272. ->order('a.endtime desc, b.book_at asc,b.id asc')
  273. ->paginate(80)
  274. ->each(function ($item, $k) use (&$catchList, &$catchIds) {
  275. $userId = isset($item['uid']) ? intval($item['uid']) : 0;
  276. $aid = isset($item['aid']) ? $item['aid'] : 0;
  277. $money = isset($item['money']) ? floatval($item['money']) : 0;
  278. $inviteInfo = Member::getInviteInfo($userId);
  279. $inviteId = isset($inviteInfo['invite_id']) ? $inviteInfo['invite_id'] : 0;
  280. //$item['invite'] = $inviteInfo;
  281. PRedis::set('markets:activity:book_temp_' . $aid . ':' . $userId . '_' . $inviteId, ['info' => $item, 'inviteInfo' => $inviteInfo], 5 * 86400);
  282. if ($inviteInfo && $inviteId > 0 && $aid > 0 && $money > 0) {
  283. if (!UserBalanceLog::checkHasMarketBySource($inviteId, $userId, $aid, 9)) {
  284. $catchList[] = $item;
  285. PRedis::set('markets:activity:book_' . $aid . ':' . $userId . '_' . $inviteId, ['info' => $item, 'inviteInfo' => $inviteInfo], 7200);
  286. Award::marketAward($inviteId, $userId, 9, $money);
  287. $catchIds[] = $item['id'];
  288. }
  289. }
  290. });
  291. if ($catchIds) {
  292. Books::whereIn('id', $catchIds)->update(['is_market' => 1, 'remark' => '分销已结算']);
  293. }
  294. $bookList = $bookList ? $bookList->toArray() : [];
  295. showJson(1005, 1001, ['total' => $bookList['total'], 'bookList' => $bookList['data'], 'catchList' => $catchList]);
  296. }
  297. /**
  298. * 更新报表数据
  299. * @throws \think\Exception
  300. * @throws \think\exception\PDOException
  301. */
  302. public function updateExport()
  303. {
  304. set_time_limit(0);
  305. $key = input('key', '');
  306. $checkKey = config('task.updateExport');
  307. if ($key != $checkKey) {
  308. showJson(1004, 2009, '', "\n");
  309. }
  310. $result = Export::updateData();
  311. showJson(1005, 1001, ['ids' => $result, 'date' => date('Y-m-d H:i:s')]);
  312. }
  313. /**
  314. * 更新销售资源过期数据
  315. * @throws \think\Exception
  316. * @throws \think\exception\PDOException
  317. */
  318. public function salesExpired()
  319. {
  320. set_time_limit(0);
  321. $key = input('key', '');
  322. $checkKey = config('task.salesExpired');
  323. if ($key != $checkKey) {
  324. showJson(1004, 2009, '', "\n");
  325. }
  326. if(date("H:i") >= '06:00' && date("H:i") <= '23:00'){
  327. showJson(1004, '非更新时间段', '', "\n");
  328. }
  329. $count = 0;
  330. $datas = [];
  331. $result = PoolModel::alias('p')
  332. ->where('p.expire_at', '>', date('Y-m-d H:i:s', time() - 7*86400))
  333. ->where(['p.type' => 0, 'p.status' => 1])
  334. ->field('id,sale_uid,user_id,followup_num,follow_time,expire_at')
  335. ->limit(100)
  336. ->order('p.stop_time asc,p.expire_at asc')
  337. ->select()
  338. ->each(function ($item, $k) use (&$count, &$datas) {
  339. $userId = isset($item['user_id']) ? $item['user_id'] : 0;
  340. $saleUid = isset($item['sale_uid']) ? $item['sale_uid'] : 0;
  341. $expireAt = isset($item['expire_at']) ? $item['expire_at'] : '';
  342. $followTime = isset($item['follow_time']) ? $item['follow_time'] : '';
  343. $followTime = $followTime && $followTime != '0000-00-00 00:00:00'? $followTime : '';
  344. $updateData = ['updated_at' => date('Y-m-d H:i:s'),'stop_time'=> date('Y-m-d H:i:s')];
  345. // 到期数据处理
  346. $state = false;
  347. if($expireAt && $expireAt <= date('Y-m-d H:i:s')){
  348. $updateData['status'] = 2;
  349. $updateData['type'] = 2;
  350. $data = [
  351. 'sale_uid' => 0,
  352. 'user_id' => $userId,
  353. 'type' => 2,
  354. 'followup_num' => 0,
  355. 'intention' => 0,
  356. 'create_time' => date('Y-m-d H:i:s'),
  357. 'updated_at' => date('Y-m-d H:i:s'),
  358. 'expire_at' => 0,
  359. 'status' => 1,
  360. ];
  361. $info = PoolModel::checkData($userId);
  362. if (empty($info)) {
  363. $datas[] = $data;
  364. } else {
  365. PoolModel::where(['id' => $info['id'], 'user_id' => $userId])->update($data);
  366. }
  367. // 到期未跟进
  368. if($item['followup_num'] <= 0 || ($followTime && $followTime <date('Y-m-d H:i:s'))){
  369. $updateData['agency'] = 3;
  370. $state = true;
  371. }
  372. }else if ($expireAt){
  373. // 今日坠海
  374. $time = strtotime($expireAt);
  375. $dayTime = strtotime(date('Y-m-d'));
  376. //
  377. if($followTime < date('Y-m-d', $dayTime+ 86400) && $followTime >= date('Y-m-d')){
  378. $updateData['agency'] = 1;
  379. $item['expire_text'] = '今日需跟进';
  380. $state = true;
  381. }else if($followTime < date('Y-m-d', $dayTime+ 2*86400) && $followTime >= date('Y-m-d', $dayTime + 86400)){
  382. $updateData['agency'] = 2;
  383. $item['expire_text'] = '明日需跟进';
  384. $state = true;
  385. }else if($followTime < date('Y-m-d')){
  386. $updateData['agency'] = 3;
  387. $item['expire_text'] = '到期未跟进';
  388. $state = true;
  389. }
  390. if($time >= time() && $time < $dayTime + 86400){
  391. $item['expire_text'] = '今天坠海';
  392. $updateData['agency'] = 4;
  393. $state = true;
  394. }else if($time>=$dayTime+86400 && $time < $dayTime + 2 * 86400){
  395. $item['expire_text'] = '明天坠海';
  396. $updateData['agency'] = 5;
  397. $state = true;
  398. }else if($time>=$dayTime+7*86400 && $time < $dayTime + 8 * 86400){
  399. $item['expire_text'] = '一礼拜后坠海';
  400. $updateData['agency'] = 6;
  401. $state = true;
  402. }else if ($time >= $dayTime + 8 * 86400){
  403. $item['expire_text'] = '超过7天';
  404. $updateData['agency'] = 7;
  405. $state = true;
  406. }
  407. }
  408. // 更新待办事项
  409. if($updateData && $state == true){
  410. $count++;
  411. PoolModel::where(['id' => $item['id']])->update($updateData);
  412. }
  413. });
  414. if ($datas) {
  415. PoolModel::insertAll($datas);
  416. }
  417. // 缓存
  418. PRedis::set("caches:sales:expired", ['count'=> $count,'datas'=> $datas,'result'=> $result, 'date'=> date('Y-m-d H:i:s')], 86400);
  419. showJson(1005, 1008, ['count' => $count, 'date' => date('Y-m-d H:i:s')]);
  420. }
  421. }