一个全新的RDS开发系统,只有两个一级菜单:系统管理和工具管理。 系统管理提供了后台系统的用户,角色,组织结构的管理,实现基于角色和组织结构的操作权限和数据权限系统。 工具管理主要功能是RDS的核心功能,通过菜单管理进行系统模块扩展,应用管理主要是创建新的API应用,因为系统内置了一个API应用,所以,这个功能基本用不到。API文档菜单是用来查看API接口文档的入口。 所以,如果希望快速学会RDS的功能,利用RDS快速开发应用。我们只需要把菜单管理学习好就可以了。

img.png

# 基本概念

为了能够更好的理解本系统的原理,我们将介绍几个核心概念,理解了这些核心概念对于完全掌握甚至扩展本系统都是至关重要的。

  1. 菜单:按照字面的意思来说,就是系统左侧的菜单项;这样理解是正确的,但是在本系统中,菜单不仅仅是一个菜单项,它还与数据库表或者数据库查询相关联,我们对业务需求的分析最终都要落实到菜单上面来。无论这个菜单与一个表关联还是与多个表关联,菜单是功能的入口。
  2. 菜单的两个核心属性——字段:一般来讲,菜单与数据库表或者查询相对应,那么如何存储和展示这些表或者查询的属性,就是通过字段完成的。他代表两个方向:录入数据库时的数据库字段的属性,从数据库查询出来的时候如何展示给用户。而我们定义字段就是为了完成这两个方面的任务:数据录入属性和数据查询展示属性。我们后面的很多问题都聚焦于此。
  3. 菜单的两个核心属性——方法:类似于面向对象中的方法的概念,他是描述对象的动作的名称。在我们的系统中,我们对数据的操作称之为方法,他也代表两个方面的对象:一个是在后端层面上来讲,方法是控制器中的方法;一个是在前端层面上来讲,方法代表这交互按钮和动作。

# 项目部署

相对于基于模板的后台开发模式来讲,前后端分离模式就是将后端系统做成API接口服务器,前端做成能够独立运行的应用,通过http请求与后端交互。也就是前后端分离的开发模式,会把项目分成多端;如果是普通的后台管理系统,那么他存在后台系统和前端系统,如果需求里面有APP或者小程序等移动端应用,那么还需要移动端的开发。这样整个项目就变成了三端或者更多端。看似项目变得复杂了,其实前后端分离将开发的边界变得清晰起来,更利于分工协作,团队合作效率将会得到提高。 为了降低开发难度,我们将系统的前后端分离尽量做到自动化的部署,不要求后端项目和前端项目分别部署。我们的实现思路是: 后端系统默认应用为admin,当我们访问项目部署的服务器时,将自动定位到admin应用的index.php控制器。 而此控制器默认是重定向到public/disk/目录的

// app/admin/controller/Index.php
class Index
{
  public function index()
  {
    return redirect((string)url('/dist/'));
  }
}

在Thinkphp工程项目中,public目录默认是应用的入口,我们访问/public/dist/目录,就是访问此目录下的网页。关键就在这里,我们将前端项目默认就编译到这个目录了。 请看文件:vue.config.js;此文件中配置编译的目的地为“../public/dist/“。通过如此配置,我们只需要专注于后端系统的部署即可,只要我们的Thinkphp项目能够正常运行,前端工程执行编译后,会自动更新dist目录中的文件,这样就实现了前端自动部署和更新了。

// ui/vue.config.js
module.exports = {
    devServer: {
        host: '127.0.0.1',
        port: 3333,
        open: true,
    },
    outputDir: '../public/dist',
    assetsDir: 'static',
    productionSourceMap: false,
    publicPath: './'
}

这只是我们配置成默认最为简单的部署模式,如果您的项目需要分离到不同的服务器部署,只需要按照上面的配置,进行适当的修改即可。

# 系统设计思路

一般情况下,一个菜单项对应一个数据库表,然后再利用方法将一对多的关系体现出来。那么随着业务需求的复杂性加大,我们在分析和设计系统的时候,需要灵活利用系统的特性,面向用户需求,利用生成代码的特性,将需求进行个性化的定制。 举一个例子,比如针对某些数据做综合表格,包含多个表的数据,这时候这个表格页面就不是对应一个数据库表,那么我们在创建菜单后,其数据列表就可以采取两个选择中的一个:

  1. 利用关联模型创建数据列表方法
  2. 利用查询创建数据列表方法

如果是相关表特别多,查询特别复杂,推荐使用利用查询创建,如果是关系清晰那就使用关联模型创建。 在这种情况下,这个菜单对应多表数据,那他就不是单纯的对应数据库表,在这种情况下,我们需要充分使用虚拟字段,也就是不创建数据库列的字段。 如下图所示: 商品的分类名称,是商品分类表的属性,供应商名称是供应商表的属性; 而我们的商品表只是存储了分类ID和供应商ID,所以,要是显示分类名称和供应商名称就需要进行多表连接或者查询,那么分类名称和供应商名称就称之为虚拟字段。其仅有展示意义无数据操作意义。 image.png 基于上述思路,我们的系统可以完全面向用户需求,以需求为核心设计菜单及UI结构,把其中的信息分成多个菜单,通过关联或者查询再整合在一起。因此,本系统要求用户对数据库设计和多表连接比较熟悉。

# 代码的自定义

生成的代码再完美都是无法满足所有需求的,因此,很多时候用户是需要修改代码的。本系统的设计思路就是为用户提供一个可以利用,可以参考的完整代码。所以,生成的代码是可以修改的。而且,我们提倡不仅仅依赖于系统生成,而是在生成的代码基础上进行完善和提高。 对于后端代码,以方法为单位,需要设置方法的“生成后端”为否,同时通过/start/ ... /end/标记方法,使此方法在生成的时候,不会被覆盖。 对于前端代码,以方法为单位,需要设置方法的“生成前端”为否。使此方法对应的文件,在生成的时候不会被覆盖。 image.png

/*start*/
/*
* @Description  修改排序开关
*/
function updateExt(){
  $data = $this->request->post();
  if(!$data['member_id']) throw new ValidateException ('参数错误');
  MemberModel::update($data);
  return json(['status'=>200,'msg'=>'操作成功']);
}
/*end*/

我们一般的思路是,在定制生成之前,将需要方法都生成好,然后禁用代码生成功能,再此基础上,对代码进行修改。