即时消息接口完结

This commit is contained in:
2025-11-19 15:34:37 +08:00
parent 45b4efa759
commit 2a89361d3e
5 changed files with 167 additions and 147 deletions

View File

@@ -95,6 +95,14 @@ class GroupController extends ApiController
return $this->error('已在群内');
}
// 再次加入时
$z_exists = Db::name('chat_group_member')->where([
'group_id' => $group_id,
'user_id' => $this->uid,
'is_kicked' => 0
])->where('quit_time', 'not null')->find();
// 被踢用户不能重新加入(需群主邀请)
$isKicked = Db::name('chat_group_member')->where([
'group_id' => $group_id,
@@ -113,6 +121,8 @@ class GroupController extends ApiController
'join_time' => d(),
];
$is_insert = true;
if($invite) {
// 验证邀请参数是否正常
$decryptedText = simple_decrypt($invite, config('cons.sercer_key'));
@@ -125,6 +135,11 @@ class GroupController extends ApiController
$insert_arr['group_id'] = $decryptedText_arr['group_id'];
$group_id = $decryptedText_arr['group_id'];
}
// 如果是再次加入
if($z_exists) {
$insert_arr['quit_time'] = null;
$is_insert = false;
}
try {
Db::startTrans();
// 插入用户信息
@@ -258,6 +273,9 @@ class GroupController extends ApiController
'quit_time' => null,
'role' => 1
])->update(['user_id' => $object_user_id, 'object_user_id' => $this->uid]);
Db::name('chat_group')->where([
'id' => $group_id,
])->update(['owner_id' => $object_user_id]);
if($res) {
return $this->success();
}

View File

