zoukankan      html  css  js  c++  java
  • easyconf——基于AugularJS的配置管理系统开发框架

    目录

    1 easyconf的诞生
    2 easyconf的设计理念
      2.1 总体设计
      2.2 细节设计
        2.2.1 CRUD操作
        2.2.2 即时校验
        2.2.3 下拉框设计
    3 easyconf使用指南
      3.1 基本步骤
      3.2 表配置文件
      3.3 easyconf.js的定制
        3.3.1 语言
        3.3.2 URL地址
        3.3.3 自定义校验方法
    4 easyconf后端开发指南
      4.1 请求说明
      4.2 返回说明
    5 下一步的工作


    1 easyconf的诞生

      大概半年前做一个原型系统,有很多配置数据存储在数据库中,用户需要对这些配置项进行管理。但凡开发过这样的配置管理系统的人都会发现,为A表编写的配置管理的代码与B表大同小异。如果能够进一步抽象,我们或许可以只用开发一套前端和后端代码,就能够满足几乎所有不同的配置表的需求。

      我很懒,不喜欢做重复的工作,所以我设计了easyconf——基于AugularJS的配置管理系统开发框架。easyconf支持json格式的表配置文件,我们可以在此文件中定义需要管理的表的各种信息,诸如列信息,以及列对应的前端控件信息等。easyconf的最小集是index.html和easyconf.js两个前端代码,后端可按照本文中的指南进行自定义开发,当然,我也提供了一个基于python的demo后端。

      虽然,easyconf被设计用来开发配置管理系统,你也可以脑洞大开地拿它来开发各种管理系统,诸如“XX学籍管理系统”,“XX图书馆管理系统”等。很熟悉吧,至少本科的课程设计做过这样的系统。如果有了easyconf,你甚至无需写1字节代码就可以做出一个管理系统,你仅仅需要做好表设计以及对表配置文件的定制化。

      截止目前(2016-07),easyconf已支持0-String/1-Long/2-Double/3-Boolean/4-Date,共5种数据类型;0-text/1-combo box,共2种控件类型;0-精确/1-包含/2-小于/3-大于/4-小于等于/5-大于等于,共6种查询方式。


    2 easyconf的设计理念

    2.1 总体设计

      MVC架构提供了Model将数据与后端中的类进行映射,而另有一些开发者将后端中的类与前端中的控件进行了映射。然而,管理系统是一类非常“单纯”的系统,大部分CRUD操作只针对单表进行,所以,我们可以放心地进行简化映射关系,将数据与前端控件直接映射起来:

      上图显示了一个生动的实例,假设我们有众多的服务器架设在全国各地,那么我们需要一张名为service的表存储这些服务器的信息,其中包括服务器的IP,端口号,所在省市,以及是否启用。使用MVC架构或者基于MVC的优化架构,我们必须至少为后端编写一定量的代码(定义类)。假若使用数据对前端控件的直接映射,那么将免去这方面的工作。

    2.2 细节设计

    2.2.1 CRUD操作

      easyconf支持对有主键的单表的CRUD操作。以服务器配置为例,打开配置管理主页如下:

      点击“新增”,将进入新增面板:

      在配置管理主页,点击“查找”,将按按照条件在主页输出查找结果:

      点击查找结果的“详情”,将进入详情面板:

      点击查找结果的“更新”,将进入更新面板:

      点击查找结果的“删除”,将删除一条配置数据:

     

    2.2.2 即时校验

      点击“提交”后再对用户的输入进行校验是不够人性化的,easyconf能够即时校验用户的输入:

      上图展示了两种校验,第一种是数据类型校验,由于定义的“服务器监听端口”字段为整型,当输入字母“a”时将提示“必须为整数”;第二种是自定义校验,对的,easyconf还支持自定义校验函数,在本例中我自定义了IP和端口合法性校验函数。

      唯一性是不太好处理的校验项:首先,为了追求真正的唯一性,在新增面板打开到关闭这段期间内进行锁表是不合适的;其次,退而求其次,每次focus在主键字段,或者修改主键字段,或者从主键字段blur都查询一下是否唯一,这种方式也是不合理的,会大大增加系统的开销。easyconf采取的是一种准即时的方式,提交新增请求后,若后端判断不满足唯一性约束,则前端记录下本次的主键字段的输入为历史输入,下一次提交前,每一次主键字段的修改都会与历史输入进行比较,只要是一致,就会提示“数据已存在”:

      

      

    2.2.3 下拉框设计

      easyconf使用了两种下拉框:静态下拉框和动态下拉框。静态下拉框的候选内容是固定的,在表配置文件中定义。动态下拉框的候选内容是可变的,其取数的方式也在表配置文件中定义。在本例中,“省”字段的候选内容从数据库表“province”中读取,“市”字段的候选内容从数据库表“city”中读取,读取的时候还需要加上“省”字段作为查询条件;“是否启用”字段为静态下拉框:


    3 easyconf使用指南

    3.1 基本步骤

      easyconf的使用可以分为以下几个基本步骤:

    3.2 表配置文件

      表配置文件的定制是使用easyconf的核心步骤,让我们看一下这个配置文件中的各种配置项的说明:

     1 {
     2     title:<title>,                      //此处定义了标题显示内容
     3     table:<table>,                      //表名
     4     count:10,                           //查询结果每页条数
     5     columns:                            //此处定义了需要显示的表的各列信息
     6     [
     7             {
     8                 id:<col1>,              //列在数据库中定义的名称
     9                 name:<列1>,             //列在页面上显示的中文名
    10                 isShow:<true>,          //在查询结果中是否显示
    11                 isPrimaryKey:[true],    //是否为主键,在新增页面时,主键的列的控件触发onchange事件后,需要进行唯一性校验。
    12                 isNull:<true>,          //是否为空,在新增或修改页面时,主键的列的控件触发onchange事件后,需要进行是否为空校验。
    13                 type:<0>,               //列的数据类型,0- String /1-Long/2-Double/3-Boolean/4-Date
    14                 control:<0>,            //列在页面上显示的控件类型,0-text/1-combo box
    15                 check:                  //在新增或修改页面时,主键的列的控件触发onchange事件后所调用的自定义校验函数
    16                 [
    17                     {
    18                     funcname:<function1>,
    19                     argument:<col1, col2…>
    20                     },                  //调用函数时,第一个参数为本控件的值,之后的参数为argument中列对应的控件的值。
    21 22                 ],    
    23                 isSelect:<true>,        //是否作为查询条件。
    24                 selectType:<0>,         //查询条件,0-精确/1-包含/2-小于/3-大于/4-小于等于/5-大于等于
    25                 candidate:<0/1>,        //0-固定值,1-动态值,为固定值时从fixed中取候选内容,为动态值时从flexible中取key,value,table和query组sql语句从数据库中查询出候选内容。候选内容的格式为”key-value”。
    26                 fixed:
    27                 [
    28                     {key1:<value1>}, 
    29                     {key2:<value2>},
    30 31                 ],
    32                 flexible:
    33                 {
    34                     key:<col>,
    35                     value:<col>,     
    36                     table:<table>,
    37                     where:<col1, col2…>
    38                 },
    39                 dft:<dft?               //默认值,查询层控件或新增页面对应控件的默认值。
    40             },
    41 42     ]
    43 }

    3.3 easyconf.js的定制

    3.3.1 语言

      在easyconf.js中我们可以定制前端上显示的要素的名称,提示的信息:

     1 //定义控件的显示名称
     2 names:{
     3     SEARCH:"查找",
     4     INSERT:"新增",
     5     DETAIL:"详情",
     6     UPDATE:"更新",
     7     DELETE:"删除",
     8     FRESH:"刷新",
     9     PREV:"上页",
    10     NEXT:"下页",
    11     GO:"跳转",
    12     RETURN:"返回",
    13     COMMIT:"提交",
    14     OPERATIONS:"操作"
    15 },
    16 //定义小标题
    17 subTitles:['查找', '详情', '更新', '新增'],
    18 //定义提示信息
    19 msgs:{
    20     OK:"通过",
    21     NOTNULL:"不允许为空",
    22     INTEGER:"必须为整数",
    23     DOUBLE:"必须为浮点数",
    24     TYPEERROR:"类型错误",
    25     DATE:"必须为日期[YYYY-MM-DD hh:mm:ss.ms]",
    26     NOTUNIQUE:"数据已存在",
    27 },

    3.3.2 URL地址

      在easyconf.js中,我们还可以定义URL地址,譬如域名为“www.domain.com”,定义INSERT请求的URL为“Insert”,那么完整的URL地址为“www.domain.com/Insert”:

    1 apps:{
    2     INIT:"Init",
    3     LIST:"Search",
    4     DELETE:"Delete",
    5     UPDATE:"Update",
    6     INSERT:"Insert",
    7     RANGE:"Range"
    8 },

    3.3.3 自定义校验方法

      在easyconf.js中,我们还可以自定义校验方法,在服务器配置的例子中,我们定义IP和端口的校验方法如下:

     1 // user's function here
     2 userfunc: {
     3     checkIp:function(ip) {
     4         var exp=/^(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5])$/; 
     5         var reg = ip.match(exp);
     6         if(reg  != null) 
     7             return true;
     8         else
     9             return false;
    10     },
    11 
    12     checkPort:function(port) {
    13         if (0 <= port && port <= 65535)
    14             return true;
    15         else
    16             return false;
    17     }
    18 }

     

    4 easyconf后端开发指南

    4.1 请求说明

      根据本指南,我们可以为easyconf开发自己的后端:

    请求 方式 url 请求数据 返回数据 说明
    配置管理主页 GET <domain>/<main>.html <main.html> domain为域名,main.html为index.html的重命名副本
    初始化 GET <domain>/<INIT> <table.json> table.json为表配置文件
    列表查询 GET <domain>/<LIST>?table=<table>&data=<col1,col2...>&query=<col1:value1,col2:value2...>&begin=<begin>&count=<count> 查询返回,见下

    后端收到请求后,解析data和query参数,data参数和query中的col和value均进行了base64编码。然后组sql语句进行查询,查询出来的结果为数据库中的第begin*count+1条到begin*(count+1)条。

    删除 POST <domain>/<DELETE> 删除请求,见下 通用返回,见下

    后端收到请求后,解析query变量。然后组sql语句进行删除。如果原数据不存在,也返回成功。

    更新 POST <domain>/<UPDATE> 更新请求,见下  通用返回,见下  后端收到请求后,解析data和query变量。然后组sql语句进行更新。如果原数据不存在,也返回成功。
    新增 POST <domain>/<INSERT> 新增请求,见下 通用返回,见下  后端收到请求后,解析data变量。然后组sql语句进行更新。
    候选项查询 GET <domain>/<LIST>?table=<table>&key=<key>&value=<value>&query=<col1:value1,col2:value2...> 候选项返回,见下 后端收到请求后,解析query参数。然后组sql语句进行查询,返回查询结果。

      删除请求:

    1 {
    2     table:<table>,
    3     query:<col1:value1,col2:value2...>
    4 }

       更新请求:

    1 {
    2     table:<table>,
    3     data:<col1:value1,col2:value2...>,
    4     query=<col1:value1,col2:value2...>
    5 }

      新增请求:

    1 {
    2     table:<table>,
    3     data:<col1:value1,col2:value2...>,
    4 }

    4.2 返回说明

      查询返回:

     1 {
     2     result:<00>,                //响应结果,00为成功
     3     message:<OK>,               //响应信息
     4     data:[                      //查询无结果则返回空列表
     5             [                   //查询出来的每一条数据
     6                 value1,         //每一条数据的每列的值,如果该列是动态下拉框,那么还需要根据表配置文件进行查询组成“key|value”的形式,key和value均base64编码
     7                 value2,
     8  9             ],
    10 11     ]
    12 }

      通用返回:

    1 {
    2     result:<00>,                 //响应结果,00为成功,插入时01为主键冲突
    3     message:<OK>,                //响应信息
    4 }

      候选项返回:

     1 {
     2     result:<00>,                //响应结果,00为成功
     3     message:<OK>,               //响应信息
     4     data:[                      //如果查询无数据则返回空列表
     5             {                   //每一条数据
     6                 key:<key>
     7                 value:<value>
     8             }
     9 10     ]
    11 }

    5 下一步的工作

      easyconf从设计到编码花了我两天时间,目前的版本能够满足基本的配置管理需求。但是仍由很多地方急需改进和优化,例如:页面的美化(并且也能够通过表配置文件定制),更加健全的异常处理,外键约束的校验,表操作的权限管理,等等。由于懒,我搞出来这个一个玩意儿,同时又给自己挖了好大一个坑,之后慢慢填吧。大家可以从GitHub上下载easyconf以及demo后端。

  • 相关阅读:
    hdu5360 Hiking(水题)
    hdu5348 MZL's endless loop(欧拉回路)
    hdu5351 MZL's Border(规律题,java)
    hdu5347 MZL's chemistry(打表)
    hdu5344 MZL's xor(水题)
    hdu5338 ZZX and Permutations(贪心、线段树)
    hdu 5325 Crazy Bobo (树形dp)
    hdu5323 Solve this interesting problem(爆搜)
    hdu5322 Hope(dp)
    Lightoj1009 Back to Underworld(带权并查集)
  • 原文地址:https://www.cnblogs.com/jasonfreak/p/5635086.html
Copyright © 2011-2022 走看看