100 lines
4.3 KiB
JavaScript
100 lines
4.3 KiB
JavaScript
/* =====================================================================
|
||
* 好友模块(friend.js)
|
||
* 好友申请 / 状态展示 / 博主审批弹窗。
|
||
* ===================================================================== */
|
||
|
||
import { state } from "./state.js";
|
||
import { escapeHtml, formatDate, openModal, showToast } from "./utils.js";
|
||
import { api } from "./api.js";
|
||
import { openLoginModal } from "./auth.js";
|
||
import { renderAuthArea } from "./router.js";
|
||
|
||
export async function applyFriend() {
|
||
if (!state.user) { openLoginModal(); showToast("请先登录后再申请好友", "info"); return; }
|
||
try {
|
||
await api("/api/friend/apply", { method: "POST" });
|
||
state.friendStatus = "pending";
|
||
renderAuthArea();
|
||
showToast("好友申请已提交,等待博主审批", "success");
|
||
} catch (err) {
|
||
showToast(err.message, "error");
|
||
}
|
||
}
|
||
|
||
// 记录当前打开的审批弹窗引用,避免重复打开时弹窗叠加
|
||
let manageModal = null;
|
||
|
||
export function openFriendManageModal() {
|
||
// 先关闭上一次打开的审批弹窗
|
||
if (manageModal) { try { manageModal.close(); } catch (e) { /* 忽略 */ } }
|
||
const body = document.createElement("div");
|
||
body.innerHTML = '<p class="muted">加载中…</p>';
|
||
manageModal = openModal({ title: "好友申请管理", content: body });
|
||
renderApplications(body);
|
||
}
|
||
|
||
export async function openFriendListModal() {
|
||
const body = document.createElement("div");
|
||
body.innerHTML = '<p class="muted">加载中…</p>';
|
||
const modal = openModal({ title: "好友列表", content: body });
|
||
try {
|
||
const friends = await api("/api/friend/list");
|
||
if (!friends.length) { body.innerHTML = '<p class="empty">还没有好友</p>'; return; }
|
||
body.innerHTML = friends.map((f) => `
|
||
<div class="friend-row">
|
||
${f.avatar ? `<img class="friend-avatar" src="${escapeHtml(f.avatar)}" alt="">` : '<span class="friend-avatar friend-avatar-empty"></span>'}
|
||
<div class="friend-info">
|
||
<strong>${escapeHtml(f.username)}</strong>
|
||
<span class="muted">${escapeHtml(f.bio || `成为好友于 ${formatDate(f.friend_since)}`)}</span>
|
||
</div>
|
||
</div>`).join("");
|
||
} catch (err) {
|
||
body.innerHTML = "";
|
||
showToast(err.message, "error");
|
||
}
|
||
}
|
||
|
||
export async function renderApplications(body) {
|
||
try {
|
||
const records = await api("/api/friend/applications");
|
||
if (!records.length) { body.innerHTML = '<p class="empty">暂无申请记录</p>'; return; }
|
||
body.innerHTML = "";
|
||
const STATUS_TEXT = { pending: "待审批", accepted: "已通过", rejected: "已拒绝" };
|
||
for (const record of records) {
|
||
const row = document.createElement("div");
|
||
row.className = "app-row";
|
||
const statusText = STATUS_TEXT[record.status] || record.status;
|
||
row.innerHTML = `
|
||
<span class="app-user">${escapeHtml(record.username || "未知用户")}</span>
|
||
<span class="app-email muted">${escapeHtml(record.email || "")}</span>
|
||
<span class="app-time muted">${formatDate(record.created_time)}</span>
|
||
<span class="app-status">${statusText}</span>`;
|
||
if (record.status === "pending") {
|
||
const approveBtn = document.createElement("button");
|
||
approveBtn.className = "btn btn-primary btn-sm"; approveBtn.textContent = "通过";
|
||
approveBtn.addEventListener("click", async () => {
|
||
try {
|
||
await api(`/api/friend/${record.id}/approve`, { method: "POST" });
|
||
showToast("已通过好友申请", "success");
|
||
await renderApplications(body); // 原地刷新当前弹窗内容,不再叠加新弹窗
|
||
} catch (err) { showToast(err.message, "error"); }
|
||
});
|
||
const rejectBtn = document.createElement("button");
|
||
rejectBtn.className = "btn btn-outline btn-sm"; rejectBtn.textContent = "拒绝";
|
||
rejectBtn.addEventListener("click", async () => {
|
||
try {
|
||
await api(`/api/friend/${record.id}/reject`, { method: "POST" });
|
||
showToast("已拒绝好友申请");
|
||
await renderApplications(body); // 原地刷新当前弹窗内容,不再叠加新弹窗
|
||
} catch (err) { showToast(err.message, "error"); }
|
||
});
|
||
row.appendChild(approveBtn);
|
||
row.appendChild(rejectBtn);
|
||
}
|
||
body.appendChild(row);
|
||
}
|
||
} catch (err) {
|
||
body.innerHTML = "";
|
||
showToast(err.message, "error");
|
||
}
|
||
} |