前端开发

开发必备

  1. 在进行开发之前,需要搭建好项目的运行环境。具体可查看“教程”-》“环境搭建”-》“软件安装”-》“Vue环境安装
  2. 需掌握一定的 Vue3open in new windowTypeScriptopen in new window 使用技能。
  3. 创建VueCMF前端项目。具体可查看“教程”-》“安装运行”-》“安装VueCMF前端

一切开发相关的都准备好了之后,就可以开始使用IDE工具(如vscodeopen in new windowwebstormopen in new window等)编写代码了。接下来开始前端代码部分介绍及如何在此基础上进行开发。

目录结构

先从代码的目录结构开始,打开你的VueCMF前端项目,你看到的项目目录结构应该是下面的形式。如下

├── node_modules                    # 依赖包所在目录
├── public                          # 项目首页及静态资源所在目录
├── src                             # 项目源码所在目录
|   ├── assets                      # 样式文件目录
|   ├── components                  # 组件目录
|   ├── model                       # 模型层文件目录
|   ├── router                      # 路由配置目录
|   ├── service                     # 服务层文件目录
|   ├── store                       # 状态管理配置目录
|   ├── typings                     # TypeScript类型配置目录
|   ├── views                       # 视图层文件目录
|   ├── App.vue                     # 模板首页
|   ├── main.ts                     # 项目入口文件
|   ├── registerServiceWorker.ts    # 资源缓存服务文件
|   └── shims-vue.d.ts              # TypeScript的.vue的适配定义文件
├── .browserslistrc                 # 浏览器兼容配置文件
├── .env.development                # 开发环境的后端API配置
├── .env.production                 # 生产环境的后端API配置
├── .env.test                       # 测试环境的后端API配置
├── .eslintignore                   # 代码规范检测忽略文件配置
├── .eslintrc.js                    # 代码规范检测配置
├── .gitignore                      # git忽略文件配置
├── auto-imports.d.ts               # 组件自动导入配置
├── babel.config.js                 # babel插件配置
├── components.d.ts                 # 组件自动导入配置
├── package.json                    # 项目依赖包配置
├── README.md                       # 使用说明文档
├── tsconfig.json                   # TypeScript配置
└── vue.config.js                   # webpack配置

代码架构

介绍完VueCMF前端的目录结构,下面说说代码是如何组织的。主要分为模型层、服务层、事件层及视图层。下面就一一展开介绍。

模型层

模型层的代码文件存放在项目的src下的model目录,其作用是负责与后端API的对接。刚创建的vuecmf项目由以下四个文件组成

  1. BaseModel.ts 基础模型抽象类:里面包含有get、post请求及获取后端URL等公共方法,主要用于其它继承用。
  2. DataModel.ts 数据模型类:主要封装了一些供服务层调用的获取后端数据的方法。
  3. LayoutModel.ts 界面布局模型类:里面含有获取导航菜单数据方法
  4. LoginModel.ts 登录模型类:里面含有登录后台及获取服务器信息的方法

若需要添加新的与后端API对接(如新增批量删除功能),可在DataModel.ts 文件中添加或继承BaseModel.ts, 例如

//在model目录下创建一个PhotoModel.ts文件,内容如下
import BaseModel from "./BaseModel"

/**
 * 相册模型
 */
export default class PhotoModel extends BaseModel {
    constructor() {
        super();
    }

    /**
     * 批量删除照片
     * @param id_list  照片id,多个用英文逗号分隔
     */
    batchDel = (id_list: string): Promise<AnyObject> => {
        return this.request('photo', 'batch_del', {
            data:{ id_list: id_list }
        }).then((res) => {
            if(res.status == 200 && res.data.code == 0){
                return Promise.resolve(res.data)
            }else{
                return Promise.reject(res.data)
            }
        })
    }
    
}

BaseModel.ts 中的公共API请求方法 request 的参数说明如下

  1. table_name: 模型表名(即在后台“模型配置”列表中的“表名”)
  2. action_type: 模型的动作类型(即在后台“模型配置”列表中找到“模型动作”,点击后面的“字段”按钮,在打开的列表中找到“动作类型”后点击“选项”按钮,在打开的列表中“选项值”列即是这里要填的值)
  3. data: 发送给后端的数据
  4. method: 请求方式(get或post),默认为post

