feat(admin): add MindSpace SEO/GEO controls and template catalog page

Expose SEO/GEO switches on the MindSpace config form and add template catalog management UI wired to shared Memind modules.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
john
2026-08-10 08:06:21 +08:00
parent 7120d4b5ea
commit ed8bc6d1b1
13 changed files with 768 additions and 16 deletions
+29
View File
@@ -111,6 +111,7 @@ export function createAdminApp(services) {
wordFilterService,
planCatalogService,
subscriptionService,
templateCatalogService,
planSyncService,
} = services;
const app = express();
@@ -377,6 +378,7 @@ export function createAdminApp(services) {
if (!updateMindSpaceConfig) return res.status(503).json({ message: 'MindSpace 配置未启用' });
const result = await updateMindSpaceConfig(pool, {
publicPageLimit: req.body?.publicPageLimit,
seoGeo: req.body?.seoGeo,
analytics: req.body?.analytics,
});
res.json({ config: result });
@@ -1317,6 +1319,33 @@ export function createAdminApp(services) {
res.json(result);
});
// ── Page template catalog ─────────────────────────────────────────────────
adminApi.get('/template-catalog', requireAdmin, async (_req, res) => {
if (!templateCatalogService?.adminListCatalog) {
return res.status(503).json({ message: '模板商城未启用' });
}
res.json({ items: await templateCatalogService.adminListCatalog() });
});
adminApi.put('/template-catalog/:skillName', requireAdmin, async (req, res) => {
if (!templateCatalogService?.adminUpsertCatalog) {
return res.status(503).json({ message: '模板商城未启用' });
}
const result = await templateCatalogService.adminUpsertCatalog(req.params.skillName, req.body ?? {});
if (!result.ok) return res.status(400).json({ message: result.message });
res.json(result);
});
adminApi.post('/users/:userId/template-grants/:skillName', requireAdmin, async (req, res) => {
if (!templateCatalogService?.adminGrantTemplate) {
return res.status(503).json({ message: '模板商城未启用' });
}
const result = await templateCatalogService.adminGrantTemplate(req.params.userId, req.params.skillName);
if (!result.ok) return res.status(400).json({ message: result.message });
res.json(result);
});
app.use('/admin-api', adminApi);
if (services.createOpsApi) {