Files

390 lines
12 KiB
PHP

<?php
// +----------------------------------------------------------------------
// | YwxApp [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Author: ywxapp<admin@ywxapp.cn>
// +----------------------------------------------------------------------
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 <admin@ywxapp.cn>
*/
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;
}
}