feat(mindspace): 公开页分享组件、workspace 路径与 Plaza 发布增强

- 新增 public share widget 与 workspace relative path 解析
- 增强 publications/chat-plaza 发布链路与缩略图 demo
- 补充 schema、cover 检查脚本与回归测试

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
john
2026-07-05 23:14:41 +08:00
parent 69be1e5293
commit e2ad3bf62b
39 changed files with 2184 additions and 256 deletions
+48 -5
View File
@@ -446,6 +446,8 @@ export function createPageService(pool, options = {}) {
source.createdAt != null && Number.isFinite(Number(source.createdAt))
? Math.floor(Number(source.createdAt))
: Date.now();
const pageWorkspaceRelativePath =
normalizeWorkspaceRelativePath(source.snapshot?.relative_path) || null;
const contentAssetType = normalized.contentFormat === 'html' ? 'html' : 'markdown';
const contentMimeType =
@@ -498,8 +500,8 @@ export function createPageService(pool, options = {}) {
`INSERT INTO h5_page_records
(id, user_id, space_id, category_id, source_session_id, source_message_id,
source_asset_id, title, summary, page_type, template_id, draft_content_ref,
current_version_id, status, visibility, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'draft', 'private', ?, ?)`,
workspace_relative_path, current_version_id, status, visibility, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'draft', 'private', ?, ?)`,
[
pageId,
userId,
@@ -513,6 +515,7 @@ export function createPageService(pool, options = {}) {
normalized.pageType,
normalized.templateId,
stored.storageKey,
pageWorkspaceRelativePath,
pageVersionId,
now,
now,
@@ -539,7 +542,7 @@ export function createPageService(pool, options = {}) {
await conn.query(
`UPDATE h5_page_records
SET title = ?, summary = ?, page_type = ?, template_id = ?,
draft_content_ref = ?, current_version_id = ?, updated_at = ?
draft_content_ref = ?, workspace_relative_path = ?, current_version_id = ?, updated_at = ?
WHERE id = ? AND user_id = ?`,
[
normalized.title,
@@ -547,6 +550,7 @@ export function createPageService(pool, options = {}) {
normalized.pageType,
normalized.templateId,
stored.storageKey,
pageWorkspaceRelativePath,
pageVersionId,
now,
pageId,
@@ -659,14 +663,52 @@ export function createPageService(pool, options = {}) {
LEFT JOIN h5_publish_records pr ON pr.id = p.current_publish_id AND pr.status = 'online'
WHERE p.user_id = ?
AND p.status <> 'deleted'
AND JSON_UNQUOTE(JSON_EXTRACT(pv.source_snapshot_json, '$.relative_path')) = ?
AND (
p.workspace_relative_path = ?
OR (
(p.workspace_relative_path IS NULL OR p.workspace_relative_path = '')
AND JSON_UNQUOTE(JSON_EXTRACT(pv.source_snapshot_json, '$.relative_path')) = ?
)
)
ORDER BY p.updated_at DESC, p.id DESC
LIMIT 1`,
[userId, normalized],
[userId, normalized, normalized],
);
return rows[0] ? pageResponse(rows[0]) : null;
};
const findPlazaContextByWorkspacePath = async (userId, relativePath) => {
const normalized = normalizeWorkspaceRelativePath(relativePath);
if (!normalized) return null;
const [rows] = await pool.query(
`SELECT p.id AS page_id, pr.id AS publication_id, pp.id AS post_id, pp.status AS post_status
FROM h5_page_records p
JOIN h5_page_versions pv ON pv.id = p.current_version_id
LEFT JOIN h5_publish_records pr ON pr.page_id = p.id AND pr.user_id = p.user_id AND pr.status = 'online'
LEFT JOIN plaza_posts pp ON pp.publication_id = pr.id AND pp.user_id = p.user_id AND pp.status != 'hidden'
WHERE p.user_id = ?
AND p.status <> 'deleted'
AND (
p.workspace_relative_path = ?
OR JSON_UNQUOTE(JSON_EXTRACT(pv.source_snapshot_json, '$.relative_path')) = ?
)
ORDER BY
CASE pp.status WHEN 'published' THEN 0 WHEN 'pending_review' THEN 1 ELSE 2 END,
p.updated_at DESC,
p.id DESC
LIMIT 1`,
[userId, normalized, normalized],
);
const row = rows[0];
if (!row) return null;
return {
pageId: row.page_id,
publicationId: row.publication_id ?? null,
postId: row.post_id ?? null,
postStatus: row.post_status ?? null,
};
};
const listPages = async (userId, filters = {}) => {
const clauses = [`p.user_id = ?`, `p.status <> 'deleted'`];
const params = [userId];
@@ -1448,6 +1490,7 @@ export function createPageService(pool, options = {}) {
findPageBySourceAsset,
findPageBySourceMessage,
findPageByRelativePath,
findPlazaContextByWorkspacePath,
getPage,
getDeletePreview,
deletePage,