diff --git a/app/Http/Controllers/FriendController.php b/app/Http/Controllers/FriendController.php index 2d69aa3..de1cfa1 100644 --- a/app/Http/Controllers/FriendController.php +++ b/app/Http/Controllers/FriendController.php @@ -220,13 +220,17 @@ class FriendController extends Controller return; } - // 根据操作类型和互相状态生成不同文案 + // 根据操作类型和互相状态生成不同文案(含内联快捷操作链接) + $btnStyle = 'font-weight:bold;text-decoration:underline;margin-left:6px;'; + $btnAdd = "➕ 回加好友"; + $btnRemove = "🗑️ 同步移除"; + $content = match ($action) { 'added' => $mutual ? "💚 {$fromUsername} 将你加为好友了!你们现在互为好友 🎉" - : "💚 {$fromUsername} 将你加为好友了!但你还没有添加对方为好友。", + : "💚 {$fromUsername} 将你加为好友了!但你还没有添加对方为好友。{$btnAdd}", 'removed' => $mutual - ? "💔 {$fromUsername} 已将你从好友列表移除。你的好友列表中仍保留对方。" + ? "💔 {$fromUsername} 已将你从好友列表移除。你的好友列表中仍保留对方。{$btnRemove}" : "💔 {$fromUsername} 已将你从他的好友列表移除。", 'online' => "🟢 你的好友 {$fromUsername} 上线啦!", default => '', diff --git a/resources/views/chat/partials/scripts.blade.php b/resources/views/chat/partials/scripts.blade.php index 0fd79be..2f2472c 100644 --- a/resources/views/chat/partials/scripts.blade.php +++ b/resources/views/chat/partials/scripts.blade.php @@ -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 被点击的 元素,用于更新显示状态 + */ + 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 = `🤖【AI小班长】${data.message || '回复失败,请稍后重试'}`; + errDiv.innerHTML = + `🤖【AI小班长】${data.message || '回复失败,请稍后重试'}`; container.appendChild(errDiv); } } catch (e) {