feat: add chat page export actions

This commit is contained in:
john
2026-07-02 19:52:26 +08:00
parent 2d777ef394
commit ddfa60607a
7 changed files with 544 additions and 17 deletions
+37
View File
@@ -109,6 +109,7 @@ import {
renderLongImage,
renderLongImageBuffer,
} from './mindspace-long-image.mjs';
import { generateDocxBuffer } from './mindspace-docx-export.mjs';
import { scanContent } from './mindspace-content-scan.mjs';
import { renderImageAssetViewerHtml, wantsInlineImageViewer } from './mindspace-asset-preview.mjs';
import { createRechargeService } from './billing-recharge.mjs';
@@ -219,6 +220,7 @@ function csrfOriginCheck(req, res, next) {
app.use('/api', csrfOriginCheck);
app.use('/auth', csrfOriginCheck);
app.use('/mindspace', csrfOriginCheck);
const jsonBody = express.json({ limit: '1mb' });
const jsonUnlessMultipart = (req, res, next) => {
@@ -3132,6 +3134,40 @@ api.post('/mindspace/v1/pages/quick-share-from-chat', async (req, res) => {
}
});
async function handleChatSaveDocx(req, res) {
if (!mindSpacePages) return res.status(503).json({ message: 'MindSpace 未启用' });
try {
const bundle = await resolveChatSaveBundle(req.currentUser, __dirname, req.body);
const title =
bundle.previewTitle ||
bundle.resolvedHtml?.suggestedTitle ||
bundle.analysis?.suggestedTitle ||
'AI 创作文档';
const content = bundle.resolvedHtml?.content ?? bundle.source.content;
const contentFormat = bundle.resolvedHtml?.content ? 'html' : 'markdown';
const buffer = generateDocxBuffer({ title, content, contentFormat });
const filenameBase = String(title)
.replace(/[\\/:*?"<>|]+/g, '-')
.replace(/\s+/g, '-')
.replace(/^-+|-+$/g, '')
.slice(0, 60) || 'mindspace-document';
const filename = `${filenameBase}.docx`;
res.set('Content-Type', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document');
res.set(
'Content-Disposition',
`attachment; filename="${encodeURIComponent(filename)}"; filename*=UTF-8''${encodeURIComponent(filename)}`,
);
res.set('Cache-Control', 'no-store');
res.setHeader('X-Request-Id', req.requestId);
return res.send(buffer);
} catch (error) {
return mindSpaceError(res, req, error);
}
}
api.post('/mindspace/v1/pages/chat-save-docx', handleChatSaveDocx);
api.post('/v1/pages/chat-save-docx', handleChatSaveDocx);
api.post('/mindspace/v1/pages/save-from-chat', async (req, res) => {
if (!mindSpacePages || !mindSpaceAssets) {
return res.status(503).json({ message: 'MindSpace 未启用' });
@@ -4458,6 +4494,7 @@ api.use(
);
app.use('/api', api);
app.use('/mindspace', api);
function scriptSrcDirective({ inline = false, urls = [], hashes = [] } = {}) {
const parts = [];