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:
@@ -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) {
|
||||
|
||||
@@ -165,6 +165,12 @@ export async function bootstrapAdminServices() {
|
||||
getPlanAsync: (planType) => planCatalogService.getPlan(planType),
|
||||
});
|
||||
subscriptionService._planCatalogService = planCatalogService;
|
||||
const { createPageTemplateCatalogService } = await importMemind('page-template-catalog.mjs');
|
||||
const templateCatalogService = createPageTemplateCatalogService(pool, {
|
||||
userAuth,
|
||||
h5Root,
|
||||
});
|
||||
await templateCatalogService.ensureReady();
|
||||
await ensureSystemTestAccountSchema(pool);
|
||||
const systemTestAccountService = createSystemTestAccountService(pool);
|
||||
|
||||
@@ -196,6 +202,7 @@ export async function bootstrapAdminServices() {
|
||||
wordFilterService,
|
||||
planCatalogService,
|
||||
subscriptionService,
|
||||
templateCatalogService,
|
||||
USER_COOKIE,
|
||||
userLoginCookies,
|
||||
clearUserSessionCookie,
|
||||
|
||||
@@ -117,6 +117,7 @@ ready
|
||||
wordFilterService,
|
||||
planCatalogService,
|
||||
subscriptionService,
|
||||
templateCatalogService,
|
||||
planSyncService,
|
||||
USER_COOKIE,
|
||||
userLoginCookies,
|
||||
@@ -146,6 +147,7 @@ ready
|
||||
wordFilterService,
|
||||
planCatalogService,
|
||||
subscriptionService,
|
||||
templateCatalogService,
|
||||
planSyncService,
|
||||
USER_COOKIE,
|
||||
userLoginCookies,
|
||||
|
||||
Reference in New Issue
Block a user