功能:好友悄悄话内嵌快捷操作链接

后端:
- notifyOnlineUser 生成带内联 <a> 标签的内容
- added 未互相 → 嵌入 ' 回加好友' 链接
- removed 互相  → 嵌入 '🗑️ 同步移除' 链接
- 链接调用全局 quickFriendAction(act, username, el)

前端:
- 新增 window.quickFriendAction() 全局函数
- 防重复点击(dataset.done 标记)
- 成功后更新链接文字 ' 已回加' / ' 已移除',不刷新页面
This commit is contained in:
2026-03-01 01:03:10 +08:00
parent cc16f89bbe
commit 212f7a0096
2 changed files with 58 additions and 4 deletions
@@ -712,6 +712,55 @@
* @param {string} color 左边框 / 主题颜色
* @param {object|null} action 可选操作按钮 { label, username, action:'add'|'remove' }
*/
/**
* 聊天区悄悄话内嵌链接的快捷好友操作。
* 由后端生成的 onclick="quickFriendAction('add'/'remove', username, this)" 调用。
*
* @param {string} act 'add' | 'remove'
* @param {string} username 目标用户名
* @param {HTMLElement} el 被点击的 <a> 元素,用于更新显示状态
*/
window.quickFriendAction = async function(act, username, el) {
if (el.dataset.done) return;
el.dataset.done = '1';
const origText = el.textContent;
el.textContent = '处理中…';
el.style.pointerEvents = 'none';
try {
const method = act === 'add' ? 'POST' : 'DELETE';
const url = `/friend/${encodeURIComponent(username)}/${act === 'add' ? 'add' : 'remove'}`;
const csrf = document.querySelector('meta[name="csrf-token"]')?.content ?? '';
const res = await fetch(url, {
method,
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': csrf,
'Accept': 'application/json',
},
body: JSON.stringify({
room_id: window.chatContext?.roomId
}),
});
const data = await res.json();
if (data.status === 'success') {
el.textContent = act === 'add' ? '✅ 已回加' : '✅ 已移除';
el.style.color = '#16a34a';
el.style.textDecoration = 'none';
} else {
el.textContent = '❌ ' + (data.message || '操作失败');
el.style.color = '#cc4444';
}
} catch (e) {
el.textContent = '❌ 网络错误';
el.style.color = '#cc4444';
delete el.dataset.done;
el.style.pointerEvents = '';
}
};
function showFriendToast(html, color = '#16a34a', action = null) {
const toast = document.createElement('div');
toast.style.cssText = `
@@ -1541,7 +1590,8 @@
if (!res.ok || data.status !== 'success') {
const errDiv = document.createElement('div');
errDiv.className = 'msg-line';
errDiv.innerHTML = `<span style="color: #dc2626;">🤖【AI小班长】${data.message || '回复失败,请稍后重试'}</span>`;
errDiv.innerHTML =
`<span style="color: #dc2626;">🤖【AI小班长】${data.message || '回复失败,请稍后重试'}</span>`;
container.appendChild(errDiv);
}
} catch (e) {