Files
im/app/api/controller/FriendCircleController.php
T

444 lines
15 KiB
PHP
Raw Normal View History

2025-12-24 16:59:05 +08:00
<?php
namespace app\api\controller;
2026-01-12 12:42:08 +08:00
use app\model\FriendCircle;
2025-12-24 16:59:05 +08:00
use Shopwwi\WebmanFilesystem\FilesystemFactory;
use Shopwwi\WebmanFilesystem\Facade\Storage;
use app\model\User as UserModel;
use app\model\Realname as RealnameModel;
use app\model\FriendCircle as FriendCircleModel;
use app\model\FriendCircleLike as FriendCircleLikeModel;
use app\model\FriendCircleComment as FriendCircleCommentModel;
use support\Request;
use support\Response;
use support\think\Db;
use hg\apidoc\annotation as Apidoc;
/**
* 朋友圈
*/
class FriendCircleController extends BaseController{
/**
* 不需要鉴权的方法
* @var array
*/
public $noNeedAuth = ['*'];
/**
* 无需登录及鉴权的方法
* @var array
*/
public $noNeedLogin = [];
/**
* 朋友圈设置
* @return void
*/
function info(Request $request): Response{
2026-02-15 19:41:56 +08:00
$user_id = Input('user_id');
if($user_id){
2026-03-01 21:05:19 +08:00
$user_id = \support\Encrypt::userIDDecode($user_id);
2026-02-15 19:41:56 +08:00
$json= [
'top_unread_items' =>[],
'unread_item_ids' =>[],
'unread_count' =>0,
'settings' => Db::name('friend_circle_setting')->where('user_id',$user_id)->order('id','desc')->findOrEmpty()
];
return $this->success('ok',$json);
}else{
$user = \support\Jwt::getUser();
if (!$user) {
return $this->fail('请先登录');
}
$user_id = $user->id;
$res = $this->newcount($request);
$response = $res->rawBody();
$json = json_decode($response,true);
$json['data']['settings'] = Db::name('friend_circle_setting')->where('user_id',$user_id)->order('id','desc')->findOrEmpty();
// [
// 'bg' => '',
// ];
$top_unread_items = FriendCircleModel::whereIn('id',$json['data']['unread_item_ids'])
->with(['user' => function($query) {
$query->field('id,nickname,avatar');
}])
->order('id', 'desc')
->limit(0,3)
->select();
$json['data']['top_unread_items'] = $top_unread_items ?: [];
$res->withBody(json_encode($json));
return $res;
2026-01-12 12:42:08 +08:00
}
2025-12-24 16:59:05 +08:00
}
/**
* @Apidoc\Title("列表")
* @Apidoc\Method("GET")
* @Apidoc\Query("page", type="int", require=true, desc="页码",default=1)
* @Apidoc\Query("limit", type="int", require=true, desc="分页大小",default=10)
* @Apidoc\Query("user_id", type="int", require=false, desc="用户ID,不传则获取所有")
*/
function list(Request $request): Response
{
2026-01-12 12:42:08 +08:00
$current_user = \support\Jwt::getUser();
$current_user_id = $current_user ? $current_user->id : 0;
2026-02-15 19:41:56 +08:00
$page = (int)Input('page', 1);
$limit = (int)Input('limit', 10);
$user_id = Input('user_id', 0);
if($user_id){
2026-03-01 21:05:19 +08:00
$user_id = \support\Encrypt::userIDDecode($user_id);
2026-02-15 19:41:56 +08:00
}
2025-12-24 16:59:05 +08:00
$query = FriendCircleModel::where('status', 1)
2026-01-12 12:42:08 +08:00
->whereIn('user_id',$this->getFriendUserIds($current_user_id))
2025-12-24 16:59:05 +08:00
->with(['user' => function($query) {
$query->field('id,nickname,avatar');
}])
->order('created_at', 'desc');
// 如果指定了用户ID,只获取该用户的朋友圈
if ($user_id > 0) {
$query->where('user_id', $user_id);
}
$list = $query->paginate([
'list_rows' => $limit,
'page' => $page,
]);
2026-02-15 19:41:56 +08:00
if(!$user_id){
cache('circle_last_read_id_'.$current_user_id,$list[0]['id']);
}
2025-12-24 16:59:05 +08:00
// 处理每条朋友圈数据
$items = $list->items();
$list->each(function($item) use ($current_user_id){
// 获取点赞列表
2026-02-15 19:41:56 +08:00
$likes = Db::name('friend_circle_like')->alias('f')
2026-01-12 12:42:08 +08:00
->join('user u','u.id=f.user_id')
2026-02-15 19:41:56 +08:00
->where('f.circle_id', $item->id)
2026-01-12 12:42:08 +08:00
->field('f.*,u.avatar,u.nickname')
->order('f.created_at', 'desc')
2025-12-24 16:59:05 +08:00
->limit(20)
->select();
2026-01-12 12:42:08 +08:00
$likes = $likes ? $likes->toArray() : [];
2025-12-24 16:59:05 +08:00
// 检查当前用户是否已点赞
$is_liked = false;
if ($current_user_id > 0) {
2026-01-12 12:42:08 +08:00
$is_liked = null !== array_find($likes,function($item)use($current_user_id){
return $item['user_id'] == $current_user_id;
});
// FriendCircleLikeModel::where('circle_id', $item->id)
// ->where('user_id', $current_user_id)
// ->count() > 0;
2025-12-24 16:59:05 +08:00
}
2026-01-12 12:42:08 +08:00
2025-12-24 16:59:05 +08:00
// 获取评论列表(最新10条)
$comments = FriendCircleCommentModel::where('circle_id', $item->id)
->where('status', 1)
->with(['user' => function($query) {
$query->field('id,nickname,avatar');
}, 'replyUser' => function($query) {
$query->field('id,nickname,avatar');
}])
->order('created_at', 'asc')
->limit(10)
->select();
// 格式化数据
$item->is_liked = $is_liked;
$item->likes = $likes;
$item->comments = $comments;
// 处理图片URL
if (!empty($item->files)) {
$files = is_array($item->files) ? $item->files : json_decode($item->files, true);
if (is_array($files)) {
$item->files = array_map(function($file) {
return cdnurl($file);
}, $files);
} else {
$item->files = [];
}
} else {
$item->files = [];
}
// 处理用户头像
if ($item->user && $item->user->avatar) {
$item->user->avatar = cdnurl($item->user->avatar);
}
// 处理点赞用户头像
foreach ($item->likes as $like) {
2026-01-12 12:42:08 +08:00
if ($like->user) {
$like->avatar = cdnurl($like->avatar);
2025-12-24 16:59:05 +08:00
}
}
// 处理评论用户头像
foreach ($item->comments as $comment) {
if ($comment->user && $comment->user->avatar) {
$comment->user->avatar = cdnurl($comment->user->avatar);
}
if ($comment->replyUser && $comment->replyUser->avatar) {
$comment->replyUser->avatar = cdnurl($comment->replyUser->avatar);
}
}
return $item;
});
return $this->success('ok', $list);
}
/**
* @Apidoc\Title("最近更新的数量")
* @Apidoc\Method("POST")
* @Apidoc\Param("last_see", type="string",require=false, desc="最近查看的时间戳")
*/
function newcount(Request $request): Response
{
$user = \support\Jwt::getUser();
if (!$user) {
return $this->fail('请先登录');
}
2026-02-15 19:41:56 +08:00
$user_id = $user->id;
$circle_last_read_id = cache('circle_last_read_id_'.$user_id) ?: 0;
2025-12-24 16:59:05 +08:00
// 统计从上次查看时间到现在新增的朋友圈数量
2026-01-12 12:42:08 +08:00
$unread_item_ids = FriendCircleModel::where('status', 1)
2026-02-15 19:41:56 +08:00
->whereIn('user_id',$this->getFriendUserIds($user_id))
2026-01-12 12:42:08 +08:00
->where('id', '>', $circle_last_read_id)
->order('id', 'desc')
->column('id');
2025-12-24 16:59:05 +08:00
2026-01-12 12:42:08 +08:00
return $this->success('ok', [
'unread_count' => count($unread_item_ids),
'unread_item_ids'=>$unread_item_ids
]);
2025-12-24 16:59:05 +08:00
}
/**
* @Apidoc\Title("发布朋友圈")
* @Apidoc\Method("POST")
* @Apidoc\Param("body", type="string",require=false, desc="内容")
* @Apidoc\Param("files", type="string",require=false, desc="图片列表(JSON数组)")
*/
function create(Request $request): Response
{
$user = \support\Jwt::getUser();
if (!$user) {
return $this->fail('请先登录');
}
$body = $request->post('content', '');
$files = $request->post('files', '');
$address = $request->post('address', '');
$releaseType = $request->post('releaseType', '');
// 验证内容
if (empty($body)) {
return $this->fail('什么内容都木有啊');
}
// 处理图片列表
$files_array = [];
if (!empty($files)) {
if (is_string($files)) {
$files_array = json_decode($files, true);
} elseif (is_array($files)) {
$files_array = $files;
}
if (!is_array($files_array)) {
return $this->fail('图片列表格式错误');
}
// 限制图片数量
if (count($files_array) > 9) {
return $this->fail('最多只能上传9张图片');
}
}
// 创建朋友圈动态
$circle = FriendCircleModel::create([
'user_id' => $user->id,
'releaseType' => $releaseType,
'body' => $body,
'files' => $files_array,
'address' => $address,
'status' => 1,
]);
2026-02-15 19:41:56 +08:00
return $this->success('发布成功', ['id' => $circle->id,'data' => $circle]);
2025-12-24 16:59:05 +08:00
}
/**
* @Apidoc\Title("发表评论")
* @Apidoc\Method("POST")
* @Apidoc\Param("body", type="string",require=true, desc="内容")
* @Apidoc\Param("id", type="int",require=true, desc="朋友圈动态ID")
* @Apidoc\Param("reply_user_id", type="int",require=false, desc="回复的用户ID(回复评论时使用)")
*/
function comment(Request $request): Response
{
$user = \support\Jwt::getUser();
if (!$user) {
return $this->fail('请先登录');
}
$body = $request->post('body', '');
$circle_id = (int)$request->post('id', 0);
$reply_user_id = (int)$request->post('reply_user_id', 0);
if (empty($body)) {
return $this->fail('评论内容不能为空');
}
if ($circle_id <= 0) {
return $this->fail('朋友圈动态ID错误');
}
// 检查朋友圈动态是否存在
$circle = FriendCircleModel::where('id', $circle_id)
->where('status', 1)
->find();
if (!$circle) {
return $this->fail('朋友圈动态不存在');
}
// 如果回复评论,检查被回复的用户是否存在
if ($reply_user_id > 0) {
$reply_user = UserModel::where('id', $reply_user_id)->find();
if (!$reply_user) {
return $this->fail('被回复的用户不存在');
}
}
// 创建评论
$comment = FriendCircleCommentModel::create([
'circle_id' => $circle_id,
'user_id' => $user->id,
'reply_user_id' => $reply_user_id,
'body' => $body,
'status' => 1,
]);
// 更新朋友圈评论数
$circle->comment_count = FriendCircleCommentModel::where('circle_id', $circle_id)
->where('status', 1)
->count();
$circle->save();
2026-01-12 12:42:08 +08:00
$comment->user = Db::name('user')->where('id',$comment->user_id)->find();
$comment->replyUser=null;
if($comment->reply_user_id){
$comment->replyUser = Db::name('user')->where('id',$comment->reply_user_id)->find();
}
return $this->success('评论成功', $comment);
2025-12-24 16:59:05 +08:00
}
/**
* @Apidoc\Title("点赞")
* @Apidoc\Method("POST")
* @Apidoc\Param("id", type="int",require=true, desc="朋友圈动态ID")
*/
function like(Request $request): Response
{
$user = \support\Jwt::getUser();
if (!$user) {
return $this->fail('请先登录');
}
$circle_id = (int)$request->post('id', 0);
if ($circle_id <= 0) {
return $this->fail('朋友圈动态ID错误');
}
// 检查朋友圈动态是否存在
$circle = FriendCircleModel::where('id', $circle_id)
->where('status', 1)
->find();
if (!$circle) {
return $this->fail('朋友圈动态不存在');
}
// 检查是否已点赞
$like = FriendCircleLikeModel::where('circle_id', $circle_id)
->where('user_id', $user->id)
->find();
if ($like) {
// 取消点赞
$like->delete();
$circle->like_count = max(0, $circle->like_count - 1);
$circle->save();
return $this->success('取消点赞成功', ['is_liked' => false]);
} else {
// 添加点赞
FriendCircleLikeModel::create([
'circle_id' => $circle_id,
'user_id' => $user->id,
]);
$circle->like_count = $circle->like_count + 1;
$circle->save();
return $this->success('点赞成功', ['is_liked' => true]);
}
}
2026-01-12 12:42:08 +08:00
protected function getFriendUserIds($user_id):array{
if (!$user_id) {
return [];
}
2026-02-15 19:41:56 +08:00
$cache_key = 'friend_id_list_'.$user_id;
$result = cache($cache_key) ?: [];
2026-01-12 12:42:08 +08:00
if(count($result) === 0){
2026-03-01 21:05:19 +08:00
$res = request()->IM->friend->getFriendList(\support\Encrypt::userIDencode($user_id));
2026-01-12 12:42:08 +08:00
$friendsInfo = $res['friendsInfo'];
foreach($friendsInfo as $k=>$v){
array_push($result,$v['friendUser']['userID']);
}
2026-02-15 19:41:56 +08:00
cache($cache_key,$result,3600);
2026-01-12 12:42:08 +08:00
}
2026-02-15 19:41:56 +08:00
$result[] = $user_id;
2026-01-12 12:42:08 +08:00
return $result;
}
2026-02-15 19:41:56 +08:00
function delete(Request $request): Response{
$id = $request->post('id');
$user = \support\Jwt::getUser();
if (!$user) {
return $this->fail('请先登录');
}
if($id){
FriendCircleModel::where('id',$id)->where('user_id',$user->id)->delete();
}
return $this->success('删除成功');
}
function upload_bg(Request $request){
try {
$user = \support\Jwt::getUser();
if (!$user) {
return $this->fail('请先登录');
}
$res = $this->_upload($request);
if(is_string($res)){
return $this->fail( $res);
}
Db::name('friend_circle_setting')->replace()->insert([
'user_id' => $user->id,
'bg' => $res[0]['file_name'],
'allow_days'=>0,
'created_at'=>0
]);
//$result->ss = cdnurl($result->url);
//P($result);
return $this->success(__('successful'),[
'url'=>$res[0]['file_name']
]);
}catch (\Exception $e){
return $this->error($e->getMessage());
}
}
2025-12-24 16:59:05 +08:00
}