Procházet zdrojové kódy

优化动态表单

zhouhao před 7 roky
rodič
revize
486da6e605
15 změnil soubory, kde provedl 376 přidání a 55 odebrání
  1. 1 0
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/annotation/Authorize.java
  2. 1 1
      hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/CreateController.java
  3. 1 1
      hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/QueryController.java
  4. 53 14
      hsweb-system/hsweb-system-dynamic-form/hsweb-system-dynamic-form-controller/src/main/java/org/hswebframework/web/controller/form/DynamicFormColumnController.java
  5. 53 2
      hsweb-system/hsweb-system-dynamic-form/hsweb-system-dynamic-form-controller/src/main/java/org/hswebframework/web/controller/form/DynamicFormController.java
  6. 7 0
      hsweb-system/hsweb-system-dynamic-form/hsweb-system-dynamic-form-controller/src/main/java/org/hswebframework/web/controller/form/DynamicFormDeployLogController.java
  7. 7 3
      hsweb-system/hsweb-system-dynamic-form/hsweb-system-dynamic-form-dao/hsweb-system-dynamic-form-dao-api/src/main/java/org/hswebframework/web/dao/form/DynamicFormDao.java
  8. 4 0
      hsweb-system/hsweb-system-dynamic-form/hsweb-system-dynamic-form-dao/hsweb-system-dynamic-form-dao-mybatis/src/main/resources/org/hswebframework/web/dao/mybatis/mappers/form/DynamicFormMapper.xml
  9. 42 0
      hsweb-system/hsweb-system-dynamic-form/hsweb-system-dynamic-form-entity/src/main/java/org/hswebframework/web/entity/form/DynamicFormColumnBindEntity.java
  10. 7 0
      hsweb-system/hsweb-system-dynamic-form/hsweb-system-dynamic-form-entity/src/main/java/org/hswebframework/web/entity/form/DynamicFormColumnEntity.java
  11. 15 4
      hsweb-system/hsweb-system-dynamic-form/hsweb-system-dynamic-form-entity/src/main/java/org/hswebframework/web/entity/form/DynamicFormEntity.java
  12. 20 0
      hsweb-system/hsweb-system-dynamic-form/hsweb-system-dynamic-form-service/hsweb-system-dynamic-form-service-api/src/main/java/org/hswebframework/web/service/form/DynamicFormService.java
  13. 151 22
      hsweb-system/hsweb-system-dynamic-form/hsweb-system-dynamic-form-service/hsweb-system-dynamic-form-service-simple/src/main/java/org/hswebframework/web/service/form/simple/SimpleDynamicFormService.java
  14. 10 7
      hsweb-system/hsweb-system-dynamic-form/hsweb-system-dynamic-form-starter/src/test/java/org/hswebframework/web/service/form/simple/SimpleDynamicFormServiceTest.java
  15. 4 1
      hsweb-system/hsweb-system-dynamic-form/hsweb-system-dynamic-form-starter/src/test/resources/application.yml

+ 1 - 0
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/annotation/Authorize.java

@@ -28,6 +28,7 @@ import java.lang.annotation.*;
  * 基础权限控制注解,提供基本的控制配置
  *
  * @author zhouhao
+ * @see org.hswebframework.web.authorization.Authentication
  * @since 3.0
  */
 @Target({ElementType.TYPE, ElementType.METHOD})

+ 1 - 1
hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/CreateController.java

