自定义页面
1. 功能概述
自定义页面模块允许管理员通过可视化方式创建和管理网站页面,无需编写代码即可实现页面的设计和布局,包含以下主要功能:
- 自定义页面管理:创建、编辑、删除、查询自定义页面
- 页面装修:可视化编辑页面内容和布局
- 模板管理:使用和切换页面模板
- 自定义路由:管理页面的访问路径
- 分享设置:配置页面的分享内容
2. 路由配置
自定义页面相关的路由配置位于 backend/app/adminapi/route/diy.php 文件中,主要包含以下路由组:
2.1 自定义页面管理
GET /diy/diy:自定义页面分页列表GET /diy/carousel_search:自定义页面分页列表(轮播搜索组件用)POST /diy/diy:添加自定义页面PUT /diy/diy/:id:编辑自定义页面GET /diy/diy/:id:自定义页面详情DELETE /diy/diy/:id:删除自定义页面GET /diy/list:获取自定义页面列表PUT /diy/use/:id:设为使用PUT /diy/diy/share:编辑自定义页面分享内容
2.2 页面装修
GET /diy/decorate:页面装修列表PUT /diy/change:切换模板GET /diy/init:页面初始化数据
2.3 模板管理
GET /diy/template:获取页面模板GET /diy/template/pages:获取模板页面列表POST /diy/copy:复制模板
2.4 自定义路由管理
GET /diy/route:自定义路由列表GET /diy/route/apps:获取路由列表(存在的应用插件列表)GET /diy/route/info:获取自定义路由分享内容PUT /diy/route/share:编辑自定义路由分享内容
2.5 其他功能
GET /diy/apps:获取模板页面(存在的应用插件列表)GET /diy/page_link:获取页面链接
3. 核心功能实现
3.1 自定义页面管理
3.1.1 页面列表
- 支持分页查询
- 支持按条件筛选
- 显示页面的基本信息和状态
3.1.2 页面创建
- 设置页面基本信息(标题、描述等)
- 选择页面模板
- 配置页面路由
3.1.3 页面编辑
- 修改页面基本信息
- 编辑页面内容和布局
- 更新页面路由
3.1.4 页面删除
- 软删除页面
- 清理页面相关数据
- 记录删除操作日志
3.1.5 页面详情
- 获取页面的详细信息
- 查看页面的内容和布局
- 检查页面的路由配置
3.2 页面装修
3.2.1 可视化编辑
- 拖拽式组件编辑
- 实时预览页面效果
- 支持多种组件类型
3.2.2 模板切换
- 选择不同的页面模板
- 保留页面内容的同时切换模板
- 预览模板效果
3.2.3 页面初始化
- 加载页面的初始数据
- 初始化页面的组件和布局
- 准备页面编辑环境
3.3 模板管理
3.3.1 模板列表
- 显示可用的页面模板
- 模板分类和筛选
- 模板预览
3.3.2 模板使用
- 选择模板创建新页面
- 应用模板到现有页面
- 自定义模板内容
3.3.3 模板复制
- 复制现有模板创建新模板
- 修改复制的模板内容
- 保存为新模板
3.4 自定义路由管理
3.4.1 路由列表
- 显示所有自定义路由
- 路由状态和配置
- 路由的访问统计
3.4.2 路由配置
- 设置路由路径
- 绑定页面到路由
- 配置路由的访问权限
3.4.3 分享设置
- 配置页面的分享标题和描述
- 设置分享图片
- 配置分享链接
3.5 其他功能
3.5.1 应用插件集成
- 集成系统中的应用插件
- 在页面中使用插件功能
- 扩展页面的功能
3.5.2 页面链接
- 生成页面的访问链接
- 支持短链接生成
- 链接的有效期设置
4. 数据模型
4.1 自定义页面模型
- 表名:
diy - 主要字段:
id:页面IDname:页面名称title:页面标题description:页面描述keywords:页面关键词template:页面模板content:页面内容(JSON格式)route:页面路由is_use:是否使用(0:未使用,1:使用中)create_time:创建时间update_time:更新时间
4.2 自定义路由模型
- 表名:
diy_route - 主要字段:
id:路由IDname:路由名称route:路由路径page_id:关联页面IDshare_title:分享标题share_desc:分享描述share_image:分享图片create_time:创建时间update_time:更新时间
4.3 模板模型
- 表名:
diy_theme - 主要字段:
id:模板IDname:模板名称description:模板描述preview:模板预览图content:模板内容(JSON格式)create_time:创建时间update_time:更新时间
5. 开发规范
5.1 代码结构
- 控制器:位于
backend/app/adminapi/controller/diy/目录 - 模型:位于
backend/app/model/diy/目录 - 验证器:位于
backend/app/validate/diy/目录 - 字典:位于
backend/app/dict/diy/目录
5.2 组件开发
- 遵循组件开发规范
- 确保组件的可重用性
- 提供组件的配置选项
5.3 模板开发
- 模板结构清晰
- 支持响应式设计
- 易于自定义和扩展
5.4 性能优化
- 页面内容缓存
- 组件懒加载
- 资源压缩
5.5 安全规范
- 页面内容的XSS防护
- 路由访问权限控制
- 防止恶意操作
6. 注意事项
- 页面性能:自定义页面的内容和组件数量会影响页面加载速度
- SEO优化:合理设置页面标题、描述和关键词
- 响应式设计:确保页面在不同设备上的显示效果
- 兼容性:确保页面在不同浏览器中的兼容性
- 备份:定期备份自定义页面数据,防止数据丢失
7. 开发流程
- 需求分析:明确自定义页面的功能需求
- 模板设计:设计页面模板和组件
- 功能开发:实现自定义页面的核心功能
- 测试验证:测试页面的各种功能和场景
- 部署上线:将自定义页面功能部署到生产环境
8. 常见问题
8.1 页面加载缓慢
- 减少页面组件数量
- 优化图片和资源
- 启用页面缓存
8.2 页面显示异常
- 检查浏览器兼容性
- 检查组件配置
- 检查模板结构
8.3 路由冲突
- 确保路由路径唯一
- 检查路由配置
- 重启路由服务
8.4 分享功能异常
- 检查分享配置
- 检查微信等平台的分享规则
- 测试分享链接的有效性
9. 核心代码实现
9.1 页面模板定义
实现代码:
php
// PagesDict.php 中的 getPages 方法
public static function getPages($params = [])
{
$default_index_value = [
"path" => "edit-graphic-nav",
"id" => unique_random(10),
"componentName" => "GraphicNav",
"componentTitle" => "图文导航",
"uses" => 0,
"layout" => "horizontal",
"mode" => "graphic",
"showStyle" => "fixed",
"rowCount" => 4,
"pageCount" => 2,
"carousel" => [
"type" => "circle",
"color" => "#FFFFFF"
],
"imageSize" => 30,
"aroundRadius" => 25,
"font" => [
"size" => 14,
"weight" => "normal",
"color" => "#303133"
],
// 其他配置...
];
$pages = [
'DIY_INDEX' => [
'default_index' => [ // 页面标识
"title" => "首页", // 页面名称
'cover' => '', // 页面封面图
'preview' => '', // 页面预览图
'desc' => '官方推出的系统首页', // 页面描述
'mode' => 'diy', // 页面模式:diy:自定义,fixed:固定
// 页面数据源
"data" => [
"global" => [
"title" => "首页",
'pageStartBgColor' => '#F8F8F8',
'pageEndBgColor' => '',
'pageGradientAngle' => 'to bottom',
'bgUrl' => '',
// 其他全局配置...
],
"value" => [
[
"id" => unique_random(10),
"componentName" => "ImageAds",
"componentTitle" => "图片广告",
"path" => "edit-image-ads",
"uses" => 0,
"ignore" => [],
"imageHeight" => 180,
"isSameScreen" => false,
"list" => [
[
"imageUrl" => "static/resource/images/diy/template/index.png",
"imgWidth" => 750,
"imgHeight" => 580,
"link" => [
"name" => ""
],
"id" => "397htiaqung0",
"width" => 355,
"height" => 274.53
],
],
// 其他配置...
],
// 其他组件...
]
]
],
],
// 其他页面模板...
];
return $pages;
}9.2 自定义页面服务实现
实现代码:
php
// DiyService.php 中的 getInfo 方法
public function getInfo(array $params = [])
{
$start_up_page = [];
$page_template = [];
if (!empty($params[ 'name' ])) {
// 查询启动页
$diy_config_service = new DiyConfigService();
$start_up_page = $diy_config_service->getStartUpPageConfig($params[ 'name' ]);
$page_template = TemplateDict::getTemplate([ 'key' => [ $params[ 'name' ] ] ]);
if (!empty($page_template)) {
$page_template = $page_template [ $params[ 'name' ] ];
}
}
if (empty($params[ 'id' ]) && !empty($start_up_page) && !empty($page_template) && !empty($start_up_page[ 'page' ]) && $start_up_page[ 'page' ] != $page_template[ 'page' ]) {
$info = $start_up_page;
return $info;
} else {
$condition = [];
if (!empty($params[ 'id' ])) {
$condition[] = [ 'id', '=', $params[ 'id' ] ];
} elseif (!empty($params[ 'name' ])) {
$condition[] = [ 'name', '=', $params[ 'name' ] ];
$condition[] = [ 'is_default', '=', 1 ];
}
$field = 'id,title,name,type,template, mode,value,is_default,share,visit_count';
$info = $this->model->field($field)->where($condition)->findOrEmpty()->toArray();
if (empty($info)) {
// 查询默认页面数据
if (!empty($params[ 'name' ])) {
$page_data = $this->getFirstPageData($params[ 'name' ]);
if (!empty($page_data)) {
$info = [
'title' => $page_data[ 'title' ],
'name' => $page_data[ 'type' ],
'type' => $page_data[ 'type' ],
'template' => $page_data[ 'template' ],
'mode' => $page_data[ 'mode' ],
'value' => json_encode($page_data[ 'data' ], JSON_UNESCAPED_UNICODE),
'is_default' => 1,
'share' => '',
'visit_count' => 0
];
}
}
}
return $info;
}
}
// DiyService.php 中的 getFirstPageData 方法
public function getFirstPageData($type)
{
$pages = PagesDict::getPages([ 'type' => $type ]);
if (!empty($pages)) {
$template = array_key_first($pages);
$page = array_shift($pages);
$page[ 'template' ] = $template;
$page[ 'type' ] = $type;
return $page;
}
return [];
}
// DiyService.php 中的 getDiyTheme 方法
public function getDiyTheme()
{
// 查询当前选中的主题
$theme_data = (new DiyTheme())->where([['is_selected', '=', 1]])->field('title,theme')->findOrEmpty()->toArray();
if (empty($theme_data)) {
// 如果没有选中主题,返回默认主题
return [
'title' => '默认绿色',
'theme' => [
'--primary-color' => '#00c905',
'--primary-light-color' => '#9cff57',
'--secondary-color' => '#f5f5f5',
'--secondary-light-color' => '#ffffff',
'--secondary-dark-color' => '#e6e6e6',
'--primary-text-color' => '#3c3c3c',
'--secondary-text-color' => '#555555'
]
];
}
return $theme_data;
}9.3 自定义页面控制器实现
实现代码:
php
// Diy.php 控制器
class Diy extends BaseApiController
{
/**
* 自定义页面信息
* @return Response
*/
public function info()
{
$params = $this->request->params([
[ 'id', '' ],
[ 'name', '' ]
]);
return success(( new DiyService() )->getInfo($params));
}
/**
* 底部菜单信息
* @return Response
*/
public function tabbar()
{
$params = $this->request->params([
[ 'key', 'app' ],
]);
return success(( new DiyConfigService() )->getBottomConfig($params[ 'key' ]));
}
/**
* 分享内容
* @return Response
*/
public function share()
{
$data = $this->request->params([
[ 'route', '' ],
[ 'params', '' ]
]);
return success(( new DiyRouteService() )->getShare($data));
}
/**
* 获取主题配置
* @return Response
*/
public function theme()
{
return success(( new DiyService() )->getDiyTheme());
}
}10. 页面创建和装修流程
10.1 页面创建流程
mermaid
flowchart TD
A[开始] --> B[选择页面类型]
B --> C[选择模板]
C --> D[设置页面信息]
D --> E[保存页面]
E --> F[生成页面ID]
F --> G[结束]
subgraph 页面类型
B --> B1[首页]
B --> B2[个人中心]
B --> B3[商品列表]
B --> B4[自定义页面]
end
subgraph 模板选择
C --> C1[系统模板]
C --> C2[自定义模板]
C --> C3[复制现有页面]
end
subgraph 页面信息
D --> D1[页面标题]
D --> D2[页面描述]
D --> D3[关键词设置]
D --> D4[路由配置]
end10.2 页面装修流程
mermaid
flowchart TD
A[开始] --> B[进入装修模式]
B --> C[添加组件]
C --> D[配置组件]
D --> E[调整布局]
E --> F[预览效果]
F --> G[保存发布]
G --> H[结束]
subgraph 组件操作
C --> C1[基础组件]
C --> C2[布局组件]
C --> C3[功能组件]
C --> C4[营销组件]
end
subgraph 组件配置
D --> D1[属性设置]
D --> D2[样式设置]
D --> D3[数据设置]
D --> D4[链接设置]
end
subgraph 预览发布
F --> F1[PC端预览]
F --> F2[移动端预览]
F --> F3[平板预览]
G --> G1[保存配置]
G --> G2[发布页面]
G --> G3[更新路由]
end10.3 页面管理流程
mermaid
flowchart TD
A[开始] --> B[查看页面列表]
B --> C{选择操作}
C -->|编辑| D[编辑页面]
C -->|复制| E[复制页面]
C -->|删除| F[删除页面]
C -->|预览| G[预览页面]
D --> H[保存更改]
E --> I[创建新页面]
F --> J[确认删除]
G --> K[查看效果]
H --> L[结束]
I --> L
J --> L
K --> L
subgraph 页面操作
D --> D1[修改基本信息]
D --> D2[编辑内容]
D --> D3[更新路由]
E --> E1[复制配置]
E --> E2[修改名称]
E --> E3[保存为新页面]
end11. 组件使用说明
11.1 基础组件
- 文本组件:用于显示文本内容,支持字体、颜色、对齐方式等设置
- 图片组件:用于显示图片,支持图片上传、链接设置等
- 按钮组件:用于添加按钮,支持样式、链接设置等
- 分割线组件:用于添加分割线,支持样式设置
11.2 布局组件
- 容器组件:用于组织其他组件,支持背景、边距等设置
- 网格组件:用于创建网格布局,支持列数、间距等设置
- 轮播图组件:用于创建图片轮播,支持自动播放、指示器等设置
11.3 功能组件
- 导航组件:用于添加导航菜单,支持链接设置
- 商品列表组件:用于显示商品列表,支持数据源设置
- 会员信息组件:用于显示会员信息,支持样式设置
11.4 营销组件
- 优惠券组件:用于显示优惠券,支持样式和链接设置
- 活动倒计时组件:用于显示活动倒计时,支持时间设置
- 拼团组件:用于显示拼团活动,支持数据源设置
12. 代码示例
12.1 获取页面信息
php
// 实例化自定义页面服务
$diyService = new DiyService();
// 获取页面信息
$params = [
'name' => 'DIY_INDEX' // 页面类型
];
$pageInfo = $diyService->getInfo($params);
// 处理页面数据
if (!empty($pageInfo)) {
$pageTitle = $pageInfo['title'];
$pageData = json_decode($pageInfo['value'], true);
// 渲染页面
}12.2 获取主题配置
php
// 实例化自定义页面服务
$diyService = new DiyService();
// 获取主题配置
$themeConfig = $diyService->getDiyTheme();
// 应用主题
if (!empty($themeConfig['theme'])) {
$themeVariables = $themeConfig['theme'];
// 应用主题变量到页面
}13. 注意事项
- 组件使用:合理使用组件,避免页面过于复杂导致加载缓慢
- 图片优化:优化图片大小和格式,提高页面加载速度
- 响应式设计:确保页面在不同设备上的适配性
- 数据备份:定期备份页面配置,防止数据丢失
- 性能优化:避免过多的组件和复杂的布局,保持页面简洁
- 安全考虑:确保页面内容和链接的安全性
- 测试验证:在发布前充分测试页面在不同设备和浏览器上的表现
