diff --git a/admin/src/components/LinkPickerDialog.vue b/admin/src/components/LinkPickerDialog.vue
new file mode 100644
index 0000000..75b25c0
--- /dev/null
+++ b/admin/src/components/LinkPickerDialog.vue
@@ -0,0 +1,143 @@
+
+
+
+
+ confirm(row.path)"
+ >
+
+
+
+
+ 选择
+
+
+
+
+
+
+ confirm(fileUrl(row))"
+ >
+
+
+
+
+ 选择
+
+
+
+
+
+
+
+
+ 使用此地址
+
+
+
+
+
+
+
diff --git a/admin/src/components/PageBuilderAnimFields.vue b/admin/src/components/PageBuilderAnimFields.vue
new file mode 100644
index 0000000..1eb2955
--- /dev/null
+++ b/admin/src/components/PageBuilderAnimFields.vue
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+ 延迟ms
+
+ 时长ms
+
+
+
+
+
+
diff --git a/admin/src/components/PageBuilderBlocks.vue b/admin/src/components/PageBuilderBlocks.vue
new file mode 100644
index 0000000..34e3321
--- /dev/null
+++ b/admin/src/components/PageBuilderBlocks.vue
@@ -0,0 +1,320 @@
+
+
+
+
+
{{ typeLabel(block.type) }}
+
+ 上移
+ 下移
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 选择
+ 删
+
+
+ + 添加链接
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 选择链接
+
+
+
+
+ 主色
+ 线框
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 分割线
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 区块内模块(可继续嵌套)
+ patchSectionChildren(idx, v)"
+ />
+
+
+
+ 未知类型 {{ block.type }}
+
+
+
+
+
+
+ + 添加模块
+
+
+
+ 标题
+ 段落文字
+ 链接组
+ 按钮
+ HTML
+ 留白
+ 分割线
+ 区块(嵌套)
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/admin/src/components/PageBuilderEditor.vue b/admin/src/components/PageBuilderEditor.vue
new file mode 100644
index 0000000..917b7cb
--- /dev/null
+++ b/admin/src/components/PageBuilderEditor.vue
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+
diff --git a/admin/src/views/sites/PageList.vue b/admin/src/views/sites/PageList.vue
index 7bdb86f..5f3a309 100644
--- a/admin/src/views/sites/PageList.vue
+++ b/admin/src/views/sites/PageList.vue
@@ -50,7 +50,13 @@
-
+
@@ -70,15 +76,18 @@
-
+
插入积木模板
-
-
+
+
+
+
+
@@ -94,6 +103,7 @@ import { ref, reactive, onMounted, watch } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { getSites } from '../../api/admin'
import { getPages, createPage, updatePage, deletePage } from '../../api/admin'
+import PageBuilderEditor from '../../components/PageBuilderEditor.vue'
const siteId = ref('')
const sites = ref([])
@@ -289,4 +299,8 @@ onMounted(() => {
justify-content: space-between;
align-items: center;
}
+.builder-form-item :deep(.el-form-item__content) {
+ display: block;
+ margin-left: 0 !important;
+}
diff --git a/docs/PAGE_BUILDER.md b/docs/PAGE_BUILDER.md
index 3b8b65f..6da8ffb 100644
--- a/docs/PAGE_BUILDER.md
+++ b/docs/PAGE_BUILDER.md
@@ -4,7 +4,8 @@
- 在 **网页管理** 中创建页面,设置 **前台路径**(`route_path` 或默认 `/{slug}`)、**发布**、**内容模式**。
- **HTML**:`content` 为 HTML 字符串,前台用 `v-html` 渲染(仅信任后台内容)。
-- **积木(builder)**:`content` 为 JSON,结构如下,前台按模块渲染并支持入场动画。
+- **积木(builder)**:后台使用 **可视化编辑器**(添加模块、拖拽顺序、配置动画);链接可在弹窗中选择 **站内页面**、**可下载文件** 或 **自定义地址**。亦可展开「高级」直接改 JSON。
+- 存储仍为 JSON,结构如下,前台按模块渲染并支持入场动画。
## 动态路由