模型中代码写好后,如何配置与后端接口的映射呢?可在后台的“模型配置”中设置,如下

  1. 默认系统中已内置了常用的动作类型,若没有你想要动作类型,可在“模型配置”列表找到“模型动作”,点击后面的“字段”按钮,在打开的弹窗列表中找到“动作类型”后,点击“动作类型”所在行后面的“选项”按钮,在打开的列表窗口中,点击“新增”按钮

新增模型动作

  1. 在“模型配置”列表找到需要添加动作类型的模型(如相册管理模型),点击该模型所在行后面的“动作”按钮,在打开的“设置(相册管理)动作”弹窗列表中,点击“新增”按钮, 如下

新增模型动作

通过上面两步操作就完成的前端与后端接口的对接。这样就可以在前端代码中通过 BaseModel 中的 request 方法传入参数table_name(photo)以及action_type(batch_del)与后端进行交互了。

注意

在新增模型的动作时,“后端请求地址”必须以“/”开头,不得以“/”结尾,否则在设置权限时不会生效。 例如

  1. 正确:/vuecmf/photo/batchDel
  2. 错误:vuecmf/photo/batchDel, vuecmf/photo/batchDel/, /vuecmf/photo/batchDel/

模型层介绍完了,接下来就是服务层了。

服务层

服务层代码文件存放在项目的src下的service目录,其作用是调用事件层及模型层供视图层中的模板(.vue文件)调用。刚创建的vuecmf项目由以下event目录和四个文件组成, 如下

  1. event 目录:存放事件类文件。在后面的“事件层”中有详细介绍。
  2. BaseService.ts 基础服务抽象类: 主要包含公共的变更及异常处理方法等,供其它服务类继承。
  3. ContentService.ts 内容服务类: 后台内容展示区的核心类,主要包含列表管理、用户、角色、权限、模型及事件处理。
  4. LayoutService.ts 后台布局服务类:主要包含调用LayoutModel来加载菜单及路由、标签页管理,界面响应式处理。
  5. LoginService.ts 登录服务类:主要包含调用LoginModel的登录、获取用户登录信息及服务器信息的事件方法。

例如,创建一个PhotoService服务类并添加一个批量删除方法

//在service目录下创建一个PhotoService.ts文件,内容如下
import BaseService from "@/service/BaseService";
import PhotoEvent from "@/service/event/PhotoEvent";
import PhotoModel from "@/model/PhotoModel";

/**
 * 相册服务类
 */
export default class PhotoService extends BaseService{

    //列表后端接口地址
    api_list_server: string
    
    constructor() {
        super();
        const photoModel = new PhotoModel()  //实例化PhotoModel类
        this.api_list_server = photoModel.getApiUrl('photo','list')  //调用后端列表接口
    }
    
    /**
     * 批量删除照片
     * @param selectRows  选择的行数据
     */
    public batchDel = (selectRows: any):void => {
        if(selectRows){
            let id_arr = []
            selectRows.forEach((row) => {
                id_arr.push(row.id)
            })
            const photoEvent = new PhotoEvent()
            photoEvent.batchDel(id_arr.join(','))
        }
    }
    
}

现服务类创建好了,有没有发现上面的PhotoEvent事件类还没创建呢,接下来就是创建该事件类的时候了。

事件层

事件层代码文件存放在项目的src下的service目录中的event目录,其作用是调用模型层并提供事件方法供服务类调用。刚创建的vuecmf项目由以下六个文件组成,如下

  1. BaseEvent.ts 基础事件抽象类:主要封装了初始化列表及权限相关事件处理,供其它事件类继承。
  2. AdminEvent.ts 管理员事件类:主要提供管理员事件的配置及事件方法供ContentService服务类调用(如设置角色、设置权限)。
  3. MenuEvent.ts 菜单事件类:主要提供菜单事件的配置及菜单列表中按钮权限的控制。
  4. ModelConfigEvent.ts 模型配置事件类:主要提供模型配置列表的事件配置及设置字段、设置索引、设置动作及设置表单等事件方法。
  5. RolesEvent.ts 角色事件类:主要提供角色管理列表中的事件配置及添加子角色、设置权限及设置用户事件方法。
  6. DefaultEvent.ts 默认事件类:事件配置及方法继承自BaseEvent,在后台“模型配置”列表中新增的模型都是调用此事件类。你可以在此事件类中自定义自己需要的功能,可参考其它事件类写法(如AdminEvent)

下面就接着上面服务层介绍中还没有创建的PhotoEvent事件类,在这里开始创建。如下

