134 lines
4.8 KiB
JavaScript
134 lines
4.8 KiB
JavaScript
function assertRouter(api) {
|
|
if (
|
|
!api ||
|
|
typeof api.get !== 'function' ||
|
|
typeof api.post !== 'function'
|
|
) {
|
|
throw new Error(
|
|
'attachPortalMindSpaceSpaceRoutes requires an Express-compatible router',
|
|
);
|
|
}
|
|
}
|
|
|
|
export function attachPortalMindSpaceSpaceRoutes(
|
|
api,
|
|
{
|
|
getMindSpace = () => null,
|
|
getScheduleService = () => null,
|
|
getMindSpaceCleanup = () => null,
|
|
getMindSpaceAudit = () => null,
|
|
ensureMindSpaceEnabled = () => false,
|
|
sendData = (res, _req, data) => res.json({ data }),
|
|
sendError = (res, _req, status, code, message) =>
|
|
res.status(status).json({ error: { code, message } }),
|
|
handleMindSpaceError = (_res, _req, error) => {
|
|
throw error;
|
|
},
|
|
} = {},
|
|
) {
|
|
assertRouter(api);
|
|
|
|
api.get('/mindspace/v1/space', async (req, res) => {
|
|
const mindSpace = getMindSpace();
|
|
if (!mindSpace || !ensureMindSpaceEnabled(res, req)) return;
|
|
const space = await mindSpace.getSpace(req.currentUser.id);
|
|
if (!space) {
|
|
return sendError(res, req, 404, 'resource_not_found', '用户空间不存在');
|
|
}
|
|
return sendData(res, req, space);
|
|
});
|
|
|
|
api.post('/mindspace/v1/schedule/reminders/:reminderId/ignore', async (req, res) => {
|
|
const scheduleService = getScheduleService();
|
|
if (!ensureMindSpaceEnabled(res, req) || !scheduleService) {
|
|
return sendError(res, req, 503, 'feature_disabled', '日程服务未启用');
|
|
}
|
|
try {
|
|
const reminder = await scheduleService.cancelReminder({
|
|
userId: req.currentUser.id,
|
|
reminderId: req.params.reminderId,
|
|
});
|
|
return sendData(res, req, reminder);
|
|
} catch (err) {
|
|
const message = err instanceof Error ? err.message : '忽略提醒失败';
|
|
return sendError(res, req, 400, 'invalid_schedule_input', message);
|
|
}
|
|
});
|
|
|
|
api.post('/mindspace/v1/schedule/reminders/bulk-delete', async (req, res) => {
|
|
const scheduleService = getScheduleService();
|
|
if (!ensureMindSpaceEnabled(res, req) || !scheduleService) {
|
|
return sendError(res, req, 503, 'feature_disabled', '日程服务未启用');
|
|
}
|
|
try {
|
|
const ids = Array.isArray(req.body?.ids) ? req.body.ids.map(String) : [];
|
|
const deleted = await scheduleService.deleteReminders({
|
|
userId: req.currentUser.id,
|
|
reminderIds: ids,
|
|
});
|
|
return sendData(res, req, { deleted });
|
|
} catch (err) {
|
|
const message = err instanceof Error ? err.message : '删除提醒失败';
|
|
return sendError(res, req, 400, 'invalid_schedule_input', message);
|
|
}
|
|
});
|
|
|
|
api.get('/mindspace/v1/space/quota', async (req, res) => {
|
|
const mindSpace = getMindSpace();
|
|
if (!mindSpace) return res.status(503).json({ message: 'MindSpace 未启用' });
|
|
const quota = await mindSpace.getQuota(req.currentUser.id);
|
|
if (!quota) return res.status(404).json({ message: '用户空间不存在' });
|
|
return res.json({ data: quota });
|
|
});
|
|
|
|
api.get('/mindspace/v1/space/categories', async (req, res) => {
|
|
const mindSpace = getMindSpace();
|
|
if (!mindSpace) return res.status(503).json({ message: 'MindSpace 未启用' });
|
|
const categories = await mindSpace.listCategories(req.currentUser.id);
|
|
if (!categories) return res.status(404).json({ message: '用户空间不存在' });
|
|
return res.json({ data: categories });
|
|
});
|
|
|
|
api.get('/mindspace/v1/space/cleanup', async (req, res) => {
|
|
const mindSpaceCleanup = getMindSpaceCleanup();
|
|
if (!mindSpaceCleanup || !ensureMindSpaceEnabled(res, req)) return;
|
|
try {
|
|
const username = req.currentUser.username ?? req.currentUser.slug;
|
|
const items = await mindSpaceCleanup.listCandidates(req.currentUser.id, username);
|
|
const totalBytes = items.reduce((sum, item) => sum + item.sizeBytes, 0);
|
|
return sendData(res, req, { items, totalBytes });
|
|
} catch (error) {
|
|
return handleMindSpaceError(res, req, error);
|
|
}
|
|
});
|
|
|
|
api.post('/mindspace/v1/space/cleanup', async (req, res) => {
|
|
const mindSpaceCleanup = getMindSpaceCleanup();
|
|
if (!mindSpaceCleanup || !ensureMindSpaceEnabled(res, req)) return;
|
|
try {
|
|
const username = req.currentUser.username ?? req.currentUser.slug;
|
|
const itemIds = Array.isArray(req.body?.item_ids) ? req.body.item_ids : [];
|
|
const result = await mindSpaceCleanup.runCleanup(
|
|
req.currentUser.id,
|
|
username,
|
|
itemIds,
|
|
);
|
|
const quota = await getMindSpace().getQuota(req.currentUser.id);
|
|
await getMindSpaceAudit()?.write({
|
|
userId: req.currentUser.id,
|
|
action: 'space.cleanup',
|
|
objectType: 'space',
|
|
objectId: req.currentUser.id,
|
|
ip: req.ip,
|
|
detail: {
|
|
removedCount: result.removedCount,
|
|
freedBytes: result.freedBytes,
|
|
},
|
|
});
|
|
return sendData(res, req, { ...result, quota });
|
|
} catch (error) {
|
|
return handleMindSpaceError(res, req, error);
|
|
}
|
|
});
|
|
}
|