Filter business blocks by page scope

This commit is contained in:
王鹏
2026-06-19 23:23:22 +08:00
parent da872fa133
commit 3d4294a164
5 changed files with 344 additions and 5 deletions

View File

@@ -134,6 +134,64 @@ export function saveDatabase(projectId, data) {
}).then(unwrap)
}
export function listPageDesigns(projectId, scope = 'frontend') {
return request({
url: `/front/project/${projectId}/page-designs`,
method: 'get',
params: { scope }
}).then(unwrap)
}
export function initPageDesigns(projectId, scope = 'frontend') {
return request({
url: `/front/project/${projectId}/page-designs/init`,
method: 'post',
params: { scope }
}).then(unwrap)
}
export function createPageDesign(projectId, data, scope = 'frontend') {
return request({
url: `/front/project/${projectId}/page-designs`,
method: 'post',
params: { scope },
data
}).then(unwrap)
}
export function getPageDesign(projectId, designId, scope = 'frontend') {
return request({
url: `/front/project/${projectId}/page-designs/${designId}`,
method: 'get',
params: { scope }
}).then(unwrap)
}
export function savePageDesign(projectId, designId, data, scope = 'frontend') {
return request({
url: `/front/project/${projectId}/page-designs/${designId}`,
method: 'put',
params: { scope },
data
}).then(unwrap)
}
export function deletePageDesign(projectId, designId, scope = 'frontend') {
return request({
url: `/front/project/${projectId}/page-designs/${designId}`,
method: 'delete',
params: { scope }
}).then(unwrap)
}
export function listBusinessBlocks(projectId, scope = 'frontend') {
return request({
url: `/front/project/${projectId}/business-blocks`,
method: 'get',
params: { scope }
}).then(unwrap)
}
export function generateProject(projectId) {
return request({
url: `/front/project/${projectId}/preview`,
@@ -167,3 +225,25 @@ export function downloadProject(projectId, templateType) {
timeout: GENERATE_REQUEST_TIMEOUT
}).then(unwrap)
}
export function startRunPreview(projectId) {
return request({
url: `/front/project/${projectId}/run-preview`,
method: 'post',
timeout: GENERATE_REQUEST_TIMEOUT
}).then(unwrap)
}
export function getRunPreviewStatus(projectId) {
return request({
url: `/front/project/${projectId}/run-preview`,
method: 'get'
}).then(unwrap)
}
export function stopRunPreview(projectId) {
return request({
url: `/front/project/${projectId}/run-preview/stop`,
method: 'post'
}).then(unwrap)
}

View File

@@ -36,7 +36,7 @@
ref="designerRef"
:designs="pageDesigns"
:database="database"
:block-definitions="scope === 'frontend' ? businessBlockDefinitions : []"
:block-definitions="businessBlockDefinitions"
:mode="scope"
:show-header="false"
:saving="saving"
@@ -150,7 +150,7 @@ async function loadDesignerData() {
getProject(projectId.value),
getDatabase(projectId.value),
listPageDesigns(projectId.value, scope.value),
listBusinessBlocks(projectId.value)
listBusinessBlocks(projectId.value, scope.value)
])
projectName.value = projectResult?.projectName || ''
database.value = normalizeDatabase(databaseResult)
@@ -443,7 +443,7 @@ onBeforeRouteUpdate(async () => {
.designer-card {
min-height: 0;
overflow: hidden;
overflow: visible;
}
.designer-card :deep(.page-designer-body) {

View File

@@ -11,6 +11,14 @@ function readSource(relativePath) {
return readFileSync(resolve(srcDir, relativePath), 'utf8')
}
function cssBlock(source, selector, offset = 0) {
const start = source.indexOf(`${selector} {`, offset)
assert.notEqual(start, -1)
const end = source.indexOf('\n}', start)
assert.notEqual(end, -1)
return source.slice(start, end)
}
test('router exposes standalone page designer route', () => {
const routerSource = readSource('router/index.js')
@@ -34,13 +42,27 @@ test('standalone page designer wraps the focused designer component', () => {
assert.equal(source.includes('预览页面'), true)
})
test('standalone page designer does not trap sticky designer sidebars', () => {
const source = readSource('views/PageDesignerView.vue')
const sharedCardStyleStart = source.indexOf('.designer-card {')
const cardStyle = cssBlock(source, '.designer-card', sharedCardStyleStart + 1)
assert.equal(cardStyle.includes('overflow: hidden'), false)
assert.equal(cardStyle.includes('overflow: visible'), true)
})
test('standalone page designer loads scope-specific designs and business blocks', () => {
const source = readSource('views/PageDesignerView.vue')
const apiSource = readSource('api/project.js')
assert.equal(source.includes('const scope = computed'), true)
assert.equal(source.includes("route.query.scope === 'admin'"), true)
assert.equal(source.includes('listPageDesigns(projectId.value, scope.value)'), true)
assert.equal(source.includes('listBusinessBlocks(projectId.value)'), true)
assert.equal(source.includes('listBusinessBlocks(projectId.value, scope.value)'), true)
assert.equal(source.includes(':block-definitions="businessBlockDefinitions"'), true)
assert.equal(source.includes("scope === 'frontend' ? businessBlockDefinitions : []"), false)
assert.equal(apiSource.includes("export function listBusinessBlocks(projectId, scope = 'frontend')"), true)
assert.equal(apiSource.includes('params: { scope }'), true)
assert.equal(source.includes('initPageDesigns(projectId.value, scope.value)'), true)
assert.equal(source.includes('createPageDesign(projectId.value, design, scope.value)'), true)
assert.equal(source.includes('savePageDesign(projectId.value, design.designId, design, scope.value)'), true)