表单字段类型

This commit is contained in:
jinqiming 2021-11-25 20:34:34 +08:00
parent 3047feace8
commit 4caeef0090
11 changed files with 299 additions and 157 deletions

View File

@ -44,6 +44,7 @@
<jsqlparser.version>1.4</jsqlparser.version>
<googlecode.aviator.version>2.3.3</googlecode.aviator.version>
<kotlin.stdlib.verson>1.3.70</kotlin.stdlib.verson>
<zxing.version>3.4.0</zxing.version>
</properties>
<!-- 依赖声明 -->
@ -344,6 +345,12 @@
<artifactId>kotlin-stdlib</artifactId>
<version>${kotlin.stdlib.verson}</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>${zxing.version}</version>
</dependency>
</dependencies>
</dependencyManagement>

View File

@ -35,6 +35,8 @@ public enum FormFieldTypeEnums {
COLOR_PICKER("colorpicker","颜色选择器"),
ICON_PICKER("iconPicker","颜色选择器"),
CRON("cron","Cron表达式"),
SIGN("sign","签名组件"),

View File

@ -195,7 +195,7 @@ public class SendMessageEventLister extends AbstractEventListener {
map.put("toUser", getUserInfo(processInstance.getStartUserId()).getUserName());
map.put("starttime", DateUtil.formatDateTime(processInstance.getStartTime()));
map.put("processInstance", processInstance.getProcessDefinitionName());
map.put("url", "http://localhost/flow/getMyHistoricProcessInstance");
map.put("url", CacheUtils.getSysConfig(CacheConstants.SYS_DOMAIN,"http://localhost")+"/flow/getMyHistoricProcessInstance");
map.put("datetime", DateUtil.formatDateTime(new Date()));
SysSendMessageDTO sysSendMessageDTO = SysSendMessageDTO.builder().templateByCode(MessageConstants.PROCESS_STARTED_CODE)
.receiver(getUserInfo(processInstance.getStartUserId()).getEmail())

View File

@ -25,6 +25,12 @@
<artifactId>snow-framework</artifactId>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.4.0</version>
</dependency>
</dependencies>
</project>

View File

@ -1,109 +0,0 @@
package com.snow.from.controller;
import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.snow.common.enums.FormFieldTypeEnums;
import com.snow.from.domain.field.*;
import com.snow.from.domain.response.BaseFormDataResponse;
import java.util.List;
/**
* @program: snow
* @description
* @author: 没用的阿吉
* @create: 2021-11-24 21:37
**/
public class BaseFieldController{
public String warpFormField(String formData, String formField){
//填写的表单值
JSONObject formFieldObject = JSON.parseObject(formField);
//原始表单
JSONArray formDataArray = JSON.parseArray(formData);
//把填写的表单值装填到原始表单上
for(int i=0;i<formDataArray.size();i++){
JSONObject fieldObject=formDataArray.getJSONObject(i);
//一行多列布局
if(fieldObject.getString("tag").equals(FormFieldTypeEnums.GRID.getCode())){
JSONObject jsonObject = formDataArray.getJSONObject(i);
JSONArray columnsArray= jsonObject.getJSONArray("columns");
for(int n=0;n<columnsArray.size();n++){
JSONObject columnObject = columnsArray.getJSONObject(n);
JSONArray listArray = columnObject.getJSONArray("list");
for(int j=0;j<listArray.size();j++){
//获取组件类型
String tag= JSON.parseObject(listArray.getString(j)).getString("tag");
belongField(tag,j,columnsArray,formFieldObject);
}
}
}else {
//正常单行布局
belongField(fieldObject.getString("tag"),i,formDataArray,formFieldObject);
}
}
System.out.println(JSONArray.toJSONString(formDataArray));
return JSONArray.toJSONString(formDataArray);
}
private void belongField(String tag,int index,JSONArray columnsArray,JSONObject formFieldObject){
if(tag.equals(FormFieldTypeEnums.INPUT.getCode())){
warpDefaultValueField(index,columnsArray,formFieldObject);
}else if(tag.equals(FormFieldTypeEnums.TEXTAREA.getCode())){
warpDefaultValueField(index,columnsArray,formFieldObject);
}else if(tag.equals(FormFieldTypeEnums.NUMBER_INPUT.getCode())){
warpDefaultValueField(index,columnsArray,formFieldObject);
}else if(tag.equals(FormFieldTypeEnums.DATE.getCode())){
warpDateDefaultValueField(index,columnsArray,formFieldObject);
}else if(tag.equals(FormFieldTypeEnums.DATE_RANGE.getCode())){
warpDateRangeDefaultValueField(index,columnsArray,formFieldObject);
}else if(tag.equals(FormFieldTypeEnums.CHECKBOX.getCode())){
warpCheckedValueField(index,columnsArray,formFieldObject,FormFieldTypeEnums.CHECKBOX);
}else if(tag.equals(FormFieldTypeEnums.RADIO.getCode())){
warpCheckedValueField(index,columnsArray,formFieldObject,FormFieldTypeEnums.RADIO);
}else if(tag.equals(FormFieldTypeEnums.SELECT.getCode())){
warpCheckedValueField(index,columnsArray,formFieldObject,FormFieldTypeEnums.SELECT);
}
}
/**
* 组装input
* @param columnsArray
* @param formFieldObject
*/
public void warpDefaultValueField(int index,JSONArray columnsArray,JSONObject formFieldObject ){
JSONObject jsonObject = columnsArray.getJSONObject(index);
String value = formFieldObject.getString(jsonObject.getString("id"));
jsonObject.put("defaultValue",value);
}
public void warpDateDefaultValueField(int index,JSONArray columnsArray,JSONObject formFieldObject ){
JSONObject jsonObject = columnsArray.getJSONObject(index);
String value = formFieldObject.getString(jsonObject.getString("id"));
jsonObject.put("dateDefaultValue",value);
}
public void warpDateRangeDefaultValueField(int index,JSONArray columnsArray,JSONObject formFieldObject ){
JSONObject jsonObject = columnsArray.getJSONObject(index);
String value = formFieldObject.getString(jsonObject.getString("id"));
jsonObject.put("dateRangeDefaultValue",value);
}
public void warpCheckedValueField(int index,JSONArray columnsArray,JSONObject formFieldObject,FormFieldTypeEnums formFieldTypeEnums){
JSONObject jsonObject = columnsArray.getJSONObject(index);
String value = formFieldObject.getString(jsonObject.getString("id"));
if(formFieldTypeEnums.getCode().equals(FormFieldTypeEnums.SELECT.getCode())){
jsonObject.put("remoteDefaultValue",value);
}
JSONArray optionsArray= jsonObject.getJSONArray("options");
for(int k=0;k<optionsArray.size();k++){
JSONObject optionObject = optionsArray.getJSONObject(k);
//值相等则设置为checked
if(optionObject.get("value").equals(value)){
optionObject.put("checked",true);
}else {
optionObject.put("checked",false);
}
}
}
}

View File

@ -1,27 +1,29 @@
package com.snow.from.controller;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.extra.qrcode.QrConfig;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.snow.common.constant.CacheConstants;
import com.snow.common.core.domain.AjaxResult;
import com.snow.common.enums.FormFieldTypeEnums;
import com.snow.common.utils.CacheUtils;
import com.snow.common.utils.StringUtils;
import com.snow.framework.util.ShiroUtils;
import com.snow.from.domain.SysFormDataRecord;
import com.snow.from.domain.SysFormField;
import com.snow.from.domain.SysFormInstance;
import com.snow.from.domain.field.*;
import com.snow.from.domain.request.FormFieldRequest;
import com.snow.from.domain.request.FormRequest;
import com.snow.from.domain.response.BaseFormDataResponse;
import com.snow.from.service.impl.SysFormDataRecordServiceImpl;
import com.snow.from.service.impl.SysFormFieldServiceImpl;
import com.snow.from.service.impl.SysFormInstanceServiceImpl;
import com.snow.from.util.FormUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@ -29,9 +31,13 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Optional;
/**
@ -43,7 +49,7 @@ import java.util.Optional;
@Controller
@RequestMapping()
@Slf4j
public class FormController extends BaseFieldController{
public class FormController{
@Autowired
private SysFormInstanceServiceImpl sysFormInstanceService;
@ -142,9 +148,7 @@ public class FormController extends BaseFieldController{
@RequestParam String formField){
//把用户填写的值赋值到表单里面去
String newFormData = warpFormField(formData, formField);
String s=null;
s.getBytes();
String newFormData = FormUtils.fillFormFieldValue(formData, formField);
Long userId = ShiroUtils.getUserId();
SysFormDataRecord sysFormDataRecord=new SysFormDataRecord();
sysFormDataRecord.setBelongUserId(String.valueOf(userId));
@ -172,7 +176,7 @@ public class FormController extends BaseFieldController{
SysFormInstance sysFormInstance = sysFormInstanceService.selectSysFormInstanceById(Long.valueOf(sysFormDataRecord.getFormId()));
map.put("id",id);
map.put("name",sysFormInstance.getFormName());
map.put("createTime",DateUtil.formatDateTime(sysFormInstance.getCreateTime()));
map.put("createTime",DateUtil.formatDateTime(sysFormDataRecord.getCreateTime()));
return "formDetail";
}
@ -194,16 +198,71 @@ public class FormController extends BaseFieldController{
* @param formData 表单数据
*/
private void saveFormField(Long formId,String formData ){
List<FormFieldRequest> formFieldRequestList = JSON.parseArray(formData, FormFieldRequest.class);
for (int i=0;i<formFieldRequestList.size();i++){
FormFieldRequest formFieldRequest = formFieldRequestList.get(i);
SysFormField sysFormField = BeanUtil.copyProperties(formFieldRequest, SysFormField.class,"id");
sysFormField.setFromId(formId);
sysFormField.setFieldKey(formFieldRequest.getId());
sysFormField.setFieldName(formFieldRequest.getLabel());
sysFormField.setFieldType(formFieldRequest.getTag());
sysFormField.setFieldHtml(JSON.parseArray(formData).getString(i));
sysFormFieldService.insertSysFormField(sysFormField);
//解析表单
JSONArray formDataArray = JSON.parseArray(formData);
for(int i=0;i<formDataArray.size();i++){
JSONObject fieldObject=formDataArray.getJSONObject(i);
//一行多列布局
if(fieldObject.getString("tag").equals(FormFieldTypeEnums.GRID.getCode())){
JSONObject gridObject = formDataArray.getJSONObject(i);
JSONArray columnArray= gridObject.getJSONArray("columns");
for(int j=0;j<columnArray.size();j++){
JSONObject columnObject = columnArray.getJSONObject(j);
JSONArray listArray = columnObject.getJSONArray("list");
for(int k=0;k<listArray.size();k++){
JSONObject listObject=listArray.getJSONObject(k);
FormFieldRequest formFieldRequest = listObject.toJavaObject(FormFieldRequest.class);
saveSysFormField(formFieldRequest,formId,JSON.toJSONString(listObject));
}
}
}
//正常单行布局
else {
FormFieldRequest formFieldRequest = fieldObject.toJavaObject(FormFieldRequest.class);
saveSysFormField(formFieldRequest,formId,JSON.toJSONString(fieldObject));
}
}
}
/**
* 保存
*/
public void saveSysFormField( FormFieldRequest formFieldRequest,Long formId,String jsonString){
SysFormField sysFormField = BeanUtil.copyProperties(formFieldRequest, SysFormField.class,"id");
sysFormField.setFromId(formId);
sysFormField.setFieldKey(formFieldRequest.getId());
sysFormField.setFieldName(formFieldRequest.getLabel());
sysFormField.setFieldType(formFieldRequest.getTag());
sysFormField.setFieldHtml(jsonString);
sysFormFieldService.insertSysFormField(sysFormField);
}
/**
* 生成二维码
*/
@GetMapping("/createQRCode")
public void createQRCode(@RequestParam("id") int id, HttpServletResponse response){
Object domain = CacheUtils.getSysConfig(CacheConstants.SYS_DOMAIN, "http://localhost");
QrConfig config = new QrConfig(500, 500);
// 设置边距既二维码和背景之间的边距
config.setMargin(3);
// 设置前景色既二维码颜色青色
config.setForeColor(Color.CYAN);
// 设置背景色灰色
config.setBackColor(Color.GRAY);
config.setQrVersion(10);
// config.setImg("https://qimetons.oss-cn-beijing.aliyuncs.com/45a22bcc93644dfe8bcacf690fe133f3.png");
// 生成二维码
BufferedImage bufferedImage = QrCodeUtil.generate(StrUtil.format("{}/toFormRecordDetail?id={}",domain,id), config);
try {
//以PNG格式向客户端发送
ServletOutputStream os = response.getOutputStream();
ImageIO.write(bufferedImage, "PNG",os);
os.flush();
os.close();
} catch (IOException e) {
throw new RuntimeException("生成二维码异常");
}
}
}

View File

@ -1,25 +0,0 @@
package com.snow.from.domain.response;
import lombok.Data;
import java.io.Serializable;
/**
* @program: snow
* @description
* @author: 没用的阿吉
* @create: 2021-11-24 21:56
**/
@Data
public class BaseFormDataResponse implements Serializable {
private static final long serialVersionUID = -5690261925196737207L;
/**
* 表单内容
*/
private String formData;
/**
* 表单字典
*/
private String formField;
}

View File

@ -0,0 +1,167 @@
package com.snow.from.util;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.snow.common.enums.FormFieldTypeEnums;
import com.snow.common.exception.BusinessException;
import com.snow.from.domain.field.InputField;
import java.util.Optional;
/**
* @author qimingjin
* @Title: DingFlow form表单工具类
* @Description:
* @date 2021/11/25 15:25
*/
public class FormUtils {
//选中标识
private static final String CHECKED="checked";
/**
* 填充表单值
* @param formData 原始表单数据json
* @param formField 用户填写的数据
* @return 返回组装后的json数据
*/
public static String fillFormFieldValue(String formData, String formField){
//填写的表单值
JSONObject formFieldObject = JSON.parseObject(formField);
//原始表单
JSONArray formDataArray = JSON.parseArray(formData);
//把填写的表单值装填到原始表单上
for(int i=0;i<formDataArray.size();i++){
JSONObject fieldObject=formDataArray.getJSONObject(i);
//一行多列布局
if(fieldObject.getString("tag").equals(FormFieldTypeEnums.GRID.getCode())){
JSONObject gridObject = formDataArray.getJSONObject(i);
JSONArray columnArray= gridObject.getJSONArray("columns");
for(int j=0;j<columnArray.size();j++){
JSONObject columnObject = columnArray.getJSONObject(j);
JSONArray listArray = columnObject.getJSONArray("list");
for(int k=0;k<listArray.size();k++){
//获取组件类型
String tag= JSON.parseObject(listArray.getString(k)).getString("tag");
JSONObject listObject=listArray.getJSONObject(k);
//根据组件类型填充值
fillValueField(tag,listObject,formFieldObject);
}
}
}else {
//正常单行布局
fillValueField(fieldObject.getString("tag"),fieldObject,formFieldObject);
}
}
return JSON.toJSONString(formDataArray);
}
private static void fillValueField(String tag,JSONObject listObject,JSONObject formFieldObject){
if(isDefaultValue(tag)){
warpDefaultValueField(listObject,formFieldObject);
} else if(tag.equals(FormFieldTypeEnums.SWITCH.getCode())){
warpSwitchValueField(listObject,formFieldObject);
} else if(tag.equals(FormFieldTypeEnums.SIGN.getCode())){
warpDateField(listObject,formFieldObject);
} else if(tag.equals(FormFieldTypeEnums.DATE.getCode())){
warpDateDefaultValueField(listObject,formFieldObject);
}else if(tag.equals(FormFieldTypeEnums.DATE_RANGE.getCode())){
warpDateRangeDefaultValueField(listObject,formFieldObject);
}else if(tag.equals(FormFieldTypeEnums.CHECKBOX.getCode())){
warpCheckBoxValueField(listObject,formFieldObject);
}else if(tag.equals(FormFieldTypeEnums.RADIO.getCode())){
warpCheckedValueField(listObject,formFieldObject,FormFieldTypeEnums.RADIO);
}else if(tag.equals(FormFieldTypeEnums.SELECT.getCode())){
warpCheckedValueField(listObject,formFieldObject,FormFieldTypeEnums.SELECT);
}else {
throw new BusinessException(StrUtil.format("暂不支持的组件:{}",tag));
}
}
/**
* 判断是否是默认值形式
* @param tag 表单字段类型
* @return 是否
*/
private static boolean isDefaultValue(String tag){
return tag.equals(FormFieldTypeEnums.INPUT.getCode()) || tag.equals(FormFieldTypeEnums.TEXTAREA.getCode()) || tag.equals(FormFieldTypeEnums.PASSWORD.getCode())
|| tag.equals(FormFieldTypeEnums.NUMBER_INPUT.getCode()) || tag.equals(FormFieldTypeEnums.RATE.getCode()) || tag.equals(FormFieldTypeEnums.CRON.getCode())
|| tag.equals(FormFieldTypeEnums.FILE.getCode()) ||tag.equals(FormFieldTypeEnums.IMAGE.getCode()) ||tag.equals(FormFieldTypeEnums.COLOR_PICKER.getCode())
||tag.equals(FormFieldTypeEnums.ICON_PICKER.getCode()) ||tag.equals(FormFieldTypeEnums.SLIDER.getCode());
}
//输入框
public static void warpDefaultValueField(JSONObject fieldObject,JSONObject formFieldObject ){
String value = formFieldObject.getString(fieldObject.getString("id"));
fieldObject.put("defaultValue",value);
}
//构建输入框对象
public static InputField warpInputField(JSONObject fieldObject, JSONObject formFieldObject ){
String value = formFieldObject.getString(fieldObject.getString("id"));
InputField inputField = fieldObject.toJavaObject(InputField.class);
inputField.setDefaultValue(value);
return inputField;
}
//开关
public static void warpSwitchValueField(JSONObject fieldObject,JSONObject formFieldObject ){
String value = formFieldObject.getString(fieldObject.getString("id"));
fieldObject.put("switchValue",value);
}
//日期
public static void warpDateDefaultValueField(JSONObject fieldObject,JSONObject formFieldObject ){
String value = formFieldObject.getString(StrUtil.format("date{}",fieldObject.getString("id")));
fieldObject.put("dateDefaultValue",value);
}
//日期范围
public static void warpDateRangeDefaultValueField(JSONObject fieldObject,JSONObject formFieldObject ){
String startValue = formFieldObject.getString(StrUtil.format("start{}",fieldObject.getString("id")));
String endValue = formFieldObject.getString(StrUtil.format("end{}",fieldObject.getString("id")));
fieldObject.put("dateRangeDefaultValue",StrUtil.format("{} - {}",startValue,endValue));
}
//签名sign
public static void warpDateField(JSONObject fieldObject,JSONObject formFieldObject ){
String value = formFieldObject.getString(fieldObject.getString("id"));
fieldObject.put("data",value);
}
//下拉和单选
public static void warpCheckedValueField(JSONObject fieldObject,JSONObject formFieldObject,FormFieldTypeEnums formFieldTypeEnums){
String value = formFieldObject.getString(fieldObject.getString("id"));
if(formFieldTypeEnums.getCode().equals(FormFieldTypeEnums.SELECT.getCode())){
fieldObject.put("remoteDefaultValue",value);
}
JSONArray optionsArray= fieldObject.getJSONArray("options");
for(int k=0;k<optionsArray.size();k++){
JSONObject optionObject = optionsArray.getJSONObject(k);
//值相等则设置为checked
if(optionObject.get("value").equals(value)){
optionObject.put(CHECKED,true);
}else {
optionObject.put(CHECKED,false);
}
}
}
//复选框赋值
public static void warpCheckBoxValueField(JSONObject fieldObject,JSONObject formFieldObject){
JSONArray optionsArray= fieldObject.getJSONArray("options");
for(int k=0;k<optionsArray.size();k++){
JSONObject optionObject = optionsArray.getJSONObject(k);
String key=StrUtil.format("{}[{}]",fieldObject.getString("id"),optionObject.get("value"));
String value = Optional.ofNullable(formFieldObject.getString(key)).orElse("off");
//如果为on 则checked选中
if(value.equals("on")){
optionObject.put(CHECKED,true);
}else {
optionObject.put(CHECKED,false);
}
}
}
}

View File

@ -412,7 +412,7 @@ layui.define(['layer'], function (exports) {
defaultValue: null,
width:"100%",
readonly: false,
disabled: false,//这里就是readonly的医生
disabled: false,
required: true,
document: ''
},

View File

@ -43,6 +43,25 @@
</div>
</div>
</div>
<div class="modal fade" id="formQRCode" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content animated fadeIn">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
<h4 class="modal-title text-primary">表单二维码</h4>
</div>
<div class="modal-body">
<div class="form-group">
<img class="imgcode" width="85%"/>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-white" data-dismiss="modal">关闭</button>
</div>
</div>
</div>
</div>
<th:block th:include="include :: footer" />
<script th:inline="javascript">
var editFlag = [[${@permission.hasPermi('system:instance:edit')}]];
@ -83,6 +102,7 @@
actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.edit(\'' + row.id + '\')"><i class="fa fa-edit"></i>编辑</a> ');
actions.push('<a class="btn btn-success btn-xs" href="javascript:void(0)" onclick="fromDetail(\'' + row.id+ '\')"><i class="fa fa-add"></i>填写表单</a> ');
actions.push('<a class="btn btn-success btn-xs" href="javascript:void(0)" onclick="formRecordDetail(\'' + row.id+ '\')"><i class="fa fa-eyes"></i>查看表单</a> ');
actions.push('<a class="btn btn-success btn-xs" data-toggle="modal" data-target="#formQRCode" th:data-id="' + row.id+ '" ><i class="fa fa-add"></i>二维码</a> ');
actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="$.operate.remove(\'' + row.id + '\')"><i class="fa fa-remove"></i>删除</a>');
return actions.join('');
}
@ -104,6 +124,21 @@
var detailUrl="/from/instance/formRecord?id="+id;
$.modal.openTab("表单数据列表", detailUrl);
}
function createQRCode(id) {
var detailUrl="/createQRCode?id="+id;
$.modal.open("表单二维码", detailUrl);
}
$('#formQRCode').on('show.bs.modal', function (event) {
var button = $(event.relatedTarget)
console.log("=====>"+JSON.stringify(button));
var id = button.data('id')
console.log("=====>"+id);
var url ="/createQRCode?id="+id;
$(".imgcode").attr("src", url);
});
</script>
</body>
</html>

View File

@ -38,7 +38,7 @@
url: "/from/instance/recordList",
removeUrl: "/from/instance/removeRecord",
queryParams:queryParams,
modalName: "数据记录",
modalName: "数据记录",
columns: [{
checkbox: true
},