feat(mindspace): 全部页面管理、级联删除与页面同步去重
支持全部页面分页/多选/删除/分享,删除时可选移除广场帖并清理工作区附件;修复并发同步重复创建页面,并补齐预览下载链接重写与 iframe 下载权限。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+29
-1
@@ -35,6 +35,23 @@ function extractHtmlSummary(content) {
|
||||
return match?.[1]?.trim().slice(0, 1000) ?? '';
|
||||
}
|
||||
|
||||
async function findPageByWorkspaceRelativePath(pool, userId, relativePath) {
|
||||
const [rows] = await pool.query(
|
||||
`SELECT p.id, p.updated_at
|
||||
FROM h5_page_records p
|
||||
JOIN h5_page_versions pv ON pv.id = p.current_version_id
|
||||
WHERE p.user_id = ?
|
||||
AND p.status <> 'deleted'
|
||||
AND JSON_UNQUOTE(JSON_EXTRACT(pv.source_snapshot_json, '$.relative_path')) = ?
|
||||
ORDER BY p.updated_at DESC, p.id DESC
|
||||
LIMIT 1`,
|
||||
[userId, relativePath],
|
||||
);
|
||||
const row = rows[0];
|
||||
if (!row) return null;
|
||||
return { id: row.id, updatedAt: Number(row.updated_at ?? 0) };
|
||||
}
|
||||
|
||||
async function loadIndexedWorkspacePages(pool, userId) {
|
||||
const [rows] = await pool.query(
|
||||
`SELECT p.id, p.updated_at, p.source_asset_id, pv.source_snapshot_json
|
||||
@@ -99,6 +116,7 @@ async function listPublishPublicHtmlFiles(publishDir) {
|
||||
}
|
||||
|
||||
async function upsertWorkspaceHtmlPage({
|
||||
pool,
|
||||
pageService,
|
||||
userId,
|
||||
indexedPages,
|
||||
@@ -109,10 +127,18 @@ async function upsertWorkspaceHtmlPage({
|
||||
}) {
|
||||
const title = extractHtmlTitle(content) || titleFromRelativePath(relativePath);
|
||||
const summary = extractHtmlSummary(content);
|
||||
const existing =
|
||||
let existing =
|
||||
indexedPages.get(relativePath) ??
|
||||
(assetId ? indexedPages.get(`asset:${assetId}`) : null);
|
||||
|
||||
if (!existing && pool) {
|
||||
existing = await findPageByWorkspaceRelativePath(pool, userId, relativePath);
|
||||
if (existing) {
|
||||
indexedPages.set(relativePath, existing);
|
||||
if (assetId) indexedPages.set(`asset:${assetId}`, existing);
|
||||
}
|
||||
}
|
||||
|
||||
const pageInput = {
|
||||
title,
|
||||
summary,
|
||||
@@ -186,6 +212,7 @@ export async function syncGeneratedPagesFromPublicAssets({
|
||||
continue;
|
||||
}
|
||||
const result = await upsertWorkspaceHtmlPage({
|
||||
pool,
|
||||
pageService,
|
||||
userId,
|
||||
indexedPages,
|
||||
@@ -237,6 +264,7 @@ export async function syncGeneratedPagesFromPublicAssets({
|
||||
const { path: assetPath } = await assetService.readAsset(userId, asset.id);
|
||||
const content = await fs.readFile(assetPath, 'utf8');
|
||||
const result = await upsertWorkspaceHtmlPage({
|
||||
pool,
|
||||
pageService,
|
||||
userId,
|
||||
indexedPages,
|
||||
|
||||
Reference in New Issue
Block a user