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) {