@@ -54,7 +54,7 @@ public interface CreateController<E, PK, M> {
     @PostMapping
     @AccessLogger("{action_add}")
     @ResponseStatus(HttpStatus.CREATED)
-    @ApiOperation(value = "创建数据")
+    @ApiOperation(value = "创建数据", responseReference = "add")
     @ApiResponses({
             @ApiResponse(code = 201, message = "创建成功,返回创建数据的ID"),
             @ApiResponse(code = 401, message = "未授权"),

+ 1 - 1
hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/QueryController.java

@@ -68,7 +68,7 @@ public interface QueryController<E, PK, Q extends Entity> {
     @Authorize(action = Permission.ACTION_QUERY)
     @GetMapping
     @AccessLogger("{dynamic_query}")
-    @ApiOperation("根据动态条件查询数据")
+    @ApiOperation(value = "根据动态条件查询数据", responseReference = "get")
     @ApiResponses({
             @ApiResponse(code = 200, message = "查询成功"),
             @ApiResponse(code = 401, message = "未授权"),

+ 53 - 14
hsweb-system/hsweb-system-dynamic-form/hsweb-system-dynamic-form-controller/src/main/java/org/hswebframework/web/controller/form/DynamicFormColumnController.java

@@ -1,14 +1,17 @@
 package org.hswebframework.web.controller.form;
 
-import org.hswebframework.web.entity.form.DynamicFormColumnEntity;
-import org.hswebframework.web.service.form.DynamicFormColumnService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.hswebframework.web.authorization.Permission;
 import org.hswebframework.web.authorization.annotation.Authorize;
-import org.hswebframework.web.commons.entity.param.QueryParamEntity;
-import org.hswebframework.web.controller.SimpleGenericEntityController;
+import org.hswebframework.web.controller.message.ResponseMessage;
+import org.hswebframework.web.entity.form.DynamicFormColumnEntity;
 import org.hswebframework.web.logging.AccessLogger;
+import org.hswebframework.web.service.form.DynamicFormService;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
 
 /**
  * 动态表单
@@ -16,21 +19,57 @@ import org.springframework.web.bind.annotation.RestController;
  * @author hsweb-generator-online
  */
 @RestController
-@RequestMapping("${hsweb.web.mappings.dynamic/form/column:dynamic/form-column}")
+@RequestMapping("${hsweb.web.mappings.dynamic/form/column:dynamic/form/column}")
 @Authorize(permission = "dynamic-form")
 @AccessLogger("动态表单")
-public class DynamicFormColumnController implements SimpleGenericEntityController<DynamicFormColumnEntity, String, QueryParamEntity> {
+@Api(tags = "dynamic-form", description = "动态表单")
+public class DynamicFormColumnController {
 
-    private DynamicFormColumnService dynamicFormColumnService;
+    private DynamicFormService dynamicFormService;
 
     @Autowired
-    public void setDynamicFormColumnService(DynamicFormColumnService dynamicFormColumnService) {
-        this.dynamicFormColumnService = dynamicFormColumnService;
+    public void setDynamicFormService(DynamicFormService dynamicFormService) {
+        this.dynamicFormService = dynamicFormService;
+    }
+
+    @PatchMapping("/batch")
+    @Authorize(action = Permission.ACTION_ADD)
+    @AccessLogger("保存多个表单列")
+    @ApiOperation("保存多个表单列")
+    public ResponseMessage<List<String>> add(@RequestBody List<DynamicFormColumnEntity> columnEntities) {
+        return ResponseMessage.ok(dynamicFormService.saveOrUpdateColumn(columnEntities));
+    }
+
+    @PatchMapping
+    @Authorize(action = Permission.ACTION_ADD)
+    @AccessLogger("保存表单列")
+    @ApiOperation("保存表单列")
+    public ResponseMessage<String> add(@RequestBody DynamicFormColumnEntity columnEntity) {
+        return ResponseMessage.ok(dynamicFormService.saveOrUpdateColumn(columnEntity));
+    }
+
+    @DeleteMapping
+    @Authorize(action = Permission.ACTION_DELETE)
+    @AccessLogger("删除列")
+    @ApiOperation("删除列")
+    public ResponseMessage<DynamicFormColumnEntity> delete(String id) {
+        return ResponseMessage.ok(dynamicFormService.deleteColumn(id));
+    }
+
+    @DeleteMapping("/batch")
+    @Authorize(action = Permission.ACTION_DELETE)
+    @AccessLogger("删除多列")
+    @ApiOperation("删除多列")
+    public ResponseMessage<List<DynamicFormColumnEntity>> delete(List<String> id) {
+        return ResponseMessage.ok(dynamicFormService.deleteColumn(id));
     }
 
-    @Override
-    public DynamicFormColumnService getService() {
-        return dynamicFormColumnService;
+    @GetMapping("/{formId}")
+    @Authorize(action = Permission.ACTION_GET)
+    @AccessLogger("获取表单的所有列")
+    @ApiOperation("获取表单的所有列")
+    public ResponseMessage<List<DynamicFormColumnEntity>> getByFormId(@PathVariable String formId) {
+        return ResponseMessage.ok(dynamicFormService.selectColumnsByFormId(formId));
     }
 
 }

+ 53 - 2
hsweb-system/hsweb-system-dynamic-form/hsweb-system-dynamic-form-controller/src/main/java/org/hswebframework/web/controller/form/DynamicFormController.java

@@ -1,14 +1,17 @@
 package org.hswebframework.web.controller.form;
 
+import io.swagger.annotations.Api;
+import org.hswebframework.web.authorization.Authentication;
 import org.hswebframework.web.authorization.annotation.Authorize;
 import org.hswebframework.web.commons.entity.param.QueryParamEntity;
 import org.hswebframework.web.controller.SimpleGenericEntityController;
+import org.hswebframework.web.controller.message.ResponseMessage;
+import org.hswebframework.web.entity.form.DynamicFormColumnBindEntity;
 import org.hswebframework.web.entity.form.DynamicFormEntity;
 import org.hswebframework.web.logging.AccessLogger;
 import org.hswebframework.web.service.form.DynamicFormService;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 
 /**
  * 动态表单
@@ -19,6 +22,7 @@ import org.springframework.web.bind.annotation.RestController;
 @RequestMapping("${hsweb.web.mappings.dynamic/form:dynamic/form}")
 @Authorize(permission = "dynamic-form")
 @AccessLogger("动态表单")
+@Api(tags = "dynamic-form", description = "动态表单")
 public class DynamicFormController implements SimpleGenericEntityController<DynamicFormEntity, String, QueryParamEntity> {
 
     private DynamicFormService dynamicFormService;
@@ -32,4 +36,51 @@ public class DynamicFormController implements SimpleGenericEntityController<Dyna
     public DynamicFormService getService() {
         return dynamicFormService;
     }
+
+    @Override
+    public ResponseMessage<String> add(@RequestBody DynamicFormEntity data) {
+        Authentication authentication = Authentication.current().orElse(null);
+        if (null != authentication) {
+            data.setCreatorId(authentication.getUser().getId());
+        }
+        data.setCreateTime(System.currentTimeMillis());
+        return SimpleGenericEntityController.super.add(data);
+    }
+
+    @PutMapping("/{id}/deploy")
+    @Authorize(action = "deploy")
+    @AccessLogger("发布表单")
+    public ResponseMessage<Void> deploy(@PathVariable String id) {
+        dynamicFormService.deploy(id);
+        return ResponseMessage.ok();
+    }
+
+    @PutMapping("/{id}/un-deploy")
+    @Authorize(action = "deploy")
+    @AccessLogger("取消发布表单")
+    public ResponseMessage<Void> unDeploy(@PathVariable String id) {
+        dynamicFormService.unDeploy(id);
+        return ResponseMessage.ok();
+    }
+
+    @GetMapping("/{id}/editing")
+    @Authorize(action = "get")
+    @AccessLogger("获取当前正在编辑的表单")
+    public ResponseMessage<DynamicFormColumnBindEntity> getEditing(@PathVariable String id) {
+        return ResponseMessage.ok(dynamicFormService.selectEditing(id));
+    }
+
+    @GetMapping("/{id}/latest")
+    @Authorize(action = "get")
+    @AccessLogger("获取最新发布的表单")
+    public ResponseMessage<DynamicFormColumnBindEntity> selectDeployed(@PathVariable String id) {
+        return ResponseMessage.ok(dynamicFormService.selectLatestDeployed(id));
+    }
+
+    @GetMapping("/{id}/{version:\\d+}")
+    @Authorize(action = "get")
+    @AccessLogger("获取指定版本的表单")
+    public ResponseMessage<DynamicFormColumnBindEntity> selectDeployed(@PathVariable String id, @PathVariable int version) {
+        return ResponseMessage.ok(dynamicFormService.selectDeployed(id, version));
+    }
 }

+ 7 - 0
hsweb-system/hsweb-system-dynamic-form/hsweb-system-dynamic-form-controller/src/main/java/org/hswebframework/web/controller/form/DynamicFormDeployLogController.java

@@ -3,13 +3,18 @@ package org.hswebframework.web.controller.form;
 import org.hswebframework.web.authorization.annotation.Authorize;
 import org.hswebframework.web.commons.entity.param.QueryParamEntity;
 import org.hswebframework.web.controller.SimpleGenericEntityController;
+import org.hswebframework.web.controller.message.ResponseMessage;
 import org.hswebframework.web.entity.form.DynamicFormDeployLogEntity;
 import org.hswebframework.web.logging.AccessLogger;
 import  org.hswebframework.web.service.form.DynamicFormDeployLogService;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PutMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
+import java.util.List;
+
 /**
  *  表单发布日志
  *
@@ -32,4 +37,6 @@ public class DynamicFormDeployLogController implements SimpleGenericEntityContro
     public DynamicFormDeployLogService getService() {
         return dynamicFormDeployLogService;
     }
+
+
 }

+ 7 - 3
hsweb-system/hsweb-system-dynamic-form/hsweb-system-dynamic-form-dao/hsweb-system-dynamic-form-dao-api/src/main/java/org/hswebframework/web/dao/form/DynamicFormDao.java

@@ -3,9 +3,13 @@ package org.hswebframework.web.dao.form;
 import org.hswebframework.web.dao.CrudDao;
 import org.hswebframework.web.entity.form.DynamicFormEntity;
 
+import java.util.concurrent.atomic.AtomicInteger;
+
 /**
-*  动态表单 DAO接口
-*  @author hsweb-generator-online
+ * 动态表单 DAO接口
+ *
+ * @author hsweb-generator-online
  */
-public interface DynamicFormDao extends CrudDao<DynamicFormEntity,String> {
+public interface DynamicFormDao extends CrudDao<DynamicFormEntity, String> {
+    void incrementVersion(String formId);
 }

+ 4 - 0
hsweb-system/hsweb-system-dynamic-form/hsweb-system-dynamic-form-dao/hsweb-system-dynamic-form-dao-mybatis/src/main/resources/org/hswebframework/web/dao/mybatis/mappers/form/DynamicFormMapper.xml

@@ -46,6 +46,10 @@
         <include refid="BasicMapper.buildUpdateSql"/>
     </update>
 
+    <update id="incrementVersion" parameterType="String">
+        update s_dyn_form set version=version+1 where u_id = #{id}
+    </update>
+
     <select id="query" parameterType="org.hswebframework.web.commons.entity.Entity" resultMap="DynamicFormResultMap">
         <include refid="config"/>
         <include refid="BasicMapper.buildSelectSql"/>

+ 42 - 0
hsweb-system/hsweb-system-dynamic-form/hsweb-system-dynamic-form-entity/src/main/java/org/hswebframework/web/entity/form/DynamicFormColumnBindEntity.java

@@ -0,0 +1,42 @@
+package org.hswebframework.web.entity.form;
+
+import org.hswebframework.web.commons.entity.Entity;
+
+import java.util.List;
+
+/**
+ * 动态表单和表单列关联实体
+ *
+ * @author zhouhao
+ * @since 3.0
+ */
+public class DynamicFormColumnBindEntity implements Entity {
+    private DynamicFormEntity form;
+
+    private List<DynamicFormColumnEntity> columns;
+
+
+    public DynamicFormColumnBindEntity() {
+    }
+
+    public DynamicFormColumnBindEntity(DynamicFormEntity form, List<DynamicFormColumnEntity> columns) {
+        this.form = form;
+        this.columns = columns;
+    }
+
+    public DynamicFormEntity getForm() {
+        return form;
+    }
+
+    public void setForm(DynamicFormEntity form) {
+        this.form = form;
+    }
+
+    public List<DynamicFormColumnEntity> getColumns() {
+        return columns;
+    }
+
+    public void setColumns(List<DynamicFormColumnEntity> columns) {
+        this.columns = columns;
+    }
+}

+ 7 - 0
hsweb-system/hsweb-system-dynamic-form/hsweb-system-dynamic-form-entity/src/main/java/org/hswebframework/web/entity/form/DynamicFormColumnEntity.java

@@ -1,6 +1,8 @@
 package org.hswebframework.web.entity.form;
 
+import org.hibernate.validator.constraints.NotBlank;
 import org.hswebframework.web.commons.entity.GenericEntity;
+import org.hswebframework.web.validator.group.CreateGroup;
 
 /**
  * 动态表单 实体
@@ -74,6 +76,7 @@ public interface DynamicFormColumnEntity extends GenericEntity<String> {
     /**
      * @return 表单ID
      */
+    @NotBlank(groups = CreateGroup.class)
     String getFormId();
 
     /**
@@ -84,6 +87,7 @@ public interface DynamicFormColumnEntity extends GenericEntity<String> {
     /**
      * @return 字段名称
      */
+    @NotBlank(groups = CreateGroup.class)
     String getName();
 
     /**
@@ -94,6 +98,7 @@ public interface DynamicFormColumnEntity extends GenericEntity<String> {
     /**
      * @return 数据库列
      */
+    @NotBlank(groups = CreateGroup.class)
     String getColumnName();
 
     /**
@@ -124,6 +129,7 @@ public interface DynamicFormColumnEntity extends GenericEntity<String> {
     /**
      * @return java类型
      */
+    @NotBlank(groups = CreateGroup.class)
     String getJavaType();
 
     /**
@@ -134,6 +140,7 @@ public interface DynamicFormColumnEntity extends GenericEntity<String> {
     /**
      * @return jdbc类型
      */
+    @NotBlank(groups = CreateGroup.class)
     String getJdbcType();
 
     /**

+ 15 - 4
hsweb-system/hsweb-system-dynamic-form/hsweb-system-dynamic-form-entity/src/main/java/org/hswebframework/web/entity/form/DynamicFormEntity.java

@@ -1,6 +1,9 @@
 package org.hswebframework.web.entity.form;
 
+import io.swagger.annotations.ApiModelProperty;
+import org.hibernate.validator.constraints.NotBlank;
 import org.hswebframework.web.commons.entity.GenericEntity;
+import org.hswebframework.web.validator.group.CreateGroup;
 
 /**
  * 动态表单 实体
@@ -59,10 +62,6 @@ public interface DynamicFormEntity extends GenericEntity<String> {
      * 数据源id,为空使用默认数据源
      */
     String dataSourceId      = "dataSourceId";
-    /**
-     * 其他配置
-     */
-    String properties        = "properties";
     /**
      * 表单类型
      */
@@ -71,6 +70,8 @@ public interface DynamicFormEntity extends GenericEntity<String> {
     /**
      * @return 表单名称
      */
+    @ApiModelProperty(value = "表单名称", required = true, example = "测试表单")
+    @NotBlank(groups = CreateGroup.class)
     String getName();
 
     /**
@@ -81,6 +82,8 @@ public interface DynamicFormEntity extends GenericEntity<String> {
     /**
      * @return 数据库表名
      */
+    @ApiModelProperty(value = "数据库表名", required = true, example = "f_test_form")
+    @NotBlank(groups = CreateGroup.class)
     String getDatabaseTableName();
 
     /**
@@ -91,6 +94,7 @@ public interface DynamicFormEntity extends GenericEntity<String> {
     /**
      * @return 备注
      */
+
     String getDescribe();
 
     /**
@@ -101,6 +105,7 @@ public interface DynamicFormEntity extends GenericEntity<String> {
     /**
      * @return 版本
      */
+    @ApiModelProperty(value = "版本号,无需设置,每次保存自动自增.", example = "1")
     Long getVersion();
 
     /**
@@ -111,6 +116,7 @@ public interface DynamicFormEntity extends GenericEntity<String> {
     /**
      * @return 创建人id
      */
+    @ApiModelProperty(value = "创建人,根据当前用户自动获取.", example = "1")
     String getCreatorId();
 
     /**
@@ -121,6 +127,7 @@ public interface DynamicFormEntity extends GenericEntity<String> {
     /**
      * @return 创建时间
      */
+    @ApiModelProperty(value = "创建时间,新增时自动设置.")
     Long getCreateTime();
 
     /**
@@ -131,6 +138,7 @@ public interface DynamicFormEntity extends GenericEntity<String> {
     /**
      * @return 修改时间
      */
+    @ApiModelProperty(value = "创建时间,修改时自动设置.")
     Long getUpdateTime();
 
     /**
@@ -141,6 +149,7 @@ public interface DynamicFormEntity extends GenericEntity<String> {
     /**
      * @return 是否已发布
      */
+    @ApiModelProperty(value = "是否已发布,发布时自动设置.", example = "false")
     Boolean isDeployed();
 
     /**
@@ -151,6 +160,7 @@ public interface DynamicFormEntity extends GenericEntity<String> {
     /**
      * @return 别名
      */
+    @ApiModelProperty(value = "表别名.", example = "testForm")
     String getAlias();
 
     /**
@@ -161,6 +171,7 @@ public interface DynamicFormEntity extends GenericEntity<String> {
     /**
      * @return 触发器
      */
+    @ApiModelProperty(value = "触发器.", example = "[{\"language\":\"groovy\",\"script\":\" return true;\"}]")
     String getTriggers();
 
     /**

+ 20 - 0
hsweb-system/hsweb-system-dynamic-form/hsweb-system-dynamic-form-service/hsweb-system-dynamic-form-service-api/src/main/java/org/hswebframework/web/service/form/DynamicFormService.java

@@ -1,8 +1,12 @@
 package org.hswebframework.web.service.form;
 
+import org.hswebframework.web.entity.form.DynamicFormColumnBindEntity;
+import org.hswebframework.web.entity.form.DynamicFormColumnEntity;
 import org.hswebframework.web.entity.form.DynamicFormEntity;
 import org.hswebframework.web.service.CrudService;
 
+import java.util.List;
+
 /**
  * 动态表单 服务类
  *
@@ -17,4 +21,20 @@ public interface DynamicFormService extends CrudService<DynamicFormEntity, Strin
 
     void unDeploy(String formId);
 
+    String saveOrUpdateColumn(DynamicFormColumnEntity columnEntity);
+
+    List<String> saveOrUpdateColumn(List<DynamicFormColumnEntity> columnEntities);
+
+    DynamicFormColumnEntity deleteColumn(String id);
+
+    List<DynamicFormColumnEntity> deleteColumn(List<String> ids);
+
+    List<DynamicFormColumnEntity> selectColumnsByFormId(String formId);
+
+    DynamicFormColumnBindEntity selectLatestDeployed(String formId);
+
+    DynamicFormColumnBindEntity selectEditing(String formId);
+
+    DynamicFormColumnBindEntity selectDeployed(String formId, int version);
+
 }

+ 151 - 22
hsweb-system/hsweb-system-dynamic-form/hsweb-system-dynamic-form-service/hsweb-system-dynamic-form-service-simple/src/main/java/org/hswebframework/web/service/form/simple/SimpleDynamicFormService.java

@@ -1,7 +1,6 @@
 package org.hswebframework.web.service.form.simple;
 
 import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONObject;
 import org.hsweb.ezorm.core.ValueConverter;
 import org.hsweb.ezorm.rdb.RDBDatabase;
 import org.hsweb.ezorm.rdb.meta.RDBColumnMetaData;
@@ -11,26 +10,32 @@ import org.hsweb.ezorm.rdb.render.dialect.Dialect;
 import org.hswebframework.web.commons.entity.DataStatus;
 import org.hswebframework.web.dao.form.DynamicFormColumnDao;
 import org.hswebframework.web.dao.form.DynamicFormDao;
+import org.hswebframework.web.entity.form.DynamicFormColumnBindEntity;
 import org.hswebframework.web.entity.form.DynamicFormColumnEntity;
 import org.hswebframework.web.entity.form.DynamicFormDeployLogEntity;
 import org.hswebframework.web.entity.form.DynamicFormEntity;
 import org.hswebframework.web.id.IDGenerator;
+import org.hswebframework.web.service.DefaultDSLDeleteService;
 import org.hswebframework.web.service.DefaultDSLQueryService;
+import org.hswebframework.web.service.DefaultDSLUpdateService;
 import org.hswebframework.web.service.GenericEntityService;
 import org.hswebframework.web.service.form.DatabaseRepository;
 import org.hswebframework.web.service.form.DynamicFormDeployLogService;
 import org.hswebframework.web.service.form.DynamicFormService;
 import org.hswebframework.web.service.form.OptionalConvertBuilder;
+import org.hswebframework.web.validator.group.CreateGroup;
+import org.hswebframework.web.validator.group.UpdateGroup;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheConfig;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.cache.annotation.Cacheable;
 import org.springframework.stereotype.Service;
 import org.springframework.util.StringUtils;
 
 import java.sql.JDBCType;
 import java.sql.SQLException;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * 默认的服务实现
@@ -38,6 +43,7 @@ import java.util.Map;
  * @author hsweb-generator-online
  */
 @Service("dynamicFormService")
+@CacheConfig(cacheNames = "dyn-form")
 public class SimpleDynamicFormService extends GenericEntityService<DynamicFormEntity, String>
         implements DynamicFormService {
     @Autowired
@@ -65,11 +71,6 @@ public class SimpleDynamicFormService extends GenericEntityService<DynamicFormEn
         return dynamicFormDao;
     }
 
-    @Override
-    public int updateByPk(String s, DynamicFormEntity entity) {
-        return super.updateByPk(s, entity);
-    }
-
     @Override
     public void deployAllFromLog() {
         List<DynamicFormEntity> entities = createQuery()
@@ -88,6 +89,7 @@ public class SimpleDynamicFormService extends GenericEntityService<DynamicFormEn
     }
 
     @Override
+    @CacheEvict(value = "dyn-form-deploy", allEntries = true)
     public void deployAll() {
         createQuery()
                 .select(DynamicFormEntity.id)
@@ -101,30 +103,51 @@ public class SimpleDynamicFormService extends GenericEntityService<DynamicFormEn
         entity.setDeployTime(System.currentTimeMillis());
         entity.setVersion(form.getVersion());
         entity.setFormId(form.getId());
-        Map<String, Object> meta = new HashMap<>();
-        meta.put("form", form);
-        meta.put("columns", columns);
-        entity.setMetaData(JSON.toJSONString(meta));
+        DynamicFormColumnBindEntity bindEntity = new DynamicFormColumnBindEntity();
+        bindEntity.setForm(form);
+        bindEntity.setColumns(columns);
+        entity.setMetaData(JSON.toJSONString(bindEntity));
         return entity;
     }
 
     public void deployFromLog(DynamicFormDeployLogEntity logEntity) {
-        JSONObject metadata = JSON.parseObject(logEntity.getMetaData());
-        DynamicFormEntity form = metadata.getObject("form", DynamicFormEntity.class);
-        List<DynamicFormColumnEntity> columns = metadata.getJSONArray("columns").toJavaList(DynamicFormColumnEntity.class);
+        DynamicFormColumnBindEntity entity = JSON.parseObject(logEntity.getMetaData(), DynamicFormColumnBindEntity.class);
+        DynamicFormEntity form = entity.getForm();
+        List<DynamicFormColumnEntity> columns = entity.getColumns();
         if (logger.isDebugEnabled()) {
             logger.debug("do deploy form {} , columns size:{}", form.getName(), columns.size());
         }
         deploy(form, columns);
     }
 
+
     @Override
+    @CacheEvict(key = "'form_id:'+#entity.id")
     public String insert(DynamicFormEntity entity) {
         entity.setDeployed(false);
+        entity.setVersion(1L);
+        entity.setCreateTime(System.currentTimeMillis());
         return super.insert(entity);
     }
 
     @Override
+    @CacheEvict(key = "'form_id:'+#id")
+    public DynamicFormEntity selectByPk(String id) {
+        return super.selectByPk(id);
+    }
+
+    @Override
+    @CacheEvict(key = "'form_id:'+#id")
+    public int updateByPk(String id, DynamicFormEntity entity) {
+        entity.setVersion(null);
+        entity.setDeployed(null);
+        entity.setUpdateTime(System.currentTimeMillis());
+        getDao().incrementVersion(id);
+        return super.updateByPk(id, entity);
+    }
+
+    @Override
+    @CacheEvict(value = "dyn-form-deploy", allEntries = true)
     public void unDeploy(String formId) {
         DynamicFormEntity form = selectByPk(formId);
         assertNotNull(form);
@@ -137,6 +160,111 @@ public class SimpleDynamicFormService extends GenericEntityService<DynamicFormEn
         database.removeTable(form.getDatabaseTableName());
     }
 
+    private String saveOrUpdate0(DynamicFormColumnEntity columnEntity) {
+        if (StringUtils.isEmpty(columnEntity.getId())
+                || DefaultDSLQueryService.createQuery(formColumnDao)
+                .where(DynamicFormColumnEntity.id, columnEntity.getId())
+                .total() == 0) {
+            if (StringUtils.isEmpty(columnEntity.getId())) {
+                columnEntity.setId(getIDGenerator().generate());
+            }
+            tryValidate(columnEntity, CreateGroup.class);
+            formColumnDao.insert(columnEntity);
+        } else {
+            tryValidate(columnEntity, UpdateGroup.class);
+            DefaultDSLUpdateService
+                    .createUpdate(formColumnDao, columnEntity)
+                    .where(DynamicFormColumnEntity.id, columnEntity.getId())
+                    .exec();
+        }
+        return columnEntity.getId();
+    }
+
+    @Override
+    @CacheEvict(key = "'form-columns:'+#columnEntity.formId")
+    public String saveOrUpdateColumn(DynamicFormColumnEntity columnEntity) {
+        String id = saveOrUpdate0(columnEntity);
+        getDao().incrementVersion(columnEntity.getFormId());
+        return id;
+    }
+
+    @Override
+    @CacheEvict(allEntries = true)
+    public List<String> saveOrUpdateColumn(List<DynamicFormColumnEntity> columnEntities) {
+        Set<String> formId = new HashSet<>();
+
+        List<String> columnIds = columnEntities.stream()
+                .peek(columnEntity -> formId.add(columnEntity.getFormId()))
+                .map(this::saveOrUpdateColumn)
+                .collect(Collectors.toList());
+
+        formId.forEach(getDao()::incrementVersion);
+        return columnIds;
+
+    }
+
+    @Override
+    @CacheEvict(key = "'form-columns:'+#formId")
+    public DynamicFormColumnEntity deleteColumn(String formId) {
+        DynamicFormColumnEntity oldColumn = DefaultDSLQueryService
+                .createQuery(formColumnDao)
+                .where(DynamicFormColumnEntity.id, formId)
+                .single();
+        assertNotNull(oldColumn);
+        DefaultDSLDeleteService.createDelete(formColumnDao)
+                .where(DynamicFormDeployLogEntity.id, formId)
+                .exec();
+        return oldColumn;
+    }
+
+    @Override
+    @CacheEvict(allEntries = true)
+    public List<DynamicFormColumnEntity> deleteColumn(List<String> ids) {
+        Objects.requireNonNull(ids);
+        if (ids.isEmpty()) return Collections.emptyList();
+        List<DynamicFormColumnEntity> oldColumns = DefaultDSLQueryService
+                .createQuery(formColumnDao)
+                .where()
+                .in(DynamicFormColumnEntity.id, ids)
+                .listNoPaging();
+
+        DefaultDSLDeleteService.createDelete(formColumnDao)
+                .where().in(DynamicFormDeployLogEntity.id, ids)
+                .exec();
+        return oldColumns;
+    }
+
+    @Override
+    public List<DynamicFormColumnEntity> selectColumnsByFormId(String formId) {
+        Objects.requireNonNull(formId);
+        return DefaultDSLQueryService.createQuery(formColumnDao)
+                .where(DynamicFormColumnEntity.formId, formId)
+                .listNoPaging();
+    }
+
+    @Override
+    @Cacheable(value = "dyn-form-deploy", key = "'form-deploy:'+#formId+':'+#version")
+    public DynamicFormColumnBindEntity selectDeployed(String formId, int version) {
+        DynamicFormDeployLogEntity entity = dynamicFormDeployLogService.selectDeployed(formId, version);
+        assertNotNull(entity);
+        return JSON.parseObject(entity.getMetaData(), DynamicFormColumnBindEntity.class);
+    }
+
+    @Override
+    @Cacheable(value = "dyn-form-deploy", key = "'form-deploy:'+#formId+':latest'")
+    public DynamicFormColumnBindEntity selectLatestDeployed(String formId) {
+        DynamicFormDeployLogEntity entity = dynamicFormDeployLogService.selectLastDeployed(formId);
+        assertNotNull(entity);
+        return JSON.parseObject(entity.getMetaData(), DynamicFormColumnBindEntity.class);
+    }
+
+    @Override
+    public DynamicFormColumnBindEntity selectEditing(String formId) {
+        Objects.requireNonNull(formId);
+        return new DynamicFormColumnBindEntity(selectByPk(formId), selectColumnsByFormId(formId));
+    }
+
+    @CacheEvict(value = "dyn-form-deploy", key = "'form-deploy:'+#formId+':latest'")
     public void deploy(String formId) {
         DynamicFormEntity formEntity = selectByPk(formId);
         assertNotNull(formEntity);
@@ -174,17 +302,18 @@ public class SimpleDynamicFormService extends GenericEntityService<DynamicFormEn
         metaData.setName(form.getDatabaseTableName());
         metaData.setProperties(form.getProperties());
         metaData.setAlias(form.getAlias());
-        columns.stream().map(column -> {
+        columns.forEach(column -> {
             RDBColumnMetaData columnMeta = new RDBColumnMetaData();
-            columnMeta.setName(column.getName());
+            columnMeta.setName(column.getColumnName());
             columnMeta.setAlias(column.getAlias());
-            columnMeta.setComment(column.getDescribe());
+            columnMeta.setComment(column.getName());
             columnMeta.setLength(column.getLength() == null ? 0 : column.getLength());
             columnMeta.setPrecision(column.getPrecision() == null ? 0 : column.getPrecision());
             columnMeta.setScale(column.getScale() == null ? 0 : column.getScale());
             columnMeta.setJdbcType(JDBCType.valueOf(column.getJdbcType()));
             columnMeta.setJavaType(getJavaType(column.getJavaType()));
             columnMeta.setProperties(column.getProperties() == null ? new HashMap<>() : column.getProperties());
+            columnMeta.setValidator(columnMeta.getValidator());
             if (StringUtils.isEmpty(column.getDataType())) {
                 Dialect dialect = database.getMeta().getDialect();
                 columnMeta.setDataType(dialect.buildDataType(columnMeta));
@@ -196,8 +325,8 @@ public class SimpleDynamicFormService extends GenericEntityService<DynamicFormEn
                 columnMeta.setOptionConverter(optionalConvertBuilder.buildFromDict(column.getDictId(), column.getDictParserId()));
             }
             customColumnSetting(database, form, metaData, column, columnMeta);
-            return columnMeta;
-        }).forEach(metaData::addColumn);
+            metaData.addColumn(columnMeta);
+        });
         customTableSetting(database, form, metaData);
         return metaData;
     }

+ 10 - 7
hsweb-system/hsweb-system-dynamic-form/hsweb-system-dynamic-form-starter/src/test/java/org/hswebframework/web/service/form/simple/SimpleDynamicFormServiceTest.java

@@ -9,8 +9,11 @@ import org.hswebframework.web.tests.SimpleWebApplicationTests;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 
+import java.sql.Array;
 import java.sql.JDBCType;
 import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.stream.Stream;
 
 /**
  * TODO 完成注释
@@ -36,29 +39,29 @@ public class SimpleDynamicFormServiceTest extends SimpleWebApplicationTests {
         String id = dynamicFormService.insert(form);
         DynamicFormColumnEntity column_id = entityFactory.newInstance(DynamicFormColumnEntity.class);
         column_id.setFormId(id);
-        column_id.setName("id");
-        column_id.setDescribe("ID");
+        column_id.setColumnName("id");
+        column_id.setName("ID");
         column_id.setJavaType("string");
         column_id.setJdbcType(JDBCType.VARCHAR.getName());
         column_id.setLength(32);
         DynamicFormColumnEntity column_name = entityFactory.newInstance(DynamicFormColumnEntity.class);
         column_name.setFormId(id);
-        column_name.setName("name");
-        column_name.setDescribe("姓名");
+        column_name.setName("姓名");
+        column_name.setColumnName("name");
         column_name.setJavaType("string");
         column_name.setJdbcType(JDBCType.VARCHAR.getName());
         column_name.setLength(32);
 
         DynamicFormColumnEntity column_age = entityFactory.newInstance(DynamicFormColumnEntity.class);
         column_age.setFormId(id);
-        column_age.setName("age");
-        column_age.setDescribe("年龄");
+        column_age.setName("年龄");
+        column_age.setColumnName("age");
         column_age.setJavaType("int");
         column_age.setJdbcType(JDBCType.NUMERIC.getName());
         column_age.setPrecision(4);
         column_age.setScale(0);
 
-        dynamicFormColumnService.insert(column_id);
+        Stream.of(column_id, column_name, column_age).forEach(dynamicFormColumnService::insert);
         dynamicFormService.deploy(id);
 
         sqlExecutor.list("select * from f_test");

+ 4 - 1
hsweb-system/hsweb-system-dynamic-form/hsweb-system-dynamic-form-starter/src/test/resources/application.yml

@@ -10,4 +10,7 @@ spring:
 hsweb:
     app:
       name: 动态表单测试
-      version: 3.0.0
+      version: 3.0.0
+logging:
+  level:
+    org.hswebframework: debug