瀏覽代碼

BPM Form 表单的完善

YunaiV 3 年之前
父節點
當前提交
930c5ec490
共有 22 個文件被更改,包括 340 次插入229 次删除
  1. 4 9
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/form/BpmFormController.java
  2. 4 7
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/form/vo/BpmFormBaseVO.java
  3. 11 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/form/vo/BpmFormCreateReqVO.java
  4. 0 34
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/form/vo/BpmFormExcelVO.java
  5. 0 14
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/form/vo/BpmFormExportReqVO.java
  6. 1 1
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/form/vo/BpmFormPageReqVO.java
  7. 17 4
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/form/vo/BpmFormRespVO.java
  8. 10 1
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/form/vo/BpmFormUpdateReqVO.java
  9. 6 9
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/form/BpmFormConvert.java
  10. 6 6
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/dataobject/form/BpmFormDO.java
  11. 3 3
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/dataobject/form/BpmFormDataDO.java
  12. 4 7
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/mysql/form/BpmFormMapper.java
  13. 4 4
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/form/BpmFormService.java
  14. 8 8
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/form/impl/BpmFormServiceImpl.java
  15. 122 0
      yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/bpm/service/form/BpmFormServiceTest.java
  16. 1 0
      yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/bpm/service/package-info.java
  17. 3 0
      yudao-admin-server/src/test/resources/sql/clean.sql
  18. 16 0
      yudao-admin-server/src/test/resources/sql/create_tables.sql
  19. 25 25
      yudao-admin-ui/src/utils/generator/drawingDefalut.js
  20. 79 11
      yudao-admin-ui/src/views/bpm/form/formEditor.vue
  21. 8 86
      yudao-admin-ui/src/views/bpm/form/index.vue
  22. 8 0
      yudao-framework/yudao-spring-boot-starter-test/src/main/java/cn/iocoder/yudao/framework/test/core/util/RandomUtils.java

+ 4 - 9
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/form/BpmFormController.java

@@ -1,13 +1,11 @@
 package cn.iocoder.yudao.adminserver.modules.bpm.controller.form;
 
 import cn.iocoder.yudao.adminserver.modules.bpm.convert.form.BpmFormConvert;
-import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.form.BpmForm;
+import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.form.BpmFormDO;
 import cn.iocoder.yudao.adminserver.modules.bpm.service.form.BpmFormService;
 import cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo.*;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
-import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiOperation;
@@ -16,14 +14,11 @@ import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
-import javax.servlet.http.HttpServletResponse;
 import javax.validation.Valid;
-import java.io.IOException;
 import java.util.Collection;
 import java.util.List;
 
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
-import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
 
 @Api(tags = "动态表单")
 @RestController