//在event目录下创建一个PhotoEvent.ts文件,内容如下
import PhotoModel from "@/model/PhotoModel";
import {ElMessage} from "element-plus/es";

/**
 * 相册事件类
 */
export default class PhotoEvent {

    photoModel: any  //定义一个相册模型实例

    /**
     * 构造方法
     * @protected
     */
    protected constructor()
    {
        //实例化PhotoModel类
        this.photoModel = new PhotoModel() 
    }

    /**
     * 批量删除照片
     * @param id_list  照片id,多个用英文逗号分隔
     */
    public batchDel = (id_list: string):void => {
        this.photoModel.batchDel(id_list).then((res:AnyObject) => {
            if(res.status == 200 && res.data.code == 0){
                ElMessage.success(res.data.msg)
            }else{
                ElMessage.error(res.data.msg)
            }
        })
    }
    
}

业务逻辑代码现都写好了,那么该如何加到模板文件(.vue)中,在后台界面中实现最终用户使用的功能呢?接下来,视图层就是解决这个问题的。

视图层

视图层的模板文件存放在项目的src下的views目录中,其作用是渲染后台界面,直接面对用户的。刚创建的vuecmf项目由template目录和四个模板文件组成,如下

  1. template 目录:存放后台主内容展示区的模板文件(如列表页模板)。
  2. Layout.vue 后台界面框架布局模板:主要功能是调用LayoutService加载菜单及路由信息并渲染后台整体的框架布局。
  3. Login.vue 登录页模板:主要功能是调用LoginService提供用户登录后台的界面。
  4. Refresh.vue 刷新页模板:供后台刷新界面事件调用。
  5. Welcome.vue 欢迎页模板:登录后台的欢迎页,主要展示当前服务器的配置信息等。

下面就接着上面事件层留下的一个问题,在template目录下开始创建一个相册列表模板文件(PhotoList.vue),并加入调用业务逻辑代码。如下

<template>
  <vuecmf-table
      ref="photo_list_ref"
      height="460px"
      :selectable="true"
      :checkbox="true"
      :token="token"
      :server="server"
  >
    <!-- 表格头部左边 自定义按钮操作 -->
    <template #headerAction="selectRows">
      <el-button type="danger" @click.prevent="batchDel(selectRows)">批量删除</el-button>
    </template>
  </vuecmf-table>
</template>

<script lang="ts" setup>
import PhotoService from "@/service/PhotoService";

const service = new PhotoService()

//调用服务类中成员变量
const server = service.api_list_server
const token = service.token

//调用服务类中成员方法
const batchDel = service.batchDel

</script>
<script lang="ts">
import {defineComponent} from "vue";

export default defineComponent({
  name: "PhotoList"
})
</script>

模板文件创建好了,下面就可以将模板文件通过后台的“模型配置”列表,找到“模型配置”模型,点击后面的“字段”按钮,在弹出的“设置(模型配置)字段”列表中找到“组件模板”字段,然后点击后面的“选项”按钮,在弹出的“设置(组件模板)字段选项”窗口中,点击“新增”按钮添加即可。如下

新增组件模板

组件模板添加好后,就可以在“模型配置”列表中新增或编辑对应模型的表单中选择添加的“组件模板”了。

到目前为止,前端项目的功能开发已全部完成了。 若你开发功能比较复杂,单个模板文件内容比较多,那你就可以按功能模块拆分将其封装成一个个组件,然后再加入模板文件中,这样可以便于代码阅读及后期模板维护。接下来就开始介绍这块了

组件

组件的.vue文件存放在项目的src下的components目录中,其作用是封装模板文件中可复用的功能供各模板文件调用。刚创建的vuecmf项目在components目录下有四个组件文件,如下

  1. LayoutAsideMenu.vue 后台左边菜单列表组件
  2. LayoutAsideMenuItem.vue 后台左边菜单列表中子菜单项组件
  3. LayoutHeader.vue 后台顶部导航主菜单组件
  4. LayoutTabs.vue 后台标签页管理组件

以下是Layout.vue模板文件中调用组件的部分代码,具体详细代码可查看项目中对应的代码文件,这里就不全部贴出来了。

<template>
  <el-container>
    <!-- 左侧菜单 -->
    <el-aside :width="aside_width" >
      <vuecmf-layout-aside-menu
          :aside_menu_active="aside_menu_active"
          :is_side_collapse="is_side_collapse"
          :aside_menu_list="aside_menu_list"
          :collapse="collapse"
          :addTab="addTab"
      ></vuecmf-layout-aside-menu>
    </el-aside>
    <!-- 这里省略部分代码, 具体详细代码可查看项目中对应的代码文件-->
  </el-container>
