缓存问题
This commit is contained in:
@@ -7,7 +7,6 @@ use app\chukebao\model\FriendSettings;
|
|||||||
use library\ResponseHelper;
|
use library\ResponseHelper;
|
||||||
use think\Db;
|
use think\Db;
|
||||||
use think\facade\Env;
|
use think\facade\Env;
|
||||||
use think\facade\Cache;
|
|
||||||
use app\common\service\AuthService;
|
use app\common\service\AuthService;
|
||||||
|
|
||||||
class MessageController extends BaseController
|
class MessageController extends BaseController
|
||||||
@@ -31,105 +30,75 @@ class MessageController extends BaseController
|
|||||||
return ResponseHelper::error('请先登录');
|
return ResponseHelper::error('请先登录');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 缓存键
|
// 直接查询好友ID列表
|
||||||
$cacheKeyFriends = 'message_list_friends_' . $accountId;
|
$ids = Db::table('s2_wechat_friend')
|
||||||
$cacheKeyChatrooms = 'message_list_chatrooms_' . $accountId;
|
->where(['accountId' => $accountId, 'isDeleted' => 0])
|
||||||
$cacheKeyMessages = 'message_list_messages_' . $accountId;
|
->column('id');
|
||||||
|
$friendIds = empty($ids) ? [0] : $ids; // 避免 IN 查询为空
|
||||||
|
|
||||||
|
// 直接查询好友信息
|
||||||
|
$friends = Db::table('s2_wechat_friend')
|
||||||
|
->where(['accountId' => $accountId, 'isDeleted' => 0])
|
||||||
|
->column('id,nickname,avatar,conRemark,labels,groupId,wechatAccountId,wechatId,extendFields,phone,region,isTop');
|
||||||
|
|
||||||
|
// 直接查询群聊信息
|
||||||
|
$chatrooms = Db::table('s2_wechat_chatroom')
|
||||||
|
->where(['accountId' => $accountId, 'isDeleted' => 0])
|
||||||
|
->column('id,nickname,chatroomAvatar,chatroomId,isTop');
|
||||||
|
|
||||||
|
// 获取群聊ID列表
|
||||||
|
$chatroomIds = array_keys($chatrooms);
|
||||||
|
if (empty($chatroomIds)) {
|
||||||
|
$chatroomIds = [0];
|
||||||
|
}
|
||||||
|
|
||||||
// 缓存时间:好友和群聊信息5分钟,消息列表30秒
|
// 1. 查询群聊最新消息
|
||||||
$cacheTimeFriends = 300; // 5分钟
|
$chatroomMessages = [];
|
||||||
$cacheTimeChatrooms = 300; // 5分钟
|
if (!empty($chatroomIds) && $chatroomIds[0] != 0) {
|
||||||
$cacheTimeMessages = 30; // 30秒
|
$chatroomIdsStr = implode(',', array_map('intval', $chatroomIds));
|
||||||
|
$chatroomLatestQuery = "
|
||||||
// 从缓存获取好友ID列表
|
SELECT wc.id as chatroomId, m.id, m.content, m.wechatChatroomId, m.createTime, m.wechatTime, m.wechatAccountId,
|
||||||
$friendIds = Cache::get($cacheKeyFriends . '_ids');
|
wc.nickname, wc.chatroomAvatar as avatar, wc.chatroomId, wc.isTop, 2 as msgType
|
||||||
if ($friendIds === false) {
|
FROM s2_wechat_chatroom wc
|
||||||
$ids = Db::table('s2_wechat_friend')
|
INNER JOIN (
|
||||||
->where(['accountId' => $accountId, 'isDeleted' => 0])
|
SELECT wechatChatroomId, MAX(wechatTime) as maxTime, MAX(id) as maxId
|
||||||
->column('id');
|
FROM s2_wechat_message
|
||||||
$friendIds = empty($ids) ? [0] : $ids; // 避免 IN 查询为空
|
WHERE type = 2 AND wechatChatroomId IN ({$chatroomIdsStr})
|
||||||
Cache::set($cacheKeyFriends . '_ids', $friendIds, $cacheTimeFriends);
|
GROUP BY wechatChatroomId
|
||||||
|
) latest ON wc.id = latest.wechatChatroomId
|
||||||
|
INNER JOIN s2_wechat_message m ON m.wechatChatroomId = latest.wechatChatroomId
|
||||||
|
AND m.wechatTime = latest.maxTime AND m.id = latest.maxId
|
||||||
|
WHERE wc.accountId = {$accountId} AND wc.isDeleted = 0
|
||||||
|
";
|
||||||
|
$chatroomMessages = Db::query($chatroomLatestQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 从缓存获取好友信息
|
// 2. 查询好友最新消息
|
||||||
$friends = Cache::get($cacheKeyFriends);
|
$friendMessages = [];
|
||||||
if ($friends === false) {
|
if (!empty($friendIds) && $friendIds[0] != 0) {
|
||||||
$friends = Db::table('s2_wechat_friend')
|
$friendIdsStr = implode(',', array_map('intval', $friendIds));
|
||||||
->where(['accountId' => $accountId, 'isDeleted' => 0])
|
$friendLatestQuery = "
|
||||||
->column('id,nickname,avatar,conRemark,labels,groupId,wechatAccountId,wechatId,extendFields,phone,region,isTop');
|
SELECT m.wechatFriendId, m.id, m.content, m.createTime, m.wechatTime,
|
||||||
Cache::set($cacheKeyFriends, $friends, $cacheTimeFriends);
|
f.wechatAccountId, 1 as msgType, 0 as isTop
|
||||||
|
FROM s2_wechat_message m
|
||||||
|
INNER JOIN (
|
||||||
|
SELECT wechatFriendId, MAX(wechatTime) as maxTime, MAX(id) as maxId
|
||||||
|
FROM s2_wechat_message
|
||||||
|
WHERE type = 1 AND wechatFriendId IN ({$friendIdsStr})
|
||||||
|
GROUP BY wechatFriendId
|
||||||
|
) latest ON m.wechatFriendId = latest.wechatFriendId
|
||||||
|
AND m.wechatTime = latest.maxTime AND m.id = latest.maxId
|
||||||
|
INNER JOIN s2_wechat_friend f ON f.id = m.wechatFriendId
|
||||||
|
WHERE m.type = 1 AND m.wechatFriendId IN ({$friendIdsStr})
|
||||||
|
";
|
||||||
|
$friendMessages = Db::query($friendLatestQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 从缓存获取群聊信息
|
// 合并结果并排序
|
||||||
$chatrooms = Cache::get($cacheKeyChatrooms);
|
$allMessages = array_merge($chatroomMessages, $friendMessages);
|
||||||
if ($chatrooms === false) {
|
usort($allMessages, function ($a, $b) {
|
||||||
$chatrooms = Db::table('s2_wechat_chatroom')
|
return $b['wechatTime'] <=> $a['wechatTime'];
|
||||||
->where(['accountId' => $accountId, 'isDeleted' => 0])
|
});
|
||||||
->column('id,nickname,chatroomAvatar,chatroomId,isTop');
|
|
||||||
Cache::set($cacheKeyChatrooms, $chatrooms, $cacheTimeChatrooms);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 优化:分别查询群聊和好友的最新消息,使用缓存
|
|
||||||
// 从缓存获取最新消息列表(短时间缓存,保证消息实时性)
|
|
||||||
$allMessages = Cache::get($cacheKeyMessages);
|
|
||||||
if ($allMessages === false) {
|
|
||||||
// 获取群聊ID列表
|
|
||||||
$chatroomIds = array_keys($chatrooms);
|
|
||||||
if (empty($chatroomIds)) {
|
|
||||||
$chatroomIds = [0];
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1. 查询群聊最新消息
|
|
||||||
$chatroomMessages = [];
|
|
||||||
if (!empty($chatroomIds) && $chatroomIds[0] != 0) {
|
|
||||||
$chatroomIdsStr = implode(',', array_map('intval', $chatroomIds));
|
|
||||||
$chatroomLatestQuery = "
|
|
||||||
SELECT wc.id as chatroomId, m.id, m.content, m.wechatChatroomId, m.createTime, m.wechatTime, m.wechatAccountId,
|
|
||||||
wc.nickname, wc.chatroomAvatar as avatar, wc.chatroomId, wc.isTop, 2 as msgType
|
|
||||||
FROM s2_wechat_chatroom wc
|
|
||||||
INNER JOIN (
|
|
||||||
SELECT wechatChatroomId, MAX(wechatTime) as maxTime, MAX(id) as maxId
|
|
||||||
FROM s2_wechat_message
|
|
||||||
WHERE type = 2 AND wechatChatroomId IN ({$chatroomIdsStr})
|
|
||||||
GROUP BY wechatChatroomId
|
|
||||||
) latest ON wc.id = latest.wechatChatroomId
|
|
||||||
INNER JOIN s2_wechat_message m ON m.wechatChatroomId = latest.wechatChatroomId
|
|
||||||
AND m.wechatTime = latest.maxTime AND m.id = latest.maxId
|
|
||||||
WHERE wc.accountId = {$accountId} AND wc.isDeleted = 0
|
|
||||||
";
|
|
||||||
$chatroomMessages = Db::query($chatroomLatestQuery);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. 查询好友最新消息
|
|
||||||
$friendMessages = [];
|
|
||||||
if (!empty($friendIds) && $friendIds[0] != 0) {
|
|
||||||
$friendIdsStr = implode(',', array_map('intval', $friendIds));
|
|
||||||
$friendLatestQuery = "
|
|
||||||
SELECT m.wechatFriendId, m.id, m.content, m.createTime, m.wechatTime,
|
|
||||||
f.wechatAccountId, 1 as msgType, 0 as isTop
|
|
||||||
FROM s2_wechat_message m
|
|
||||||
INNER JOIN (
|
|
||||||
SELECT wechatFriendId, MAX(wechatTime) as maxTime, MAX(id) as maxId
|
|
||||||
FROM s2_wechat_message
|
|
||||||
WHERE type = 1 AND wechatFriendId IN ({$friendIdsStr})
|
|
||||||
GROUP BY wechatFriendId
|
|
||||||
) latest ON m.wechatFriendId = latest.wechatFriendId
|
|
||||||
AND m.wechatTime = latest.maxTime AND m.id = latest.maxId
|
|
||||||
INNER JOIN s2_wechat_friend f ON f.id = m.wechatFriendId
|
|
||||||
WHERE m.type = 1 AND m.wechatFriendId IN ({$friendIdsStr})
|
|
||||||
";
|
|
||||||
$friendMessages = Db::query($friendLatestQuery);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 合并结果并排序
|
|
||||||
$allMessages = array_merge($chatroomMessages, $friendMessages);
|
|
||||||
usort($allMessages, function ($a, $b) {
|
|
||||||
return $b['wechatTime'] <=> $a['wechatTime'];
|
|
||||||
});
|
|
||||||
|
|
||||||
// 存入缓存
|
|
||||||
Cache::set($cacheKeyMessages, $allMessages, $cacheTimeMessages);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 计算总数
|
// 计算总数
|
||||||
$totalCount = count($allMessages);
|
$totalCount = count($allMessages);
|
||||||
|
|||||||
Reference in New Issue
Block a user