@@ -8,6 +8,7 @@ use app\chat\model\ChatUser;
use app\chat\model\ChatGroup;
use app\common\controller\ApiController;
use app\utils\Session;
use support\Redis;
use support\Request;
use support\Response;
use support\think\Db;
@@ -48,10 +49,11 @@ class MessageController extends ApiController
// 分页查询(倒序取,再正序返回)
$total = $query->count();
$messages = $query->order('send_time', 'desc')
$messages = $query->alias('msg')->order('send_time', 'desc')
->leftJoin('chat_user user', 'msg.from_id = user.user_id')
->field('msg.id,from_id,to_id,chat_type,msg_type,content,image_url,order_id,is_read,send_time,session_id,nick_name,user_id,avatar,type')
->page($page, $size)
->select()->toArray();
$messages = array_reverse($messages);
// 单聊自动标记已读
if ($chatType == 1) {
@@ -67,7 +69,9 @@ class MessageController extends ApiController
'session_id' => $session_id
])->update(['count' => 0, 'updated_time' => d()]);
}
foreach ($messages as $k => &$v) {
$v['send_time'] = formatWeChatTime($v['send_time']);
}
return $this->success([
'list' => $messages,
'page' => $page,
@@ -80,42 +84,33 @@ class MessageController extends ApiController
*/
public function markRead(Request $request): Response
{
$uid = $request->uid;
$msgIds = $request->post('msg_ids', []);
if (empty($msgIds) || !is_array($msgIds)) {
return json(['code' => 400, 'msg' => '请传入有效消息ID数组']);
$msgIds = $request->post('msg_ids');
if (empty($msgIds) || !is_string($msgIds)) {
return $this->error('请传入有效消息ID');
}
$msgIds = explode(',', $msgIds);
$query = Db::name('chat_message')->whereIn('id', $msgIds)->where('to_id', $this->uid)
->where('is_read', 0);
// 标记已读(仅自己接收的消息)
$messages = ChatMessage::whereIn('id', $msgIds)
->where('to_id', $uid)
->where('is_read', 0)
->get();
if (empty($messages)) {
return json(['code' => 200, 'msg' => '无未读消息可标记']);
$count = $query->count();
if (empty($count)) {
return $this->error('无未读消息可标记');
}
// 批量更新
$sessionIds = $messages->pluck('session_id')->unique()->toArray();
ChatMessage::whereIn('id', $msgIds)->where('to_id', $uid)->update(['is_read' => 1]);
// 更新未读计数
foreach ($sessionIds as $sessionId) {
$reduceNum = ChatMessage::whereIn('id', $msgIds)
->where('session_id', $sessionId)
->count();
$unread = ChatUnreadCount::where(['user_id' => $uid, 'session_id' => $sessionId])->first();
if ($unread) {
$newCount = max(0, $unread->count - $reduceNum);
$unread->count = $newCount;
$unread->updated_at = time();
$unread->save();
try {
Db::startTrans();
$sessionIds = $query->group('session_id')->column('session_id');
// 更新未读计数
foreach ($sessionIds as $sessionId) {
Db::name('chat_unread_count')->where(['user_id' => $this->uid, 'session_id' => $sessionId])->update(['count' => 0, 'updated_time' => d()]);
}
// 批量更新
$query->update(['is_read' => 1]);
Db::commit();
return $this->success();
}catch (\Throwable $exception) {
Db::rollback();
return $this->error($exception->getMessage());
}
return json(['code' => 200, 'msg' => '标记已读成功']);
}
/**
@@ -123,27 +118,27 @@ class MessageController extends ApiController
*/
public function markReadAll(Request $request): Response
{
$uid = $request->uid;
$sessionId = $request->post('session_id', '');
if (empty($sessionId)) {
return json(['code' => 400, 'msg' => '缺少session_id']);
$msgIds = $request->post('session_ids');
if (empty($msgIds) || !is_string($msgIds)) {
return $this->error('请传入有效会话ID');
}
$msgIds = explode(',', $msgIds);
$query = Db::name('chat_message')->whereIn('session_id', $msgIds)->where('to_id', $this->uid)
->where('is_read', 0);
try {
Db::startTrans();
// 更新未读计数
foreach ($msgIds as $sessionId) {
Db::name('chat_unread_count')->where(['user_id' => $this->uid, 'session_id' => $sessionId])->update(['count' => 0, 'updated_time' => d()]);
}
// 批量更新
$query->update(['is_read' => 1]);
Db::commit();
return $this->success();
}catch (\Throwable $exception) {
Db::rollback();
return $this->error($exception->getMessage());
}
// 标记该会话所有未读消息已读
ChatMessage::where([
'session_id' => $sessionId,
'to_id' => $uid,
'is_read' => 0
])->update(['is_read' => 1]);
// 重置未读计数
ChatUnreadCount::where([
'user_id' => $uid,
'session_id' => $sessionId
])->update(['count' => 0, 'updated_at' => time()]);
return json(['code' => 200, 'msg' => '标记全部已读成功']);
}
/**
@@ -151,10 +146,8 @@ class MessageController extends ApiController
*/
public function getUnreadCount(Request $request): Response
{
$uid = $request->uid;
$total = ChatUnreadCount::where('user_id', $uid)->sum('count');
return json(['code' => 200, 'msg' => 'success', 'data' => ['total' => $total]]);
$total = Db::name('chat_unread_count')->where('user_id', $this->uid)->sum('count');
return $this->success(['total' => $total]);
}
/**
@@ -162,93 +155,17 @@ class MessageController extends ApiController
*/
public function getSessionList(Request $request): Response
{
$uid = $request->uid;
// 获取所有会话ID
$sessionIds = ChatMessage::where(function ($query) use ($uid) {
$query->where('from_id', $uid)->orWhere('to_id', $uid);
})->groupBy('session_id')->pluck('session_id')->toArray();
$sessionIds = Db::name('chat_message')->where('from_id', $this->uid)->WhereOr('to_id', $this->uid)
->group('session_id')->column('session_id');
if (empty($sessionIds)) {
return json(['code' => 200, 'msg' => 'success', 'data' => ['list' => []]]);
return $this->success();
}
$sessionList = [];
foreach ($sessionIds as $sessionId) {
// 置顶状态
$top = ChatTop::where(['user_id' => $uid, 'session_id' => $sessionId])->first();
$isTop = $top && $top->status == 1 ? 1 : 0;
$sort = $top ? $top->sort : 0;
// 未读计数
$unread = ChatUnreadCount::where(['user_id' => $uid, 'session_id' => $sessionId])->first();
$unreadCount = $unread ? $unread->count : 0;
// 最后一条消息
$lastMsg = ChatMessage::where('session_id', $sessionId)
->orderBy('send_time', 'desc')
->first([
'id', 'from_id', 'msg_type', 'content', 'image_url',
'order_id', 'send_time', 'is_read'
]);
if (!$lastMsg) continue;
// 会话类型(单聊/群聊)
$chatType = strpos($sessionId, 'group_') === 0 ? 2 : 1;
$targetInfo = [];
if ($chatType == 1) {
// 单聊解析对方ID
list($minId, $maxId) = explode('_', $sessionId);
$targetUid = $uid == $minId ? $maxId : $minId;
$targetUser = ChatUser::find($targetUid);
if ($targetUser) {
$targetInfo = [
'id' => $targetUser->id,
'name' => $targetUser->username,
'avatar' => $targetUser->avatar,
'type' => $targetUser->type
];
}
} else {
// 群聊解析群ID
$groupId = str_replace('group_', '', $sessionId);
$group = ChatGroup::find($groupId);
if ($group) {
$targetInfo = [
'id' => $group->id,
'name' => $group->name,
'avatar' => $group->avatar,
'owner_id' => $group->owner_id
];
}
}
$sessionList[] = [
'session_id' => $sessionId,
'chat_type' => $chatType,
'is_top' => $isTop,
'sort' => $sort,
'unread_count' => $unreadCount,
'last_msg' => $lastMsg ? $lastMsg->toArray() : [],
'target_info' => $targetInfo
];
$list = Redis::get('usermsg:list:' . $this->user_type . ':' . $this->uid);
if($list) {
return $this->success(['list' => json_decode($list, true)]);
}else {
return $this->success(['list' => ChatMessage::getconverlist($this->uid, $this->user_type)]);
}
// 排序置顶按sort降序→ 非置顶(按最后消息时间降序)
usort($sessionList, function ($a, $b) {
if ($a['is_top'] != $b['is_top']) {
return $b['is_top'] - $a['is_top'];
}
if ($a['is_top'] == 1) {
return $b['sort'] - $a['sort'];
}
$aTime = $a['last_msg']['send_time'] ?? 0;
$bTime = $b['last_msg']['send_time'] ?? 0;
return $bTime - $aTime;
});
return json(['code' => 200, 'msg' => 'success', 'data' => ['list' => $sessionList]]);
}
}