MemberService.php 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | Laravel框架 [ Laravel ]
  4. // +----------------------------------------------------------------------
  5. // | 版权所有 2017~2021 Laravel研发中心
  6. // +----------------------------------------------------------------------
  7. // | 官方网站: http://www.laravel.cn
  8. // +----------------------------------------------------------------------
  9. // | Author: wesmiler <12345678@qq.com>
  10. // +----------------------------------------------------------------------
  11. namespace App\Services;
  12. use App\Models\CityModel;
  13. use App\Models\FansModel;
  14. use App\Models\FollowModel;
  15. use App\Models\MemberModel;
  16. use App\Models\SiyuanModel;
  17. use App\Models\TradeModel;
  18. use SimpleSoftwareIO\QrCode\Facades\QrCode;
  19. /**
  20. * 会员管理-服务类
  21. * @author wesmiler
  22. * @since 2020/11/11
  23. * Class MemberService
  24. * @package App\Services
  25. */
  26. class MemberService extends BaseService
  27. {
  28. protected static $instance = null;
  29. /**
  30. * 构造函数
  31. * @author wesmiler
  32. * @since 2020/11/11
  33. * MemberService constructor.
  34. */
  35. public function __construct()
  36. {
  37. $this->model = new MemberModel();
  38. $this->cityModel = new CityModel();
  39. }
  40. /**
  41. * 静态入口
  42. * @return MemberService|null
  43. */
  44. public static function make(){
  45. if(!self::$instance){
  46. self::$instance = new MemberService();
  47. }
  48. return self::$instance;
  49. }
  50. /**
  51. * 添加会编辑会员
  52. * @return array
  53. * @since 2020/11/11
  54. * @author wesmiler
  55. */
  56. public function edit()
  57. {
  58. // 请求参数
  59. $data = request()->all();
  60. // 头像处理
  61. $avatar = trim($data['avatar']);
  62. if (strpos($avatar, "temp")) {
  63. $data['avatar'] = save_image($avatar, 'member');
  64. } else {
  65. $data['avatar'] = str_replace(IMG_URL, "", $data['avatar']);
  66. }
  67. // 出生日期
  68. if ($data['birthday']) {
  69. $data['birthday'] = strtotime($data['birthday']);
  70. }
  71. // 城市处理
  72. $city = isset($data['city']) ? $data['city'] : [3];
  73. if (!empty($data['city'])) {
  74. // 省份
  75. $data['province_id'] = $city[0];
  76. // 城市
  77. $data['city_id'] = $city[1];
  78. // 县区
  79. $data['district_id'] = $city[2];
  80. }
  81. unset($data['city']);
  82. return parent::edit($data); // TODO: Change the autogenerated stub
  83. }
  84. /**
  85. * 获取用户信息
  86. * @param $openid OPENID
  87. * @param array $field m用户表
  88. * @return array
  89. */
  90. public function getUserInfo($where, $field = [], $type=0)
  91. {
  92. $field = $field ? $field : ['m.id', 'm.openid', 'm.invite_id','m.birthday','m.age','m.gender','m.intro','m.province_id','m.city_id','m.district_id', 'ms.type as mtype', 'yg.status as yigong_status','yg.on_siyuan as yg_on_siyuan','yg.siyuan_id','ms.siyuan','ms.on_siyuan as sr_on_siyuan', 'ms.master_type', 'ms.realname as master_name', 'ms.status as master_status', 'm.mobile', 'm.nickname', 'm.avatar', 'm.gender', 'm.member_level', 'm.is_vip','m.vip_expire', 'm.realname', 'm.balance', 'm.salary', 'm.merits_num', 'm.coupon', 'm.score', 'm.login_time','m.intro', 'm.status'];
  93. $info = $this->model::from('member as m')
  94. ->leftJoin('member_level as ml', 'ml.id', '=', 'm.member_level')
  95. ->leftJoin('master as ms', 'ms.user_id', '=', 'm.id')
  96. ->leftJoin('yigong as yg', 'yg.user_id', '=', 'm.id')
  97. ->select($field)
  98. ->where($where)
  99. ->where('m.status', '>', 0)
  100. ->first();
  101. $info = $info ? $info->toArray() : [];
  102. if (isset($info['avatar'])) {
  103. $info['avatar'] = $info['avatar'] ? get_image_url($info['avatar']) : '';
  104. }
  105. if($info){
  106. // 僧人参数
  107. if(array_key_exists('mtype', $info)){
  108. $info['mtype'] = $info['mtype']? intval($info['mtype']) : 0;
  109. }
  110. if(array_key_exists('master_type', $info)){
  111. $info['master_type'] = $info['master_type']? intval($info['master_type']) : 0;
  112. }
  113. if(array_key_exists('master_status', $info)){
  114. $info['master_status'] = $info['master_status']? intval($info['master_status']) : 0;
  115. }
  116. if(array_key_exists('master_name', $info)){
  117. $info['master_name'] = $info['master_name']? trim($info['master_name']) : '';
  118. }
  119. if(array_key_exists('yigong_siyuan', $info)){
  120. $info['yigong_siyuan'] = $info['yigong_siyuan']? trim($info['yigong_siyuan']) : '';
  121. }
  122. if(array_key_exists('yg_on_siyuan', $info)){
  123. $info['yg_on_siyuan'] = $info['yg_on_siyuan']? intval($info['yg_on_siyuan']) : 0;
  124. }
  125. if(array_key_exists('yigong_status', $info)){
  126. $info['yigong_status'] = $info['yigong_status']? intval($info['yigong_status']) : 0;
  127. }
  128. if(array_key_exists('siyuan', $info)){
  129. $info['siyuan'] = $info['siyuan']? trim($info['siyuan']) : '';
  130. }
  131. if(array_key_exists('sr_on_siyuan', $info)){
  132. $info['sr_on_siyuan'] = $info['sr_on_siyuan']? intval($info['sr_on_siyuan']) : 0;
  133. }
  134. $info['yg_siyuan'] = '';
  135. if(array_key_exists('siyuan_id', $info) && $info['siyuan_id']){
  136. $info['yg_siyuan'] = $info['siyuan_id']? SiyuanModel::where('id', $info['siyuan_id'])->value('title') : '';
  137. }
  138. if($type == 1) {
  139. // 城市
  140. $cityData = [0, 0, 0];
  141. $cityNames = [];
  142. if (isset($info['province_id'])) {
  143. $info['province_name'] = $info['province_id'] ? CityService::make()->getName($info['province_id']) : '';
  144. $cityData[0] = $info['province_id'] ? $info['province_id'] : 0;
  145. $cityNames[] = $info['province_name'] ? $info['province_name'] : '';
  146. }
  147. if (isset($info['city_id'])) {
  148. $info['city_name'] = $info['city_id'] ? CityService::make()->getName($info['city_id']) : '';
  149. $openid = isset($info['openid']) ? $info['openid'] : '';
  150. $cityData[1] = $info['city_id'] ? $info['city_id'] : 0;
  151. $cityNames[] = $info['city_name'] ? $info['city_name'] : '';
  152. if (empty($info['city_name']) && $openid) {
  153. $info['city_name'] = FansModel::where(['openid' => $openid])->value('city');
  154. }
  155. }
  156. if (isset($info['district_id'])) {
  157. $info['district_name'] = $info['district_id'] ? CityService::make()->getName($info['district_id']) : '';
  158. $cityData[2] = $info['district_id'] ? $info['district_id'] : 0;
  159. $cityNames[] = $info['district_name'] ? $info['district_name'] : '';
  160. }
  161. if ($cityData) {
  162. $info['cityData'] = $cityData;
  163. $info['cityText'] = implode(' ', array_filter($cityNames));
  164. }
  165. if (is_empty($info['age'])) {
  166. if (!is_empty($info['birthday'])) {
  167. $year = date('Y', $info['birthday']);
  168. $info['age'] = date('Y') - $year > 0 ? date('Y') - $year : 0;
  169. } else {
  170. $info['age'] = 0;
  171. }
  172. }
  173. if (is_empty($info['birthday'])) {
  174. $info['birthday'] = 0;
  175. } else {
  176. $info['birthday'] = date('Y-m-d', $info['birthday']);
  177. }
  178. if (is_empty($info['intro'])) {
  179. $info['intro'] = '';
  180. }
  181. if (is_empty($info['realname'])) {
  182. $info['realname'] = '';
  183. }
  184. // 二维码
  185. $url = env('WEB_URL') . '/pages/entry/auth?sid=' . $info['id'];
  186. $qrcode = WechatService::makeNormalQrcode($url);
  187. $info['qrcode'] = $qrcode ? get_image_url($qrcode) : '';
  188. // 会员
  189. if($info['is_vip'] && $info['vip_expire'] >= time()){
  190. $info['vip_expire_text'] = date('Y-m-d H:i:s', $info['vip_expire']);
  191. }else{
  192. $info['is_vip'] = 0;
  193. $info['vip_expire_text'] = '';
  194. }
  195. }
  196. }
  197. return $info;
  198. }
  199. /**
  200. * 保存资料
  201. * @param $userId
  202. * @return array
  203. */
  204. public function saveInfo($userId){
  205. $params = request()->all();
  206. $memberInfo = $this->model::where(['id'=> $userId])->first();
  207. if(!$memberInfo){
  208. return message('用户账号不可操作', false);
  209. }
  210. if($params['avatar']){
  211. $memberInfo->avatar = trim($params['avatar']);
  212. }
  213. if($params['birthday']){
  214. $memberInfo->birthday = strtotime($params['birthday']);
  215. }
  216. if($params['age']){
  217. $memberInfo->age = strtotime($params['age']);
  218. }
  219. if(!is_empty($params['intro'])){
  220. $memberInfo->intro = trim($params['intro']);
  221. }
  222. if(!is_empty($params['mobile'])){
  223. $memberInfo->mobile = trim($params['mobile']);
  224. }
  225. if(!empty($params['cityCodes'])){
  226. $cityData = $params['cityCodes'];
  227. if(!is_empty($cityData[0]) && $cityData[0]){
  228. $memberInfo->province_id = $cityData[0];
  229. }
  230. if(!is_empty($cityData[1]) && $cityData[1]){
  231. $memberInfo->city_id = $cityData[1];
  232. }
  233. if(!is_empty($cityData[2]) && $cityData[2]){
  234. $memberInfo->district_id = $cityData[2];
  235. }
  236. }
  237. $memberInfo->nickname = trim($params['nickname']);
  238. $memberInfo->gender = intval($params['gender']);
  239. if($memberInfo->save()){
  240. return message('保存成功', true);
  241. }else{
  242. return message('保存失败', false);
  243. }
  244. }
  245. /**
  246. * 账号注销
  247. * @param $userId
  248. * @return array
  249. */
  250. public function logout($userId){
  251. $memberInfo = $this->model::where(['id'=> $userId,'mark'=> 1,'status'=> 1])->first();
  252. if(!$memberInfo){
  253. return message('用户账号不可操作', false);
  254. }
  255. $memberInfo->mark = 0;
  256. $memberInfo->status = 2;
  257. $memberInfo->black_remark = request()->get('remark','');
  258. if($memberInfo->save()){
  259. return message('操作成功', true);
  260. }else{
  261. return message('操作失败', false);
  262. }
  263. }
  264. /**
  265. * 邀请奖励
  266. * @param $userId 注册用户
  267. * @param $inviteId 邀请用户
  268. * @param string $nickname 注册用户昵称
  269. * @return bool
  270. */
  271. public function inviteAward($userId, $inviteId, $nickname=''){
  272. // 验证当前用户是否已经奖励过
  273. $cacheKey = "caches:invite:u{$userId}_s{$inviteId}";
  274. $check = TradeModel::where(['user_id'=> $userId,'type'=> 6,'source_uid'=> $inviteId,'status'=>1,'mark'=> 1])->value('id');
  275. if($check){
  276. RedisService::set($cacheKey.':error_catched', ['error'=>'当前奖励已发放','date'=> date('Y-m-d H:i:s')], 7200);
  277. return false;
  278. }
  279. // 验证当前邀请用户是否账户有效
  280. $inviteInfo = $this->model::where(['id'=> $inviteId,'mark'=> 1,'status'=> 1])
  281. ->select(['id','openid','nickname','score','coupon','merits_num'])
  282. ->first();
  283. if(!$inviteInfo){
  284. RedisService::set($cacheKey.':error_invite', ['error'=>'当前邀请用户状态异常','date'=> date('Y-m-d H:i:s')], 7200);
  285. return false;
  286. }
  287. // 是否到达人数限制
  288. $curTime = strtotime(date('Y-m-d'));
  289. $inviteConfig = ConfigService::make()->getConfigByGroup(14);
  290. $inviteLimit = isset($inviteConfig['invite_limit'])? $inviteConfig['invite_limit']['value'] : 0;
  291. $checkCount = TradeModel::where(['user_id'=> $userId,'type'=> 6,'status'=>1,'mark'=> 1])
  292. ->where('create_time','>=',$curTime)
  293. ->count('id');
  294. if($inviteLimit>0 && $checkCount>=$inviteLimit){
  295. RedisService::set($cacheKey.':error_limit', ['error'=>'今日奖励已到达限制人数:'.$inviteLimit,'date'=> date('Y-m-d H:i:s')], 7200);
  296. return false;
  297. }
  298. // 奖励花灯券
  299. \DB::beginTransaction();
  300. $coupon = isset($inviteConfig['invite_give_coupon'])? intval($inviteConfig['invite_give_coupon']['value']) : 0;
  301. if($coupon>0){
  302. // 账户
  303. if(!$this->model::where(['id'=> $inviteId])->increment('coupon', $coupon)){
  304. \DB::rollBack();
  305. RedisService::set($cacheKey.':error_coupon', ['error'=>'奖励花灯券账户更新失败:'.$coupon,'date'=> date('Y-m-d H:i:s')], 7200);
  306. return false;
  307. }
  308. $data = [
  309. 'user_id'=> $inviteId,
  310. 'source_uid'=> $userId,
  311. 'type'=> 6,
  312. 'coin_type'=> 1,
  313. 'pay_type'=> 4,
  314. 'money'=> $coupon,
  315. 'change_type'=> 1,
  316. 'balance'=> $inviteInfo->coupon,
  317. 'create_time'=> time(),
  318. 'remark'=> "邀请用户[{$nickname}],奖励{$coupon}花灯券",
  319. 'status'=> 1,
  320. ];
  321. if(!TradeModel::insertGetId($data)){
  322. \DB::rollBack();
  323. RedisService::set($cacheKey.':error_acccount_coupon', ['error'=>'奖励花灯券账户明细处理失败','data'=> $data,'date'=> date('Y-m-d H:i:s')], 7200);
  324. return false;
  325. }
  326. }
  327. // 奖励功德值
  328. $giveGd = isset($inviteConfig['invite_give_gd'])? intval($inviteConfig['invite_give_gd']['value']) : 0;
  329. if($giveGd>0){
  330. // 账户
  331. if(!$this->model::where(['id'=> $inviteId])->increment('merits_num', $giveGd)){
  332. \DB::rollBack();
  333. RedisService::set($cacheKey.':error_gd', ['error'=>'奖励功德值账户更新失败:'.$giveGd,'date'=> date('Y-m-d H:i:s')], 7200);
  334. return false;
  335. }
  336. $data = [
  337. 'user_id'=> $inviteId,
  338. 'source_uid'=> $userId,
  339. 'type'=> 6,
  340. 'coin_type'=> 4,
  341. 'pay_type'=> 4,
  342. 'money'=> $giveGd,
  343. 'change_type'=> 1,
  344. 'balance'=> $inviteInfo->merits_num,
  345. 'create_time'=> time(),
  346. 'remark'=> "邀请用户[{$nickname}],奖励{$giveGd}功德值",
  347. 'status'=> 1,
  348. ];
  349. if(!TradeModel::insertGetId($data)){
  350. \DB::rollBack();
  351. RedisService::set($cacheKey.':error_acccount_gd', ['error'=>'奖励花灯券账户明细处理失败','data'=> $data,'date'=> date('Y-m-d H:i:s')], 7200);
  352. return false;
  353. }
  354. }
  355. // 奖励积分
  356. \DB::commit();
  357. return true;
  358. }
  359. /**
  360. * 加入会员
  361. * @param $userId
  362. */
  363. public function buyVip($userId){
  364. $memberInfo = $this->model::where(['id'=> $userId,'mark'=> 1,'status'=> 1])
  365. ->select(['id','nickname','openid','coupon','mobile','is_vip','vip_expire'])
  366. ->first();
  367. if(!$memberInfo){
  368. return message('用户账户不可操作,请联系客服',false);
  369. }
  370. $params = request()->all();
  371. $receiveVipMessage = isset($params['receive_vip_message'])? $params['receive_vip_message'] : 0;
  372. if($receiveVipMessage>0 && empty($memberInfo->mobile)){
  373. return message('接收消息通知,请先到个人资料设置手机号码再尝试',false);
  374. }
  375. // 是否已经加入了会员
  376. $isVip = false;
  377. if($memberInfo->is_vip && $memberInfo->vip_expire>=time()){
  378. $isVip = true;
  379. }
  380. // 验证账户
  381. $config = ConfigService::make()->getConfigByGroup(15);
  382. $vipPrice = isset($config['vip_price'])? intval($config['vip_price']['value']) : 0;
  383. $vipGiveCoupon = isset($config['vip_give_coupon'])? intval($config['vip_give_coupon']['value']) : 0;
  384. if($vipPrice<=0){
  385. return message('当前会员价格参数设置错误,请联系客服',false);
  386. }
  387. if($vipPrice<=$vipGiveCoupon){
  388. return message('当前会员赠送参数设置错误,请联系客服',false);
  389. }
  390. if($memberInfo->coupon < $vipPrice){
  391. return message('您的账户花灯券不足,请先充值后重试',false,[],'10003');
  392. }
  393. // 操作账户
  394. \DB::beginTransaction();
  395. if(!$this->model::where(['id'=> $userId,'mark'=> 1])->decrement('coupon',($vipPrice - $vipGiveCoupon))){
  396. \DB::rollBack();
  397. return message('扣除用户账户失败,请刷新后重试',false);
  398. }
  399. // 更新会员有效期
  400. if($isVip){
  401. $vipExpire = $memberInfo->vip_expire+365*24*3600;
  402. }else{
  403. $vipExpire = time()+365*24*3600;
  404. }
  405. if(!$this->model::where(['id'=> $userId,'mark'=> 1])->update(['is_vip'=> 1,'receive_vip_message'=> $receiveVipMessage,'vip_expire'=> $vipExpire])){
  406. \DB::rollBack();
  407. return message('更新会员有效期失败,请刷新后重试',false);
  408. }
  409. // 账户明细
  410. $data = [
  411. 'user_id'=> $userId,
  412. 'type'=> 1,
  413. 'coin_type'=> 1,
  414. 'pay_type'=> 1,
  415. 'money'=> $vipPrice,
  416. 'change_type'=> 2,
  417. 'balance'=> $memberInfo->coupon,
  418. 'create_time'=> time(),
  419. 'remark'=> ($isVip? '续费':'加入')."会员扣除{$vipPrice}花灯券",
  420. 'status'=> 1,
  421. ];
  422. if(!TradeModel::insertGetId($data)){
  423. \DB::rollBack();
  424. return message('处理账户明细失败,请刷新后重试',false);
  425. }
  426. // 赠送
  427. if($vipGiveCoupon>0){
  428. $data = [
  429. 'user_id'=> $userId,
  430. 'type'=> 3,
  431. 'coin_type'=> 1,
  432. 'pay_type'=> 4,
  433. 'money'=> $vipGiveCoupon,
  434. 'change_type'=> 1,
  435. 'balance'=> ($memberInfo->coupon-$vipPrice),
  436. 'create_time'=> time()+1,
  437. 'remark'=> ($isVip? '续费':'加入')."会员赠送{$vipGiveCoupon}花灯券",
  438. 'status'=> 1,
  439. ];
  440. if(!TradeModel::insertGetId($data)){
  441. \DB::rollBack();
  442. return message('赠送券处理失败,请刷新后重试',false);
  443. }
  444. }
  445. \DB::commit();
  446. return message(($isVip? '续费':'加入').'会员成功',true);
  447. }
  448. /**
  449. * 签到
  450. * @param $userId
  451. * @return array
  452. */
  453. public function sign($userId){
  454. $memberInfo = $this->model::where(['id'=> $userId, 'mark'=>1 ,'status'=> 1])
  455. ->select(['id','openid','nickname','score','sign_time'])
  456. ->first();
  457. if(!$memberInfo){
  458. return message('账户不可操作,请联系客服',false);
  459. }
  460. if($memberInfo->sign_time >= strtotime(date('Y-m-d'))){
  461. return message('您今天已签到过,请明天再来',false);
  462. }
  463. // 参数
  464. $score = ConfigService::make()->getConfigByCode('sign_give_score');
  465. $score = $score? $score : 0;
  466. // 处理
  467. \DB::beginTransaction();
  468. if($score>0){
  469. if(!$this->model::where(['id'=> $userId,'mark'=> 1])->increment('score', $score)){
  470. \DB::rollBack();
  471. return message('更新账户积分失败,请刷新后重试',false);
  472. }
  473. $data = [
  474. 'user_id'=> $userId,
  475. 'type'=> 3,
  476. 'coin_type'=> 3,
  477. 'pay_type'=> 4,
  478. 'money'=> $score,
  479. 'change_type'=> 1,
  480. 'balance'=> $memberInfo->score,
  481. 'create_time'=> time(),
  482. 'remark'=> "每日签到赠送{$score}积分",
  483. 'status'=> 1,
  484. ];
  485. if(!TradeModel::insertGetId($data)){
  486. \DB::rollBack();
  487. return message('积分奖励处理失败,请刷新后重试',false);
  488. }
  489. }
  490. if(!$this->model::where(['id'=> $userId,'mark'=> 1])->update(['sign_time'=> time()])){
  491. \DB::rollBack();
  492. return message('签到处理失败,请刷新后重试',false);
  493. }
  494. \DB::commit();
  495. return message('签到成功',true);
  496. }
  497. /**
  498. * 获取功德榜列表
  499. * @return array
  500. * @since 2020/11/11
  501. * @author wesmiler
  502. */
  503. public function gdList($userId)
  504. {
  505. $params = request()->all();
  506. $page = isset($params['pageSize']) ? intval($params['pageSize']) : PAGE;
  507. $pageSize = isset($params['pageSize']) ? intval($params['pageSize']) : PERPAGE;
  508. $dataList = $this->model::where(['mark'=>1,'status'=> 1])
  509. ->where('merits_num','>',0)
  510. ->select(['id', 'avatar', 'nickname','gender','merits_num','status','create_time'])
  511. ->orderBy('merits_num', 'desc')
  512. ->orderBy('create_time', 'asc')
  513. ->paginate($pageSize);
  514. $dataList = $dataList ? $dataList->toArray() : [];
  515. if ($dataList) {
  516. foreach ($dataList['data'] as &$item) {
  517. $item['avatar'] = $item['avatar']? get_image_url($item['avatar']) : '';
  518. $item['create_time'] = $item['create_time'] ? datetime($item['create_time'],'Y-m-d H:i:s') : '';
  519. }
  520. unset($item);
  521. }
  522. $meritsNum = $this->model::where(['id'=> $userId])->value('merits_num');
  523. $ranks['id'] = $userId;
  524. $ranks['rank'] = 0;
  525. $ranks['merits_num'] = $meritsNum>0? $meritsNum : 0;
  526. if($meritsNum>0){
  527. $model = $this->model::from(\DB::raw(env('DB_PREFIX').'member as m,(select (@rank:=0)) as rank'))
  528. ->where(['mark'=> 1,'status'=> 1])
  529. ->where('merits_num','>',0)
  530. ->orderBy('merits_num', 'desc')
  531. ->orderBy('create_time', 'asc')
  532. ->select(['merits_num','mark','id',\DB::raw('(@rank:=@rank+1) as rank')]);
  533. $binds = $model->getBindings();
  534. $sql = str_replace('?', '%s', $model->toSql());
  535. $sql = sprintf($sql, ...$binds);
  536. $ranks = $this->model::from(\DB::raw("({$sql}) as a"))
  537. ->where(['id'=> $userId])
  538. ->select(['merits_num','id','rank'])
  539. ->first();
  540. }
  541. return [
  542. 'code' => 0,
  543. 'success'=> true,
  544. 'msg' => '操作成功',
  545. 'ranks' => $ranks,
  546. 'count' => isset($dataList['total']) ? $dataList['total'] : 0,
  547. 'data' => isset($dataList['data']) ? $dataList['data'] : 0,
  548. ];
  549. }
  550. /**
  551. * 关注
  552. * @param $userId
  553. * @return array
  554. */
  555. public function follow($userId){
  556. $params = request()->all();
  557. $followUid = isset($params['follow_uid'])? $params['follow_uid'] : 0;
  558. $status = isset($params['status'])? $params['status'] : 1;
  559. $status = $status<=0? 1 : $status;
  560. if(empty($followUid)){
  561. return message('参数错误', false);
  562. }
  563. if(!in_array($status, [1,2])){
  564. return message('参数错误', false);
  565. }
  566. $memberInfo = $this->model::where(['id'=> $userId, 'maek'=> 1,'status'=> 1])
  567. ->select(['id','openid','nickname','status'])
  568. ->first();
  569. if(!$memberInfo){
  570. return message('账户不可操作已冻结或不存在,请联系客服',false);
  571. }
  572. $followInfo = FollowModel::where(['id'=> $followUid, 'maek'=> 1,'status'=> 1])
  573. ->select(['id','openid','nickname','status'])
  574. ->first();
  575. if(!$followInfo){
  576. return message('关注用户不可操作或不存在',false);
  577. }
  578. $info = FollowModel::where(['user_id'=> $userId, 'follow_uid'=> $followUid])->select(['id','status'])->first();
  579. if($info && $info->status == 1 && $status == 1){
  580. return message('您已关注过', false);
  581. }else if($info && $info->status == 2 && $status == 2){
  582. return message('您已取消关注', false);
  583. }else if(!$info && $status == 2){
  584. return message('您未关注过', false);
  585. }
  586. // 处理
  587. if($info){
  588. $info->status = $status;
  589. $info->create_time = time();
  590. if($info->save()){
  591. return message($status == 1? '关注成功':'取消关注成功', true);
  592. }
  593. }else{
  594. $data = [
  595. 'user_id'=> $userId,
  596. 'follow_uid'=> $followUid,
  597. 'create_time'=> time(),
  598. 'status'=> 1,
  599. ];
  600. if(FollowModel::insertGetId($data)){
  601. return message('关注成功', true);
  602. }
  603. }
  604. return message('操作失败', false);
  605. }
  606. /**
  607. * 关注的人
  608. * @return array
  609. * @since 2020/11/11
  610. * @author wesmiler
  611. */
  612. public function followList($userId)
  613. {
  614. $params = request()->all();
  615. $page = isset($params['pageSize']) ? intval($params['pageSize']) : PAGE;
  616. $pageSize = isset($params['pageSize']) ? intval($params['pageSize']) : PERPAGE;
  617. $dataList = $this->model::from('member_follow as mf')
  618. ->leftJoin('member as m','mf.follow_uid','=','m.id')
  619. ->where(['m.mark'=>1,'m.status'=> 1,'mf.mark'=> 1,'mf.status'=> 1])
  620. ->select(['mf.id', 'mf.user_id','mf.follow_uid','m.avatar','m.nickname', 'm.merits_num','m.gender','m.status','m.create_time'])
  621. ->orderBy('m.merits_num', 'desc')
  622. ->orderBy('mf.create_time', 'asc')
  623. ->paginate($pageSize);
  624. $dataList = $dataList ? $dataList->toArray() : [];
  625. if ($dataList) {
  626. foreach ($dataList['data'] as &$item) {
  627. $item['avatar'] = $item['avatar']? get_image_url($item['avatar']) : '';
  628. $item['create_time'] = $item['create_time'] ? datetime($item['create_time'],'Y-m-d H:i:s') : '';
  629. }
  630. unset($item);
  631. }
  632. return [
  633. 'code' => 0,
  634. 'success'=> true,
  635. 'msg' => '操作成功',
  636. 'count' => isset($dataList['total']) ? $dataList['total'] : 0,
  637. 'data' => isset($dataList['data']) ? $dataList['data'] : 0,
  638. ];
  639. }
  640. /**
  641. * 感兴趣的人
  642. * @param $userId
  643. * @return array
  644. */
  645. public function recommand($userId){
  646. $params = request()->all();
  647. $page = isset($params['pageSize']) ? intval($params['pageSize']) : PAGE;
  648. $pageSize = isset($params['pageSize']) ? intval($params['pageSize']) : PERPAGE;
  649. $dataList = $this->model::from('member as m')
  650. ->leftJoin('member_follow as mf','mf.follow_uid','=','m.id')
  651. ->where(['m.mark'=>1,'m.status'=> 1])
  652. ->whereNotIn(function($query) use ($userId){
  653. $query->from('member_follow')->where(['user_id'=> $userId])->select(['follow_uid']);
  654. })
  655. ->select(['m.id', 'm.avatar','m.nickname','m.gender','m.status','m.create_time'])
  656. ->orderBy('mf.create_time', 'asc')
  657. ->paginate($pageSize);
  658. $dataList = $dataList ? $dataList->toArray() : [];
  659. if ($dataList) {
  660. foreach ($dataList['data'] as &$item) {
  661. $item['avatar'] = $item['avatar']? get_image_url($item['avatar']) : '';
  662. $item['create_time'] = $item['create_time'] ? datetime($item['create_time'],'Y-m-d H:i:s') : '';
  663. }
  664. unset($item);
  665. }
  666. return [
  667. 'code' => 0,
  668. 'success'=> true,
  669. 'msg' => '操作成功',
  670. 'count' => isset($dataList['total']) ? $dataList['total'] : 0,
  671. 'data' => isset($dataList['data']) ? $dataList['data'] : 0,
  672. ];
  673. }
  674. }