419 lines
12 KiB
JavaScript
419 lines
12 KiB
JavaScript
function assertRouter(api) {
|
|
if (
|
|
!api ||
|
|
typeof api.get !== 'function' ||
|
|
typeof api.post !== 'function' ||
|
|
typeof api.put !== 'function' ||
|
|
typeof api.delete !== 'function'
|
|
) {
|
|
throw new Error(
|
|
'attachPortalMindSpacePageCoreRoutes requires an Express-compatible router',
|
|
);
|
|
}
|
|
}
|
|
|
|
export function attachPortalMindSpacePageCoreRoutes(
|
|
api,
|
|
{
|
|
getMindSpacePages = () => null,
|
|
getMindSpacePublications = () => null,
|
|
getMindSpace = () => null,
|
|
getMindSpaceAudit = () => null,
|
|
getMindSpacePageLiveEdit = () => null,
|
|
getMindSpacePageEditSession = () => null,
|
|
getUserAuth = () => null,
|
|
syncUserGeneratedPages,
|
|
ownsAgentSession,
|
|
ensureMindSpaceEnabled,
|
|
sendData,
|
|
sendError,
|
|
handleMindSpaceError,
|
|
} = {},
|
|
) {
|
|
assertRouter(api);
|
|
if (
|
|
typeof syncUserGeneratedPages !== 'function' ||
|
|
typeof ownsAgentSession !== 'function' ||
|
|
typeof ensureMindSpaceEnabled !== 'function' ||
|
|
typeof sendData !== 'function' ||
|
|
typeof sendError !== 'function' ||
|
|
typeof handleMindSpaceError !== 'function'
|
|
) {
|
|
throw new Error(
|
|
'attachPortalMindSpacePageCoreRoutes requires page route dependencies',
|
|
);
|
|
}
|
|
|
|
api.post('/mindspace/v1/pages', async (req, res) => {
|
|
const pages = getMindSpacePages();
|
|
if (!pages) {
|
|
return res.status(503).json({ message: 'MindSpace 未启用' });
|
|
}
|
|
try {
|
|
const page = await pages.createPage(req.currentUser.id, {
|
|
title: req.body?.title,
|
|
summary: req.body?.summary,
|
|
content: req.body?.content,
|
|
contentFormat:
|
|
req.body?.content_format === 'html' ? 'html' : undefined,
|
|
templateId: req.body?.template_id,
|
|
pageType: req.body?.page_type,
|
|
categoryCode: req.body?.category_code,
|
|
});
|
|
return res.status(201).json({ data: page });
|
|
} catch (error) {
|
|
return handleMindSpaceError(res, req, error);
|
|
}
|
|
});
|
|
|
|
api.get('/mindspace/v1/pages', async (req, res) => {
|
|
const pages = getMindSpacePages();
|
|
if (!pages) {
|
|
return res.status(503).json({ message: 'MindSpace 未启用' });
|
|
}
|
|
try {
|
|
await syncUserGeneratedPages(req.currentUser.id);
|
|
const limit = Number.parseInt(String(req.query.limit ?? ''), 10);
|
|
const offset = Number.parseInt(String(req.query.offset ?? ''), 10);
|
|
const result = await pages.listPages(req.currentUser.id, {
|
|
status:
|
|
typeof req.query.status === 'string'
|
|
? req.query.status
|
|
: undefined,
|
|
categoryCode:
|
|
typeof req.query.category_code === 'string'
|
|
? req.query.category_code
|
|
: undefined,
|
|
...(Number.isFinite(limit) ? { limit } : {}),
|
|
...(Number.isFinite(offset) ? { offset } : {}),
|
|
});
|
|
return res.json({
|
|
data: result.items,
|
|
page: {
|
|
total: result.total,
|
|
limit: result.limit,
|
|
offset: result.offset,
|
|
has_more: result.hasMore,
|
|
next_cursor: null,
|
|
},
|
|
});
|
|
} catch (error) {
|
|
return handleMindSpaceError(res, req, error);
|
|
}
|
|
});
|
|
|
|
api.get('/mindspace/v1/pages/:pageId', async (req, res) => {
|
|
const pages = getMindSpacePages();
|
|
if (!pages) {
|
|
return res.status(503).json({ message: 'MindSpace 未启用' });
|
|
}
|
|
try {
|
|
const [page, versions, publication] = await Promise.all([
|
|
pages.getPage(req.currentUser.id, req.params.pageId),
|
|
pages.listVersions(req.currentUser.id, req.params.pageId),
|
|
getMindSpacePublications()?.getCurrent(
|
|
req.currentUser.id,
|
|
req.params.pageId,
|
|
) ?? null,
|
|
]);
|
|
return res.json({
|
|
data: {
|
|
...page,
|
|
versions,
|
|
publication,
|
|
},
|
|
});
|
|
} catch (error) {
|
|
return handleMindSpaceError(res, req, error);
|
|
}
|
|
});
|
|
|
|
api.delete('/mindspace/v1/pages/:pageId', async (req, res) => {
|
|
const pages = getMindSpacePages();
|
|
if (!pages || !ensureMindSpaceEnabled(res, req)) return;
|
|
try {
|
|
const removeFromPlaza =
|
|
String(
|
|
req.query?.remove_from_plaza ??
|
|
req.body?.remove_from_plaza ??
|
|
'',
|
|
).toLowerCase() === 'true' ||
|
|
req.query?.remove_from_plaza === '1' ||
|
|
req.body?.remove_from_plaza === true;
|
|
const result = await pages.deletePage(
|
|
req.currentUser.id,
|
|
req.params.pageId,
|
|
{ removeFromPlaza },
|
|
);
|
|
const quota = await getMindSpace().getQuota(req.currentUser.id);
|
|
await getMindSpaceAudit()?.write({
|
|
userId: req.currentUser.id,
|
|
action: 'page.delete',
|
|
objectType: 'page',
|
|
objectId: req.params.pageId,
|
|
ip: req.ip,
|
|
detail: {
|
|
offlinedPublicationCount:
|
|
result.offlinedPublicationCount,
|
|
hiddenPlazaPostCount: result.hiddenPlazaPostCount,
|
|
deletedAssetCount: result.deletedAssetCount,
|
|
freedBytes: result.freedBytes,
|
|
},
|
|
});
|
|
return sendData(res, req, { ...result, quota });
|
|
} catch (error) {
|
|
return handleMindSpaceError(res, req, error);
|
|
}
|
|
});
|
|
|
|
api.get(
|
|
'/mindspace/v1/pages/:pageId/delete-preview',
|
|
async (req, res) => {
|
|
const pages = getMindSpacePages();
|
|
if (!pages || !ensureMindSpaceEnabled(res, req)) return;
|
|
try {
|
|
return sendData(
|
|
res,
|
|
req,
|
|
await pages.getDeletePreview(
|
|
req.currentUser.id,
|
|
req.params.pageId,
|
|
),
|
|
);
|
|
} catch (error) {
|
|
return handleMindSpaceError(res, req, error);
|
|
}
|
|
},
|
|
);
|
|
|
|
api.put('/mindspace/v1/pages/:pageId', async (req, res) => {
|
|
const pages = getMindSpacePages();
|
|
if (!pages) {
|
|
return res.status(503).json({ message: 'MindSpace 未启用' });
|
|
}
|
|
try {
|
|
const page = await pages.updatePage(
|
|
req.currentUser.id,
|
|
req.params.pageId,
|
|
{
|
|
expectedVersion: req.body?.expected_version,
|
|
title: req.body?.title,
|
|
summary: req.body?.summary,
|
|
content: req.body?.content,
|
|
templateId: req.body?.template_id,
|
|
pageType: req.body?.page_type,
|
|
changeNote: req.body?.change_note,
|
|
},
|
|
);
|
|
return res.json({ data: page });
|
|
} catch (error) {
|
|
return handleMindSpaceError(res, req, error);
|
|
}
|
|
});
|
|
|
|
api.post(
|
|
'/mindspace/v1/pages/:pageId/live-edit/bind',
|
|
async (req, res) => {
|
|
const pageLiveEdit = getMindSpacePageLiveEdit();
|
|
const pages = getMindSpacePages();
|
|
if (!pageLiveEdit || !pages) {
|
|
return res.status(503).json({ message: 'MindSpace 未启用' });
|
|
}
|
|
try {
|
|
const sessionId = String(req.body?.session_id ?? '').trim();
|
|
if (!sessionId) {
|
|
return sendError(
|
|
res,
|
|
req,
|
|
400,
|
|
'invalid_request',
|
|
'缺少 session_id',
|
|
);
|
|
}
|
|
const owns = await ownsAgentSession(
|
|
req.currentUser.id,
|
|
sessionId,
|
|
);
|
|
if (!owns) {
|
|
return sendError(
|
|
res,
|
|
req,
|
|
403,
|
|
'forbidden',
|
|
'无权绑定该 Agent 会话',
|
|
);
|
|
}
|
|
await pages.getPage(
|
|
req.currentUser.id,
|
|
req.params.pageId,
|
|
);
|
|
const parentSessionId =
|
|
String(req.body?.parent_session_id ?? '').trim() || null;
|
|
return sendData(
|
|
res,
|
|
req,
|
|
pageLiveEdit.bindSession({
|
|
userId: req.currentUser.id,
|
|
sessionId,
|
|
pageId: req.params.pageId,
|
|
parentSessionId,
|
|
}),
|
|
);
|
|
} catch (error) {
|
|
return handleMindSpaceError(res, req, error);
|
|
}
|
|
},
|
|
);
|
|
|
|
api.post(
|
|
'/mindspace/v1/pages/:pageId/live-edit/fork-session',
|
|
async (req, res) => {
|
|
const pageEditSession = getMindSpacePageEditSession();
|
|
if (!pageEditSession || !getMindSpacePages()) {
|
|
return res.status(503).json({ message: 'MindSpace 未启用' });
|
|
}
|
|
try {
|
|
const parentSessionId = String(
|
|
req.body?.parent_session_id ?? '',
|
|
).trim();
|
|
if (!parentSessionId) {
|
|
return sendError(
|
|
res,
|
|
req,
|
|
400,
|
|
'invalid_request',
|
|
'缺少 parent_session_id',
|
|
);
|
|
}
|
|
const gate = await getUserAuth().canUseChat(
|
|
req.currentUser.id,
|
|
);
|
|
if (!gate.ok) {
|
|
return sendError(
|
|
res,
|
|
req,
|
|
402,
|
|
gate.code ?? 'insufficient_balance',
|
|
gate.message,
|
|
);
|
|
}
|
|
return sendData(
|
|
res,
|
|
req,
|
|
await pageEditSession.forkSession({
|
|
userId: req.currentUser.id,
|
|
pageId: req.params.pageId,
|
|
parentSessionId,
|
|
h5ApiBase:
|
|
String(
|
|
req.body?.h5_api_base ??
|
|
req.body?.h5ApiBase ??
|
|
'',
|
|
).trim() || null,
|
|
}),
|
|
);
|
|
} catch (error) {
|
|
if (error?.code === 'forbidden') {
|
|
return sendError(
|
|
res,
|
|
req,
|
|
403,
|
|
error.code,
|
|
error.message,
|
|
);
|
|
}
|
|
if (error?.code === 'invalid_request') {
|
|
return sendError(
|
|
res,
|
|
req,
|
|
400,
|
|
error.code,
|
|
error.message,
|
|
);
|
|
}
|
|
return handleMindSpaceError(res, req, error);
|
|
}
|
|
},
|
|
);
|
|
|
|
api.post(
|
|
'/mindspace/v1/pages/:pageId/live-edit/close-session',
|
|
async (req, res) => {
|
|
const pageEditSession = getMindSpacePageEditSession();
|
|
if (!pageEditSession || !getMindSpacePages()) {
|
|
return res.status(503).json({ message: 'MindSpace 未启用' });
|
|
}
|
|
try {
|
|
const sessionId = String(req.body?.session_id ?? '').trim();
|
|
if (!sessionId) {
|
|
return sendError(
|
|
res,
|
|
req,
|
|
400,
|
|
'invalid_request',
|
|
'缺少 session_id',
|
|
);
|
|
}
|
|
return sendData(
|
|
res,
|
|
req,
|
|
await pageEditSession.closeSession({
|
|
userId: req.currentUser.id,
|
|
pageId: req.params.pageId,
|
|
sessionId,
|
|
parentSessionId:
|
|
String(req.body?.parent_session_id ?? '').trim() ||
|
|
null,
|
|
summary: String(req.body?.summary ?? ''),
|
|
}),
|
|
);
|
|
} catch (error) {
|
|
if (
|
|
error?.code === 'forbidden' ||
|
|
error?.code === 'page_binding_mismatch'
|
|
) {
|
|
return sendError(
|
|
res,
|
|
req,
|
|
403,
|
|
error.code,
|
|
error.message,
|
|
);
|
|
}
|
|
if (error?.code === 'invalid_request') {
|
|
return sendError(
|
|
res,
|
|
req,
|
|
400,
|
|
error.code,
|
|
error.message,
|
|
);
|
|
}
|
|
return handleMindSpaceError(res, req, error);
|
|
}
|
|
},
|
|
);
|
|
|
|
api.get(
|
|
'/mindspace/v1/pages/:pageId/live-edit/revision',
|
|
async (req, res) => {
|
|
const pageLiveEdit = getMindSpacePageLiveEdit();
|
|
if (!pageLiveEdit || !getMindSpacePages()) {
|
|
return res.status(503).json({ message: 'MindSpace 未启用' });
|
|
}
|
|
try {
|
|
return sendData(
|
|
res,
|
|
req,
|
|
await pageLiveEdit.getRevisionSnapshot(
|
|
req.currentUser.id,
|
|
req.params.pageId,
|
|
),
|
|
);
|
|
} catch (error) {
|
|
return handleMindSpaceError(res, req, error);
|
|
}
|
|
},
|
|
);
|
|
}
|