// +---------------------------------------------------------------------- declare (strict_types = 1); namespace addon\wxchat\controller\api; use addon\wxchat\model\WxchatFollow as UserFollow; use addon\wxchat\model\WxchatIntimacy as UserIntimacy; use think\facade\Db; use think\facade\Request; use ywxapp\controller\FrontendBase; use ywxapp\model\MemberUser as UserModel; /** * Follow 类 * * @author ywxapp */ class Follow extends FrontendBase { /** * Summary of needLogin * @var array */ protected $noNeedLogin = ['*']; /** * Summary of needRight * @var array */ protected $noNeedVerify = ['*']; /** * 控制器初始化 _initialize * @return void */ protected function initialize() { } /** * 关注/取消关注用户 * @return Json */ public function toggleFollow(): Json { $uid = $this->request->param('uid', 88888888); $targetUid = $this->request->param('target_uid', 88888891); $action = $this->request->param('action', 1); // 1-关注,0-取消关注 if (! $uid || ! $targetUid) { $this->error('用户ID和目标用户ID不能为空', 400); } if ($uid == $targetUid) { $this->error('不能关注自己', 400); } // 检查目标用户是否存在 $targetUser = UserModel::where('uid', $targetUid)->findOrEmpty(); if ($targetUser->isEmpty()) { $this->error('目标用户不存在', 404); } // 检查是否已关注 $follow = UserFollow::where('uid', $uid)->where('fid', $targetUid)->findOrEmpty(); DB::startTrans(); try { if ($follow->isEmpty()) { $follow = new UserFollow(); $follow->uid = $uid; $follow->fid = $targetUid; $follow->status = 1; $follow->save(); } else { $follow->status = $follow->status == 1 ? 0 : 1; $follow->save(); } if ($follow->status == 1) { // UserModel::where('id', $uid)->inc('following_count')->update(); // UserModel::where('id', $targetuid)->inc('follower_count')->update(); $mutual = UserFollow::where('fid', $targetUid) ->where('uid', $uid) ->where('status', 1) ->find(); $isMutual = $mutual ? 1 : 0; // 增加亲密度 $this->updateIntimacy($uid, $targetUid, 5); DB::commit(); $this->success(['is_mutual' => $isMutual, 'follow_status' => 1], '关注成功'); } else { // 更新用户关注数 // UserModel::where('id', $uid)->dec('following_count')->update(); // UserModel::where('id', $targetUid)->dec('follower_count')->update(); // 减少亲密度 $this->updateIntimacy($uid, $targetUid, -5); DB::commit(); $this->success(['follow_status' => 0], '取消关注成功'); } } catch (\Exception $e) { DB::rollback(); $this->error('操作失败: ' . $e->getMessage()); } } /** * 获取关注列表 * @return Json */ public function getFollowingList(): Json { $uid = $this->request->param('uid', 0); $page = $this->request->param('page', 1); $size = $this->request->param('size', 20); if (! $uid) { $this->error('用户ID不能为空', 400); } // 我关注的人:uid=当前用户,取 fid 列表 $total = UserFollow::where('uid', $uid) ->where('status', 1) ->count(); $follows = UserFollow::where('uid', $uid) ->where('status', 1) ->order('id', 'desc') ->page($page, $size) ->select(); $targetIds = []; foreach ($follows as $follow) { $targetIds[] = $follow->fid; } // 批量取用户资料(按 uid 匹配,规避关联主键歧义) $userMap = []; if (! empty($targetIds)) { $users = UserModel::whereIn('uid', $targetIds) ->field('uid,nickname,avatar') ->select(); foreach ($users as $u) { $userMap[$u->uid] = $u; } } // 对方是否也关注了我(互关判断) $backIds = UserFollow::where('fid', $uid) ->where('status', 1) ->column('uid'); $backSet = array_flip($backIds); $list = []; foreach ($follows as $follow) { $user = $userMap[$follow->fid] ?? null; $list[] = [ 'id' => $follow->fid, 'nickname' => $user ? $user->nickname : '', 'avatar' => $user ? $user->avatar : '', 'is_mutual' => isset($backSet[$follow->fid]) ? 1 : 0, 'follow_time' => date('Y-m-d H:i:s', (int) $follow->create_at), ]; } $this->success([ 'list' => $list, 'total' => $total, 'page' => $page, 'size' => $size, ], '获取成功'); } /** * 获取粉丝列表 * @return Json */ public function getFollowerList(): Json { $uid = $this->request->param('uid', 0); $page = $this->request->param('page', 1); $size = $this->request->param('size', 20); if (! $uid) { $this->error('用户ID不能为空', 400); } // 粉丝:谁关注了我,fid=当前用户,取 uid 列表 $follows = UserFollow::where('fid', $uid) ->where('status', 1) ->order('id', 'desc') ->page($page, $size) ->select(); $total = UserFollow::where('fid', $uid) ->where('status', 1) ->count(); $fanIds = []; foreach ($follows as $follow) { $fanIds[] = $follow->uid; } // 批量取粉丝资料(按 uid 匹配) $userMap = []; if (! empty($fanIds)) { $users = UserModel::whereIn('uid', $fanIds) ->field('uid,nickname,avatar') ->select(); foreach ($users as $u) { $userMap[$u->uid] = $u; } } // 我是否也关注了该粉丝(互关判断) $myFollowIds = UserFollow::where('uid', $uid) ->where('status', 1) ->column('fid'); $mySet = array_flip($myFollowIds); $list = []; foreach ($follows as $follow) { $user = $userMap[$follow->uid] ?? null; $list[] = [ 'id' => $follow->uid, 'nickname' => $user ? $user->nickname : '', 'avatar' => $user ? $user->avatar : '', 'is_mutual' => isset($mySet[$follow->uid]) ? 1 : 0, 'follow_time' => date('Y-m-d H:i:s', (int) $follow->create_at), ]; } $this->success([ 'list' => $list, 'total' => $total, 'page' => $page, 'size' => $size, ], '获取成功'); } /** * 获取互关列表 * @return Json */ public function getMutualList(): Json { $uid = $this->request->param('uid', 0); $page = $this->request->param('page', 1); $size = $this->request->param('size', 20); if (! $uid) { $this->error('用户ID不能为空', 400); } // 获取互关用户ID $mutualIds = UserFollow::alias('f1') ->join('user_follows f2', 'f1.uid = f2.fid AND f1.fid = f2.uid') ->where('f1.uid', $uid) ->where('f1.status', 1) ->where('f2.status', 1) ->column('f1.fid'); if (empty($mutualIds)) { $this->success([ 'list' => [], 'total' => 0, 'page' => $page, 'size' => $size, ], '获取成功'); } $users = UserModel::whereIn('id', $mutualIds) ->field('id,username,nickname,avatar,following_count,follower_count') ->page($page, $size) ->select(); $total = count($mutualIds); $list = []; foreach ($users as $user) { // 获取亲密度 $intimacy = $this->getIntimacy($uid, $user->id); $list[] = [ 'id' => $user->id, 'nickname' => $user->nickname, 'avatar' => $user->avatar, 'following_count' => $user->following_count, 'follower_count' => $user->follower_count, 'intimacy' => $intimacy['intimacy'], 'intimacy_level' => $intimacy['level'], 'free_message_count' => $this->getFreeMessageCount($intimacy['level']), ]; } $this->success([ 'list' => $list, 'total' => $total, 'page' => $page, 'size' => $size, ], '获取成功'); } /** * 更新亲密度 */ private function updateIntimacy($uid, $targetuid, $value) { $record = UserIntimacy::where('uid', $uid) ->where('target_uid', $targetuid) ->find(); if ($record) { $newIntimacy = $record->intimacy + $value; $newIntimacy = max(0, min(100, $newIntimacy)); // 限制在0-100之间 $record->intimacy = $newIntimacy; $record->level = $this->calculateIntimacyLevel($newIntimacy); $record->last_interaction = date('Y-m-d H:i:s'); $record->save(); } else { $intimacy = max(0, min(100, $value)); $record = new UserIntimacy(); $record->uid = $uid; $record->target_uid = $targetuid; $record->intimacy = $intimacy; $record->level = $this->calculateIntimacyLevel($intimacy); $record->save(); } // 同时更新对方的亲密度 $this->updateIntimacy($targetuid, $uid, $value); } /** * 获取亲密度 */ private function getIntimacy($uid, $targetuid) { $record = UserIntimacy::where('uid', $uid) ->where('target_uid', $targetuid) ->find(); if ($record) { return [ 'intimacy' => $record->intimacy, 'level' => $record->level, ]; } return ['intimacy' => 0, 'level' => 1]; } /** * 计算亲密度等级 */ private function calculateIntimacyLevel($intimacy) { if ($intimacy >= 90) { return 5; } if ($intimacy >= 80) { return 4; } if ($intimacy >= 60) { return 3; } if ($intimacy >= 40) { return 2; } return 1; } /** * 获取免费消息数量 */ private function getFreeMessageCount($level) { $counts = [0, 0, 2, 4, 5, PHP_INT_MAX]; return $counts[$level] ?? 0; } }