@@ -63,7 +58,7 @@ public class BpmFormController {
     @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
     @PreAuthorize("@ss.hasPermission('bpm:form:query')")
     public CommonResult<BpmFormRespVO> getForm(@RequestParam("id") Long id) {
-        BpmForm form = formService.getForm(id);
+        BpmFormDO form = formService.getForm(id);
         return success(BpmFormConvert.INSTANCE.convert(form));
     }
 
@@ -72,7 +67,7 @@ public class BpmFormController {
     @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
     @PreAuthorize("@ss.hasPermission('bpm:form:query')")
     public CommonResult<List<BpmFormRespVO>> getFormList(@RequestParam("ids") Collection<Long> ids) {
-        List<BpmForm> list = formService.getFormList(ids);
+        List<BpmFormDO> list = formService.getFormList(ids);
         return success(BpmFormConvert.INSTANCE.convertList(list));
     }
 
@@ -80,7 +75,7 @@ public class BpmFormController {
     @ApiOperation("获得动态表单分页")
     @PreAuthorize("@ss.hasPermission('bpm:form:query')")
     public CommonResult<PageResult<BpmFormRespVO>> getFormPage(@Valid BpmFormPageReqVO pageVO) {
-        PageResult<BpmForm> pageResult = formService.getFormPage(pageVO);
+        PageResult<BpmFormDO> pageResult = formService.getFormPage(pageVO);
         return success(BpmFormConvert.INSTANCE.convertPage(pageResult));
     }
 

+ 4 - 7
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/form/vo/BpmFormBaseVO.java

@@ -11,18 +11,15 @@ import javax.validation.constraints.*;
 @Data
 public class BpmFormBaseVO {
 
-    @ApiModelProperty(value = "表单名称", required = true)
+    @ApiModelProperty(value = "表单名称", required = true, example = "芋道")
     @NotNull(message = "表单名称不能为空")
     private String name;
 
-    @ApiModelProperty(value = "商户状态", required = true)
-    @NotNull(message = "商户状态不能为空")
+    @ApiModelProperty(value = "表单状态", required = true, notes = "参见 CommonStatusEnum 枚举", example = "1")
+    @NotNull(message = "表单状态不能为空")
     private Integer status;
 
-    @ApiModelProperty(value = "表单JSON")
-    private String formJson;
-
-    @ApiModelProperty(value = "备注")
+    @ApiModelProperty(value = "备注", example = "我是备注")
     private String remark;
 
 }

+ 11 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/form/vo/BpmFormCreateReqVO.java

@@ -3,10 +3,21 @@ package cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo;
 import lombok.*;
 import io.swagger.annotations.*;
 
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
 @ApiModel("动态表单创建 Request VO")
 @Data
 @EqualsAndHashCode(callSuper = true)
 @ToString(callSuper = true)
 public class BpmFormCreateReqVO extends BpmFormBaseVO {
 
+    @ApiModelProperty(value = "表单的配置", required = true, notes = "JSON 字符串")
+    @NotNull(message = "表单的配置不能为空")
+    private String conf;
+
+    @ApiModelProperty(value = "表单项的数组", required = true, notes = "JSON 字符串的数组")
+    @NotNull(message = "表单项的数组不能为空")
+    private List<String> fields;
+
 }

+ 0 - 34
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/form/vo/BpmFormExcelVO.java

@@ -1,34 +0,0 @@
-package cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo;
-
-import com.alibaba.excel.annotation.ExcelProperty;
-import lombok.Data;
-
-import java.util.Date;
-
-/**
- * 动态表单 Excel VO
- *
- * @author 芋艿
- */
-@Data
-public class BpmFormExcelVO {
-
-    @ExcelProperty("表单编号")
-    private Long id;
-
-    @ExcelProperty("表单名称")
-    private String name;
-
-    @ExcelProperty("商户状态")
-    private Integer status;
-
-    @ExcelProperty("表单JSON")
-    private String formJson;
-
-    @ExcelProperty("备注")
-    private String remark;
-
-    @ExcelProperty("创建时间")
-    private Date createTime;
-
-}

+ 0 - 14
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/form/vo/BpmFormExportReqVO.java

@@ -1,14 +0,0 @@
-package cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo;
-
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
-import lombok.Data;
-
-@ApiModel(value = "动态表单 Excel 导出 Request VO", description = "参数和 BpmFormPageReqVO 是一致的")
-@Data
-public class BpmFormExportReqVO {
-
-    @ApiModelProperty(value = "表单名称")
-    private String name;
-
-}

+ 1 - 1
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/form/vo/BpmFormPageReqVO.java

@@ -13,7 +13,7 @@ import lombok.ToString;
 @ToString(callSuper = true)
 public class BpmFormPageReqVO extends PageParam {
 
-    @ApiModelProperty(value = "表单名称")
+    @ApiModelProperty(value = "表单名称", example = "芋道")
     private String name;
 
 }

+ 17 - 4
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/form/vo/BpmFormRespVO.java

@@ -1,8 +1,14 @@
 package cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo;
 
-import lombok.*;
-import java.util.*;
-import io.swagger.annotations.*;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+import javax.validation.constraints.NotNull;
+import java.util.Date;
+import java.util.List;
 
 @ApiModel("动态表单 Response VO")
 @Data
@@ -10,8 +16,15 @@ import io.swagger.annotations.*;
 @ToString(callSuper = true)
 public class BpmFormRespVO extends BpmFormBaseVO {
 
-    @ApiModelProperty(value = "表单编号", required = true)
+    @ApiModelProperty(value = "表单编号", required = true, example = "1024")
     private Long id;
+    @ApiModelProperty(value = "表单的配置", required = true, notes = "JSON 字符串")
+    @NotNull(message = "表单的配置不能为空")
+    private String conf;
+
+    @ApiModelProperty(value = "表单项的数组", required = true, notes = "JSON 字符串的数组")
+    @NotNull(message = "表单项的数组不能为空")
+    private List<String> fields;
 
     @ApiModelProperty(value = "创建时间", required = true)
     private Date createTime;

+ 10 - 1
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/form/vo/BpmFormUpdateReqVO.java

@@ -3,6 +3,7 @@ package cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo;
 import lombok.*;
 import io.swagger.annotations.*;
 import javax.validation.constraints.*;
+import java.util.List;
 
 @ApiModel("动态表单更新 Request VO")
 @Data
@@ -10,8 +11,16 @@ import javax.validation.constraints.*;
 @ToString(callSuper = true)
 public class BpmFormUpdateReqVO extends BpmFormBaseVO {
 
-    @ApiModelProperty(value = "表单编号", required = true)
+    @ApiModelProperty(value = "表单编号", required = true, example = "1024")
     @NotNull(message = "表单编号不能为空")
     private Long id;
 
+    @ApiModelProperty(value = "表单的配置", required = true, notes = "JSON 字符串")
+    @NotNull(message = "表单的配置不能为空")
+    private String conf;
+
+    @ApiModelProperty(value = "表单项的数组", required = true, notes = "JSON 字符串的数组")
+    @NotNull(message = "表单项的数组不能为空")
+    private List<String> fields;
+
 }

+ 6 - 9
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/form/BpmFormConvert.java

@@ -1,10 +1,9 @@
 package cn.iocoder.yudao.adminserver.modules.bpm.convert.form;
 
 import cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo.BpmFormCreateReqVO;
-import cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo.BpmFormExcelVO;
 import cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo.BpmFormRespVO;
 import cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo.BpmFormUpdateReqVO;
-import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.form.BpmForm;
+import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.form.BpmFormDO;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import org.mapstruct.Mapper;
 import org.mapstruct.factory.Mappers;
@@ -21,16 +20,14 @@ public interface BpmFormConvert {
 
     BpmFormConvert INSTANCE = Mappers.getMapper(BpmFormConvert.class);
 
-    BpmForm convert(BpmFormCreateReqVO bean);
+    BpmFormDO convert(BpmFormCreateReqVO bean);
 
-    BpmForm convert(BpmFormUpdateReqVO bean);
+    BpmFormDO convert(BpmFormUpdateReqVO bean);
 
-    BpmFormRespVO convert(BpmForm bean);
+    BpmFormRespVO convert(BpmFormDO bean);
 
-    List<BpmFormRespVO> convertList(List<BpmForm> list);
+    List<BpmFormRespVO> convertList(List<BpmFormDO> list);
 
-    PageResult<BpmFormRespVO> convertPage(PageResult<BpmForm> page);
-
-    List<BpmFormExcelVO> convertList02(List<BpmForm> list);
+    PageResult<BpmFormRespVO> convertPage(PageResult<BpmFormDO> page);
 
 }

+ 6 - 6
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/dataobject/form/BpmForm.java → yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/dataobject/form/BpmFormDO.java

@@ -22,7 +22,7 @@ import java.util.List;
 @Builder
 @NoArgsConstructor
 @AllArgsConstructor
-public class BpmForm extends BaseDO {
+public class BpmFormDO extends BaseDO {
 
     /**
      * 编号
@@ -37,12 +37,12 @@ public class BpmForm extends BaseDO {
      * 状态
      */
     private Integer status;
-//    /**
-//     * 表单JSON
-//     */
-//    private String formJson;
     /**
-     * 表单配置
+     * 表单的配置
+     */
+    private String conf;
+    /**
+     * 表单项的数组
      *
      * 目前直接将 https://github.com/JakHuang/form-generator 生成的 JSON 串,直接保存
      * 定义:https://github.com/JakHuang/form-generator/issues/46

+ 3 - 3
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/dataobject/form/BpmFormData.java → yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/dataobject/form/BpmFormDataDO.java

@@ -22,7 +22,7 @@ import java.util.Map;
 @Builder
 @NoArgsConstructor
 @AllArgsConstructor
-public class BpmFormData extends BaseDO {
+public class BpmFormDataDO extends BaseDO {
 
     /**
      * 编号
@@ -31,7 +31,7 @@ public class BpmFormData extends BaseDO {
     /**
      * 表单编号
      *
-     * 关联 {@link BpmForm#getId()}
+     * 关联 {@link BpmFormDO#getId()}
      */
     private Long formId;
     /**
@@ -41,7 +41,7 @@ public class BpmFormData extends BaseDO {
     /**
      * 表单配置
      *
-     * 冗余 {@link BpmForm#getFields()}
+     * 冗余 {@link BpmFormDO#getFields()}
      * 主要考虑,表单是可以修改的
      */
     @TableField(typeHandler = JacksonTypeHandler.class)

+ 4 - 7
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/mysql/form/BpmFormMapper.java

@@ -1,26 +1,23 @@
 package cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.form;
 
 
-import cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo.BpmFormExportReqVO;
 import cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo.BpmFormPageReqVO;
-import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.form.BpmForm;
+import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.form.BpmFormDO;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
 import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
 import org.apache.ibatis.annotations.Mapper;
 
-import java.util.List;
-
 /**
  * 动态表单 Mapper
  *
  * @author 风里雾里
  */
 @Mapper
-public interface BpmFormMapper extends BaseMapperX<BpmForm> {
+public interface BpmFormMapper extends BaseMapperX<BpmFormDO> {
 
-    default PageResult<BpmForm> selectPage(BpmFormPageReqVO reqVO) {
-        return selectPage(reqVO, new QueryWrapperX<BpmForm>()
+    default PageResult<BpmFormDO> selectPage(BpmFormPageReqVO reqVO) {
+        return selectPage(reqVO, new QueryWrapperX<BpmFormDO>()
                 .likeIfPresent("name", reqVO.getName())
                 .orderByDesc("id"));
     }

+ 4 - 4
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/form/BpmFormService.java

@@ -3,7 +3,7 @@ package cn.iocoder.yudao.adminserver.modules.bpm.service.form;
 import cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo.BpmFormCreateReqVO;
 import cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo.BpmFormPageReqVO;
 import cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo.BpmFormUpdateReqVO;
-import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.form.BpmForm;
+import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.form.BpmFormDO;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 
 import javax.validation.Valid;
@@ -46,7 +46,7 @@ public interface BpmFormService {
      * @param id 编号
      * @return 动态表单
      */
-    BpmForm getForm(Long id);
+    BpmFormDO getForm(Long id);
 
     /**
      * 获得动态表单列表
@@ -54,7 +54,7 @@ public interface BpmFormService {
      * @param ids 编号
      * @return 动态表单列表
      */
-    List<BpmForm> getFormList(Collection<Long> ids);
+    List<BpmFormDO> getFormList(Collection<Long> ids);
 
     /**
      * 获得动态表单分页
@@ -62,6 +62,6 @@ public interface BpmFormService {
      * @param pageReqVO 分页查询
      * @return 动态表单分页
      */
-    PageResult<BpmForm> getFormPage(BpmFormPageReqVO pageReqVO);
+    PageResult<BpmFormDO> getFormPage(BpmFormPageReqVO pageReqVO);
 
 }

+ 8 - 8
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/form/BpmFormServiceImpl.java → yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/form/impl/BpmFormServiceImpl.java

@@ -1,12 +1,12 @@
-package cn.iocoder.yudao.adminserver.modules.bpm.service.form;
+package cn.iocoder.yudao.adminserver.modules.bpm.service.form.impl;
 
 import cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo.BpmFormCreateReqVO;
-import cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo.BpmFormExportReqVO;
 import cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo.BpmFormPageReqVO;
 import cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo.BpmFormUpdateReqVO;
 import cn.iocoder.yudao.adminserver.modules.bpm.convert.form.BpmFormConvert;
-import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.form.BpmForm;
+import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.form.BpmFormDO;
 import cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.form.BpmFormMapper;
+import cn.iocoder.yudao.adminserver.modules.bpm.service.form.BpmFormService;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
@@ -33,7 +33,7 @@ public class BpmFormServiceImpl implements BpmFormService {
     @Override
     public Long createForm(BpmFormCreateReqVO createReqVO) {
         // 插入
-        BpmForm form = BpmFormConvert.INSTANCE.convert(createReqVO);
+        BpmFormDO form = BpmFormConvert.INSTANCE.convert(createReqVO);
         formMapper.insert(form);
         // 返回
         return form.getId();
@@ -44,7 +44,7 @@ public class BpmFormServiceImpl implements BpmFormService {
         // 校验存在
         this.validateFormExists(updateReqVO.getId());
         // 更新
-        BpmForm updateObj = BpmFormConvert.INSTANCE.convert(updateReqVO);
+        BpmFormDO updateObj = BpmFormConvert.INSTANCE.convert(updateReqVO);
         formMapper.updateById(updateObj);
     }
 
@@ -63,17 +63,17 @@ public class BpmFormServiceImpl implements BpmFormService {
     }
 
     @Override
-    public BpmForm getForm(Long id) {
+    public BpmFormDO getForm(Long id) {
         return formMapper.selectById(id);
     }
 
     @Override
-    public List<BpmForm> getFormList(Collection<Long> ids) {
+    public List<BpmFormDO> getFormList(Collection<Long> ids) {
         return formMapper.selectBatchIds(ids);
     }
 
     @Override
-    public PageResult<BpmForm> getFormPage(BpmFormPageReqVO pageReqVO) {
+    public PageResult<BpmFormDO> getFormPage(BpmFormPageReqVO pageReqVO) {
         return formMapper.selectPage(pageReqVO);
     }
 

+ 122 - 0
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/bpm/service/form/BpmFormServiceTest.java

@@ -0,0 +1,122 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.service.form;
+
+import cn.iocoder.yudao.adminserver.BaseDbUnitTest;
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo.BpmFormCreateReqVO;
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo.BpmFormPageReqVO;
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.form.vo.BpmFormUpdateReqVO;
+import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.form.BpmFormDO;
+import cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.form.BpmFormMapper;
+import cn.iocoder.yudao.adminserver.modules.bpm.service.form.impl.BpmFormServiceImpl;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import org.junit.jupiter.api.Test;
+import org.springframework.context.annotation.Import;
+
+import javax.annotation.Resource;
+
+import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.BPM_FORM_NOT_EXISTS;
+import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
+import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
+import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
+import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
+import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * {@link BpmFormServiceImpl} 的单元测试类
+ *
+ * @author 芋道源码
+ */
+@Import(BpmFormServiceImpl.class)
+public class BpmFormServiceTest extends BaseDbUnitTest {
+
+    @Resource
+    private BpmFormServiceImpl formService;
+
+    @Resource
+    private BpmFormMapper formMapper;
+
+    @Test
+    public void testCreateForm_success() {
+        // 准备参数
+        BpmFormCreateReqVO reqVO = randomPojo(BpmFormCreateReqVO.class);
+
+        // 调用
+        Long formId = formService.createForm(reqVO);
+        // 断言
+        assertNotNull(formId);
+        // 校验记录的属性是否正确
+        BpmFormDO form = formMapper.selectById(formId);
+        assertPojoEquals(reqVO, form);
+    }
+
+    @Test
+    public void testUpdateForm_success() {
+        // mock 数据
+        BpmFormDO dbForm = randomPojo(BpmFormDO.class);
+        formMapper.insert(dbForm);// @Sql: 先插入出一条存在的数据
+        // 准备参数
+        BpmFormUpdateReqVO reqVO = randomPojo(BpmFormUpdateReqVO.class, o -> {
+            o.setId(dbForm.getId()); // 设置更新的 ID
+        });
+
+        // 调用
+        formService.updateForm(reqVO);
+        // 校验是否更新正确
+        BpmFormDO form = formMapper.selectById(reqVO.getId()); // 获取最新的
+        assertPojoEquals(reqVO, form);
+    }
+
+    @Test
+    public void testUpdateForm_notExists() {
+        // 准备参数
+        BpmFormUpdateReqVO reqVO = randomPojo(BpmFormUpdateReqVO.class);
+
+        // 调用, 并断言异常
+        assertServiceException(() -> formService.updateForm(reqVO), BPM_FORM_NOT_EXISTS);
+    }
+
+    @Test
+    public void testDeleteForm_success() {
+        // mock 数据
+        BpmFormDO dbForm = randomPojo(BpmFormDO.class);
+        formMapper.insert(dbForm);// @Sql: 先插入出一条存在的数据
+        // 准备参数
+        Long id = dbForm.getId();
+
+        // 调用
+        formService.deleteForm(id);
+        // 校验数据不存在了
+        assertNull(formMapper.selectById(id));
+    }
+
+    @Test
+    public void testDeleteForm_notExists() {
+        // 准备参数
+        Long id = randomLongId();
+
+        // 调用, 并断言异常
+        assertServiceException(() -> formService.deleteForm(id), BPM_FORM_NOT_EXISTS);
+    }
+
+    @Test
+    public void testGetFormPage() {
+        // mock 数据
+        BpmFormDO dbForm = randomPojo(BpmFormDO.class, o -> { // 等会查询到
+            o.setName("芋道源码");
+        });
+        formMapper.insert(dbForm);
+        // 测试 name 不匹配
+        formMapper.insert(cloneIgnoreId(dbForm, o -> o.setName("源码")));
+        // 准备参数
+        BpmFormPageReqVO reqVO = new BpmFormPageReqVO();
+        reqVO.setName("芋道");
+
+        // 调用
+        PageResult<BpmFormDO> pageResult = formService.getFormPage(reqVO);
+        // 断言
+        assertEquals(1, pageResult.getTotal());
+        assertEquals(1, pageResult.getList().size());
+        assertPojoEquals(dbForm, pageResult.getList().get(0));
+    }
+
+}

+ 1 - 0
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/bpm/service/package-info.java

@@ -0,0 +1 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.service;

+ 3 - 0
yudao-admin-server/src/test/resources/sql/clean.sql

@@ -25,3 +25,6 @@ DELETE FROM "sys_sms_log";
 DELETE FROM "sys_error_code";
 DELETE FROM "sys_social_user";
 DELETE FROM "sys_tenant";
+
+-- bpm 开头的 DB
+DELETE FROM "bpm_form";

+ 16 - 0
yudao-admin-server/src/test/resources/sql/create_tables.sql

@@ -472,3 +472,19 @@ CREATE TABLE IF NOT EXISTS "sys_tenant" (
     "deleted" bit NOT NULL DEFAULT FALSE,
     PRIMARY KEY ("id")
 ) COMMENT '租户';
+
+
+CREATE TABLE IF NOT EXISTS "bpm_form" (
+    "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+    "name" varchar(63) NOT NULL,
+    "status" tinyint NOT NULL,
+    "fields" varchar(255) NOT NULL,
+    "conf" varchar(255) NOT NULL,
+    "remark" varchar(255),
+    "creator" varchar(64) DEFAULT '',
+    "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+    "updater" varchar(64) DEFAULT '',
+    "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+    "deleted" bit NOT NULL DEFAULT FALSE,
+    PRIMARY KEY ("id")
+) COMMENT '动态表单';

+ 25 - 25
yudao-admin-ui/src/utils/generator/drawingDefalut.js

@@ -1,29 +1,29 @@
 export default [
   {
-    // layout: 'colFormItem',
-    // tagIcon: 'input',
-    // label: '手机号',
-    // vModel: 'mobile',
-    // formId: 6,
-    // tag: 'el-input',
-    // placeholder: '请输入手机号',
-    // defaultValue: '',
-    // span: 24,
-    // style: { width: '100%' },
-    // clearable: true,
-    // prepend: '',
-    // append: '',
-    // 'prefix-icon': 'el-icon-mobile',
-    // 'suffix-icon': '',
-    // maxlength: 11,
-    // 'show-word-limit': true,
-    // readonly: false,
-    // disabled: false,
-    // required: true,
-    // changeTag: true,
-    // regList: [{
-    //   pattern: '/^1(3|4|5|7|8|9)\\d{9}$/',
-    //   message: '手机号格式错误'
-    // }]
+    layout: 'colFormItem',
+    tagIcon: 'input',
+    label: '手机号',
+    vModel: 'mobile',
+    formId: 6,
+    tag: 'el-input',
+    placeholder: '请输入手机号',
+    defaultValue: '',
+    span: 24,
+    style: { width: '100%' },
+    clearable: true,
+    prepend: '',
+    append: '',
+    'prefix-icon': 'el-icon-mobile',
+    'suffix-icon': '',
+    maxlength: 11,
+    'show-word-limit': true,
+    readonly: false,
+    disabled: false,
+    required: true,
+    changeTag: true,
+    regList: [{
+      pattern: '/^1(3|4|5|7|8|9)\\d{9}$/',
+      message: '手机号格式错误'
+    }]
   }
 ]

+ 79 - 11
yudao-admin-ui/src/views/bpm/form/formEditor.vue

@@ -32,7 +32,7 @@
             </div>
           </draggable>
           <div class="components-title">
-            <svg-icon icon-class="component" /> 布局型组件
+            <svg-icon icon-class="component" />布局型组件
           </div>
           <draggable class="components-draggable" :list="layoutComponents" :group="{ name: 'componentsGroup', pull: 'clone', put: false }"
                      :clone="cloneComponent" draggable=".components-item" :sort="false" @end="onEnd">
@@ -66,11 +66,10 @@
     <div class="center-board">
       <!-- 上面:操作按钮 -->
       <div class="action-bar">
-        <el-button class="delete-btn" icon="el-icon-delete" type="text" @click="empty">
-          清空
-        </el-button>
+        <el-button icon="el-icon-check" type="text" @click="save">保存</el-button>
+        <el-button class="delete-btn" icon="el-icon-delete" type="text" @click="empty">清空</el-button>
       </div>
-      <!-- 中间,表单 -->
+      <!-- 中间,表单 -->
       <el-scrollbar class="center-scrollbar">
         <el-row class="center-board-row" :gutter="formConf.gutter">
           <el-form :size="formConf.size" :label-position="formConf.labelPosition" :disabled="formConf.disabled"
@@ -102,6 +101,8 @@ import drawingDefalut from '@/utils/generator/drawingDefalut'
 // import logo from '@/assets/logo/logo.png'
 import DraggableItem from './../../tool/build/DraggableItem'
 import RightPanel from './../../tool/build/RightPanel'
+import {createForm, getForm, updateForm} from "@/api/bpm/form";
+import {SysCommonStatusEnum} from "@/utils/constants";
 
 // const emptyActiveData = { style: {}, autosize: {} }
 let oldActiveId
@@ -123,22 +124,25 @@ export default {
       selectComponents,
       layoutComponents,
       labelWidth: 100,
-      drawingList: drawingDefalut, // 表单项的数组
-      drawingData: {},
-      activeId: drawingDefalut[0].formId,
+
+      drawingData: {}, // 生成后的表单数据
+
+      drawingList: [], // 表单项的数组
+      activeId: 0,
+      activeData: {},
       // drawerVisible: false,
       // formData: {},
       // dialogVisible: false,
       // showFileName: false,
-      activeData: drawingDefalut[0],
 
       // 表单参数
-      form: {},
+      form: {
+        status: SysCommonStatusEnum.ENABLE,
+      },
       // 表单校验
       rules: {
         name: [{ required: true, message: "表单名不能为空", trigger: "blur" }],
         status: [{ required: true, message: "开启状态不能为空", trigger: "blur" }],
-        fields: [{ required: true, message: "表单配置不能为空", trigger: "blur" }],
       }
     }
   },
@@ -161,6 +165,23 @@ export default {
       immediate: true
     }
   },
+  created() {
+    // 读取表单配置
+    const formId = this.$route.query && this.$route.query.formId
+    if (formId) {
+      getForm(formId).then(response => {
+        const data = response.data
+        this.form = {
+          id: data.id,
+          name: data.name,
+          status: data.status,
+          remark: data.remark
+        }
+        this.formConf = JSON.parse(data.conf)
+        this.drawingList = this.decodeFields(data.fields)
+      });
+    }
+  },
   methods: {
     activeFormItem(element) {
       this.activeData = element
@@ -202,6 +223,53 @@ export default {
         ...this.formConf
       }
     },
+    save() {
+      // this.AssembleFormData()
+      // console.log(this.formData)
+      this.$refs["form"].validate(valid => {
+        if (!valid) {
+          return;
+        }
+        const form = {
+          conf: JSON.stringify(this.formConf), // 表单配置
+          // fields: JSON.stringify(this.drawingList), // 表单项的数组
+          fields: this.encodeFields(), // 表单项的数组
+          ...this.form // 表单名等
+        }
+        // 修改的提交
+        if (this.form.id != null) {
+          updateForm(form).then(response => {
+            this.msgSuccess("修改成功");
+            this.close()
+          });
+          return;
+        }
+        // 添加的提交
+        createForm(form).then(response => {
+          this.msgSuccess("新增成功");
+          this.close()
+        });
+      });
+    },
+    /** 关闭按钮 */
+    close() {
+      this.$store.dispatch("tagsView/delView", this.$route);
+      this.$router.push({ path: "/bpm/manager/form", query: { t: Date.now()}})
+    },
+    encodeFields() {
+      const fields = []
+      this.drawingList.forEach(item => {
+        fields.push(JSON.stringify(item))
+      })
+      return fields
+    },
+    decodeFields(fields) {
+      const drawingList = []
+      fields.forEach(item => {
+        drawingList.push(JSON.parse(item))
+      })
+      return drawingList
+    },
     empty() {
       this.$confirm('确定要清空所有组件吗?', '提示', { type: 'warning' }).then(
         () => {

+ 8 - 86
yudao-admin-ui/src/views/bpm/form/index.vue

@@ -30,7 +30,6 @@
           <span>{{ getDictDataLabel(DICT_TYPE.SYS_COMMON_STATUS, scope.row.status) }}</span>
         </template>
       </el-table-column>
-      <el-table-column label="表单配置" align="center" prop="fields" />
       <el-table-column label="备注" align="center" prop="remark" />
       <el-table-column label="创建时间" align="center" prop="createTime" width="180">
         <template slot-scope="scope">
@@ -49,36 +48,11 @@
     <!-- 分页组件 -->
     <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
                 @pagination="getList"/>
-
-    <!-- 对话框(添加 / 修改) -->
-    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
-      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
-        <el-form-item label="表单名" prop="name">
-          <el-input v-model="form.name" placeholder="请输入表单名" />
-        </el-form-item>
-        <el-form-item label="开启状态" prop="status">
-          <el-radio-group v-model="form.status">
-            <el-radio v-for="dict in this.getDictDatas(DICT_TYPE.SYS_COMMON_STATUS)"
-                      :key="dict.value" :label="parseInt(dict.value)">{{dict.label}}</el-radio>
-          </el-radio-group>
-        </el-form-item>
-        <el-form-item label="表单配置" prop="fields">
-          <el-input v-model="form.fields" placeholder="请输入表单配置" />
-        </el-form-item>
-        <el-form-item label="备注" prop="remark">
-          <el-input v-model="form.remark" placeholder="请输入备注" />
-        </el-form-item>
-      </el-form>
-      <div slot="footer" class="dialog-footer">
-        <el-button type="primary" @click="submitForm">确 定</el-button>
-        <el-button @click="cancel">取 消</el-button>
-      </div>
-    </el-dialog>
   </div>
 </template>
 
 <script>
-import { createForm, updateForm, deleteForm, getForm, getFormPage, exportFormExcel } from "@/api/bpm/form";
+import { deleteForm, getFormPage} from "@/api/bpm/form";
 
 export default {
   name: "Form",
@@ -94,24 +68,12 @@ export default {
       total: 0,
       // 工作流的列表
       list: [],
-      // 弹出层标题
-      title: "",
-      // 是否显示弹出层
-      open: false,
       // 查询参数
       queryParams: {
         pageNo: 1,
         pageSize: 10,
         name: null,
       },
-      // 表单参数
-      form: {},
-      // 表单校验
-      rules: {
-        name: [{ required: true, message: "表单名不能为空", trigger: "blur" }],
-        status: [{ required: true, message: "开启状态不能为空", trigger: "blur" }],
-        fields: [{ required: true, message: "表单配置不能为空", trigger: "blur" }],
-      }
     };
   },
   created() {
@@ -130,22 +92,6 @@ export default {
         this.loading = false;
       });
     },
-    /** 取消按钮 */
-    cancel() {
-      this.open = false;
-      this.reset();
-    },
-    /** 表单重置 */
-    reset() {
-      this.form = {
-        id: undefined,
-        name: undefined,
-        status: undefined,
-        fields: undefined,
-        remark: undefined,
-      };
-      this.resetForm("form");
-    },
     /** 搜索按钮操作 */
     handleQuery() {
       this.queryParams.pageNo = 1;
@@ -158,41 +104,17 @@ export default {
     },
     /** 新增按钮操作 */
     handleAdd() {
-      this.reset();
-      this.open = true;
-      this.title = "添加工作流的";
+      this.$router.push({
+        path:"/bpm/manager/form/edit"
+      });
     },
     /** 修改按钮操作 */
     handleUpdate(row) {
-      this.reset();
-      const id = row.id;
-      getForm(id).then(response => {
-        this.form = response.data;
-        this.open = true;
-        this.title = "修改工作流的";
-      });
-    },
-    /** 提交按钮 */
-    submitForm() {
-      this.$refs["form"].validate(valid => {
-        if (!valid) {
-          return;
-        }
-        // 修改的提交
-        if (this.form.id != null) {
-          updateForm(this.form).then(response => {
-            this.msgSuccess("修改成功");
-            this.open = false;
-            this.getList();
-          });
-          return;
+      this.$router.push({
+        path:"/bpm/manager/form/edit",
+        query:{
+          formId: row.id
         }
-        // 添加的提交
-        createForm(this.form).then(response => {
-          this.msgSuccess("新增成功");
-          this.open = false;
-          this.getList();
-        });
       });
     },
     /** 删除按钮操作 */

+ 8 - 0
yudao-framework/yudao-spring-boot-starter-test/src/main/java/cn/iocoder/yudao/framework/test/core/util/RandomUtils.java

@@ -31,6 +31,14 @@ public class RandomUtils {
         // 字符串
         PODAM_FACTORY.getStrategy().addOrReplaceTypeManufacturer(String.class,
                 (dataProviderStrategy, attributeMetadata, map) -> randomString());
+        // Integer
+        PODAM_FACTORY.getStrategy().addOrReplaceTypeManufacturer(Integer.class, (dataProviderStrategy, attributeMetadata, map) -> {
+            // 如果是 status 的字段,返回 0 或 1
+            if (attributeMetadata.getAttributeName().equals("status")) {
+                return RandomUtil.randomEle(CommonStatusEnum.values()).getStatus();
+            }
+            return RandomUtil.randomInt();
+        });
         // Boolean
         PODAM_FACTORY.getStrategy().addOrReplaceTypeManufacturer(Boolean.class, (dataProviderStrategy, attributeMetadata, map) -> {
             // 如果是 deleted 的字段,返回非删除