</template>

状态管理

状态管理的代码文件存放在项目的src下的store目录中,主要包含后台导航菜单列表及后端API映射列表的状态。关于状态管理如何配置及使用可查看vuex官方文档open in new window

下面是项目中状态管理的部分代码,详细的可查看src下的store目录中的index.ts文件

import { createStore } from 'vuex'

export default createStore({
    state: {
        nav_menu_list: [], //系统导航菜单列表
        api_maps: [], //后端API映射列表
    },
    //后面的代码省略,详细可查看对应代码文件
})

路由

路由的代码文件存放在项目的src下的router目录中,其作用是处理菜单链接的跳转处理及界面内容切换。刚创建的vuecmf项目在router目录下有一个index.ts路由配置文件,里面已全部配置好了,一般不推荐修改此文件。若你需要在路由跳转时做一些特殊处理,可以修改此文件。关于路由如何设置,可以查阅Vue Router官方文档open in new window

以下项目中的路由配置的部分代码,详细配置可查看src下的router目录中的index.ts文件

const routes: Array<RouteRecordRaw> = [
  {
    path: '/',
    name: 'home',
    component: () => import('@/views/Layout.vue'),
    redirect: 'welcome',
    children: [
      {
        path: 'welcome',
        component: () => import('@/views/Welcome.vue'),
        name: 'welcome',
        meta: { breadcrumb_list: ['欢迎页'], title: 'welcome! - Powered by www.vuecmf.com', icon: 'welcome', noCache: true,topId:0, id:0, token:'123'}
      },
    ]
  },
    //后面配置代码已省略,详细配置可查看src下的router目录中的index.ts文件
]

类型配置

TypeScript的类型配置代码文件存放在项目的src下的typings目录中,其作用是定义一些类型用于TypeScript的类型检查。刚创建的vuecmf项目在typings目录下有一个vuecmf.ts文件。 你可以在此文件中添加自己的类型定义, 例如文件中已定义好的Tag类型,如下

export interface Tag {
    title: string,
    path: string
}

调试

代码都编写好了,下面就需要进行功能调试了,验证功能是否可用,有没有什么Bug。打开命令行终端,将目录切换到自己项目的根目录,然后输入“yarn dev”回车,即进入开发调试模式

yarn dev

部署

当调试没有问题,功能可以正常使用后,就可以打包项目,部署到生产环境了。打开命令行终端,将目录切换到自己项目的根目录,然后输入“yarn build”回车,即开始打包项目了

yarn build

详细的操作请参考:“教程”下面的 安装vuecmf前端 章节

后端API开发

