/** * 知资札记 - 文章详情页逻辑 */ (function () { 'use strict'; const API_BASE = '/api/zhizi_notes'; const STORAGE_KEY = 'zhizi_notes_theme'; const $ = function (sel) { return document.querySelector(sel); }; let articleId = null; let isFavorited = false; // ── 解析 URL 参数 ── function getParam(name) { const params = new URLSearchParams(window.location.search); return params.get(name); } // ── Toast ── function showToast(msg, type) { type = type || 'info'; const t = $('#zd-toast'); if (!t) return; t.textContent = msg; t.className = 'zs-toast ' + type + ' show'; clearTimeout(t._timer); t._timer = setTimeout(function () { t.classList.remove('show'); }, type === 'error' ? 4000 : 2000); } // ── 暗黑模式 ── function initTheme() { const saved = localStorage.getItem(STORAGE_KEY); if (saved === 'dark') { document.documentElement.setAttribute('data-theme', 'dark'); } const btn = $('#zs-theme-btn'); if (btn) { btn.textContent = saved === 'dark' ? '☀️' : '🌙'; btn.addEventListener('click', function () { const isDark = document.documentElement.getAttribute('data-theme') === 'dark'; if (isDark) { document.documentElement.removeAttribute('data-theme'); localStorage.setItem(STORAGE_KEY, 'light'); btn.textContent = '🌙'; } else { document.documentElement.setAttribute('data-theme', 'dark'); localStorage.setItem(STORAGE_KEY, 'dark'); btn.textContent = '☀️'; } }); } } // ── API ── async function apiGet(path) { try { const res = await fetch(API_BASE + path, { credentials: 'same-origin' }); return await res.json(); } catch (e) { return { ok: false, error: e.message }; } } async function apiPost(path, body) { try { const res = await fetch(API_BASE + path, { method: 'POST', headers: { 'Content-Type': 'application/json' }, credentials: 'same-origin', body: JSON.stringify(body) }); return await res.json(); } catch (e) { return { ok: false, error: e.message }; } } // ── 加载详情 ── async function loadDetail() { articleId = getParam('id'); if (!articleId) { showError('缺少文章ID'); return; } const data = await apiGet('/articles/' + articleId); const loading = $('#zd-loading'); if (loading) loading.style.display = 'none'; if (!data.ok) { showError(data.error || '文章不存在'); return; } renderArticle(data.data); } function showError(msg) { const loading = $('#zd-loading'); const error = $('#zd-error'); if (loading) loading.style.display = 'none'; if (error) { error.style.display = 'block'; $('#zd-error-msg').textContent = msg; } } // ── 渲染文章 ── function renderArticle(article) { const articleEl = $('#zd-article'); if (!articleEl) return; articleEl.style.display = 'block'; // 标题 $('#zd-title').textContent = article.title; document.title = article.title + ' · 知资札记'; // 元信息 $('#zd-category').textContent = article.category || '未分类'; $('#zd-source').textContent = article.source ? '来源:' + article.source : ''; $('#zd-date').textContent = (article.created_at || '').slice(0, 10); $('#zd-views').textContent = (article.views || 0) + ' 阅读'; // 收藏按钮 isFavorited = article.fav_count > 0; updateFavBtn(); const favBtn = $('#zd-fav-btn'); if (favBtn) { favBtn.addEventListener('click', function () { toggleFavorite(); }); } // 标签 const tagsEl = $('#zd-tags'); try { const tags = JSON.parse(article.tags_json || '[]'); if (tags.length > 0 && tagsEl) { tagsEl.innerHTML = ''; tags.forEach(function (t) { const span = document.createElement('span'); span.className = 'zd-tag'; span.textContent = t; tagsEl.appendChild(span); }); } else if (tagsEl) { tagsEl.style.display = 'none'; } } catch (e) { if (tagsEl) tagsEl.style.display = 'none'; } // 封面图 if (article.cover_url) { const cover = $('#zd-cover'); const coverImg = $('#zd-cover-img'); if (cover) cover.style.display = 'block'; if (coverImg) coverImg.src = article.cover_url; } // 正文 const contentEl = $('#zd-content'); if (contentEl) { contentEl.innerHTML = article.content || article.content_plain || ''; } // 图片集 if (article.images && article.images.length > 0) { const gallery = $('#zd-gallery'); const grid = $('#zd-gallery-grid'); if (gallery) gallery.style.display = 'block'; if (grid) { grid.innerHTML = ''; article.images.forEach(function (img) { const item = document.createElement('div'); item.className = 'gallery-item'; const imgEl = document.createElement('img'); imgEl.src = '/uploads/zhizi_notes/' + img.filename; imgEl.alt = img.original_name || ''; imgEl.loading = 'lazy'; item.appendChild(imgEl); grid.appendChild(item); }); } } } // ── 收藏切换 ── async function toggleFavorite() { const data = await apiPost('/articles/' + articleId + '/toggle_favorite', {}); if (data.ok) { isFavorited = data.data ? data.data.favorited : !isFavorited; updateFavBtn(); showToast(isFavorited ? '已收藏' : '已取消收藏', isFavorited ? 'success' : 'info'); } else { showToast('操作失败:' + (data.error || '未知错误'), 'error'); } } function updateFavBtn() { const btn = $('#zd-fav-btn'); if (!btn) return; if (isFavorited) { btn.classList.add('favorited'); btn.textContent = '♥'; } else { btn.classList.remove('favorited'); btn.textContent = '♡'; } } // ── 初始化 ── function init() { initTheme(); loadDetail(); // 返回按钮 const backBtn = $('#zd-back'); if (backBtn) { backBtn.addEventListener('click', function () { if (document.referrer && document.referrer.indexOf('/tools/zhizi_notes') !== -1) { history.back(); } else { location.href = '/tools/zhizi_notes/index.html'; } }); } } document.addEventListener('DOMContentLoaded', init); })();