Skip to content

自定义页面

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:页面ID
    • name:页面名称
    • title:页面标题
    • description:页面描述
    • keywords:页面关键词
    • template:页面模板
    • content:页面内容(JSON格式)
    • route:页面路由
    • is_use:是否使用(0:未使用,1:使用中)
    • create_time:创建时间
    • update_time:更新时间

4.2 自定义路由模型

  • 表名:diy_route
  • 主要字段:
    • id:路由ID
    • name:路由名称
    • route:路由路径
    • page_id:关联页面ID
    • share_title:分享标题
    • share_desc:分享描述
    • share_image:分享图片
    • create_time:创建时间
    • update_time:更新时间

4.3 模板模型

  • 表名:diy_theme
  • 主要字段:
    • id:模板ID
    • name:模板名称
    • 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. 注意事项

  1. 页面性能:自定义页面的内容和组件数量会影响页面加载速度
  2. SEO优化:合理设置页面标题、描述和关键词
  3. 响应式设计:确保页面在不同设备上的显示效果
  4. 兼容性:确保页面在不同浏览器中的兼容性
  5. 备份:定期备份自定义页面数据,防止数据丢失

7. 开发流程

  1. 需求分析:明确自定义页面的功能需求
  2. 模板设计:设计页面模板和组件
  3. 功能开发:实现自定义页面的核心功能
  4. 测试验证:测试页面的各种功能和场景
  5. 部署上线:将自定义页面功能部署到生产环境

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[路由配置]
    end

10.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[更新路由]
    end

10.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[保存为新页面]
    end

11. 组件使用说明

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. 注意事项

  • 组件使用:合理使用组件,避免页面过于复杂导致加载缓慢
  • 图片优化:优化图片大小和格式,提高页面加载速度
  • 响应式设计:确保页面在不同设备上的适配性
  • 数据备份:定期备份页面配置,防止数据丢失
  • 性能优化:避免过多的组件和复杂的布局,保持页面简洁
  • 安全考虑:确保页面内容和链接的安全性
  • 测试验证:在发布前充分测试页面在不同设备和浏览器上的表现