Member.php 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  1. <?php
  2. /**
  3. * 会员服务
  4. */
  5. namespace app\weixin\service;
  6. use app\weixin\model\AccountLog;
  7. use app\weixin\model\AuthLog;
  8. use app\weixin\model\Complain;
  9. use app\weixin\model\UserBalanceLog;
  10. use app\weixin\model\UserProfile;
  11. use app\weixin\model\Member as MemberModel;
  12. use app\weixin\model\Wechat;
  13. use think\Db;
  14. class Member
  15. {
  16. /**
  17. * 会员信息认证审核
  18. * @param $userId 用户ID
  19. * @param $status 审核状态:2-成功,3-失败
  20. * @param string $scene 审核类型:idcard-身份证,education-学历,position-职业/工作
  21. * @param string $failRemark 审核失败原因
  22. * @return array|int
  23. */
  24. public static function checkAuth($userId, $status, $scene='idcard', $failRemark=''){
  25. try {
  26. // 验证认证信息是否存在
  27. $field = 'id,userid,idcard,idcard_check,education_check,position_check';
  28. $info = UserProfile::getInfo(['userid'=> $userId],$field);
  29. if(empty($info)){
  30. return 2122;
  31. }
  32. if(!in_array($status, [2,3])){
  33. return 2127;
  34. }
  35. //var_dump($info);
  36. // 审核处理
  37. $sceneNames = ['idcard'=>'身份证','education'=> '学历','position'=> '工作'];
  38. switch($scene){
  39. case 'idcard': // 身份认证审核
  40. // 验证状态
  41. $idcardCheck = isset($info['idcard_check'])? intval($info['idcard_check']) : 0;
  42. if($idcardCheck != 0 && $idcardCheck != 1 && $status == 2){
  43. return 2123;
  44. }
  45. $data = [
  46. 'idcard_check'=> $status,
  47. 'idcard_online_check'=> $status==3? 0 : 1,
  48. 'idcard_fail'=> $failRemark? trim($failRemark) : '',
  49. ];
  50. break;
  51. case 'education': // 学历认证审核
  52. // 验证状态
  53. $educationCheck = isset($info['education_check'])? intval($info['education_check']) : 0;
  54. if($educationCheck != 0 && $educationCheck != 1 && $status == 2){
  55. return 2123;
  56. }
  57. $data = [
  58. 'education_check'=> $status,
  59. 'education_fail'=> $failRemark? trim($failRemark) : '',
  60. ];
  61. break;
  62. case 'position': // 工作认证审核
  63. // 验证状态
  64. $positionCheck = isset($info['position_check'])? intval($info['position_check']) : 0;
  65. if($positionCheck != 0 && $positionCheck != 1 && $status == 2){
  66. return 2123;
  67. }
  68. $data = [
  69. 'position_check'=> $status,
  70. 'position_fail'=> $failRemark? trim($failRemark) : '',
  71. ];
  72. break;
  73. default:
  74. return 2126;
  75. break;
  76. }
  77. // 更新数据处理
  78. Db::startTrans();
  79. if(!UserProfile::saveData(['userid'=> $userId], $data)){
  80. Db::rollback();
  81. return 2125;
  82. }
  83. // 审核通过奖励处理
  84. $remark = '';
  85. $sceneName = isset($sceneNames[$scene])? $sceneNames[$scene] : '信息';
  86. $field = 'id,openid,parent_id,user_nickname,real_name,redheart';
  87. $memberInfo = MemberModel::getInfo(['id'=> $userId], $field);
  88. $inviteId = isset($memberInfo['parent_id'])? $memberInfo['parent_id'] : 0;
  89. $nickname = isset($memberInfo['user_nickname'])? $memberInfo['user_nickname'] : '';
  90. if($status == 2){
  91. // 身份认证更新生日
  92. $idcard = isset($info['idcard'])? trim($info['idcard']) : '';
  93. if($scene == 'idcard' && $idcard){
  94. $birthday = substr($idcard, 6,8);
  95. $birthday = substr($birthday,0,4).'-'.substr($birthday,4,2).'-'.substr($birthday,6,2);
  96. $birthday = $birthday? strtotime($birthday) : 0;
  97. if($birthday){
  98. MemberModel::saveData(['id'=> $userId], ['birthday'=> $birthday]);
  99. }
  100. }
  101. $siteInfo = cmf_get_site_info();
  102. $awardNum = isset($siteInfo[$scene.'_award_redheart'])? intval($siteInfo[$scene.'_award_redheart']) : 0;
  103. $inviteAwardNum = isset($siteInfo[$scene.'_invite_award_redheart'])? intval($siteInfo[$scene.'_invite_award_redheart']) : 0;
  104. if($awardNum){
  105. $redheart = isset($memberInfo['redheart'])? intval($memberInfo['redheart']) : 0;
  106. if(!MemberModel::saveData(['id'=> $userId], ['redheart'=> intval($redheart + $awardNum)])){
  107. Db::rollback();
  108. return 2125;
  109. }
  110. // 账户明细
  111. $remark = "{$sceneName}认证成功奖励{$awardNum}个爱心";
  112. $accountData = [
  113. 'type' => 4,
  114. 'account_type' => 1,
  115. 'change_type' => 1,
  116. 'user_id' => $userId,
  117. 'money' => $awardNum,
  118. 'balance' => $redheart,
  119. 'created_at' => date('Y-m-d H:i:s'),
  120. 'remark' => "{$sceneName}认证成功奖励{$awardNum}个爱心",
  121. ];
  122. AccountLog::insertGetId($accountData);
  123. }
  124. // 邀请人奖励
  125. $field = 'id,openid,parent_id,user_nickname,receive_share_msg,real_name,redheart';
  126. $inviteInfo = MemberModel::getInfo(['id'=> $inviteId], $field);
  127. if($inviteAwardNum && $inviteId && $inviteInfo){
  128. $inviteRedheart = isset($inviteInfo['redheart'])? intval($inviteInfo['redheart']) : 0;
  129. if(!MemberModel::saveData(['id'=> $inviteId], ['redheart'=> intval($inviteRedheart + $inviteAwardNum)])){
  130. Db::rollback();
  131. return 2125;
  132. }
  133. // 账户明细
  134. $accountData = [
  135. 'type' => 4,
  136. 'account_type' => 1,
  137. 'change_type' => 1,
  138. 'user_id' => $inviteId,
  139. 'money' => $inviteAwardNum,
  140. 'balance' => $inviteRedheart,
  141. 'created_at' => date('Y-m-d H:i:s'),
  142. 'remark' => "邀请用户{$nickname}完成{$sceneName}认证",
  143. ];
  144. AccountLog::insertGetId($accountData);
  145. }
  146. }
  147. Db::commit();
  148. // 推送审核信息
  149. $openid = isset($memberInfo['openid'])? $memberInfo['openid'] : '';
  150. if ($openid) {
  151. $realname = isset($memberInfo['real_name']) ? $memberInfo['real_name'] : '';
  152. $checkTime = date('Y.m.d H:i');
  153. $remark = $status==2? "感谢您的使用,点击进入公众号,遇见一段爱情!" : '请修改后重新提交';
  154. $params = [
  155. 'title' => $status==2? "恭喜!您的{$sceneName}认证已经通过审核!\n\n审核时间:\t{$checkTime}" : $failRemark."\n\n审核时间:\t{$checkTime}",
  156. 'remark' => $remark,
  157. 'type' => 'auth',
  158. 'keywords' => [
  159. /*'keyword1' => [
  160. 'value' => $realname,
  161. 'color' => '#173177',
  162. ],*/
  163. 'keyword1' => [
  164. 'value' => "{$sceneName}认证",
  165. 'color' => '#173177',
  166. ],
  167. 'keyword2' => [
  168. 'value' => $status==2? '审核通过' : '认证失败',
  169. 'color' => '#173177',
  170. ],
  171. ],
  172. 'url' => $status==2? url('/weixin/match/index', '', '', true) : url('/weixin/auth/' . $scene, '', '', true),
  173. ];
  174. PRedis::set('auths:message:u_'.$userId, ['result' => $memberInfo, 'params' => $params], 600);
  175. Wechat::sendTplMsg($openid, $params);
  176. }
  177. // 认证分销收益结算
  178. $inviteInfo = MemberModel::getInviteInfo($userId);
  179. $inviteId = isset($inviteInfo['invite_id'])? $inviteInfo['invite_id'] : 0;
  180. if($inviteInfo && $inviteId>0 && $status == 2){
  181. PRedis::set('markets:auth:entry:' . $scene.'_'.$userId, ['inviteInfo'=> $inviteInfo, 'memberInfo' => $memberInfo], 7200);
  182. $types = ['idcard'=> 5, 'education'=> 6, 'position'=> 7];
  183. $type = isset($types[$scene])? $types[$scene] : 0;
  184. if($type && !UserBalanceLog::checkHasMarket($inviteId, $userId, $type)){
  185. Award::marketAward($inviteId, $userId, $type);
  186. }
  187. }
  188. return ['id'=> $userId];
  189. } catch (\Exception $exception){
  190. // var_dump($exception);
  191. return 1015;
  192. }
  193. }
  194. /**
  195. * 投诉用户审核奖励
  196. * @param $userId 举报用户ID
  197. * @param array $info 举报数据:至少含举报用户、被举报用户、举报类型、举报内容、举报时间
  198. * @return array|false
  199. * @throws \think\Exception
  200. * @throws \think\db\exception\DataNotFoundException
  201. * @throws \think\db\exception\ModelNotFoundException
  202. * @throws \think\exception\DbException
  203. * @throws \think\exception\PDOException
  204. */
  205. public static function checkComplain($userId, $info = [])
  206. {
  207. $cid = isset($info['id'])? $info['id'] : 0;
  208. if(empty($cid) || Complain::where(['id'=> $cid])->value('status') != 1){
  209. return false;
  210. }
  211. $userInfo = MemberModel::where(['id' => $userId, 'user_status' => 1])
  212. ->field('id,user_login,user_nickname,openid,redheart')
  213. ->find();
  214. $nickname = isset($userInfo['user_nickname']) ? $userInfo['user_nickname'] : '';
  215. $redheart = isset($userInfo['redheart']) ? floatval($userInfo['redheart']) : 0;
  216. if (empty($userInfo)) {
  217. return false;
  218. }
  219. $siteInfo = cmf_get_site_info();
  220. $awardNum = isset($siteInfo['complain_award_redheart']) ? intval($siteInfo['complain_award_redheart']) : 0;
  221. if ($awardNum > 0) {
  222. $cuid = isset($info['c_uid'])? $info['c_uid'] : 0;
  223. $cUserInfo = MemberModel::alias('u')
  224. ->leftJoin('sg_user_profile sp','sp.userid=u.id')
  225. ->where(['u.id' => $cuid, 'u.user_status' => 1])
  226. ->field('u.id,u.openid,u.user_login,u.user_nickname,u.openid,u.redheart,sp.wechat_code')
  227. ->find();
  228. if (empty($cUserInfo)){
  229. return false;
  230. }
  231. // 更新状态
  232. //Complain::where(['id'=> $cid])->update(['status'=> 2]);
  233. //Db::startTrans();
  234. // 冻结被举报用户,2021,加多一个字段,顺便放入冻结选项
  235. $freezing = isset($info['remark'])? $info['remark'] : '被人举报';
  236. $result1=MemberModel::where(['id'=> $cuid,'user_type'=> 2])->update(['user_status'=> 0,'freezing'=> $freezing,'freezing_choose'=>$info['freezing_choose']]);
  237. // 奖励入账
  238. $result2= MemberModel::where(['id' => $userId])->update(['redheart' => moneyFormat($redheart + $awardNum), 'updated_at' => date('Y-m-d H:i:s')]);
  239. // echo $cuid.'::'.$userId;die();
  240. // 账户明细
  241. $dateTime = date('Y-m-d H:i:s');
  242. $cNickname = isset($cUserInfo['user_nickname']) ? $cUserInfo['user_nickname'] : '';
  243. $logData = [
  244. 'user_id' => $userId,
  245. 'type' => 4,
  246. 'account_type' => 1,
  247. 'change_type' => 1,
  248. 'money' => $awardNum,
  249. 'balance' => $redheart,
  250. 'remark' => "举报用户[ID:$cuid],昵称[{$cNickname}]审核通过奖励",
  251. 'created_at' => $dateTime,
  252. ];
  253. $result3=db('account_log')->insertGetId($logData);
  254. //if($result1 && $result2 && $result3){Db::commit();}else{Db::rollback();}
  255. // 发送模板消息给举报用户
  256. $openid = isset($userInfo['openid'])? $userInfo['openid'] : '';
  257. if($openid){
  258. $wechatCode = isset($cUserInfo['wechat_code'])? $cUserInfo['wechat_code'] : '暂无';
  259. $params = [
  260. 'title' => "尊敬的{$nickname}用户,您举报的用户经平台核实已审核通过,请谨慎与该用户联系\n\n被举报用户:\t{$cNickname}(昵称)\n\n对方微信号: \t{$wechatCode}\n\n申请时间:\t{$dateTime}",
  261. 'remark' => "脱单需主动,交友需谨慎!",
  262. 'type' => 'confirm',
  263. 'keywords' => [
  264. 'keyword1' => [
  265. 'value' => '举报用户',
  266. 'color' => '#173177',
  267. ],
  268. 'keyword2' => [
  269. 'value' => '已审核',
  270. 'color' => '#173177',
  271. ],
  272. ],
  273. ];
  274. Wechat::sendTplMsg($openid, $params);
  275. }
  276. // 被举报用户通知
  277. $cOpenid = isset($cUserInfo['openid'])? $cUserInfo['openid'] : '';
  278. $cnickname = isset($cUserInfo['user_nickname'])? $cUserInfo['user_nickname'] : '';
  279. if($cOpenid){
  280. $params = [
  281. 'title' => "尊敬的{$cnickname}用户,由于您的账号被多人举报经平台已经将您的账号冻结,若有疑问请联系平台客服\n\n举报原因:\t{$freezing}",
  282. 'remark' => "脱单需主动,交友需真诚!",
  283. 'type' => 'confirm',
  284. 'keywords' => [
  285. 'keyword1' => [
  286. 'value' => '举报反馈',
  287. 'color' => '#173177',
  288. ],
  289. 'keyword2' => [
  290. 'value' => '已审核',
  291. 'color' => '#173177',
  292. ],
  293. ],
  294. ];
  295. Wechat::sendTplMsg($cOpenid, $params);
  296. }
  297. return true;
  298. }
  299. return false;
  300. }
  301. /**
  302. * 获取认证记录
  303. * @return \think\db\Query|null
  304. * @throws \think\Exception\DbException
  305. */
  306. public static function getAuthNotices(){
  307. return AuthLog::alias('a')
  308. ->leftJoin('user u','u.id=a.user_id')
  309. ->where(['u.user_type'=> 2,'u.user_status'=> 1, 'a.status'=> 1])
  310. ->where('u.id','>', 0)
  311. ->where('a.created_at','>=', date('Y-m-d'))
  312. ->field('a.user_id,a.type,a.created_at,u.avatar,u.user_nickname as nickname')
  313. ->order('a.created_at','desc')
  314. ->limit(0,10)
  315. ->all()
  316. ->each(function($item, $k){
  317. $item['avatar'] = $item['avatar']? cmf_get_image_preview_url($item['avatar']) : '';
  318. $item['nickname'] = $item['nickname']? formatName($item['nickname']) : '';
  319. });
  320. }
  321. /**
  322. * 到期清除
  323. * @param $userId
  324. * @return bool
  325. * @throws \think\db\exception\DataNotFoundException
  326. * @throws \think\db\exception\ModelNotFoundException
  327. * @throws \think\exception\DbException
  328. */
  329. public static function clearSignRedHeart($userId){
  330. $cacheKey = "cache:signs:clear:{$userId}_".date('Ym');
  331. if(PRedis::get($cacheKey)){
  332. return false;
  333. }
  334. $siteInfo = cmf_get_option('site_info');
  335. $signClearDay = isset($siteInfo['sign_clear_day'])? intval($siteInfo['sign_clear_day']) : 0;
  336. $signClearDay = $signClearDay? min($signClearDay, 28) : 1;
  337. $signClearDay = $signClearDay<10? '0'.$signClearDay : $signClearDay;
  338. if(date('Y-m-d') < date('Y-m-'.$signClearDay)){
  339. PRedis::set($cacheKey, ['error' =>'未到清除时间','date'=> date('Y-m-d H:i:s'),'day'=> $signClearDay], rand(10, 30));
  340. return false;
  341. }
  342. $month = date('Y-m-01', strtotime(date('Y-m-01')) - 86400);
  343. $check = AccountLog::where(['user_id' => $userId, 'type'=> 13, 'status' => 2])
  344. ->where('created_at', '>=', $month)
  345. ->find();
  346. if($check){
  347. PRedis::set($cacheKey, ['error' =>'已清除过','info'=>$check,'date'=> date('Y-m-d H:i:s'),'day'=> $signClearDay], 86400);
  348. return false;
  349. }
  350. $info = MemberModel::where(['id'=> $userId])->field('id,openid,user_nickname,redheart')->find();
  351. if(empty($info)){
  352. return false;
  353. }
  354. // 最早
  355. $firstSign = AccountLog::where(['user_id'=> $userId,'type'=> 12,'status'=> 2])
  356. ->where('created_at','>=', $month)
  357. ->where('created_at','<=', date('Y-m-01 01:00:00'))
  358. ->order('created_at','asc')
  359. ->find();
  360. $time = isset($firstSign['created_at'])? $firstSign['created_at'] : '';
  361. if(empty($firstSign) || empty($time)){
  362. PRedis::set($cacheKey, ['first' => $firstSign,'user'=> $info], rand(10, 30));
  363. return false;
  364. }
  365. // 签到后总消费
  366. $totalCost = AccountLog::where(['user_id'=> $userId,'status'=> 2,'account_type'=> 1,'change_type'=>2])
  367. ->where('created_at','>=', $time)
  368. ->where('created_at','<', date('Y-m-01 01:00:00'))
  369. ->sum('money');
  370. // 退还的爱心
  371. $totalCost1 = AccountLog::where(['user_id'=> $userId,'type'=>3,'status'=> 2,'account_type'=> 1,'change_type'=>1])
  372. ->where('created_at','>=', $time)
  373. ->where('created_at','<', date('Y-m-01 01:00:00'))
  374. ->sum('money');
  375. $totalSign = AccountLog::where(['user_id'=> $userId,'type'=> 12,'status'=> 2])
  376. ->where('created_at','>=', $time)
  377. ->where('created_at','<', date('Y-m-01 01:00:00'))
  378. ->sum('money');
  379. // 清除还有未消费爱心
  380. $redheart = isset($info['redheart'])? $info['redheart'] : 0;
  381. $clearRedheart = ($totalSign+$totalCost1-$totalCost);
  382. PRedis::set($cacheKey, ['first' => $firstSign,'cost'=> $totalCost,'refund'=>$totalCost1,'sign'=> $totalSign,'user'=> $info,'time'=>$time,'month'=>$month], 120);
  383. if($clearRedheart>0 && $clearRedheart <= $redheart){
  384. db()->startTrans();
  385. if(!db()->name('user')->where(['id' => $userId])->setDec('redheart',$clearRedheart)){
  386. db()->rollback();
  387. return 2145;
  388. }
  389. $accountData = [
  390. 'type' => 13,
  391. 'account_type' => 1,
  392. 'change_type' => 2,
  393. 'user_id' => $userId,
  394. 'money' => $clearRedheart,
  395. 'balance' => $redheart,
  396. 'created_at' => date('Y-m-01 00:i:s'),
  397. 'remark' => "签到爱心过期扣除",
  398. ];
  399. PRedis::set("cache:signs:clearLog:{$userId}", ['log' => $accountData,'user'=> $info], 86400);
  400. db('account_log')->insertGetId($accountData);
  401. db()->commit();
  402. PRedis::set($cacheKey, ['log' => $accountData,'first' => $firstSign,'cost'=> $totalCost,'sign'=> $totalSign,'user'=> $info], 7*24*3600);
  403. return true;
  404. }
  405. return false;
  406. }
  407. }