feat(admin): add ephemeral staging DB, read-only posts overview, and dynamic search
- Implement ephemeral staging mode (APP_ENV=staging) to isolate test/dev DB writes in /tmp - Add read-only posts management dashboard under /guanli/posts with live links and comment counters - Add hot re-indexing endpoint (/guanli/reindex) to refresh Markdown without restarting server - Replace static recommended search config with dynamic frequency-based trending searches - Remove early scaffold mockup file (dropbox/zh.md) and clean legacy mock test queries - Add native Makefile with dev, dev-persistent, test, lint, and docker targets - Update test suite and documentation for development workflows
This commit is contained in:
@@ -102,6 +102,57 @@ router.get('/guanli/logout', (req, res) => {
|
||||
|
||||
const dbService = require('../services/db');
|
||||
|
||||
// 0. Posts Read-Only Overview Dashboard
|
||||
router.get('/guanli/posts', requireAdminAuth, (req, res) => {
|
||||
const q = (req.query.q || '').trim().toLowerCase();
|
||||
const activeCategory = (req.query.category || '').trim();
|
||||
|
||||
const allPosts = contentService.getAllPosts();
|
||||
let filteredPosts = allPosts;
|
||||
|
||||
if (activeCategory) {
|
||||
filteredPosts = filteredPosts.filter(p => (p.category || '').toLowerCase() === activeCategory.toLowerCase());
|
||||
}
|
||||
|
||||
if (q) {
|
||||
filteredPosts = filteredPosts.filter(p =>
|
||||
(p.title || '').toLowerCase().includes(q) ||
|
||||
(p.slug || '').toLowerCase().includes(q) ||
|
||||
(p.tags || []).some(t => t.toLowerCase().includes(q))
|
||||
);
|
||||
}
|
||||
|
||||
const taxonomy = contentService.getTaxonomy();
|
||||
const commentStats = dbService.getPostCommentStats();
|
||||
const stats = dbService.getAdminStats();
|
||||
|
||||
res.render('pages/admin-posts', {
|
||||
title: 'Posts Overview - Site Administration',
|
||||
posts: allPosts,
|
||||
filteredPosts,
|
||||
categories: taxonomy.categories,
|
||||
activeCategory,
|
||||
q: req.query.q || '',
|
||||
commentStats,
|
||||
stats
|
||||
});
|
||||
});
|
||||
|
||||
// Hot Content Re-index & Cache Flush endpoint
|
||||
router.post('/guanli/reindex', requireAdminAuth, (req, res) => {
|
||||
try {
|
||||
const { CONTENT_DIR } = require('../config');
|
||||
contentService.init(CONTENT_DIR);
|
||||
pageCache.clear();
|
||||
const totalPosts = contentService.getAllPosts().length;
|
||||
const totalPages = contentService.pagesBySlug.size;
|
||||
res.json({ success: true, totalPosts, totalPages });
|
||||
} catch (err) {
|
||||
console.error('[Admin] Hot re-index failed:', err);
|
||||
res.status(500).json({ success: false, error: err.message });
|
||||
}
|
||||
});
|
||||
|
||||
// 1. Comment Moderation Dashboard
|
||||
router.get('/guanli/comments', requireAdminAuth, (req, res) => {
|
||||
const status = req.query.status || 'all';
|
||||
|
||||
Reference in New Issue
Block a user