Compare commits
2
Commits
52ccf88940
...
1f1164ab69
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1f1164ab69 | ||
|
|
0620df79d3 |
+60
-2
@@ -11,7 +11,8 @@ VALUES
|
|||||||
('query', '123'),
|
('query', '123'),
|
||||||
('tom', '123'),
|
('tom', '123'),
|
||||||
('jack', '123'),
|
('jack', '123'),
|
||||||
('lucy', '123');
|
('lucy', '123'),
|
||||||
|
('lily', '123');
|
||||||
select * from chat_mysql.users;
|
select * from chat_mysql.users;
|
||||||
|
|
||||||
|
|
||||||
@@ -36,7 +37,9 @@ VALUES
|
|||||||
('query', 'admin'),
|
('query', 'admin'),
|
||||||
('query', 'tom'),
|
('query', 'tom'),
|
||||||
('tom', 'admin'),
|
('tom', 'admin'),
|
||||||
('tom', 'query');
|
('tom', 'query'),
|
||||||
|
('admin', 'lily'),
|
||||||
|
('lily', 'admin');
|
||||||
select * from chat_mysql.contacts;
|
select * from chat_mysql.contacts;
|
||||||
|
|
||||||
CREATE TABLE chat_mysql.messages (
|
CREATE TABLE chat_mysql.messages (
|
||||||
@@ -97,3 +100,58 @@ VALUES
|
|||||||
('query', 'tom', '不需要每个联系人都创建一个 WebSocket。', '2026-09-20 15:01:00'),
|
('query', 'tom', '不需要每个联系人都创建一个 WebSocket。', '2026-09-20 15:01:00'),
|
||||||
('tom', 'query', '一个用户维护一个 WebSocket 连接就可以了。', '2026-09-20 15:02:00');
|
('tom', 'query', '一个用户维护一个 WebSocket 连接就可以了。', '2026-09-20 15:02:00');
|
||||||
select * from chat_mysql.messages;
|
select * from chat_mysql.messages;
|
||||||
|
|
||||||
|
INSERT INTO chat_mysql.messages
|
||||||
|
(sender_name, receiver_name, content, created_at)
|
||||||
|
VALUES
|
||||||
|
-- admin ↔ lily
|
||||||
|
('admin', 'lily', '你好,最近怎么样?', '2026-09-20 10:00:00'),
|
||||||
|
('lily', 'admin', '挺好的,你呢?', '2026-09-20 10:01:00'),
|
||||||
|
('admin', 'lily', '我也不错,最近在做聊天项目。', '2026-09-20 10:02:00'),
|
||||||
|
('lily', 'admin', '听起来不错,是用 Vue 做的吗?', '2026-09-20 10:03:00'),
|
||||||
|
('admin', 'lily', '对,前端使用 Vue2,后端使用 Node.js。', '2026-09-20 10:04:00'),
|
||||||
|
('lily', 'admin', '那数据库使用 MySQL?', '2026-09-20 10:05:00'),
|
||||||
|
('admin', 'lily', '对,目前正在完善聊天功能。', '2026-09-20 10:06:00'),
|
||||||
|
('lily', 'admin', '聊天记录是怎么保存的?', '2026-09-20 10:07:00'),
|
||||||
|
('admin', 'lily', '目前是保存在 messages 表里面。', '2026-09-20 10:08:00'),
|
||||||
|
('lily', 'admin', '一个消息对应一条数据吗?', '2026-09-20 10:09:00'),
|
||||||
|
('admin', 'lily', '对,每条消息都有自己的 id。', '2026-09-20 10:10:00'),
|
||||||
|
('lily', 'admin', '那发送人和接收人怎么区分?', '2026-09-20 10:11:00'),
|
||||||
|
('admin', 'lily', '通过 sender_name 和 receiver_name 两个字段区分。', '2026-09-20 10:12:00'),
|
||||||
|
('lily', 'admin', '这样查询两个人的聊天记录应该比较方便。', '2026-09-20 10:13:00'),
|
||||||
|
('admin', 'lily', '对,只需要判断双方的用户名即可。', '2026-09-20 10:14:00'),
|
||||||
|
('lily', 'admin', '比如查询 admin 和 lily 之间的消息?', '2026-09-20 10:15:00'),
|
||||||
|
('admin', 'lily', '没错,可以使用 OR 和 AND 组合条件。', '2026-09-20 10:16:00'),
|
||||||
|
('lily', 'admin', '那如果消息很多怎么办?', '2026-09-20 10:17:00'),
|
||||||
|
('admin', 'lily', '不能一次把所有消息都返回给前端。', '2026-09-20 10:18:00'),
|
||||||
|
('lily', 'admin', '应该使用分页查询吧?', '2026-09-20 10:19:00'),
|
||||||
|
('admin', 'lily', '对,比如一次只查询 10 条或者 20 条。', '2026-09-20 10:20:00'),
|
||||||
|
('lily', 'admin', '这样可以减少接口返回的数据量。', '2026-09-20 10:21:00'),
|
||||||
|
('admin', 'lily', '也可以提高页面加载速度。', '2026-09-20 10:22:00'),
|
||||||
|
('lily', 'admin', '最近聊天列表也是单独查询吗?', '2026-09-20 10:23:00'),
|
||||||
|
('admin', 'lily', '对,最近聊天只需要获取每个联系人的最新消息。', '2026-09-20 10:24:00'),
|
||||||
|
('lily', 'admin', '这样左边就不用加载完整聊天记录了。', '2026-09-20 10:25:00'),
|
||||||
|
('admin', 'lily', '对,点击联系人之后再加载具体的聊天记录。', '2026-09-20 10:26:00'),
|
||||||
|
('lily', 'admin', '这个设计比较合理。', '2026-09-20 10:27:00'),
|
||||||
|
('admin', 'lily', '我现在就是准备按照这个思路修改。', '2026-09-20 10:28:00'),
|
||||||
|
('lily', 'admin', '那 Vue 里面是不是也不用保存所有消息?', '2026-09-20 10:29:00'),
|
||||||
|
('admin', 'lily', '是的,只需要保存当前联系人的消息数组。', '2026-09-20 10:30:00'),
|
||||||
|
('lily', 'admin', '分页的时候再把历史消息添加进去?', '2026-09-20 10:31:00'),
|
||||||
|
('admin', 'lily', '对,可以把下一页的数据添加到数组前面。', '2026-09-20 10:32:00'),
|
||||||
|
('lily', 'admin', '那新发送的消息就添加到数组最后面?', '2026-09-20 10:33:00'),
|
||||||
|
('admin', 'lily', '没错,因为新消息的时间是最新的。', '2026-09-20 10:34:00'),
|
||||||
|
('lily', 'admin', '左边的最近聊天还需要移动到最上面。', '2026-09-20 10:35:00'),
|
||||||
|
('admin', 'lily', '对,可以使用 unshift 把它移动到第一位。', '2026-09-20 10:36:00'),
|
||||||
|
('lily', 'admin', '同时更新左边显示的最后一条消息。', '2026-09-20 10:37:00'),
|
||||||
|
('admin', 'lily', '这样聊天列表就会实时更新了。', '2026-09-20 10:38:00'),
|
||||||
|
('lily', 'admin', '如果切换联系人,消息数组怎么办?', '2026-09-20 10:39:00'),
|
||||||
|
('admin', 'lily', '可以按照联系人 id 分别保存。', '2026-09-20 10:40:00'),
|
||||||
|
('lily', 'admin', '比如 contactMessages[18] 保存 lily 的消息?', '2026-09-20 10:41:00'),
|
||||||
|
('admin', 'lily', '对,contactMessages[20] 就可以保存另一个人的消息。', '2026-09-20 10:42:00'),
|
||||||
|
('lily', 'admin', 'Vue2 动态增加这个属性需要注意响应式问题吧?', '2026-09-20 10:43:00'),
|
||||||
|
('admin', 'lily', '对,可以使用 this.$set 来创建新的消息数组。', '2026-09-20 10:44:00'),
|
||||||
|
('lily', 'admin', '这样切换联系人就比较方便了。', '2026-09-20 10:45:00'),
|
||||||
|
('admin', 'lily', '对,聊天页面的数据结构基本就确定了。', '2026-09-20 10:46:00'),
|
||||||
|
('lily', 'admin', '那接下来就可以测试分页加载了。', '2026-09-20 10:47:00'),
|
||||||
|
('admin', 'lily', '嗯,先测试一次查询 10 条消息。', '2026-09-20 10:48:00'),
|
||||||
|
('lily', 'admin', '然后再查询下一页历史消息。', '2026-09-20 10:49:00');
|
||||||
|
|||||||
+75
-5
@@ -65,12 +65,82 @@ router.get(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// 获取所有聊天消息
|
// 获取最近联系人的最后一条聊天消息
|
||||||
router.get(
|
router.get(
|
||||||
"/messagesInfo",
|
"/recentChats",
|
||||||
authMiddleware,
|
authMiddleware,
|
||||||
(req, res) => {
|
(req, res) => {
|
||||||
const currentUserName = req.user.username;
|
const currentUserName = req.user.username;
|
||||||
|
const sql = `
|
||||||
|
SELECT
|
||||||
|
contact_name,
|
||||||
|
content,
|
||||||
|
created_at
|
||||||
|
FROM (
|
||||||
|
SELECT
|
||||||
|
CASE
|
||||||
|
WHEN sender_name = ? THEN receiver_name
|
||||||
|
ELSE sender_name
|
||||||
|
END AS contact_name,
|
||||||
|
content,
|
||||||
|
created_at,
|
||||||
|
ROW_NUMBER() OVER (
|
||||||
|
PARTITION BY
|
||||||
|
CASE
|
||||||
|
WHEN sender_name = ? THEN receiver_name
|
||||||
|
ELSE sender_name
|
||||||
|
END
|
||||||
|
ORDER BY created_at DESC
|
||||||
|
) AS rn
|
||||||
|
FROM chat_mysql.messages
|
||||||
|
WHERE sender_name = ?
|
||||||
|
OR receiver_name = ?
|
||||||
|
) t
|
||||||
|
WHERE rn = 1
|
||||||
|
ORDER BY created_at DESC;
|
||||||
|
`;
|
||||||
|
db.query(sql, [currentUserName, currentUserName, currentUserName, currentUserName], (error, results) => {
|
||||||
|
if (error) {
|
||||||
|
console.error("数据库查询失败:", error);
|
||||||
|
|
||||||
|
return res.status(500).json({
|
||||||
|
code: 500,
|
||||||
|
message: "查询失败",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (results.length > 0) {
|
||||||
|
res.json({
|
||||||
|
code: 200,
|
||||||
|
message: "查询成功",
|
||||||
|
data: {
|
||||||
|
recentChats: results.map(message => ({
|
||||||
|
contactName: message.contact_name,
|
||||||
|
content: message.content,
|
||||||
|
createdAt: message.created_at
|
||||||
|
}))
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
res.json({
|
||||||
|
code: 401,
|
||||||
|
message: "未找到联系人消息",
|
||||||
|
data: {
|
||||||
|
recentChats: []
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 获取某个联系人的最近n条聊天消息,分页获取
|
||||||
|
router.post(
|
||||||
|
"/contactMessagesInfo",
|
||||||
|
authMiddleware,
|
||||||
|
(req, res) => {
|
||||||
|
const currentUserName = req.user.username;
|
||||||
|
const { contactName, limit, offset } = req.body;
|
||||||
const sql = `
|
const sql = `
|
||||||
SELECT
|
SELECT
|
||||||
id,
|
id,
|
||||||
@@ -79,10 +149,10 @@ router.get(
|
|||||||
content,
|
content,
|
||||||
created_at
|
created_at
|
||||||
FROM chat_mysql.messages
|
FROM chat_mysql.messages
|
||||||
WHERE sender_name = ? OR receiver_name = ?
|
WHERE (sender_name = ? OR receiver_name = ?) AND (sender_name = ? OR receiver_name = ?)
|
||||||
ORDER BY created_at ASC;
|
ORDER BY created_at DESC LIMIT ? OFFSET ?;
|
||||||
`;
|
`;
|
||||||
db.query(sql, [currentUserName, currentUserName], (error, results) => {
|
db.query(sql, [currentUserName, currentUserName, contactName, contactName, limit, offset], (error, results) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
console.error("数据库查询失败:", error);
|
console.error("数据库查询失败:", error);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user