1.表单介绍
一个表单对应数据库中的一个表,但一个表可以对应多个表单。
点击表单管理,可以看到所有的表单。可以按照菜单进行分类。如下图所示。
1.1.表单基本功能
1.1.1.调用路径
就是访问该表单的URL地址,相对路径,格式为:taijiForm.do?formId=2。最后面的数字,是表单的Id。在菜单配置时,填写URL路径地址,就可以加载访问。或者表单之间有相互调用,也是这个路径地址。
1.1.2.导入表单
在不同的项目中,有些表单的功能,可能是很类似的,甚至是一模一样的。比如在A项目中,有订单管理;在B项目中,也有订单管理。而且这2个项目的订单管理,其字段和功能差不多。那么我们就可以直接把A项目中的表单配置信息,导入到B项目中来。从而就相当于把A项目的订单管理功能,复制到B项目中来,就可以非常快速的创建项目功能。
导入时,在文本框中粘贴表单的配置信息(配置信息是导出来的json数据格式)。成功导入后,会创建一个新的表单。表单的字段信息也会同步创建。
2个导入区别:在界面功能上,有2个地方可以导入表单。一个是在工具栏上,一个是在表单的“更多”操作的下拉菜单里面。
其区别是:在工具栏上导入,相当于新增一个表单。选择对应的表单进行导入,相当于是替换当前表单,会覆盖当前表单的配置信息,包括所有字段。
导入时要注意:太极框架内核的版本,要保持一致。因为不同版本内核,其表结构字段可能不一样。
导入成功后要注意:如果表单和字段中,有调用其他表单的链接(比如点击后加载其他表单数据),注意调整Id值。因为原来A项目的被调用表单Id,与当前项目的被调用组表单Id,可能是不一样的。
1.1.3.导出表单
将表单的配置信息,以及表单下的所有字段配置信息,导出为json格式的数据。用于在其他项目中进行导入。
在表单管理中,对应的表单上点击更多菜单,弹出菜单选择“导出表单配置”,会导出并下载配置信息文件。如下样例所示,是导出的JSON配置信息样例(删减了很多字段,不然太长了)。
{
"widget": {
"addActionUrl": "",
"addAfterSave": 0,
"addPageStyle": 0,
"addShowTitle": true,
"allowAdd": true,
"listLeftJoin": "qd_user.Id as AliasId\nRoleName###qd_user_role###qd_user_role.Id=qd_user.RoleId\r\nDutyName###qd_user_duty###qd_user_duty.Id=qd_user.DutyId",
"viewShowCancel": true,
"viewShowTitle": true,
"widgetName": "用户管理",
"widgetType": 1
},
"coreVersionName": "1.32",
"fields": [
{
"addItem": true,
"aliasItem": false,
"batchAddItem": false,
"defaultValue": "",
"editItem": true,
"placeholder": "请输入2到20位字符",
"readOnlyItem": false,
"requiredItem": true,
"searchItem": false,
"totalItem": false,
"viewItem": false,
"widgetId": 4
},
{ }
],
"coreVersionDate": 1567612800000
}
1.1.4.复制表单
复制表单与导入表单比较类似,都是为了快速的创建一个新表单。区别在于,复制表单只是在当前项目中进行,而导入可以从其他项目中引入配置信息。
1.1.5.检测数据排序
如果表单开启了排序功能,那么数据列表就会默认按照数据库中OrderNum这个字段值进行排序。在添加和删除数据时,也会对该字段值进行同步修改。
比如总共有100条数据,删除第49条,那么从第50条开始到100条,其OrderNum值都会减1。即OrderNum值与表中真实的数据记录行数,是一致的。如果添加一条数据,新增数据的OrderNum值是1,那么原来所有数据的OrderNum值都会加1。
正常情况下,上述增删改操作,OrderNum值都会同步更新。但是也有异常情况,会导致OrderNum的值出现错误。比如原来没有排序,中途开启了排序,那么数据库中原有数据的OrderNum值肯定是没有的。或者手动在数据库中直接添加或删除数据,也会导致OrderNum值不同步。
该功能就是检测OrderNum值是否有问题,检测的内容包括OrderNum值是否出现断层,比如出现1、2、3、5;是否出现重复,比如出现1、2、3、3、5。
1.1.6.重置数据排序
该功能就是将表中OrderNum字段的值,重新从1开始进行赋值修改,达到连续排序的目的。可以先检测排序值是否有问题,如果有问题,就可以重置排序。比如原先没有启用排序,现在新启用了排序功能,那么重置排序,初始化一下OrderNum数据。
1.2.表单基本配置项
选择一个表单进行编辑,进入编辑页面。如下图所示,有一些配置项。下面将对各个配置项的功能和作用,进行详细说明。
1.2.1.表单名称与数据名称
表单名称:指定表单功能的名称定义,如用户管理、角色管理。
数据名称:用于在某些按钮或提示语上,显示对应的数据。如设定为用户,添加按钮会显示为:添加用户。
最终列表页面展示效果,如下图所示。
1.2.2.表单类型
表单类型决定了具体的功能类型,目前仅支持2种类型的表单:普通列表表单、和树形列表表单。其他的表单类型可以忽略。
1)普通列表表单
读取数据库表数据,进行列表展示,就是普通列表表单。基本上都是普遍列表表单。
2)树形列表表单
数据结构为树状结构,每个节点有上级和下级,并额外有深度和顺序属性。比如部门组织架构、多级商品分类等。框架中设计的分类级别深度不限,为无限级树。如下图所示,为职务树的样例。
设定为树形列表表单后,相对应的数据库表也需要额外的字段进行支持。下面5个字段必须要具备。如下图所示,为上述职务树的表数据。
- OrderNum,排序值。树形列表只按照该字段值进行升序排序,即使设定其他排序字段,也会忽略。
- ParentId,父项Id。指定当前节点的父项主键Id。如果当前节点为顶级节点,则值为0。
- Depth,级别深度。从1开始,顶级节点值为1。
- Path,节点路径Id列表。就是从最顶点到该节点所经过的路径,也是该节点的所有父节点Id列表(包括自己)。如下图所示,比如值为1,2,5,6,则可以看出是一个4级节点,并且其所有的父节点Id都在路径中。
- ChildCount,子项数量。所有子子孙孙节点的数量总和。如果为0,则认为是叶子节点,即最末端的节点,无子项。
1.2.3.数据库表名
指定表单的数据,对应到数据库中的哪个表。
1.2.4.是否验证权限
如果设置不验证权限,那么该表单的访问权限是公开的。只要登录后台,就可以使用该表单的功能。
一般情况下,比如首页,需要所有人都可以访问,那么就设置为不需要验证权限。
1.2.5.自定义权限标识
设置一个字符串,用来作为权限验证对比的标识。如果不设置,则采用系统默认的字符串标识(form+表单id)。
当一个功能页面,是由很多表单组合而成。比如下图所示“我的客户咨询”,其页面是一个tab标签页,每个标签页都是1个表单列表。对于所有tab标签页面来说,其权限都是由菜单“我的客户咨询”来决定的,即他们的权限都是一样的。所以这些页面就必须要设置系统的权限字符串,以便进行统一权限控制。
如下图所示,所有tab标签页内的表单,其权限字符串统一设置为module36。该权限值,也与菜单中设置的权限字符串相同。
菜单中设置的权限字符串,与表单的权限字符串匹配。
1.2.6.是否有触发器
该选项仅作为一个记录功能。不产生任何功能效果。
太极平台框架可以实现单表的增删改查功能,直接配置字段属性就OK了。但是框架没法实现关联数据的计算,比如每个订单有多个商品,其总价是由所有商品的价格累加而来。那么添加或者删除商品,以及变更商品的单价和数量,都会引起订单总价的变化(如果我们采用的方案,是用字段值记录总价,而非实时SQL统计计算)。
此时,我们就需要搭配触发器,很方便的实现功能。在框架中只需要配置增删改查的字段,在触发器中捕捉数据更新,并重新计算总价,进行更新。我们的触发器是针对订单商品表,所以可以在后台做个标记。涉及到订单商品的表单,设置为有触发器,这样在后台可以大致了解到哪些表单配合触发器实现功能。
虽然也可以实现自动对比数据库表名称,自动加入触发器标识,但是有些表单的功能,只是数据读取,并不会引起触发器工作,直接统一标识所有关联表单都有触发器,不是太好。
1.2.7.增删改查等功能开启
框架内置了很多功能,开启后就可以直接使用这些功能。
- 启用添加。开启后,工具栏上会出现添加按钮。如果是树形表单,在操作列还会出现添加子项功能。需要搭配设置字段为添加项。
- 启用编辑。开启后,在数据列表操作列,会出现编辑操作。需要搭配设置字段为编辑项。
- 启用删除。开启后,在数据列表操作列,会出现删除操作。不需要再进行其他设置。删除操作会从数据库中彻底删除数据。如果有外键关联限制删除,删除时会异常。框架会自动捕捉到该异常,经转换处理后,进行友好的提示说明。
- 启用详情。开启后,在数据列表操作列,会出现详情操作。需要搭配设置字段为详情项。
- 启用查询。开启后,工具栏的右边,会出现搜索栏。需要搭配设置字段为搜索项,相应的搜索条件,才会出现在搜索栏上。
- 启用排序。开启后,在数据列表操作列,会出现上移、下移操作。开启后,务必确保数据库表中有OrderNum字段。对于中途开启的,最好进行排序数据的检测和重置。
- 启用导出。开启后,工具栏上出现Excel导出按钮。需要搭配设置字段为导出项。只有设置为导出项的字段,其数据才会导出来。数据导出时,如果开启了查询功能,那么会导出满足查询条件的数据。导出的数据不分页(会导出所有满足条件的数据)。
- 启用导入。开启后,工具栏上出现Excel导入按钮,点击后,下拉出现模板下载菜单。需要搭配设置字段为导入项。导入时必须严格按照模板的格式进行数据填充,系统会根据表格的列名称进行对比和识别。表头列名称不一致的列数据,会忽略掉。数据列的位置排序不影响导入,只要匹配到列表头名称,就会导入。
1.2.8.自定义工具栏
可以在框架自带的工具栏上面,追加放入其他按钮。如下图所示,添加2个自定义按钮。最终的页面效果,见下图。
在工具栏上文本框中,可以填入任何代码(不仅仅只是显示按钮的代码)。所以可以非常灵活,甚至是可以在这里填写js和css的引入,编写js方法等。
技巧:
自定义工具栏,支持Request标签和表单id标签。具体用法,样例代码如下:
这里待补充………………
加入了表单id标签${formId}和request标签。
1.3.列表页属性
进入表单编辑页面,在列表设置标签页里,进行表单数据列表页面的配置。如下图所示,为列表设置页面。
1.3.1.标题栏是否显示
指示标题栏是否显示。如果表单要内嵌在Tab标签页中,或者在弹框中,一般设置为不显示标题栏。比如上图“我的客户咨询”中,tab标签页内的表单列表,都设置为不显示标题栏。如果设置了显示标题栏,就会是下面的效果。一般对于普通的列表,都是需要显示标题栏。
1.3.2.表格样式CSS名称
表格有默认的显示样式,如果想要改变,可以进行设置。比如设定为“table table-hover no-margins”,会显示如下图所示的效果,没有交替行背景色。
1.3.3.序号列与复选框显示
设置列表数据页面,是否显示序号列,以及是否显示复选框。如下图所示,复选框列自带有全选复选框。
不显示序号列场景:一般用于页面布局比较窄,或者显示列数比较少的场景。比如首页上只显示8到10条数据,或者在左右布局的页面,放在左边作为导航的数据。
如下图所示的界面,是模仿网页版微信的群列表页面。左边显示群列表,右边显示群成员,中间显示群消息。左右两边的界面,都是通过表单直接配置出来。设置了不显示序号列,对表格设置了另外的CSS样式,头像列设置了一个自定义显示格式。中间的页面,是一个自定义的页面,调用servlet请求,转向到jsp页面。
显示复选框的场景:用于批量操作数据。一般要搭配自定义工具栏使用。在自定义工具栏中,添加一个按钮,用来获取复选框的选中数据,然后进行后续的处理。
框架自动生成的复选框,通过按F12调出源码,可以看到是一个name为rowId,value为该条记录主键Id值的复选框。这样就可以通过复选框的name来获取选中的数据Id列表了。
关于怎么获取选中复选框的值,下面有jQuery代码供仓库。上面在自定义工具栏章节,也有案例说明。
这里补充代码…………
1.3.4.分页样式
分页样式目前有3种:标准样式、简单型、极简型。
1)标准样式。默认样式,用的最多,有齐全的按钮组,有具体的页码导航。如下图样例。
2)简单型。只包含上一页、下一页、以及一个页码下拉框。选中下拉框页码后,直接加载页码数据。
3)极简型。只有上一页和下一页。
1.3.5.每页记录数
设定每页的数据记录数,默认为20条。设置为0,则不会出现分页,会列出所有数据。一般在分类或者简单的配置维护页面,不需要分页,设置为0。
1.3.6仅查询记录数
默认为0。设置大于0后,列表数据就只会显示设定的条数,也不会再显示分页导航,即分页功能会自动被屏蔽。比如在首页,只显示固定的8条或者10条,那么这里就设置为8或者10。
1.3.7.别名左连接查询
1.3.8.列表SQL附加条件
1.3.9.列表排序条件
1.3.10.列表启用自定义SQL
数据的列表,是从数据库中查询出数据,数据库通过SQL语句进行查询。框架会根据表单和字段的配置,自动生成SQL语句,查询相应的数据。
一般情况下,框架自动生成的SQL语句,都能查询出满足条件的数据。如果查询数据比较复杂,也可以通过配置左连接来实现。如果遇到特别复杂的,比如要统计计算等等,那么可以写一个特有的SQL语句,来查询出字段数据。
启用自定义SQL语句后,框架将不自动生成SQL语句,而且直接使用下面的自定义SQL语句进行数据查询。
1.3.11.列表自定义SQL语句
通过单独的SQL语句,查询出表单配置的字段信息。一般用于要通过比较复杂的查询,才能获取数据。
需要注意的是分页与排序:自定义的SQL语句中,不要加入分页(limit)和排序(order by),因为这2个条件,要配置到上面的设置项中。框架会自动组装和拼接分页与排序。
另外要注意的是搜索:自定义的SQL语句由于是一个完整的语句,而搜索功能则需要将搜索条件穿插到SQL语句中。所以如果表单需要搜索功能,那么就必须要在自定义的SQL语句中,插入搜索条件标签。
具体用法如下,在需要查询的地方,插入where或者and关键字,以及后面的查询字段标签${sqlWhere}。要注意语句中是否还有其他查询条件,来决定跟在where还是and后面。
比如:select UserName,NickName from table where ${sqlWhere}
或者:select UserName,NickName from table where Id=1 and ${sqlWhere}
1.3.12.列表页追加代码
整个后台系统,是一个单页面应用,所有需要使用的js或者css文件,都会在进入系统主页面时,加载进来了(后面框架会升级改造,根据需要用到的表单,加载相应的js和css文件,不会再一次性将所有文件加载进来)。所以如果某些功能需要通过js来实现功能,就必须要有个地方可以编写js代码,并且页面功能在加载时,还能执行编写的js代码。
列表页追加代码,就是这个作用。将要执行的代码(包括js、css、HTML等)放入其中,表单的列表页面在加载时,也会加载并执行该配置项的代码。
注意:该字段值在数据库中采用text类型,所以此处编写的代码长度要在64kb以内。
1.4.添加页属性
配置添加页面的属性。如下图所示的一些配置项。
1.4.1.标题栏是否显示
设置添加页面的标题栏是否显示。
1.4.2.添加页面样式
设置添加页面展示的方式。
- 页面添加。点击添加按钮后,页面转向,进入到添加页面(实际是ajax加载添加页面)。一般用于添加表单的字段比较多的情况。
- 弹框添加。点击添加按钮后,以弹框的形式,展示添加页面。一般用于添加表单字段较少的情况。弹框形式相对方便,页面不用撰写,在添加时可以看到当前页面数据。
- 行添加。暂未实现效果,以后升级实现。
- 批量添加。暂未实现效果,以后升级实现。
1.4.3.添加成功后
设置添加成功后,页面进行如何处理。
1)返回列表。添加成功后,会返回到数据列表页面。如果是弹框添加,则会刷新数据列表页面。添加按钮一般就在列表页面的工具栏上。
2)仅显示提示。添加成功后,仅显示一个提示信息,当前添加页面不会做任何改变,如下图所示。这种用法很少。
3)转向提示页面。添加成功后,转到一个提示页面。如下图所示,这种用法需求也比较少。
1.4.4.保存添加数据action
框架中自带的添加功能,只会进行单个表数据的添加。如果要在添加数据时,进行其他表数据的处理,也可以结合数据库的触发器来实现。但是如果要做比较复杂的逻辑运算、判断、对比等,靠框架和触发器都无法实现时,就必须要单独去写业务处理代码。
自定义的action,是一个URL地址(相对路径),点击添加按钮后,所有的表单数据会提交到设定的URL。如下图所示,将添加数据的action指定到:test.do?param1=test。会看到保存按钮的参数,已经被格式化为指定的test.do路径了,而且后面还自动添加了表单Id参数。
点击保存按钮后,数据会post和get提交到设定的action地址,如下图所示。之后,在服务端编写servlet进行接收处理即可。
服务端处理完毕后,返回相应的json数据格式,web前端页面会自动解析并提示,或转向。
服务端接收并处理,以及返回的样例代码如下。
采用servlet的doPost和doGet方法接收数据,通过action参数来区分行为。最后通过ExceptionUtil.printlnFailure和ExceptionUtil.printlnSuccess方法,来返回失败和成功后的JSON数据。通过ExceptionUtil.insertDB来记录异常。
提交返回的JSON数据格式为:{"success":true,"info":"点粉数据统计成功!"}
@WebServlet(name = "DeviceServlet", description = "处理设备相关请求功能", urlPatterns = {"/device.do"})
public class DeviceServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String action = request.getParameter("action");
if (action == null) {
action = "";
}
switch (action) {
//重置设备动态密码
case "resetdynamicpassword":
resetDynamicPassword(request, response);
break;
//解除设备绑定
case "unbind":
unbindDevice(request, response);
break;
//强制设备下线
case "logout":
deviceLogout(request, response);
break;
//重新统计进粉数据
case "calcontactadd":
reCalcContactAdd(request, response);
break;
//重新统计点粉数据
case "calconcactclick":
reCalcContactClick(request, response);
break;
//重新统计会话数量
case "calchatroom":
reCalcChatroomCount(request, response);
break;
default:
break;
}
}
//重新统计点粉数据
private void reCalcContactClick(HttpServletRequest request, HttpServletResponse response) throws IOException {
DeviceDao dao = new DeviceDao();
try {
int rows = dao.reCalcContactClick();
if (rows <= 0) {
ExceptionUtil.printlnFailure(response, "数据统计失败!");
return;
}
} catch (SQLException e) {
e.printStackTrace();
ExceptionUtil.insertDB(e, "点粉数据统计异常");
ExceptionUtil.printlnFailure(response, "点粉数据统计异常!");
return;
}
ExceptionUtil.printlnSuccess(response, "点粉数据统计成功!");
}
}
1.4.5.添加页面追加代码
类似于列表页面追加代码,在添加页面,也可以设定追加代码。在加载添加表单页面时,会执行追加的代码。
在这里可以进行一些表单控件的单独处理,比如下拉框联动事件,表单控件输入值改变事件等。如下图所示,设置代码后。
会在页面的保存按钮后面执行。
1.5.编辑页属性
1.5.1.添加页面相同配置项
下面的一些配置项含义,与添加页面相同,不再进行重复说明。
- 标题栏是否显示
- 编辑页面样式
- 编辑成功后
- 保存编辑数据action
- 编辑页追加代码
1.5.2.可编辑条件
在数据列表页面,某些条件下的数据,是不能进行编辑修改的。比如订单列表数据,如果订单状态为已完成,那么就不能进行编辑。所以在列表页面的操作列,就不能出现编辑链接功能。而且服务端在调用编辑页面时,也要对调取的数据进行校验,看是否是限定不可编辑的数据。
这里采用SQL语句的格式进行校验,支持session标签。框架后台会转换为IF格式的SQL语句,可以在IDEA中打开框架的调试功能,查看执行输出的SQL语句。
比如填写:State=1 and UserId!=${SessionInt:userid},那么就限制只有满足State=1,且用户id不等于自己时,编辑功能才可用,列表页面才会出现编辑链接。
列表查询最终会转换为SQL语句:select xxx, IF(State=1 and UserId!=10,true,false) AS CanEditData from qd_table where xxx=?
session标签会被替换为真实的值。
注意:可以看到是否可编辑,最终会通过SQL查询的CanEditData字段值来决定,所以在表单的字段列表中,CanEditData会作为系统保留字段,不可添加,以免重复。
1.6.详情页属性
1.6.1.添加页面相同配置项
下面的一些配置项含义,与添加页面相同,不再进行重复说明。
- 标题栏是否显示
- 详情页面样式
- 详情页追加代码
1.6.2.返回按钮是否显示
由于详情页面没有保存按钮,所以只有一个返回按钮,可以设置返回按钮是否显示。
1.7.删除页属性
设置数据删除的一些功能,如下图所示。
1.7.1.可删除条件
类似于可编辑条件,某些列表数据,也需要根据情况来决定是否可以删除。比如订单列表数据,已经审核通过的订单,业务规定不能删除。那么在数据列表页面,操作列中就不能出现删除链接和功能,而且服务端在处理删除操作时,也要进行这个校验。
是否可编辑,也是最终转换为SQL语句条件判断。
比如设置为:State!=1,那么就是只有满足State!=1时,才能进行删除。
列表查询最终会转换为SQL语句:select xxx, IF(State!=1,true,false) AS CanDeleteData from qd_table where xxx=?
注意:CanDeleteData被框架作为是否可删除的字段名称,所以表单也不要添加同名字段。
1.7.2.删除数据action
点击删除链接后,数据会提交到设定的URL地址。如下图所示,设置删除数据action为test.do后,删除链接会提交到新地址,并且会自动带上表单Id和数据Id。