开发必备

  1. 在进行开发之前,需要搭建好项目的运行环境。具体可查看“教程”-》“环境搭建”-》“软件安装”-》“php环境安装
  2. 需掌握一定的 PHPopen in new windowThinkPHP6open in new window 使用技能,当然你也可以根据此处的介绍及后端API文档,使用其它语言(如Java、Python、Golang、C#等)编写后端API。
  3. 创建VueCMF后端API项目。具体可查看“教程”-》“安装运行”-》“安装vuecmf后端

一切开发相关的都准备好了之后,就可以开始使用IDE工具(如vscodeopen in new windowphpstormopen in new window等)编写代码了。接下来开始后端API代码部分介绍及如何在此基础上进行开发。

目录结构

先从代码的目录结构开始,打开你的VueCMF后端API项目,你看到的项目目录结构应该是下面的形式。如下

├─app                             应用目录
│  ├─controller                   控制器目录
│  ├─vuecmf                       vuecmf应用目录
│  ├─ ...                         更多控制器基类、服务基类等文件
│  │
│  ├─common.php                   公共函数文件
│  └─event.php                    事件定义文件
│
├─config                          配置目录
│  ├─app.php                      应用配置
│  ├─cache.php                    缓存配置
│  ├─console.php                  控制台配置
│  ├─cookie.php                   Cookie配置
│  ├─database.php                 数据库配置
│  ├─filesystem.php               文件磁盘配置
│  ├─lang.php                     多语言配置
│  ├─log.php                      日志配置
│  ├─middleware.php               中间件配置
│  ├─route.php                    URL和路由配置
│  ├─session.php                  Session配置
│  ├─tauthz.php                   tauthz权限存储配置
│  ├─tauthz-rbac-model.conf       tauthz RBAC配置
│  ├─trace.php                    Trace配置
│  └─view.php                     视图配置
│
├─database                        项目数据初始化的定义文件存放目录
├─view                            视图目录
├─route                           路由定义目录
│  ├─route.php                    路由定义文件
│  └─ ...   
│
├─public                          WEB目录(对外访问目录)
│  ├─index.php                    入口文件
│  ├─router.php                   快速测试文件
│  └─.htaccess                    用于apache的重写
│
├─extend                          扩展类库目录
├─runtime                         应用的运行时目录(可写,可定制)
├─vendor                          Composer类库目录
│  ├─vuecmf                       VueCMF框架核心代码文件目录
│  │  └─framework
│  │     ├─config                 tauthz权限配置文件存放目录
│  │     ├─database               项目数据初始化的定义文件存放目录
│  │     ├─src
│  │     │  ├─command             命令行执行命令定义文件目录
│  │     │  ├─controller          控制器文件存放目录
│  │     │  ├─make                执行生成模型类文件相关功能的代码文件存放目录
│  │     │  ├─middleware          中间件文件存放目录
│  │     │  ├─model               模型文件存放目录
│  │     │  ├─subscribe           事件文件存放目录
│  │     │  ├─common.php          公共函数文件
│  │     │  ├─ConstConf.php       常量定义文件
│  │     │  ├─event.php           事件配置文件
│  │     │  ├─middleware.php      中间件配置文件
│  │     │  └─VuecmfService.php   服务配置文件
│  │     │
│  │     ├─.gitignore             git忽略文件
│  │     ├─composer.json          composer定义文件
│  │     ├─LICENSE                授权协议
│  │     └─README.md              使用说明文档
│  │     
│  ├─...                          更多其它依赖扩展包
│
├─.env                            数据库连接配置等信息文件
├─.example.env                    环境变量示例文件
├─composer.json                   composer 定义文件
├─LICENSE                         授权协议
├─LICENSE.txt                     授权说明文件
├─README.md                       使用说明文档
├─think                           命令行入口文件

代码架构

介绍完VueCMF后端API的目录结构,下面就说说代码是如何组织的。主要由模型层、事件层、门面及中间件构成。下面就一一展开介绍。

模型层

框架的模型层代码文件存放在vendor/vuecmf/framework/src/model目录下,其作用是与数据库交互并封装成方法供事件层调用。主要有以下模型文件

  1. Base.php 基础模型:主要封装了一些公共方法,供其它模型继承调用。
  2. Admin.php 管理员模型:主要包含管理员数据的增、删、改查及是否登录方法。
  3. FieldOption.php 字段选项模型:主要包含字段选项的增、删、改查及获取模型字段的选项值列表方法。
  4. GrantAuth.php 权限管理模型:主要包含增删用户角色、给角色分配用户、增删(用户或角色)权限、获取(用户或角色)权限ID列表、获取角色下所有用户及获取用户下所有角色方法。
  5. Menu.php 菜单模型:主要包含菜单的增、删、改查及获取导航菜单列表方法
  6. ModelAction.php 模型动作:主要包含模型动作的增、删、改查、获取所有指定的API映射列表、根据动作ID获取所属模型ID方法。
  7. ModelConfig.php 模型配置:主要包含模型配置的增、删、改查、获取指定模型的配置信息、根据模型ID获取对应表名、根据模型ID获取对应模型名称及根据模型ID获取对应模型实例方法。
  8. ModelField.php 模型字段:主要包含模型字段的增、删、改查、获取可模糊搜索的字符串类型字段、获取指定字段的类型、获取模型字段信息方法。
  9. ModelForm.php 模型表单: 主要包含模型表单的增、删、改查及获取模型的表单信息方法。
  10. ModelFormLinkage.php 模型表单联动:主要包含模型表单联动的增、删、改查方法。
  11. ModelFormRules.php 模型表单验证: 主要包含模型表单验证的增、删、改查、根据模型ID获取模型表单的校验规则、获取模型表单的数据验证规则方法。
  12. ModelIndex.php 模型索引:主要包含模型索引的增、删、改查及获取模型的唯一索引字段方法。
  13. ModelRelation.php 模型关联: 主要包含模型关联的增、删、改查、获取关联字段信息、获取关联下拉选项列表及获取联动关联字段信息方法。
  14. Roles.php 角色模型:主要包含角色模型的增、删、改查方法。

以上是框架的所有模型介绍。当在后台“模型配置”列表中创建一个模型后,系统会自动在项目的app/vuecmf目录下创建一个model目录并生成一个对应的模型类文件。例如创建一个相册模型(photo)生成的模型文件内容如下

<?php
declare (strict_types = 1);

namespace app\vuecmf\model;

/**
 * 相册管理模型
 * Class Photo
 * @package app\vuecmf\model
 */
class Photo extends Base
{

}

现在可以编辑此模型文件,在里面加上批量删除(batchDel)方法,如下

<?php
declare (strict_types = 1);

namespace app\vuecmf\model;

/**
 * 相册管理模型
 * Class Photo
 * @package app\vuecmf\model
 */
class Photo extends Base
{
    /**
     * 批量删除
     * @param array $id_list id 列表
     * @return bool
     */
    public function batchDel(array $id_list): bool
    {
        if(empty($id_list)) return false;
        $this->whereIn('id', $id_list)->delete();
        return true;
    }  
}

要想在其它类中不用new一个模型类,能不能像访问类的静态方法一样使用的话呢?那么接下来,门面就是解决这个问题的

门面

框架的门面代码文件存放在vendor/vuecmf/framework/src/model/facade目录下,其作用是将模型类中的方法可以转成访问类的静态方法的形式。当前已经定义好的门面类文件如下

  1. Admin.php 管理员模型的门面:转换可以静态访问的方法(判断是否已登录)
  2. FieldOption.php 字段选项模型的门面:转换可以静态访问的方法(获取模型的表单信息)
  3. GrantAuth.php 权限管理模型的门面:转换可以静态访问的方法(添加/删除用户角色、添加/删除(用户或角色)权限、为角色分配/清除用户、获取(用户或角色)所有权限ID列表、获取角色下所有用户名称、获取用户下所有角色名称)
  4. Menu.php 菜单模型的门面:转换可以静态访问的方法(获取导航菜单、获取下拉菜单列表)
  5. ModelAction.php 模型动作的门面:转换可以静态访问的方法(获取所有指定的API映射列表、根据动作ID获取所属模型ID)
  6. ModelConfig.php 模型配置的门面:转换可以静态访问的方法(根据模型ID获取对应表名、根据模型ID获取对应模型名称、根据模型ID获取对应模型实例、获取指定模型的配置信息)
  7. ModelField.php 模型字段的门面:转换可以静态访问的方法(获取可模糊搜索的字符串类型字段、获取指定字段的类型、获取字段信息)
  8. ModelForm.php 模型表单的门面:转换可以静态访问的方法(获取模型的表单信息)
  9. ModelFormRules.php 模型表单验证的门面:转换可以静态访问的方法(根据模型ID获取模型表单的校验规则、获取模型表单的数据验证规则)
  10. ModelIndex.php 模型索引的门面:转换可以静态访问的方法(获取模型的唯一索引字段)
  11. ModelRelation.php 模型关联的门面:转换可以静态访问的方法(获取关联字段信息)

以上是框架所有模型门面的介绍。下面就给Photo模型加一个门面类,先在项目的app/vuecmf/model目录下创建一个facade目录,然后新建一个门面类文件(Photo.php),如下

<?php
declare (strict_types = 1);

namespace app\vuecmf\model\facade;

/**
 * 相册管理模型
 * Class Photo
 * @package app\vuecmf\model\facade
 * @method static bool batchDel(array $id_list) 批量删除
 */
class Photo
{
    /**
     * @return string
     */
    protected static function getFacadeClass(): string
    {
        return 'app\vuecmf\model\Photo';
    }
}

创建好门面后,接下来你就可以在事件层通过访问类的静态方法一样调用batchDel方法了。

事件层

框架的事件层代码文件存放在vendor/vuecmf/framework/src/subscribe目录下,其作用是调用模型类并封装一些事件方法供控制器层调用来实现最终的后端API接口。当前已有事件类文件如下

  1. BaseEvent.php 基础事件抽象类:里面包含的事件有(列表、保存、批量保存、获取详情、删除、下拉列表),供其它事件类继承。
  2. AdminEvent.php 管理员事件类:除了继承自基础事件抽象类中所有事件外,另增加有登录、退出、添加用户角色、删除用户角色、添加用户权限、删除用户权限、获取用户所有权限、获取所有角色、获取用户下所有角色、设置用户权限、获取用户权限列表。
  3. FieldOptionEvent.php 字段选项事件类:包含继承自基础事件抽象类中所有事件。
  4. MenuEvent.php 菜单事件类:除了继承自基础事件抽象类中所有事件外,另增加有获取导航菜单列表。
  5. ModelActionEvent.php 模型动作事件类:除了继承自基础事件抽象类中所有事件外,另增加有获取API映射、获取所有模型的动作列表。
  6. ModelConfigEvent.php 模型配置事件类:包含继承自基础事件抽象类中所有事件。
  7. ModelFieldEvent.php 模型字段事件类:包含继承自基础事件抽象类中所有事件。
  8. ModelFormEvent.php 模型表单事件类:除了继承自基础事件抽象类中所有事件外,另增加有下拉列表事件。
  9. ModelFormLinkageEvent.php 模型表单联动事件类:包含继承自基础事件抽象类中所有事件。
  10. ModelFormRulesEvent.php 模型表单验证事件类:包含继承自基础事件抽象类中所有事件。
  11. ModelIndexEvent.php 模型索引事件类:包含继承自基础事件抽象类中所有事件。
  12. ModelRelationEvent.php 模型关联事件类:包含继承自基础事件抽象类中所有事件。
  13. RolesEvent.php 角色事件类:除了继承自基础事件抽象类中所有事件外,另增加有为角色分配用户、清除角色下的用户、添加角色权限、删除角色权限、获取角色所有权限、获取角色下所有用户、获取所有用户。
  14. UploadEvent.php 上传事件类:包含接收文件并保存到服务器事件。

以上是框架所有事件的介绍。当在后台“模型配置”列表中创建一个模型后,系统会自动在项目的app/vuecmf目录下创建一个subscribe目录并生成一个对应的事件类文件。例如创建一个相册模型(photo)生成的事件类文件内容如下

<?php
declare (strict_types = 1);

namespace app\vuecmf\subscribe;

/**
 * 相册管理事件
 * Class PhotoEvent
 * @package app\vuecmf\subscribe
 */
class PhotoEvent extends BaseEvent
{

}

现在可以编辑此事件类文件,在里面加上批量删除(batchDel)事件,如下

<?php
declare (strict_types = 1);

namespace app\vuecmf\subscribe;

use app\vuecmf\model\facade\Photo;
use think\Exception;
use think\Request;

/**
 * 相册管理事件
 * Class PhotoEvent
 * @package app\vuecmf\subscribe
 */
class PhotoEvent extends BaseEvent
{
    /**
     * 批量删除
     * @param Request $request
     * @return bool
     * @throws Exception
     */
    public function onBatchDel(Request $request)
    {
        $data = $request->post('data',[]);
        if(empty($data['id_list'])) throw new Exception('参数id_list不能为空');
        $id_list = explode(',', $data['id_list']);
        $res = Photo::batchDel($id_list); //Photo模型定义了门面,这里就可以通过双冒号形式调用模型的方法了
        if(!$res) throw new Exception('删除失败');
        return true;
    }
}

事件类创建好了,接下来就是在控制器层调用了。

控制器层

框架的控制器层代码文件存放在vendor/vuecmf/framework/src/controller目录下,其作用是调用事件类并定义一些动作(即最终的后端API接口)供前端请求调用。当前已有控制器类文件如下

  1. Base.php 基础控制器抽象类:主要包含的动作有(列表、保存、批量保存、详情、删除、下拉列表、树形列表),供其它控制器类继承。
  2. Admin.php 管理员控制器类:除了继承自基础控制器的所有动作外,另增加有(登录系统、退出系统、添加用户角色、删除用户角色、添加用户权限、删除用户权限、获取用户的所有权限、获取所有角色、获取用户下所有角色、添加用户权限、获取用户权限列表)。
  3. Error.php 异常控制器类:统一异常处理动作。
  4. FieldOption.php 字段选项控制器类:包含继承自基础控制器的所有动作。
  5. Menu.php 菜单控制器类:除了继承自基础控制器的所有动作外,另增加有导航菜单。
  6. ModelAction.php 模型动作控制器类:除了继承自基础控制器的所有动作外,另增加有(获取Api映射列表、获取动作列表)。
  7. ModelConfig.php 模型配置控制器类:包含继承自基础控制器的所有动作。
  8. ModelField.php 模型字段控制器类:包含继承自基础控制器的所有动作。
  9. ModelForm.php 模型表单控制器类:包含继承自基础控制器的所有动作。
  10. ModelFormLinkage.php 模型表单联动控制器类:包含继承自基础控制器的所有动作。
  11. ModelFormRules.php 模型表单验证控制器类:包含继承自基础控制器的所有动作。
  12. ModelIndex.php 模型索引控制器类:包含继承自基础控制器的所有动作。
  13. ModelRelation.php 模型关联控制器类:包含继承自基础控制器的所有动作。
  14. Roles.php 角色控制器类:除了继承自基础控制器的所有动作外,另增加有(批量分配用户、批量删除用户、添加角色权限、删除角色权限、获取角色下所有用户、获取角色下所有权限、获取所有用户)。
  15. Upload.php 文件上传控制器类:包含继承自基础控制器的所有动作。

以上是框架所有控制器的介绍。当在后台“模型配置”列表中创建一个模型后,系统会自动在项目的app/vuecmf目录下创建一个controller目录并生成一个对应的控制器类文件。例如创建一个相册模型(photo)生成的控制器类文件内容如下

<?php
declare (strict_types = 1);

namespace app\vuecmf\controller;

/**
 * 相册管理控制器
 * Class Photo
 * @package app\vuecmf\controller
 */
class Photo extends Base
{

}

现在可以编辑此控制器类文件,在里面加上批量删除(batchDel)动作,如下

<?php
declare (strict_types = 1);

namespace app\vuecmf\controller;

/**
 * 相册管理控制器
 * Class Photo
 * @package app\vuecmf\controller
 */
class Photo extends Base
{
    /**
     * 批量删除
     * @return \think\response\Json
     */
    public function batchDel(): \think\response\Json
    {
        return self::common('BatchDel', '删除成功','删除失败');
    }

}

注意

控制器中的公共方法common的第一个参数event_name(事件名称),是来自于subscribe目录下对应事件类文件中定义的事件方法(如PhotoEvent.php中的onBatchDel事件方法)去除开头的"on"(如BatchDel)

到目前为止,增加的“相册批量删除”后端API已开发完了,现需要将其对应模型的动作列表中。下面就将“批量删除”动作添加到先前创建的相册管理模型(photo)中,如下

在”模型配置“列表中找到”相册管理“模型所在行,点击后面的”动作“,在弹出的”设置(相册管理)动作“窗口中,点击”新增“按钮 新增模型动作 动作添加好后,在前端部分添加的批量删除功能,现在就可以正常使用了。

后端API开发好了,VueCMF框架是如何实现其权限控制及表单校验的呢?接下来,就是中间件来解决这个问题了

中间件

框架的中间件代码文件存放在vendor/vuecmf/framework/src/middleware目录下,其作用是对所有请求进行前置拦截并进行相应的处理(如API的权限控制)。当前已有中间件类文件如下

  1. Auth.php 访问权限控制中间件:主要负责后端API的访问权限控制及请求参数传递。
  2. DataCheck.php 数据校验中间件:主要负责表单提交的数据进行验证。

以上是框架的中间件介绍。具体实现代码就不贴出来,详细的可打开项目中对应类文件查看。

若你需要创建自己的中间件实现一些功能。可以在项目的app/vuecmf下创建一个middleware目录,在里面新建自己的中间件类文件,然后将其配置在app/vuecmf下的middleware.php配置文件中或具体的控制器类文件中,如下

<?php
// 这是系统自动生成的middleware定义文件
return [
    // Session初始化
    \think\middleware\SessionInit::class,
    //在这里添加自己创建的中间件类
];
/**
 * 相册管理控制器
 * Class Photo
 * @package app\vuecmf\controller
 */
class Photo extends Base
{
    //配置访问权限和表单数据校验中间件
    protected $middleware = [
        DataCheck::class => ['only' => ['save','saveAll']],
        //在这里添加自己创建的中间件类
    ];
    
    //......后面代码省略 
}

现在后端API已全部开发完了,接下来就调试测试了

调试

代码都编写好了,下面就需要进行功能调试了,验证功能是否可用,有没有什么Bug。 打开API测试工具(如Postmanopen in new window),如下 后端API调试后端API调试

部署

当调试没有问题,功能可以正常使用后,就可以部署到生产环境了。 详细的操作请参考:“教程”下面的 安装vuecmf后端 章节

Last Updated:
Contributors: emei8