Browse Source

[feat]集成工作流

pull/1/head
杨威 4 months ago
parent
commit
051a8cd1b5
  1. 58
      dk-common/common-workflow/pom.xml
  2. 61
      dk-common/common-workflow/src/main/java/org/dromara/common/Exception/ServiceException.java
  3. 47
      dk-common/common-workflow/src/main/java/org/dromara/common/Exception/enums/abs/AbstractBaseExceptionEnum.java
  4. 27
      dk-common/common-workflow/src/main/java/org/dromara/common/consts/ExceptionCodeConstant.java
  5. 67
      dk-common/common-workflow/src/main/java/org/dromara/common/entity/WorkflowBaseEntity.java
  6. 153
      dk-common/common-workflow/src/main/java/org/dromara/common/page/WorkflowPageFactory.java
  7. 119
      dk-common/common-workflow/src/main/java/org/dromara/common/page/WorkflowPageResult.java
  8. 355
      dk-common/common-workflow/src/main/java/org/dromara/common/param/WorkflowBaseParam.java
  9. 58
      dk-common/common-workflow/src/main/java/org/dromara/common/requestno/RequestNoContext.java
  10. 58
      dk-common/common-workflow/src/main/java/org/dromara/common/response/WorkflowErrorResponseData.java
  11. 97
      dk-common/common-workflow/src/main/java/org/dromara/common/response/WorkflowResponseData.java
  12. 54
      dk-common/common-workflow/src/main/java/org/dromara/common/response/WorkflowResult.java
  13. 691
      dk-common/common-workflow/src/main/java/org/dromara/common/response/WorkflowResultCode.java
  14. 44
      dk-common/common-workflow/src/main/java/org/dromara/common/response/WorkflowSuccessResponseData.java
  15. 68
      dk-common/common-workflow/src/main/java/org/dromara/common/util/HttpServletUtil.java
  16. 128
      dk-common/common-workflow/src/main/java/org/dromara/common/util/JsonUtil.java
  17. 87
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/controller/FormDataController.java
  18. 96
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/controller/FormDataExcelController.java
  19. 133
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/controller/FormDataInstanceController.java
  20. 97
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/domain/FormData.java
  21. 174
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/domain/FormDataLog.java
  22. 11
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/domain/FormDataLogChange.java
  23. 51
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/enums/DataAspectEnum.java
  24. 51
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/enums/WidgetType.java
  25. 17
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/mapper/FormDataLogChangeMapper.java
  26. 21
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/mapper/FormDataLogMapper.java
  27. 18
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/mapper/FormDataMapper.java
  28. 31
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/mapper/mapping/FormDataLogChangeMapper.xml
  29. 41
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/mapper/mapping/FormDataLogMapper.xml
  30. 50
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/mapper/mapping/FormDataMapper.xml
  31. 30
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/param/ActiveDataParams.java
  32. 109
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/param/DataParams.java
  33. 33
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/param/DownloadDataParams.java
  34. 71
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/param/FormDataModifyMessage.java
  35. 41
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/param/FormDataParam.java
  36. 36
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/param/ImportDataParams.java
  37. 38
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/param/TransferDataParams.java
  38. 77
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/param/UpdateDataParams.java
  39. 55
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/result/FormDataResult.java
  40. 87
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/FormDataService.java
  41. 278
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impl/FormDataServiceImpl.java
  42. 60
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/common/HeaderMergeStrategiesGenerator.java
  43. 22
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/convert/BaseConverter.java
  44. 14
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/convert/BooleanConverter.java
  45. 11
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/convert/CheckboxConverter.java
  46. 13
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/convert/ConverterBuilder.java
  47. 20
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/convert/CoordinateConverter.java
  48. 70
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/convert/DateConverter.java
  49. 10
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/convert/EmptyArrayValueConverter.java
  50. 68
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/convert/FormatNumberConverter.java
  51. 8
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/convert/GeneralConverter.java
  52. 34
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/convert/InputConverter.java
  53. 38
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/convert/LocationConverter.java
  54. 30
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/convert/MultipleDepartmentsConverter.java
  55. 30
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/convert/MultipleMemberConverter.java
  56. 11
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/convert/MultipleSelectConverter.java
  57. 8
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/convert/NullValueConverter.java
  58. 17
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/convert/PhoneConverter.java
  59. 28
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/convert/SingleDepartmentConverter.java
  60. 30
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/convert/SingleMemberConverter.java
  61. 69
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/convert/WidgetConverter.java
  62. 75
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/convert/WidgetConverterFactory.java
  63. 17
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/enums/ImportMode.java
  64. 15
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/exception/ImportDataInvalidException.java
  65. 14
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/exception/ImportValidationException.java
  66. 11
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/model/CellSpanInfo.java
  67. 44
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/model/ColumnsNeedValidate.java
  68. 19
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/model/DataAnalysisParams.java
  69. 11
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/model/DownloadTemplateParams.java
  70. 40
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/model/ExtraMergeInfoListener.java
  71. 384
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/model/ImportValidatorListener.java
  72. 27
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/model/InvalidColumnResult.java
  73. 30
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/model/PreviewResult.java
  74. 18
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/model/PreviewTableHeader.java
  75. 19
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/model/StringConverter.java
  76. 116
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/service/ImportFromExcelHelper.java
  77. 20
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/service/ImportFromExcelService.java
  78. 621
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/service/impl/ImportFromExcelServiceImpl.java
  79. 63
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/service/impl/excel/ImportDemo.java
  80. 35
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/service/impl/excel/handler/CommentWriteHandler.java
  81. 433
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/service/impl/excel/listener/DataAnalysisEventListener.java
  82. 52
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/service/impl/excel/model/CellModel.java
  83. 119
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/service/impl/excel/model/RecordModel.java
  84. 30
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/service/impl/excel/model/RowMerge.java
  85. 34
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/service/impl/excel/model/RowModel.java
  86. 84
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/validator/ValueValidator.java
  87. 20
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/log/DataLogActionService.java
  88. 37
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/log/FormDataLogService.java
  89. 53
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/log/impl/DataLogDeleteService.java
  90. 42
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/log/impl/DataLogSaveService.java
  91. 85
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/log/impl/DataLogUpdateService.java
  92. 76
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/log/impl/FormDataLogServiceImpl.java
  93. 67
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/validate/FormDataValidateService.java
  94. 265
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/validate/impl/FormDataValidateServiceImpl.java
  95. 49
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/widget/convert/base/BaseFormFieldConverter.java
  96. 82
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/widget/convert/base/FormFieldFactory.java
  97. 41
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/widget/convert/column/CheckboxConverter.java
  98. 96
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/widget/convert/column/CoordinatesConverter.java
  99. 35
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/widget/convert/column/DatalinkConverter.java
  100. 150
      dk-common/common-workflow/src/main/java/org/dromara/dataManager/widget/convert/column/DateConverter.java

58
dk-common/common-workflow/pom.xml

@ -1,58 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.dromara</groupId>
<artifactId>dk-common</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>common-workflow</artifactId>
<description>
工作流模块
</description>
<dependencies>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>common-mybatis</artifactId>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.15.0</version>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>system</artifactId>
<version>2.2.2</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

61
dk-common/common-workflow/src/main/java/org/dromara/common/Exception/ServiceException.java

@ -1,61 +0,0 @@
/*
Copyright [2020] [https://www.stylefeng.cn]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Guns采用APACHE LICENSE 2.0开源协议您在使用过程中需要注意以下几点
1.请不要删除和修改根目录下的LICENSE文件
2.请不要删除和修改Guns源码头部的版权声明
3.请保留源码和相关描述文件的项目出处作者声明等
4.分发源码时候请注明软件出处 https://gitee.com/stylefeng/guns-separation
5.在修改包名模块名称项目代码等时请注明软件出处 https://gitee.com/stylefeng/guns-separation
6.若您的项目无法满足以上几点可申请商业授权获取Guns商业授权许可请在官网购买授权地址为 https://www.stylefeng.cn
*/
package org.dromara.common.Exception;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.Exception.enums.abs.AbstractBaseExceptionEnum;
import org.dromara.common.response.WorkflowResultCode;
/**
* 业务异常
*
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class ServiceException extends RuntimeException {
private Integer code;
private String errorMessage;
public ServiceException(Integer code, String errorMessage) {
super(errorMessage);
this.code = code;
this.errorMessage = errorMessage;
}
public ServiceException(AbstractBaseExceptionEnum exception) {
super(exception.getMessage());
this.code = exception.getCode();
this.errorMessage = exception.getMessage();
}
public ServiceException(WorkflowResultCode resultCode) {
super(resultCode.message());
this.code = resultCode.code();
this.errorMessage = resultCode.message();
}
}

47
dk-common/common-workflow/src/main/java/org/dromara/common/Exception/enums/abs/AbstractBaseExceptionEnum.java

@ -1,47 +0,0 @@
/*
Copyright [2020] [https://www.stylefeng.cn]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Guns采用APACHE LICENSE 2.0开源协议您在使用过程中需要注意以下几点
1.请不要删除和修改根目录下的LICENSE文件
2.请不要删除和修改Guns源码头部的版权声明
3.请保留源码和相关描述文件的项目出处作者声明等
4.分发源码时候请注明软件出处 https://gitee.com/stylefeng/guns-separation
5.在修改包名模块名称项目代码等时请注明软件出处 https://gitee.com/stylefeng/guns-separation
6.若您的项目无法满足以上几点可申请商业授权获取Guns商业授权许可请在官网购买授权地址为 https://www.stylefeng.cn
*/
package org.dromara.common.Exception.enums.abs;
/**
* @date 2017/12/17 22:22
*/
public interface AbstractBaseExceptionEnum {
/**
* 获取异常的状态码
*
* @return 状态码
*/
Integer getCode();
/**
* 获取异常的提示信息
*
* @return 提示信息
*/
String getMessage();
}

27
dk-common/common-workflow/src/main/java/org/dromara/common/consts/ExceptionCodeConstant.java

@ -1,27 +0,0 @@
package org.dromara.common.consts;
public interface ExceptionCodeConstant {
// es错误码 {10} {00} {03} {001-100}
interface Elasticsearch {
int ES_INDEX_NOT_EXIST = 100003001;
}
// 数据源 {10} {00} {04} {001-100}
interface DataSource {
int TABLE_NAME_REPEAT = 100004001;
int COLUMN_NULL = 100004002;
int INCREMENTAL_COLUMN_NULL = 100004003;
// Incrementalolumn is not in column config
int INCREMENTAL_COLUMN_NOT_IN_CONFIG = 100004004;
}
// 业务代码异常
interface Service {
int SQL_EXCEPTION = 100008001;
int OBJECT_TARGET_NOT_EXIST = 100008051;
int VALUE_INVALID = 100010001;
}
}

67
dk-common/common-workflow/src/main/java/org/dromara/common/entity/WorkflowBaseEntity.java

@ -1,67 +0,0 @@
/*
Copyright [2020] [https://www.stylefeng.cn]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Guns采用APACHE LICENSE 2.0开源协议您在使用过程中需要注意以下几点
1.请不要删除和修改根目录下的LICENSE文件
2.请不要删除和修改Guns源码头部的版权声明
3.请保留源码和相关描述文件的项目出处作者声明等
4.分发源码时候请注明软件出处 https://gitee.com/stylefeng/guns-separation
5.在修改包名模块名称项目代码等时请注明软件出处 https://gitee.com/stylefeng/guns-separation
6.若您的项目无法满足以上几点可申请商业授权获取Guns商业授权许可请在官网购买授权地址为 https://www.stylefeng.cn
*/
package org.dromara.common.entity;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* 通用基础字段需要此通用字段的实体可继承此类
*
*/
@Data
public class WorkflowBaseEntity implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
private Date createTime;
/**
* 创建人
*/
@TableField(fill = FieldFill.INSERT)
private Long createUser;
/**
* 更新时间
*/
@TableField(fill = FieldFill.UPDATE)
private Date updateTime;
/**
* 更新人
*/
@TableField(fill = FieldFill.UPDATE)
private Long updateUser;
}

153
dk-common/common-workflow/src/main/java/org/dromara/common/page/WorkflowPageFactory.java

@ -1,153 +0,0 @@
/*
Copyright [2020] [https://www.stylefeng.cn]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Guns采用APACHE LICENSE 2.0开源协议您在使用过程中需要注意以下几点
1.请不要删除和修改根目录下的LICENSE文件
2.请不要删除和修改Guns源码头部的版权声明
3.请保留源码和相关描述文件的项目出处作者声明等
4.分发源码时候请注明软件出处 https://gitee.com/stylefeng/guns-separation
5.在修改包名模块名称项目代码等时请注明软件出处 https://gitee.com/stylefeng/guns-separation
6.若您的项目无法满足以上几点可申请商业授权获取Guns商业授权许可请在官网购买授权地址为 https://www.stylefeng.cn
*/
package org.dromara.common.page;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.servlet.http.HttpServletRequest;
import org.dromara.common.util.HttpServletUtil;
import java.util.Collections;
import java.util.List;
/**
* 默认分页参数构建
*
*/
public class WorkflowPageFactory {
/**
* 每页大小默认20
*/
private static final String PAGE_SIZE_PARAM_NAME = "pageSize";
/**
* 第几页从1开始
*/
private static final String PAGE_NO_PARAM_NAME = "pageNo";
/**
* 默认分页在使用时PageFactory.defaultPage会自动获取pageSize和pageNo参数
*
* @author xuyuxiang
* @date 2020/3/30 16:42
*/
public static <T> Page<T> defaultPage() {
int pageSize = 10;
int pageNo = 1;
HttpServletRequest request = HttpServletUtil.getRequest();
//每页条数
String pageSizeString = request.getParameter(PAGE_SIZE_PARAM_NAME);
if (ObjectUtil.isNotEmpty(pageSizeString)) {
pageSize = Integer.parseInt(pageSizeString);
}
//第几页
String pageNoString = request.getParameter(PAGE_NO_PARAM_NAME);
if (ObjectUtil.isNotEmpty(pageNoString)) {
pageNo = Integer.parseInt(pageNoString);
}
return new Page<>(pageNo, pageSize);
}
public static <T> Page<T> customPage(Integer pageSize,Integer pageNo) {
if(ObjectUtil.hasEmpty(pageNo,pageSize)){
return defaultPage();
}
return new Page<>(pageNo, pageSize);
}
public static <T> Page<T> defaultPage(Integer pageNoParam,Integer pageSizeParam) {
int pageSize = 10;
int pageNo = 1;
//每页条数 moren
if (ObjectUtil.isNotEmpty(pageSizeParam)) {
pageSize = pageSizeParam;
}
//第几页
if (ObjectUtil.isNotEmpty(pageNoParam)) {
pageNo = pageNoParam;
}
return new Page<>(pageNo, pageSize);
}
public static <T> Page<T> customPage(Boolean limited) {
if(ObjectUtil.equal(limited,true)){
return defaultPage();
}
return new Page<>(0, -1);
}
/**
* 得到分页后的数据
* @return 分页后结果
*/
public static <T>List<T> getPagedList(List<T> data) {
int pageSize = 10;
int pageNo = 1;
HttpServletRequest request = HttpServletUtil.getRequest();
//每页条数
String pageSizeString = request.getParameter(PAGE_SIZE_PARAM_NAME);
if (ObjectUtil.isNotEmpty(pageSizeString)) {
pageSize = Integer.parseInt(pageSizeString);
}
//第几页
String pageNoString = request.getParameter(PAGE_NO_PARAM_NAME);
if (ObjectUtil.isNotEmpty(pageNoString)) {
pageNo = Integer.parseInt(pageNoString);
}
int fromIndex = (pageNo - 1) * pageSize;
if (fromIndex >= data.size()) {
return Collections.emptyList();
}
int toIndex = pageNo * pageSize;
if (toIndex >= data.size()) {
toIndex = data.size();
}
return data.subList(fromIndex, toIndex);
}
}

119
dk-common/common-workflow/src/main/java/org/dromara/common/page/WorkflowPageResult.java

@ -1,119 +0,0 @@
/*
Copyright [2020] [https://www.stylefeng.cn]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Guns采用APACHE LICENSE 2.0开源协议您在使用过程中需要注意以下几点
1.请不要删除和修改根目录下的LICENSE文件
2.请不要删除和修改Guns源码头部的版权声明
3.请保留源码和相关描述文件的项目出处作者声明等
4.分发源码时候请注明软件出处 https://gitee.com/stylefeng/guns-separation
5.在修改包名模块名称项目代码等时请注明软件出处 https://gitee.com/stylefeng/guns-separation
6.若您的项目无法满足以上几点可申请商业授权获取Guns商业授权许可请在官网购买授权地址为 https://www.stylefeng.cn
*/
package org.dromara.common.page;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.PageUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* 分页结果集
*
* @author xuyuxiang
* @date 2020/3/30 15:44
*/
@Data
public class WorkflowPageResult<T> implements Serializable {
private static final long serialVersionUID = -1L;
/**
* 默认分页彩虹展示数量
*/
public static final int RAINBOW_NUM = 5;
/**
* 第几页
*/
private Integer pageNo = 1;
/**
* 每页条数
*/
private Integer pageSize = 20;
/**
* 总页数
*/
private Integer totalPage = 0;
/**
* 总记录数
*/
private Integer totalRows = 0;
/**
* 结果集
*/
private List<T> rows;
/**
* 分页彩虹
*/
private int[] rainbow;
public WorkflowPageResult() {
}
/**
* 将mybatis-plus的page转成自定义的PageResult扩展了totalPage总页数和rainBow彩虹条
*
* @author xuyuxiang
* @date 2020/4/8 19:20
*/
public WorkflowPageResult(Page<T> page) {
this.setRows(page.getRecords());
this.setTotalRows(Convert.toInt(page.getTotal()));
this.setPageNo(Convert.toInt(page.getCurrent()));
this.setPageSize(Convert.toInt(page.getSize()));
this.setTotalPage(PageUtil.totalPage(Convert.toInt(page.getTotal()),
Convert.toInt(page.getSize())));
// this.setRainbow(PageUtil.rainbow(Convert.toInt(page.getCurrent()),
// Convert.toInt(this.getTotalPage()), RAINBOW_NUM));
}
/**
* 将mybatis-plus的page转成自定义的PageResult扩展了totalPage总页数和rainBow彩虹条
* 可单独设置rows
*
* @author xuyuxiang
* @date 2020/4/14 20:55
*/
public WorkflowPageResult(IPage<?> page, List<T> t) {
this.setRows(t);
this.setTotalRows(Convert.toInt(page.getTotal()));
this.setPageNo(Convert.toInt(page.getCurrent()));
this.setPageSize(Convert.toInt(page.getSize()));
this.setTotalPage(PageUtil.totalPage(Convert.toInt(page.getTotal()),
Convert.toInt(page.getSize())));
// this.setRainbow(PageUtil.rainbow(Convert.toInt(page.getCurrent()),
// Convert.toInt(this.getTotalPage()), RAINBOW_NUM));
}
}

355
dk-common/common-workflow/src/main/java/org/dromara/common/param/WorkflowBaseParam.java

@ -1,355 +0,0 @@
/*
Copyright [2020] [https://www.stylefeng.cn]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Guns采用APACHE LICENSE 2.0开源协议您在使用过程中需要注意以下几点
1.请不要删除和修改根目录下的LICENSE文件
2.请不要删除和修改Guns源码头部的版权声明
3.请保留源码和相关描述文件的项目出处作者声明等
4.分发源码时候请注明软件出处 https://gitee.com/stylefeng/guns-separation
5.在修改包名模块名称项目代码等时请注明软件出处 https://gitee.com/stylefeng/guns-separation
6.若您的项目无法满足以上几点可申请商业授权获取Guns商业授权许可请在官网购买授权地址为 https://www.stylefeng.cn
*/
package org.dromara.common.param;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* 通用基础参数相关实体参数校验可继承此类
*
*/
@Data
public class WorkflowBaseParam implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 是否禁用权限
*/
private boolean withoutPermission = false;
/**
* 是否进行分页
*/
private Boolean showPageNation = true;
/**
* 搜索值
*/
private String searchValue;
/**
* 数据权限
*/
private List<Long> dataScope;
/**
* 开始时间
*/
private String startTime;
/**
* 结束时间
*/
private String endTime;
/**
* 状态字典 0正常 1停用 2删除
*/
private Integer searchStatus;
/**
* 参数校验分组分页
*/
public @interface page {
}
/**
* 参数校验分组列表
*/
public @interface list {
}
/**
* 参数校验分组下拉
*/
public @interface dropDown {
}
/**
* 参数校验分组增加
*/
public @interface add {
}
/**
* 参数校验分组编辑
*/
public @interface edit {
}
public @interface status {
}
/**
* 参数校验分组更新信息
*/
public @interface updateInfo {
}
/**
* 参数校验分组修改密码
*/
public @interface updatePwd {
}
/**
* 参数校验分组重置密码
*/
public @interface resetPwd {
}
/**
* 参数校验分组修改头像
*/
public @interface updateAvatar {
}
public @interface updateTask{
}
/**
* 参数校验分组删除
*/
public @interface delete {
}
/**
* 参数校验分组详情
*/
public @interface detail {
}
public @interface batch {
}
/**
* 参数校验分组授权角色
*/
public @interface grantRole {
}
/**
* 参数校验分组授权菜单
*/
public @interface grantMenu {
}
/**
* 参数校验分组授权数据
*/
public @interface grantData {
}
/**
* 参数校验分组强退
*/
public @interface force {
}
/**
* 参数校验分组停用
*/
public @interface stop {
}
/**
* 参数校验分组启用
*/
public @interface start {
}
/**
* 参数校验分组部署
*/
public @interface deploy {
}
/**
* 参数校验分组挂起
*/
public @interface suspend {
}
/**
* 参数校验分组激活
*/
public @interface active {
}
/**
* 参数校验分组调试
*/
public @interface debug {
}
/**
* 参数校验分组委托
*/
public @interface entrust {
}
/**
* 参数校验分组转办
*/
public @interface turn {
}
/**
* 参数校验分组追踪
*/
public @interface trace {
}
/**
* 参数校验分组跳转
*/
public @interface jump {
}
/**
* 参数校验分组同意
*/
public @interface agree {
}
/**
* 参数校验分组退回
*/
public @interface back {
}
/**
* 参数校验分组终止
*/
public @interface end {
}
/**
* 参数校验分组导出
*/
public @interface export {
}
/**
* 参数校验分组映射
*/
public @interface mapping {
}
/**
* 参数校验分组切换
*/
public @interface change {
}
/**
* 参数校验分组历史审批记录
*/
public @interface commentHistory {
}
/**
* 参数校验分组修改状态
*/
public @interface changeStatus {
}
/**
* 参数校验分组传阅
*/
public @interface circulate {
}
/**
* 参数校验分组加签
*/
public @interface addSign {
}
/**
* 参数校验分组减签
*/
public @interface deleteSign {
}
/**
* 参数校验分组添加节点
*/
public @interface addNode {
}
/**
* 参数校验分组节点流转
*/
public @interface flow {
}
public @interface apply {
}
public @interface submit {
}
public @interface reject {
}
public @interface cancel {
}
public @interface finish {
}
public @interface rollback {
}
/**
* 参数校验分组节点转交
*/
public @interface forward {
}
public @interface valid {}
public @interface check {}
public @interface todo {}
public @interface handle {}
public @interface cc {}
public @interface urge {}
public @interface install {
}
}

58
dk-common/common-workflow/src/main/java/org/dromara/common/requestno/RequestNoContext.java

@ -1,58 +0,0 @@
/*
Copyright [2020] [https://www.stylefeng.cn]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Guns采用APACHE LICENSE 2.0开源协议您在使用过程中需要注意以下几点
1.请不要删除和修改根目录下的LICENSE文件
2.请不要删除和修改Guns源码头部的版权声明
3.请保留源码和相关描述文件的项目出处作者声明等
4.分发源码时候请注明软件出处 https://gitee.com/stylefeng/guns-separation
5.在修改包名模块名称项目代码等时请注明软件出处 https://gitee.com/stylefeng/guns-separation
6.若您的项目无法满足以上几点可申请商业授权获取Guns商业授权许可请在官网购买授权地址为 https://www.stylefeng.cn
*/
package org.dromara.common.requestno;
/**
* 临时保存当前请求号
*
*/
public class RequestNoContext {
private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();
/**
* 保存请求号
*
*/
public static void set(String requestNo) {
CONTEXT_HOLDER.set(requestNo);
}
/**
* 获取请求号
*
*/
public static String get() {
return CONTEXT_HOLDER.get();
}
/**
* 清除请求号
*
*/
public static void clear() {
CONTEXT_HOLDER.remove();
}
}

58
dk-common/common-workflow/src/main/java/org/dromara/common/response/WorkflowErrorResponseData.java

@ -1,58 +0,0 @@
/*
Copyright [2020] [https://www.stylefeng.cn]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Guns采用APACHE LICENSE 2.0开源协议您在使用过程中需要注意以下几点
1.请不要删除和修改根目录下的LICENSE文件
2.请不要删除和修改Guns源码头部的版权声明
3.请保留源码和相关描述文件的项目出处作者声明等
4.分发源码时候请注明软件出处 https://gitee.com/stylefeng/guns-separation
5.在修改包名模块名称项目代码等时请注明软件出处 https://gitee.com/stylefeng/guns-separation
6.若您的项目无法满足以上几点可申请商业授权获取Guns商业授权许可请在官网购买授权地址为 https://www.stylefeng.cn
*/
package org.dromara.common.response;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 失败响应结果
*
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class WorkflowErrorResponseData extends WorkflowResponseData {
/**
* 异常的具体类名称
*/
private String exceptionClazz;
WorkflowErrorResponseData(String message) {
super(false, DEFAULT_ERROR_CODE, message, null);
}
public WorkflowErrorResponseData(Integer code, String message) {
super(false, code, message, null);
}
WorkflowErrorResponseData(Integer code, String message, Object object) {
super(false, code, message, object);
}
WorkflowErrorResponseData(){
super();
}
}

97
dk-common/common-workflow/src/main/java/org/dromara/common/response/WorkflowResponseData.java

@ -1,97 +0,0 @@
/*
Copyright [2020] [https://www.stylefeng.cn]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Guns采用APACHE LICENSE 2.0开源协议您在使用过程中需要注意以下几点
1.请不要删除和修改根目录下的LICENSE文件
2.请不要删除和修改Guns源码头部的版权声明
3.请保留源码和相关描述文件的项目出处作者声明等
4.分发源码时候请注明软件出处 https://gitee.com/stylefeng/guns-separation
5.在修改包名模块名称项目代码等时请注明软件出处 https://gitee.com/stylefeng/guns-separation
6.若您的项目无法满足以上几点可申请商业授权获取Guns商业授权许可请在官网购买授权地址为 https://www.stylefeng.cn
*/
package org.dromara.common.response;
import lombok.Data;
/**
* 响应结果数据
*
*/
@Data
public class WorkflowResponseData {
public static final String DEFAULT_SUCCESS_MESSAGE = "请求成功";
public static final String DEFAULT_ERROR_MESSAGE = "网络异常";
public static final Integer DEFAULT_SUCCESS_CODE = 200;
public static final Integer DEFAULT_ERROR_CODE = 500;
/**
* 请求是否成功
*/
private Boolean success;
/**
* 响应状态码
*/
private Integer code;
/**
* 响应信息
*/
private String message;
/**
* 响应对象
*/
private Object data;
public WorkflowResponseData() {
}
public WorkflowResponseData(Boolean success, Integer code, String message, Object data) {
this.success = success;
this.code = code;
this.message = message;
this.data = data;
}
public static WorkflowSuccessResponseData success() {
return new WorkflowSuccessResponseData();
}
public static WorkflowSuccessResponseData success(Object object) {
return new WorkflowSuccessResponseData(object);
}
public static WorkflowSuccessResponseData success(Integer code, String message, Object object) {
return new WorkflowSuccessResponseData(code, message, object);
}
public static WorkflowErrorResponseData error(String message) {
return new WorkflowErrorResponseData(message);
}
public static WorkflowErrorResponseData error(Integer code, String message) {
return new WorkflowErrorResponseData(code, message);
}
public static WorkflowErrorResponseData error(Integer code, String message, Object object) {
return new WorkflowErrorResponseData(code, message, object);
}
}

54
dk-common/common-workflow/src/main/java/org/dromara/common/response/WorkflowResult.java

@ -1,54 +0,0 @@
package org.dromara.common.response;
import lombok.Data;
/**
* API 接口返回对象
*/
@Data
public class WorkflowResult extends WorkflowResponseData {
public static WorkflowSuccessResponseData success(){
WorkflowSuccessResponseData result = new WorkflowSuccessResponseData();
result.setSuccess(true);
result.setCode(WorkflowResultCode.SUCCESS.code());
result.setMessage(WorkflowResultCode.SUCCESS.message());
return result;
}
public static WorkflowSuccessResponseData success(Object data){
WorkflowSuccessResponseData result = new WorkflowSuccessResponseData();
result.setSuccess(true);
result.setCode(WorkflowResultCode.SUCCESS.code());
result.setMessage(WorkflowResultCode.SUCCESS.message());
result.setData(data);
return result;
}
public static WorkflowSuccessResponseData success(Object data, String message){
WorkflowSuccessResponseData result = new WorkflowSuccessResponseData();
result.setSuccess(true);
result.setCode(WorkflowResultCode.SUCCESS.code());
result.setMessage(message);
result.setData(data);
return result;
}
public static WorkflowErrorResponseData error(WorkflowResultCode resultCode){
WorkflowErrorResponseData result = new WorkflowErrorResponseData();
result.setSuccess(false);
result.setCode(resultCode.code());
result.setMessage(resultCode.message());
return result;
}
public static WorkflowErrorResponseData error(WorkflowResultCode resultCode, Object data){
WorkflowErrorResponseData result = new WorkflowErrorResponseData();
result.setSuccess(false);
result.setCode(resultCode.code());
result.setMessage(resultCode.message());
result.setData(data);
return result;
}
}

691
dk-common/common-workflow/src/main/java/org/dromara/common/response/WorkflowResultCode.java

@ -1,691 +0,0 @@
package org.dromara.common.response;
public enum WorkflowResultCode {
/** 200~299 成功,操作被成功接收和处理 */
SUCCESS(200,"执行成功"),
/** 500~599 失败,服务器再处理请求过程中发生得错误 */
FAIL(500,"糟糕,服务器竟然出岔子了,建议刷新页面再试试"),
SAVE_FAIL(501,"新增失败"),
UPDATE_FAIL(502,"修改失败"),
DELETE_FAIL(503,"删除失败"),
NOT_SUPPORT(504,"不支持该操作"),
/** 1001~9999 业务执行错误码 */
/** 998 Ladp服务 */
ERROR_LADP_FAIL(998000, "认证失败!"),
ERROR_LADP_NONE_USER(998001, "无效用户!"),
ERROR_LADP_ERROR(998002, "认证异常!"),
CAS_INVALID_TICKET(9020,"CAS Ticket无效"),
/** 角色 ****/
ROLE_NOT_EXIST(9020,"角色不存在 "),
ROLE_DATA_SCOPE_EMPTY(9020,"角色数据模型为空 "),
USER_ROLE_NOT_EXIST(9020,"登录用户无角色信息,请联系管理员 "),
ROLE_SYSTEM_FLAG(9020,"系统预设无法删除! "),
/**
* 应用
*/
APP_NOT_FOUND(1921,"应用不存在"),
/** 组织机构 */
DEPT_PARENT_NOT_EXIST(1010,"上级部门不存在"),
DEPT_CODE_REPEAT(1011,"部门代码重复"),
DEPT_NAME_REPEAT(1012,"部门名称重复"),
DEPT_NOT_EXIST(1013,"部门不存在"),
DEPT_DEL_FAIL(1014,"删除失败"),
DEPT_ERROR_FAIL(1015,"部门信息添加失败"),
DEPT_NOT_VALID(1016,"部门不合法"),
/** 教师 */
TEACHER_GH_REPEAT(1030, "工号重复"),
TEACHER_NOT_EXIST(1031, "教师不存在"),
TEACHER_CLASS_EXIST(1032, "班级已添加辅导员,无法添加,请重新选择!"),
/** 学生 */
STU_XH_REPEAT(1050,"学号重复"),
STU_NOT_EXIST(1051, "学生不存在"),
/** 白名单 */
ALERT_WHITE_EXIST(1056,"此学生已存在于白名单中,请勿重复添加"),
ALERT_WHITE_NOT_STU(1057,"白名单用户只能为学生,请检查后提交"),
/** 文件 */
REPORT_NOT_EXIST(1052,"分析报告不存在"),
ASSETS_PATH_NOT_EXIST(1052,"静态资源目录不存在"),
COMPOSE_FILE_ERROR(1053,"文件压缩失败"),
FILE_SUFFIX_NOT_ALLOWED(1054,"文件类型不合法"),
FEEDBACK_SETTING_NOT_FOUND(1029,"反馈设置不存在"),
WATERMARK_SETTING_NOT_FOUND(1029,"水印设置不存在"),
/** 预警分类 **/
ALERT_TYPE_REPEAT(2023,"预警分类名称重复"),
ALERT_TYPE_DELETE(2024,"已产生对应预警事件分类数据,如需删除,请联系管理员"),
USER_CANNOT_DELETE_ADMIN(9020, "超级管理员不能删除"),
USER_PERMISSION_ERROR(100105, "用户无权限,请联系管理员"),
/** 用户组 */
GROUP_NAME_NOT_EXIST(1060,"用户组名称不存在"),
GROUP_NAME_REPEAT(1061,"用户组名称重复"),
GROUP_OPENED_NOT_EXIST(1062,"用户组类型不存在"),
GROUP_USER_NOT_EXIST(1063,"用户组成员存在"),
GROUP_ID_NOT_EXIST(1064,"用户组ID不存在"),
YEAR_IS_NOT_VALID(5001,"学年不合法,请重新配置"),
SCHOOL_CALENDAR_SERVER_ERROR(5002,"节假日API服务异常"),
SCHOOL_CALENDAR_SETTING_NOT_FOUND(5003,"校历管理设置不存在"),
SCHOOL_CALENDAR_DATE_NOT_RANGE(5003,"设置的日期不在配置的时间范围内,请重新选择!"),
SCHOOL_CALENDAR_DURATION(5003,"节假日期间不允许同步预警"),
/**
* 自定义表单
*/
FORM_MAKING_NAME_REPEAT(1061,"表单名称重复"),
FORM_NOT_VALID(4027,"表单数据格式不正确"),
FORM_WIDGET_NOT_ALLOWED(1240, "不合法的表单字段"),
/**
* 文件
*/
FILE_UPLOAD_FAIL(1870, "上传失败!"),
/** 字典 */
DICT_TYPE_NOT_EXIST(1150, "字典不存在"),
/**
* 用户认证
*/
PWD_ERROR(1,"密码错误,请联系管理员"),
ACCOUNT_PWD_EMPTY(1, "账号或密码为空,请检查账号或密码"),
ACCOUNT_PWD_ERROR(2, "账号或密码错误,请检查账号或密码"),
VALID_CODE_ERROR(3, "验证码错误,请检查captcha参数"),
REQUEST_TOKEN_EMPTY(4, "请求token为空,请携带token访问本接口"),
NOT_VALID_TOKEN_TYPE(5, "token格式不正确,token请以Bearer开头,并且Bearer后边带一个空格"),
REQUEST_TOKEN_ERROR(6, "请求token错误"),
ACCOUNT_FREEZE_ERROR(7, "账号已停用,请联系管理员"),
LOGIN_EXPIRED(8, "登录已过期,请重新登录"),
NO_LOGIN_USER(9, "无登录用户"),
MODE_NOT_PERMISSION(10, "当前接口只允许在开发和测试环境调用"),
TEMP_USER_NO_PERMISSION(11, "临时用户无访问权限"),
USER_IS_NOT_ADMIN(12, "非管理员用户无法访问"),
REFERER_ERROR(77, "REFER非法"),
PARAM_IS_INVALID(9001,"参数无效"),
PARAM_IS_BLANK(9002,"参数为空"),
PARAM_BAD_TYPE(9003,"参数类型错误"),
PARAM_MISSING(9004,"参数缺失"),
RESULT_EMPTY(9004, "查询结果为空"),
PARAM_PARSE_ERROR(9005,"参数解析异常"),
DOWNLOAD_FILE_ERROR(9006,"附件下载异常"),
ENV_NOT_ALLOWED(9001,"系统环境异常,请联系管理员"),
FILE_UPLOAD_ERROR(1055,"文件上传失败"),
SYSTEM_NOT_FOUND(3006, "应用不存在"),
MODULE_NOT_FOUND(3006, "模块不存在"),
/**
*开放接口鉴权
*/
AUTH_PARAM_APPKEY_NOT_FOUND(7001,"APP_KEY参数缺失"),
AUTH_PARAM_APPKEY_ERROR(7001,"APP_KEY参数错误"),
AUTH_PARAM_SIGN_NOT_FOUND(7002,"签名参数缺失"),
AUTH_PARAM_TIMESTAMP_NOT_FOUND(7003,"时间戳参数缺失"),
AUTH_PARAM_TIMESTAMP_ERROR(7004,"时间戳参数错误"),
AUTH_PARAM_SIGN_ERROR(7005,"签名校验失败"),
AUTH_PARAM_SIGN_TYPE_ERROR(7006,"签名类型不合法"),
AUTH_DATA_ACCOUNT_EMPTY(7100, "账号为空"),
TAG_NOT_EXIST(2001,"未找到标签"),
TAG_FACTORY_NOT_CONFIG(2001,"标签工厂未配置"),
TAG_FACTORY_SERVER_ERROR(9017, "标签工厂服务异常"),
TAG_FACTORY_SERVER_EMPTY(9017, "标签工厂服务返回为空"),
TAG_FACTORY_URL_EMPTY(9018, "标签工厂地址未设置,无法配置同步预警对象,请先设置地址!"),
TAG_FACTORY_CONFIG_ERROR(9019, "未设置标签工厂信息,请联系管理员"),
AUTHORIZE_SETTING_ERROR(100102, "免登认证配置不合法,请检查配置"),
/**
* 用户
*/
USER_NOT_EXIST(9010,"用户不存在"),
USER_LOGIN_ERROR(9011,"账户不存在或密码错误"),
USER_ACCT_FORBIDDEN(9012,"账户已禁用"),
USER_HAS_EXIST(9013,"用户已存在"),
USER_ACCT_PWD_EMPTY(9014, "账号或密码为空"),
USER_AUTH_FAIL(9015, "认证失败"),
AUTH_WXWORK_NO_CODE(9016, "企业微信认证失败:code 参数为空"),
AUTH_CAS_NO_TICKET(9017, "CAS认证失败:ticket 参数为空"),
AUTH_SC_CAS_NO_UID(9017, "CAS认证失败:uid 参数为空"),
USER_PHONE_EXIST(9018,"手机号已存在"),
SOURCE_NOT_EXIST(1136, "资源不存在"),
ALERT_STATUS_ERROR(2001,"预警状态异常"),
ALERT_TAG_FLOW_NOT_EXIST(2001,"预警标签未配置流程"),
ALERT_NOT_EXIST(2001,"未找到预警信息"),
ALERT_TAG_NOT_EXIST(2001,"预警事件不存在"),
ALERT_TEMPLATE_NOT_EXIST(2001,"预警模板不存在"),
ALERT_TEMPLATE_RULE_INSTALLED(2001,"预警模板已安装"),
ALERT_TEMPLATE_NAME_REPEAT(2001,"预警模板已重复"),
/**
* 机构管理
*/
DELETE_HAS_SUB_DEPART(3000, "本部门存在下级部门,不允许删除"),
DELETE_HAS_USERS_IN_DEPART(3001, "部门内存在成员,不允许删除"),
CONTACT_MANAGER_NOT_EXIST(3002, "管理组不存在"),
CONTACT_MANAGER_MORE_ONE(3003, "一个用户只能存在一个管理组中"),
CONTACT_MANAGER_SUPER_ADMIN_CANNOT_SET(3004, "超级管理员不能添加到任何权限组"),
CONTACT_MANAGER_SYSTEM_DELETE(3005, "系统管理组不能删除"),
CONTACT_MANAGER_SYSTEM_UPDATE(3006, "系统管理组不能编辑"),
CONTACT_MANAGER_USER_NOT_IN(3007, "当前用户不是管理员"),
/**
* 开放平台
*/
PLUGIN_CODE_REPEAT(7200,"插件已存在,请勿重复添加"),
PLUGIN_CODE_NOT_EXIST(7201,"插件不存在,请联系管理员"),
INSTANCE_STAGE_ERROR(992,"流程实例状态异常"),
INSTANCE_STAGE_FINISHED(993,"流程已结束,请勿重复操作"),
INSTANCE_STAGE_COMPETED(994,"流程已完成,请勿重复操作"),
HANDLER_USER_NOT_EXIST(995,"处理人不存在,请联系系统管理员"),
DEFINITION_NOT_EXIST(996,"未找到流程配置信息"),
DEFINITION_RUNNING_NODE_NOT_EXIST(997,"未找到正在运行的流程定义"),
DEFINITION_NODE_NOT_EXIST(998,"未找到流程节点配置信息"),
DEFINITION_NODE_FLOW_RULE_NOT_EXIST(998,"未找到流程节点流转规则配置"),
NODE_TYPE_NOT_EXIST(999,"节点类型不存在"),
NODE_START_NOT_EXIST(1000,"开始节点不存在"),
NODE_CHECKER_TASK_NOT_EXIST(1001,"任务不存在"),
NODE_STARTING_TRIGGER_SCENE_NOT_PERMISSION(1002,"节点不满足触发场景条件"),
NODE_OPERATION_NOT_EXIST(1003,"节点操作类型不存在"),
NODE_STARTING_TRIGGER_FIELD_NOT_PERMISSION(1004,"节点不满足触发字段条件"),
NODE_STARTING_TRIGGER_DATA_NOT_PERMISSION(1005,"节点不满足触发数据条件"),
NODE_STARTING_DATA_NOT_PERMISSION(1006,"节点数据校验不满足条件"),
NODE_NOT_EXIST(1007,"未找到流程节点"),
NODE_NEXT_NOT_EXIST(1008,"找不到审核节点"),
NODE_CHECKER_NOT_PERMISSION(1009,"当前用户无审核权限"),
NODE_CHECKER_NOT_EXIST(1010,"审核节点审核人不存在"),
FORWARD_USER_NOT_EXIST(1011,"转交人为空"),
FORWARD_USER_ERROR(1012,"转交人不能是当前处理人"),
INSTANCE_NOT_EXIST(1003,"流程数据不存在"),
NODE_TYPE_ERROR(1014,"节点类型参数异常"),
NODE_SUGGEST_NOT_EMPTY(1015,"审核节点文本意见不能为空"),
NODE_SIGNATURE_NOT_EMPTY(1016,"审核节点手写签名不能为空"),
PERMISSION_SUBMIT_NO_PERMISSION(1017,"当前处理人无发起流程权限"),
TASK_HAS_EXPIRED(1017,"待办任务已失效,请刷新页面"),
PERMISSION_FORWARD_NO_PERMISSION(1018,"当前处理人无转交处理流程权限"),
PERMISSION_RECALL_NOT_OPEN(1019,"系统未开启撤回功能"),
PERMISSION_RECALL_NO_PERMISSION(1020,"当前处理人无撤回流程权限"),
PERMISSION_RECALL_APPROVAL_NO_PERMISSION(1021,"任务节点已有人提交,发起人无法撤回"),
PERMISSION_ROLLBACK_NOT_OPEN(1022,"系统未开启回退功能"),
ROLLBACK_KEY_NOT_EXIST(1022,"回退节点不存在"),
ROLLBACK_NODE_NOT_PERMISSION(1027,"回退节点不合法"),
ROLLBACK_START_USER_NOT_EXIST(1028,"流程为匿名填报,无法回退到开始节点"),
ROLLBACK_TASK_USER_NOT_EXIST(1029,"流程回退节点找不到负责人,请检查流程设定配置"),
MOVING_NEXT_NODE_NOT_EXIST(1023,"找不到下一节点,流程无法流转"),
MOVING_NEXT_NODE_CHECKER_NOT_EXIST(1024,"未找到下一个节点审核人"),
NODE_FLOW_ERROR(1025,"提交失败,不符合流转条件"),
INVALID_OPERATION(1026,"无效的操作类型"),
INSTANCE_STATUS_ERROR(1028,"流程状态异常"),
NODE_ACTIVE_NOT_EXIST(1029,"找不到激活节点"),
SETTING_ARCHIVE_NOT_EXIST(1029,"归档设置异常,请检查流程设置"),
ARCHIVE_USER_NOT_PERMISSION(1030,"用户无权限发起归档"),
CC_USER_NOT_PERMISSION(1031,"用户无权限发起抄送"),
CC_USER_NOT_EXIST(1031,"抄送用户不存在"),
CC_TASK_NOT_EXIST(1032,"抄送任务不存在"),
ENGINE_RESULT_EMPTY(1033,"流程引擎结果为空"),
FLOW_RUNTIME_EXCEPTION(1034, "流程引擎发生异常,请联系管理员"),
FLOW_STAGE_ERROR(1034, "存在未处理的预警,请检查后重新提交"),
NODE_CHECKER_USER_LIMIT(1035,"节点审核人数量不能超过100人"),
NODE_CC_USER_LIMIT(1036,"节点抄送人数量不能超过100人"),
FORM_DATA_HAS_DELETE(1037,"数据已被删除"),
FORM_DETAIL_NOT_EXIST(1134, "表单信息不存在"),
TASK_NOT_EXIST(1038,"该流程已被处理或撤回"),
TASK_PARAM_NOT_EXIST(1039,"待办参数不存在"),
TASK_HAS_HANDLED(1040,"待办任务已处理"),
TASK_PROCESSING_HAS_CHANGED(1040,"待办任务已在处理中状态,请勿重复更新"),
NODE_TRANSFER_CHECKER_NOT_CHANGE(1041,"流程负责人未改动"),
NODE_TRANSFER_CHECKER_EMPTY(1042,"流程负责人为空"),
USER_NOT_PERMISSION(1043,"用户无权限"),
ROLE_NOT_PERMISSION(1043,"该角色暂无权限访问系统"),
FLOW_INSTANCE_STARTER_NOT_FOUND(1044,"未找到流程发起人"),
FLOW_INSTANCE_URGE_CLOSED(1045,"流程设定未开启催办"),
FLOW_INSTANCE_URGE_LIMITED(1046,"5分钟内至多发送一次督办提醒"),
FLOW_INSTANCE_URGE_NODE_ERROR(1046,"流程实例异常,请稍后再试"),
FORM_PERMISSION_FAIL(1300, "用户无表单访问权限"),
FLOW_DEFINITION_NOT_EXIST(1301, "流程定义不存在"),
FLOW_DEFINITION_START_PROCESS_NOT_EXIST(1302, "流程定义开始节点不存在"),
FLOW_INSTANCE_FAIL(1303, "表单已填报,请勿重复填报"),
FLOW_INSTANCE_NOT_EXIST(1304, "流程实例不存在"),
FLOW_INSTANCE_STATUS_ERROR(1306, "流程实例状态异常"),
DATASOURCE_NOT_FOUND(1281, "找不到数据源"),
FLOW_DRAFT_SUCCESS(1344, "草稿保存成功"),
FLOW_URGE_SUCCESS(1344, "已提醒负责人处理"),
FLOW_INSTANCE_PROCESS_NOT_EXIST(1305, "流程实例节点不存在"),
FLOW_INSTANCE_CC_NOT_EXIST(1306, "实例抄送不存在"),
FLOW_INSTANCE_EXIST(1305, "存在流程实例"),
FLOW_PERMISSION_RECALL_FAIL(1320, "用户无权限撤回"),
FLOW_APPROVAL_NOT_PERMISSION(1321, "当前用户无审核权限"),
FLOW_ROLLBACK_NOT_PERMISSION(1323, "当前用户无权限退回该流程"),
FLOW_INSTANCE_NOT_SUBMIT(1322, "实例还没填报"),
FLOW_DEFINITION_NOT_APPROVER(1323, "审批节点未设置审核人"),
FLOW_DEFINITION_INSTANCE_EXIST(1325, "该流程定义存在运行实例"),
FLOW_DEFINITION_EXIST(1327, "流程定义已存在"),
FLOW_VERSION_FORM_ERROR(1326, "表单状态异常"),
FLOW_DEFINITION_PARAM_ERROR(1327, "流程参数异常"),
FLOW_USER_ROLE_NOT_PERMISSION(1328, "用户身份校验失败"),
FLOW_DEFINITION_NODE_NOT_EXIST(1329, "流程定义节点数据不存在"),
FLOW_FORM_NOT_PERMISSION(1330, "表单参数异常"),
FLOW_LINE_ELSE_CONDITION_ERROR(1331, "连接线存在多个else条件"),
FLOW_BUTTON_ROLLBACK_ERROR(1332, "未找到回退按钮"),
FLOW_DEFINITION_VERSION_NOT_EXIST(1333, "未找到流程定义"),
FLOW_INSTANCE_NOT_FINISHED(1334, "实例未结束"),
FLOW_ENDNODE_NOT_EXIST(1335, "未找到结束节点"),
FLOW_NEXT_PROCES_NOT_EXIST(1324, "提交失败,找不到下个审核节点,可联系管理员检查流程节点后重新提交。"),
FLOW_LINE_CONDITION_ERROR(1331, "提交失败,不符合流转条件,可联系管理员检查流转条件后重新提交。"),
FLOW_NEXT_NODE_CHECKER_MISSING(1336, "提交失败,找不到下个节点负责人,可联系管理员检查节点负责人后重新提交。"),
FLOW_INSTANCE_STAGE_NOT_APPROVAL(1337, "抱歉,审核任务已过期"),
FLOW_APPROVAL_PERMISSION_ERROE(1338, "抱歉,你没有审核权限"),
FLOW_DEFINITION_VERSION_STAGE_ERROR(1339, "流程版本状态异常"),
FLOW_FORM_FIELD_PERMISSION(1340, "节点未设置表单字段"),
FLOW_FORM_APPROVAL_NOT_EXIST(1341, "审核节点未设置审核人"),
FLOW_NODE_COUNT_ERROR(1342, "回退节点数量异常"),
FLOW_INSTANCE_STAGE_FINISHED(1343, "抱歉,审核任务已结束"),
FLOW_INSTANCE_STAGE_RECALL(1344, "抱歉,审核任务已撤回"),
CHECK_PARAM_TIME_ERROR(4000, "登记时间参数格式异常"),
/**
* 业务异常
*/
MODULE_NAME_REPEAT(2, "模块已存在,请检查后提交"),
FORM_NAME_REPEAT(2, "表单已存在,请检查后提交"),
MENU_NAME_REPEAT(2, "数据中心已存在,请检查后提交"),
MENU_NAME_DEFAULT(2, "默认的数据中心只能有一个,请检查后在提交"),
MODULE_NOT_EXIST(1001,"模块不存在"),
MODULE_FIELD_NOT_EXIST(1002,"模块字段为空"),
SCHOOL_NOT_INIT(1004,"学校基础信息未初始化,无法同步师生数据"),
DATASOURCE_TYPE_NOT_SUPPORTED(1003,"数据源目前不支持此类型"),
ES_RETURN_EMPTY(2, "数据分析平台返回数据为空!"),
CLASS_RETURN_EMPTY(2, "班级信息为空!"),
FACULTY_RETURN_EMPTY(2, "学院信息为空!"),
USER_RETURN_EMPTY(2, "用户信息为空!"),
DEPART_TYPE_EMPTY(9020,"部门类型为空 "),
DEPART_NOT_FOUND(9020,"用户部门不能为空 "),
USER_MUST_INSTRUCTOR(2005,"用户角色只能为辅导员"),
/***********************************通讯录相关 start***************************************/
SYNC_TYPE_EMPTY(2, "同步通讯录类型不存在!"),
SYNC_TYPE_TASK_EMPTY(2, "同步通讯录存储过程类型不存在!"),
ES_INDEX_RETURN_EMPTY(2404, "同步索引未进行配置,请进行配置!"),
SYNC_TEACHER_INDEX_NOT_EXIST(1005,"同步教师数据索引不存在"),
SYNC_STUDENT_INDEX_NOT_EXIST(1006,"同步学生数据索引不存在"),
SYNC_FACULTY_INDEX_NOT_EXIST(1007,"同步学院数据索引不存在"),
SYNC_CLASS_INDEX_NOT_EXIST(1008,"同步班级数据索引不存在"),
SYNC_TEACHER_CLASS_INDEX_NOT_EXIST(1009,"同步带班数据索引不存在"),
ES_SERVER_ERROR(1010,"网络异常/连接ES平台异常"),
OBJECT_FIELD_NOT_VALID(1011,"数据不合法"),
OBJECT_FIELD_FACULTY_NOT_VALID(1012,"学院数据不合法"),
OBJECT_FIELD_CLASS_NOT_VALID(1013,"班级数据不合法"),
OBJECT_FIELD_ACCOUNT_NOT_VALID(1014,"教师工号数据不合法"),
OBJECT_FIELD_PARENT_CODE_NOT_VALID(1015,"父类编码数据不合法"),
/***********************************通讯录相关 end***************************************/
/***********************************预警子系统 start***************************************/
ALERT_RULE_NOT_EXIST(100101,"预警规则不存在"),
NOTIFY_CONFIG_NOT_FOUND(100102, "提醒配置信息未找到"),
TIMER_CRON_ERROR(100103, "定时设置不合法,请检查配置"),
FORM_NOT_EXIST(100104, "自定义表单不存在,请联系管理员"),
OPEN_TAG_NOT_EXIST(9004, "未找到合法的预警模型"),
SYNC_RESULT_EMPTY(9004, "预警同步结果为空"),
/***********************************预警子系统 end***************************************/
COMPONENT_NOT_FOUND(3005,"组件不存在"),
/***********************************陪伴子系统 start***************************************/
/** 陪伴主题 **/
ACMP_THEME_NOT_EXIST(2002,"陪伴主题不存在"),
ACMP_THEME_DELETE(2003,"已产生对应陪伴数据,如需删除,请联系管理员"),
ACMP_THEME_REPEAT(2004,"主题名称重复"),
/** 陪伴选项分类 **/
ACMP_TYPE_REPEAT(2005,"选项分类名称重复"),
ACMP_TYPE_DELETE(2003,"分类已有陪伴选项关联,如需删除,请联系管理员"),
ACMP_TYPE_NOT_EXIST(2002,"选项分类不存在"),
/** 陪伴中心**/
ACMP_DATA_NOT_EXIST(2006,"陪伴数据不存在"),
ACMP_DATA_NOT_SUPPORT_UPLOAD(2007,"该陪伴数据不支持上传"),
ACMP_SETTING_DISPOSE_NOT_EXIST(2004,"未设置陪伴方式,请联系管理员"),
ACMP_SYSTEM_NOT_EXIST(2002,"陪伴体系不存在"),
ACMP_SYSTEM_NAME_REPEAT(2005,"选项体系名称重复"),
ACMP_SYSTEM_CANT_DELETE(2002,"陪伴体系存在陪伴数据,无法删除"),
ACMP_OPTION_NOT_EXIST(2002,"陪伴选项不存在"),
ACMP_OPTION_CANT_DELETE(2002,"陪伴选项存在陪伴数据,无法删除"),
ACMP_OPTION_NAME_REPEAT(2005,"选项选项名称重复"),
ACMP_UPLOAD_FAIL(2006,"陪伴数据上传失败"),
ACMP_ADD_FAIL(2006,"创建陪伴记录失败"),
ACMP_CONFIG_MISS(2007,"缺少陪伴上报配置"),
ACMP_ADD_NOT_STUDENT(2008,"一对多陪伴未设置陪伴学生!"),
/***********************************陪伴子系统 end***************************************/
/***********************************关注子系统 start***************************************/
FOLLOW_STUDENT_NOT_FOLLOWED(100301,"您未关注该学生,无法取消关注"),
FOLLOW_EXCEL_ERROR(100302,"批量关注Excel格式不正确"),
/***********************************关注子系统 end***************************************/
/***********************************考核子系统 start***************************************/
CHECK_USER_MUST_INSTRUCTOR(2005,"参与考核成员必须为辅导员"),
ASSESS_FOLLOW_STUDENT_NOT_FOUND(2005,"未找到关注学生陪伴考核陪伴信息"),
ASSESS_RECOMMEND_STUDENT_NOT_FOUND(2005,"未找到关注学生陪伴考核陪伴信息"),
/***********************************考核子系统 end***************************************/
MESSAGE_NOT_FOUND(1046,"消息不存在"),
/***********************************学生预约辅导员 start***************************************/
RESERVATION_NOT_EXIST(1046,"未找到学生预约记录"),
RESERVATION_RULE_NOT_OPEN(1046,"辅导员未开启预约"),
RESERVATION_RULE_DAY_RULE_EMPTY(1002,"未找到当天预约内容"),
RESERVATION_RULE_DAY_RULE_PERIOD_NOT_FOUND(1002,"未找到当天预约时段,请联系辅导员"),
RESERVATION_PERIOD_OVERDUE(1002,"预约时段已过期,请刷新页面"),
RESERVATION_USER_REPEATED(1002,"请勿重复预约"),
RESERVATION_CANCEL_USER_NO_PERMISSION(1002,"非本人无权限撤回预约"),
RESERVATION_INSTRUCTOR_NOT_EXIST(1002,"未找到辅导员信息,请联系管理员"),
RESERVATION_STUDENT_NOT_EXIST(1002,"未找到学生,请联系管理员"),
RESERVATION_FINISH_COMMENT_NOT_EXIST(1046,"预约沟通结果不能为空"),
/***********************************学生预约辅导员 end***************************************/
/***********************************我爱记学生子系统 start***************************************/
ASSESS_CONFIG_NOT_EXIST(2002,"考试配置不存在"),
ASSESS_CONFIG_NAME_EXIST(2002,"存在名称重复的考试,请修改考试名称"),
ASSESS_QUESTION_CONFIG_NOT_EXIST(2002,"考试题库配置不存在,请联系管理员"),
ASSESS_QUESTION_EMPTY_ERROR(2002,"考试未设置题目,请检查考试题目配置"),
ASSESS_QUESTION_CONFIG_ERROR(2002,"题库配置错误,请检查题库是否配置了不存在的学生属性"),
ASSESS_EXAM_RECORD_NOT_FOUND(2002,"您已提交本次考试结果,请勿重复提交"),
ASSESS_TRAIN_RECORD_NOT_FOUND(2002,"很抱歉,未找到您的本次训练成绩,请联系管理员"),
EXAM_QUESTION_OVER_LIMIT(2002,"单场考试至多500道题目"),
ASSESS_RECORD_DELETE_ERROR(2002,"考试记录已删除,无法再次删除"),
ASSESS_RECORD_LEVEL_EXISTS(2002,"考试成绩已存在,不能再次提交答卷"),
ASSESS_CONFIG_NOT_STU(2002,"本次考试未找到符合条件的学生信息,请联系管理员"),
ASSESS_CONFIG_NOT_START(2002,"未到考试时间,无法参加考试"),
ASSESS_CONFIG_HAS_FINISHED(2002,"考试已结束"),
ASSESS_CONFIG_NOT_TIMES(2002,"您已经参加过本次考试,请勿重复考试"),
ASSESS_CONFIG_NOT_INSTRS(2002,"无考试权限:不在考试名单中,请联系管理员"),
ASSESS_RECORD_OVER_LIMIT(2002,"您目前仍有一条正在考试的记录,请先提交该考试成绩"),
ASSESS_RECORD_PERMISSION_ERROR(2002,"您没有查看此记录的权限"),
ASSESS_QUESTION_NOT_EXIST(2002,"未找到训练题目"),
ASSESS_EXAM_HAS_RECORD(2002,"当前考试有考生正在考试,请勿操作"),
ASSESS_RECORD_NOT_FOUND(2002,"该数据已被删除或者您没有查看该数据的权限"),
TEACHER_NOT_FOUND(2002,"没有教师数据权限"),
DATASOURCE_NOT_EXIST(1003,"未配置数据源,请联系管理员"),
DATASOURCE_DEFAULT_NOT_EXIST(1003,"未配置默认数据源,请联系管理员"),
/***********************************我爱记学生子系统 end***************************************/
/***********************************公权力监督 start***************************************/
PORTRAIT_TITLE_REPEAT(2006,"画像名称重复"),
PORTRAIT_NOT_EXIST(2007,"画像不存在"),
PORTRAIT_DELETE(2003,"已有对应的组件配置,如需删除,请联系管理员"),
TEMPLATE_TITLE_REPEAT(2008,"模板名称重复"),
TEMPLATE_NOT_EXIST(2009,"模板不存在"),
PORTRAIT_DASHBOARD_NOT_EXIST(2007,"数据看板不存在"),
DATACORRECTION_SETTING_NOT_FOUND(1029,"数据纠错表单地址不存在"),
DATACOLLECTION_SETTING_NOT_FOUND(1029,"数据采集表单地址不存在"),
PORTRAIT_EDIT_USER_NOT_PERMISSION(1029,"用户无权限编辑画像"),
PORTRAIT_DELETE_USER_NOT_PERMISSION(1029,"用户无权限删除画像"),
PORTRAIT_VIEW_USER_NOT_PERMISSION(1029,"用户无权限查看画像"),
DASHBOARD_EDIT_USER_NOT_PERMISSION(1029,"用户无权限编辑数据看板"),
DASHBOARD_DELETE_USER_NOT_PERMISSION(1029,"用户无权限删除数据看板"),
DASHBOARD_VIEW_USER_NOT_PERMISSION(1029,"用户无权限查看数据看板"),
VISIT_CODE_IS_EMPTY(1029,"公开访问码为空"),
VISIT_CODE_IS_NOT_CORRECT(1029,"访问码不正确"),
PORTRAIT_NOT_RELEASE(1029,"画像未发布,请联系管理员"),
/***********************************公权力监督 end***************************************/
//region 进度模块错误
TASK_RUNNING(3000,"当前任务正在运行中"),
TASK_NOT_RUNNING(3001,"任务不处于运行状态"),
TASK_NAME_NOT_NULL(3002,"任务名称不能为空"),
//endregion
//region 画像模块相关错误码
ES_CLIENT_INIT_ERROR(10000,"es数据源链接失败"),
ES_CLIENT_ERROR(10001,"es连接错误"),
PROJECT_NOT_EXIST(1029,"科研项目未找到"),
PROJECT_ALERT_EMPTY(2023,"科研项目数据为空"),
OBJECT_SCHEMA_NOT_FOUND(2001,"数据接入未设置"),
PROJECT_SQL_NOT_CONFIG(2002,"查询语句未配置"),
ES_INDEX_NOT_EXIST(10001,"未找到数据盒,请检查数据盒配置"),
//endregion
;
private Integer code;
private String message;
WorkflowResultCode(Integer code, String message){
this.code = code;
this.message = message;
}
public Integer code() {
return code;
}
public String message() {
return message;
}
}

44
dk-common/common-workflow/src/main/java/org/dromara/common/response/WorkflowSuccessResponseData.java

@ -1,44 +0,0 @@
/*
Copyright [2020] [https://www.stylefeng.cn]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Guns采用APACHE LICENSE 2.0开源协议您在使用过程中需要注意以下几点
1.请不要删除和修改根目录下的LICENSE文件
2.请不要删除和修改Guns源码头部的版权声明
3.请保留源码和相关描述文件的项目出处作者声明等
4.分发源码时候请注明软件出处 https://gitee.com/stylefeng/guns-separation
5.在修改包名模块名称项目代码等时请注明软件出处 https://gitee.com/stylefeng/guns-separation
6.若您的项目无法满足以上几点可申请商业授权获取Guns商业授权许可请在官网购买授权地址为 https://www.stylefeng.cn
*/
package org.dromara.common.response;
/**
* 成功响应结果
*
*/
public class WorkflowSuccessResponseData extends WorkflowResponseData {
public WorkflowSuccessResponseData() {
super(true, DEFAULT_SUCCESS_CODE, DEFAULT_SUCCESS_MESSAGE, null);
}
public WorkflowSuccessResponseData(Object object) {
super(true, DEFAULT_SUCCESS_CODE, DEFAULT_SUCCESS_MESSAGE, object);
}
public WorkflowSuccessResponseData(Integer code, String message, Object object) {
super(true, code, message, object);
}
}

68
dk-common/common-workflow/src/main/java/org/dromara/common/util/HttpServletUtil.java

@ -1,68 +0,0 @@
/*
Copyright [2020] [https://www.stylefeng.cn]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Guns采用APACHE LICENSE 2.0开源协议您在使用过程中需要注意以下几点
1.请不要删除和修改根目录下的LICENSE文件
2.请不要删除和修改Guns源码头部的版权声明
3.请保留源码和相关描述文件的项目出处作者声明等
4.分发源码时候请注明软件出处 https://gitee.com/stylefeng/guns-separation
5.在修改包名模块名称项目代码等时请注明软件出处 https://gitee.com/stylefeng/guns-separation
6.若您的项目无法满足以上几点可申请商业授权获取Guns商业授权许可请在官网购买授权地址为 https://www.stylefeng.cn
*/
package org.dromara.common.util;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.dromara.common.Exception.ServiceException;
import org.dromara.common.response.WorkflowResultCode;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
/**
* HttpServlet工具类获取当前request和response
*
*/
public class HttpServletUtil {
/**
* 获取当前请求的request对象
*
*/
public static HttpServletRequest getRequest() {
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (requestAttributes == null) {
throw new ServiceException(WorkflowResultCode.PARAM_IS_BLANK);
} else {
return requestAttributes.getRequest();
}
}
/**
* 获取当前请求的response对象
*
*/
public static HttpServletResponse getResponse() {
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (requestAttributes == null) {
throw new ServiceException(WorkflowResultCode.PARAM_IS_BLANK);
} else {
return requestAttributes.getResponse();
}
}
}

128
dk-common/common-workflow/src/main/java/org/dromara/common/util/JsonUtil.java

@ -1,128 +0,0 @@
package org.dromara.common.util;
import cn.hutool.core.util.ObjectUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.StringUtils;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* 定义响应结构
*/
public class JsonUtil {
private static ObjectMapper MAPPER;
static{
MAPPER=new ObjectMapper();
}
/**
* 将对象转换成json字符串
* <p>Title: pojoToJson</p>
* <p>Description: </p>
* @param data
* @return
*/
public static String toJson(Object data){
String string = null;
try {
string = MAPPER.writeValueAsString(data);
if(StringUtils.isEmpty(string)){
return null;
}
return string;
} catch (JsonProcessingException e) {
e.printStackTrace();
return null;
}
}
/**
* 将json结果集转化为对象
*
* @param jsonData json数据
* @return
*/
public static <T> T jsonToPojo(String jsonData, Class<T> beanType) {
try {
T t = MAPPER.readValue(jsonData, beanType);
return t;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 将json数据转换成pojo对象list
* <p>Title: jsonToList</p>
* <p>Description: </p>
* @param jsonData
* @param beanType
* @return
*/
public static <T>List<T> jsonToList(String jsonData, Class<T> beanType) {
JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType);
try {
List<T> list = MAPPER.readValue(jsonData, javaType);
return list;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 将Object对象里面的属性和值转化成Map对象
*
* @param obj
* @return
* @throws IllegalAccessException
*/
public static Map<String, Object> objectToMap(Object obj){
try {
Map<String, Object> map = new HashMap<String,Object>();
Class<?> clazz = obj.getClass();
for (Field field : clazz.getDeclaredFields()) {
field.setAccessible(true);
String fieldName = field.getName();
if(ObjectUtil.isNotEmpty(field.get(obj))){
Object value = field.get(obj);
map.put(fieldName, value);
}else{
map.put(fieldName, "");
}
}
return map;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static Map<String, Object> jsonToMap(String json){
try {
return MAPPER.readValue(json, new TypeReference<Map<String, Object>>(){});
} catch (JsonProcessingException e) {
e.printStackTrace();
return null;
}
}
public static LinkedHashMap<String, String> jsonToStrMap(String json){
try {
return MAPPER.readValue(json, new TypeReference<LinkedHashMap<String, String>>(){});
} catch (JsonProcessingException e) {
e.printStackTrace();
return null;
}
}
}

87
dk-common/common-workflow/src/main/java/org/dromara/dataManager/controller/FormDataController.java

@ -1,87 +0,0 @@
package org.dromara.dataManager.controller;
import org.dromara.common.response.WorkflowResponseData;
import org.dromara.common.response.WorkflowResult;
import org.dromara.dataManager.param.FormDataParam;
import org.dromara.dataManager.param.UpdateDataParams;
import org.dromara.dataManager.service.FormDataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
/**
* 表单数据服务API
*
*/
@RestController
@RequestMapping("/form")
public class FormDataController {
@Autowired
private FormDataService formDataService;
/**
* 列表查询表单数据
*/
@GetMapping("/data/page")
public WorkflowResponseData pageFormData(FormDataParam param) {
return WorkflowResult.success(formDataService.pageFormData(param));
}
/**
* 添加表单数据
*/
@PostMapping("/data/add")
public WorkflowResponseData addTFormData(
@RequestBody @Validated(FormDataParam.add.class) FormDataParam param) {
return WorkflowResult.success(formDataService.addFormData(param));
}
/**
* 编辑表单数据
*/
@PostMapping("/{formId}/data/{dataId}/edit")
public WorkflowResponseData editFormData(
@PathVariable("formId")Long formId,@PathVariable("dataId")Long dataId,
@RequestBody UpdateDataParams param) {
return WorkflowResult.success(formDataService.editFormData(param));
}
/**
* 查询单个表单数据
*/
@GetMapping("/{formId}/data/{dataId}/detail")
public WorkflowResponseData getFormDataDetail(@PathVariable("formId")Long formId, @PathVariable("dataId")Long dataId) {
return WorkflowResult.success(formDataService.getFormDataFullInfo(formId,dataId));
}
/**
* 删除表单数据
*/
@PostMapping("/{formId}/data/{dataId}/delete")
public WorkflowResponseData deleteFormData(@PathVariable("formId")Long formId, @PathVariable("dataId")Long dataId) {
return WorkflowResult.success(formDataService.deleteFormData(dataId));
}
/**
* 导出表单数据
*/
@GetMapping("/data/export")
public void exportFormData(FormDataParam param) {
}
}

96
dk-common/common-workflow/src/main/java/org/dromara/dataManager/controller/FormDataExcelController.java

@ -1,96 +0,0 @@
package org.dromara.dataManager.controller;
import jakarta.servlet.http.HttpServletResponse;
import org.dromara.common.response.WorkflowResponseData;
import org.dromara.common.response.WorkflowResult;
import org.dromara.common.response.WorkflowResultCode;
import org.dromara.dataManager.param.DownloadDataParams;
import org.dromara.dataManager.param.ImportDataParams;
import org.dromara.dataManager.service.impt.exception.ImportDataInvalidException;
import org.dromara.dataManager.service.impt.service.ImportFromExcelService;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.Map;
/**
* @description: 表单数据导入导入
*/
@Slf4j
@RestController
@RequestMapping({"/manager/data","/data"})
public class FormDataExcelController {
@Autowired
private ImportFromExcelService importFromExcelService;
/**
* 数据导出
*
* @param params
* @param response
* @throws IOException
*/
@PostMapping("/export")
public void export(@RequestBody @Validated DownloadDataParams params, HttpServletResponse response) throws IOException {
// exportESDataService.exportData(params, response);
}
/**
* 导入前预览
*
* @param params
* @return
* @throws Exception
*/
@PostMapping("/import/preview")
public WorkflowResponseData previewExcel(@RequestParam("file") MultipartFile file, ImportDataParams params) throws Exception {
return WorkflowResult.success(importFromExcelService.previewExcel(file,params.getSheetIndex()));
}
/**
* 数据导入
*
* @param params
* @return
* @throws Exception
*/
@PostMapping("/import")
public WorkflowResponseData importExcelData(ImportDataParams params) {
try {
Map<Integer, String> realMapping = new ObjectMapper().readValue(params.getMapping(), new TypeReference<Map<Integer, String>>() {});
params.setObjMapping(realMapping);
params.setValidationConfig(JSONUtil.toBean(params.getValidationConfigStr(), ImportDataParams.ValidationConfig.class));
return WorkflowResult.success(importFromExcelService.importV2(params));
} catch (ImportDataInvalidException e) {
return CollectionUtil.isEmpty(e.getInvalidRows()) ? WorkflowResult.error(e.getMessage()) : WorkflowResult.error(WorkflowResultCode.FAIL, e.getInvalidRows());
} catch (Exception e) {
log.error(e.getMessage(), e);
return WorkflowResult.error("导入数据异常" + e.getMessage());
}
}
/**
* 下载导入数据模板
*
* @param params
* @param
* @throws Exception
*/
@PostMapping("/import/template")
public void generateImportTemplate(@RequestBody ImportDataParams params,
HttpServletResponse response) throws Exception {
importFromExcelService.generateImportTemplate(response, params.getFormId(), params.getExportFields());
}
}

133
dk-common/common-workflow/src/main/java/org/dromara/dataManager/controller/FormDataInstanceController.java

@ -1,133 +0,0 @@
package org.dromara.dataManager.controller;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.response.WorkflowResponseData;
import org.dromara.common.response.WorkflowResult;
import org.dromara.common.response.WorkflowResultCode;
import org.dromara.dataManager.param.ActiveDataParams;
import org.dromara.dataManager.param.TransferDataParams;
import org.dromara.dataManager.param.UpdateDataParams;
import org.dromara.dataManager.service.FormDataService;
import org.dromara.workflow.engine.domain.Instance;
import org.dromara.workflow.result.engine.BaseActionResult;
import org.dromara.workflow.result.engine.EngineDataResult;
import org.dromara.workflow.service.external.FlowInstanceService;
import cn.hutool.core.util.ObjectUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @desc 数据管理API
*/
@RestController
@RequestMapping({"/manager/data"})
public class FormDataInstanceController {
@Autowired
private FlowInstanceService instanceService;
@Autowired
private FormDataService formDataService;
/**
* 调整流程负责人
* @param param
* @return
*/
@PostMapping("/instance/transfer")
public WorkflowResponseData transfer(@RequestBody TransferDataParams param){
if(ObjectUtil.hasEmpty(param.getDataId(),param.getData(),param.getFormId(),param.getTransferNodeId(),
param.getCheckers())){
return WorkflowResult.error(WorkflowResultCode.PARAM_MISSING);
}
Instance instance = instanceService.getInstance(param.getDataId());
//更新流程节点调整负责人
BaseActionResult actionRsp = instanceService.transferInstanceUser(instance,param.getTransferNodeId(),param.getCheckers());
if(actionRsp.getSuccess()){
//更新表单流程数据
EngineDataResult result = instanceService.transformInstanceDataResult(instance);
result.setUpdatorName(LoginHelper.getLoginUser().getNickname());
param.getData().putAll(instanceService.getInstanceData(result));
UpdateDataParams item = new UpdateDataParams(param.getFormCode(), param.getDataId(),param.getData());
item.setUser(LoginHelper.getLoginUser().getUserId(),LoginHelper.getLoginUser().getUsername(),LoginHelper.getLoginUser().getNickname());
formDataService.editFormData(item);
return WorkflowResult.success(item.getData());
}
return WorkflowResult.error(actionRsp.getCode(),actionRsp.getMessage());
}
/**
* 结束流程
* @param param
* @return
*/
@PostMapping("/instance/finish")
public WorkflowResponseData finish(@RequestBody UpdateDataParams param){
if(ObjectUtil.hasEmpty(param.getDataId(),param.getData(),param.getFormId())){
return WorkflowResult.error(WorkflowResultCode.PARAM_MISSING);
}
Instance instance = instanceService.getInstance(param.getDataId());
//结束流程
BaseActionResult actionRsp = instanceService.finishInstance(instance);
if(actionRsp.getSuccess()){
//更新表单流程数据
EngineDataResult result = new EngineDataResult(instance);
result.setUpdatorName(LoginHelper.getLoginUser().getNickname());
param.getData().putAll(instanceService.getInstanceData(result));
UpdateDataParams item = new UpdateDataParams(param.getFormCode(), param.getDataId(),param.getData());
item.setUser(LoginHelper.getLoginUser().getUserId(),LoginHelper.getLoginUser().getUsername(),LoginHelper.getLoginUser().getNickname());
formDataService.editFormData(item);
return WorkflowResult.success(item.getData());
}
return WorkflowResult.error(actionRsp.getCode(),actionRsp.getMessage());
}
/**
* 激活流程
* feat_00141最新
* @param param
* @return
*/
@PostMapping("/instance/active")
public WorkflowResponseData active(@RequestBody ActiveDataParams param){
if(ObjectUtil.hasEmpty(param.getDataId(),param.getData(),param.getFormCode())){
return WorkflowResult.error(WorkflowResultCode.PARAM_MISSING);
}
Instance instance = instanceService.getInstance(param.getDataId());
//激活流程
BaseActionResult actionRsp = instanceService.activeInstance(instance,param.getActiveNodeId(),param.getData());
if(actionRsp.getSuccess()){
//更新表单流程数据
EngineDataResult result = instanceService.transformInstanceDataResult(instance);
result.setUpdatorName(LoginHelper.getLoginUser().getNickname());
param.getData().putAll(instanceService.getInstanceData(result));
UpdateDataParams item = new UpdateDataParams(param.getFormCode(), param.getDataId(),param.getData());
item.setUser(LoginHelper.getLoginUser().getUserId(),LoginHelper.getLoginUser().getUsername(),LoginHelper.getLoginUser().getNickname());
formDataService.editFormData(item);
return WorkflowResult.success(item.getData());
}
return WorkflowResult.error(actionRsp.getCode(),actionRsp.getMessage());
}
}

97
dk-common/common-workflow/src/main/java/org/dromara/dataManager/domain/FormData.java

@ -1,97 +0,0 @@
package org.dromara.dataManager.domain;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import lombok.Data;
import org.dromara.common.entity.WorkflowBaseEntity;
import java.util.LinkedHashMap;
/**
* 表单数据
*
*/
@Data
@TableName(value = "t_form_data", autoResultMap = true)
public class FormData extends WorkflowBaseEntity {
/**
* 主键
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 表单id
*/
@TableField("form_id")
private Long formId;
/**
* 提交数据
*/
@TableField(value = "form_data", typeHandler = JacksonTypeHandler.class)
private LinkedHashMap<String,Object> formData;
/**
* 流程实例id
*/
@TableField("instance_id")
private Long instanceId;
/**
* 流程状态
*/
@TableField(value = "instance_stage",updateStrategy = FieldStrategy.IGNORED)
private String instanceStage;
/**
* 流程当前节点负责人
*/
@TableField(value = "instance_checker",updateStrategy = FieldStrategy.IGNORED )
private String instanceChecker;
/**
* 流程实例节点信息
*/
@TableField(value = "instance_node",updateStrategy = FieldStrategy.IGNORED)
private String instanceNode;
/**
* 是否删除
*/
@TableField("deleted")
private Boolean deleted;
/**
* 创建人账号
*/
@TableField("create_account")
private String createAccount;
/**
* 创建人姓名
*/
@TableField("create_name")
private String createName;
/**
* 最近一次更新人姓名
*/
@TableField("update_user_name")
private String updateUserName;
}

174
dk-common/common-workflow/src/main/java/org/dromara/dataManager/domain/FormDataLog.java

@ -1,174 +0,0 @@
package org.dromara.dataManager.domain;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.TimeZone;
/**
* 表单数据日志
*/
@Data
@TableName(value = "t_form_data_log",autoResultMap = true)
public class FormDataLog implements Serializable {
private static final long serialVersionUID = 7522827670631635795L;
@TableId(value = "id", type = IdType.AUTO)
private Long id;
@TableField("form_id")
private Long formId;
@TableField("form_code")
private String formCode;
@TableField("data_id")
private Long dataId;
@TableField("type")
private String type;
@TableField("new_value")
private String newValue;
@TableField("old_value")
private String oldValue;
@TableField("create_id")
private Long createId;
@TableField("create_account")
private String createAccount;
@TableField("create_name")
private String createName;
@TableField("add_time")
private Date addTime;
@TableField("aft")
private String aft;
@TableField("bef")
private String bef;
@TableField("changes")
private String changes;
@TableField("handled")
private boolean handled;
public FormDataLog(){
}
public FormDataLog(Long formId, String formCode){
this.formId = formId;
this.formCode = formCode;
}
public void fillData(String type,Long dataId,Map<String, Object> before, Map<String, Object> after){
this.dataId = dataId;
this.type = type;
this.fillOldData(before);
this.fillNewData(after);
}
public void fillOldData(Map<String, Object> before){
if(MapUtil.isNotEmpty(before)){
if(before.containsKey("createTime")){
before.put("createTime",formatTime(before.get("createTime")));
}
if(before.containsKey("updateTime")){
before.put("updateTime", formatTime(before.get("updateTime")));
}
this.bef = JSON.toJSONString(before, SerializerFeature.WriteMapNullValue);
}
}
public void fillNewData(Map<String, Object> after){
if(MapUtil.isNotEmpty(after)){
if(after.containsKey("createTime")){
after.put("createTime", formatTime(after.get("createTime")));
}
if(after.containsKey("updateTime")){
after.put("updateTime", formatTime(after.get("updateTime")));
}
this.aft = JSON.toJSONString(after, SerializerFeature.WriteMapNullValue);
}
}
private String formatTime(Object timestamp) {
TimeZone timeZone = TimeZone.getTimeZone("GMT+0:00");
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
simpleDateFormat.setTimeZone(timeZone);
if (timestamp instanceof Long) {
String wrappedTime = simpleDateFormat.format(new Date((long)timestamp));
if(StrUtil.isNotEmpty(wrappedTime)){
return StrUtil.replace(wrappedTime,"Z","+00:00");
}
}
if (timestamp instanceof Date) {
return StrUtil.replace(simpleDateFormat.format((Date) timestamp),"Z","+00:00");
}
return timestamp+"";
}
public void setUser(Long createId,String createName,String createAccount,Date createTime){
if(ObjectUtil.hasEmpty(createId,createAccount)){
this.createId = 0L;
this.createAccount = "system";
this.createName = "系统";
}else{
this.createId = createId;
this.createName = createName;
this.createAccount = createAccount;
}
this.addTime = createTime;
}
@Data
public static class UpdateWidgetResult {
private String model;
private String bef;
private String aft;
public UpdateWidgetResult(String model){
this.model = model;
}
public UpdateWidgetResult(String model,String bef,String aft){
this.model = model;
this.bef = bef;
this.aft = aft;
}
}
}

11
dk-common/common-workflow/src/main/java/org/dromara/dataManager/domain/FormDataLogChange.java

@ -1,11 +0,0 @@
package org.dromara.dataManager.domain;
import lombok.Data;
@Data
public class FormDataLogChange extends FormDataLog {
private static final long serialVersionUID = 1040326720258635873L;
private String userName;
}

51
dk-common/common-workflow/src/main/java/org/dromara/dataManager/enums/DataAspectEnum.java

@ -1,51 +0,0 @@
package org.dromara.dataManager.enums;
import cn.hutool.core.util.StrUtil;
import lombok.Getter;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* @Description: 数据切面枚举
**/
@Getter
public enum DataAspectEnum {
SAVE("save","save","表单提交"),
IMPORT("import","save","导入"),
UPDATE("update","update","数据编辑"),
UPDATE_FIELD("updateField","update","批量编辑"),
RECOVER("recover","recover","恢复数据"),
DELETE("delete","delete","逻辑删除"),
SHIFT_DELETE("shift_delete","delete","物理删除"),
CLEAR("clear","delete","清空数据");
private String code;
private String group;
private String name;
DataAspectEnum(String code, String group, String name){
this.code = code;
this.group = group;
this.name = name;
}
public static List<String> getGroupCode(String group){
return Arrays.stream(values()).filter(p -> StrUtil.equals(group,p.getGroup())).map(DataAspectEnum::getCode).collect(Collectors.toList());
}
}

51
dk-common/common-workflow/src/main/java/org/dromara/dataManager/enums/WidgetType.java

@ -1,51 +0,0 @@
package org.dromara.dataManager.enums;
import java.util.Arrays;
import java.util.Optional;
public enum WidgetType {
GENERAL("general"),
CHECKBOX("checkbox"),
SWITCH("switch"),
EDITOR("editor"),
TEXT("text"),
LOCATION("location"),
SINGLE_MEMBER("singlemember"),
MULTIPLE_MEMBERS("multiplemembers"),
MULTIPLE_DEPARTMENTS("multiple_departments"),
SINGLE_DEPARTMENT("singledepartment"),
TABLE("table"),
IMG_UPLOAD("imgupload"),
FILE_UPLOAD("fileupload"),
DATA_LINK("datalink"),
UNIQ_KEY("uniqkey"),
FORMAT_NUMBER("format_number"),
INPUT("input"),
TEXTAREA("textarea"),
SELECT("select"),
DATE("date"),
COORDINATES("coordinates"),
PHONE("phone"),
RADIO("radio"),
MULTIPLE_SELECT("multiple_select"),
DIVIDER("divider"),
LINK_QUERY("link_query");
private String code;
public String getCode() {
return code;
}
WidgetType(String code) {
this.code = code;
}
public static WidgetType getByCode(String code) {
Optional<WidgetType> optional = Arrays.stream(values()).filter(type -> type.getCode().equals(code)).findFirst();
return optional.orElse(null);
}
}

17
dk-common/common-workflow/src/main/java/org/dromara/dataManager/mapper/FormDataLogChangeMapper.java

@ -1,17 +0,0 @@
package org.dromara.dataManager.mapper;
import org.dromara.dataManager.domain.FormDataLog;
import org.dromara.dataManager.domain.FormDataLogChange;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface FormDataLogChangeMapper extends BaseMapper<FormDataLog> {
List<String> selectDocIds();
List<FormDataLogChange> selectLogs(@Param("docIds")List<String> docIds);
void updateLogs(@Param("logs")List<FormDataLogChange> logs);
}

21
dk-common/common-workflow/src/main/java/org/dromara/dataManager/mapper/FormDataLogMapper.java

@ -1,21 +0,0 @@
package org.dromara.dataManager.mapper;
import org.dromara.dataManager.domain.FormDataLog;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface FormDataLogMapper extends BaseMapper<FormDataLog> {
List<FormDataLog> listDataLog(@Param("formId")Long formId,@Param("dataId")Long dataId);
boolean batchSaveDataLog(@Param("logList")List<FormDataLog> dataLogs);
/**
* 批量删除
* @param docIds
*/
void deleteByDataIds(@Param("dataIds") String[] docIds);
}

18
dk-common/common-workflow/src/main/java/org/dromara/dataManager/mapper/FormDataMapper.java

@ -1,18 +0,0 @@
package org.dromara.dataManager.mapper;
import org.dromara.dataManager.result.FormDataResult;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.dromara.dataManager.domain.FormData;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
/**
* 表单数据 Mapper 接口
*
*/
public interface FormDataMapper extends BaseMapper<FormData> {
Page<FormDataResult> pageFormData(@Param("page") Page page,@Param("ew") QueryWrapper queryWrapper);
}

31
dk-common/common-workflow/src/main/java/org/dromara/dataManager/mapper/mapping/FormDataLogChangeMapper.xml

@ -1,31 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.dataManager.mapper.FormDataLogChangeMapper">
<select id="selectDocIds" resultType="string">
SELECT DISTINCT data_id FROM t_form_data_log
</select>
<select id="selectLogs" resultType="org.dromara.dataManager.domain.FormDataLogChange">
select
a.*, b.name as userName
from
t_form_data_log a
left join
sys_user b
on
a.create_id = b.id
where
a.data_id in
<foreach collection="docIds" item="docId" open="(" separator="," close=")">
#{docId}
</foreach>
order by a.add_time asc
</select>
<update id="updateLogs">
<foreach collection="logs" item="log">
UPDATE t_form_data_log SET aft = #{log.aft}, bef = #{log.bef}, changes = #{log.changes}, handled = #{log.handled} WHERE id = #{log.id};
</foreach>
</update>
</mapper>

41
dk-common/common-workflow/src/main/java/org/dromara/dataManager/mapper/mapping/FormDataLogMapper.xml

@ -1,41 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.dataManager.mapper.FormDataLogMapper">
<select id="listDataLog" resultType="org.dromara.dataManager.domain.FormDataLog">
select t.type,t.aft as 'aft',t.bef as 'bef',t.data_id as 'dataId',
t.changes as 'changes',t.add_time as 'addTime',
t.create_id as 'createId',t.create_name as 'createName',t.create_account as 'createAccount'
from t_form_data_log t
where t.form_id = #{formId} and t.data_id = #{dataId}
order by t.add_time desc
</select>
<insert id="batchSaveDataLog" parameterType="org.dromara.dataManager.domain.FormDataLog">
INSERT INTO t_form_data_log
(
form_id, form_code,data_id,type,aft,bef,changes,create_id,create_name,create_account,add_time
)
VALUES
<foreach collection="logList" item="model" separator=",">
(
#{model.formId}, #{model.formCode},
#{model.dataId}, #{model.type}, #{model.aft}, #{model.bef},#{model.changes},
#{model.createId},#{model.createName},#{model.createAccount},#{model.addTime}
)
</foreach>
</insert>
<!-- 批量删除 -->
<delete id="deleteByDataIds">
DELETE FROM
t_form_data_log
WHERE
data_id IN
<foreach collection="dataIds" open="(" separator="," close=")" item="dataId">
#{dataId}
</foreach>
</delete>
</mapper>

50
dk-common/common-workflow/src/main/java/org/dromara/dataManager/mapper/mapping/FormDataMapper.xml

@ -1,50 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.dataManager.mapper.FormDataMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="org.dromara.dataManager.result.FormDataResult">
<id column="id" property="id" />
<result column="formId" property="formId" />
<result column="formData" property="formData" javaType="java.util.LinkedHashMap"
typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler"/>
<result column="instanceId" property="instanceId" />
<result column="stage" property="stage" />
<result column="checkers" property="checkerName" />
<result column="nodes" property="nodeTitle" />
<result column="deleted" property="deleted" />
<result column="createUser" property="createUser" />
<result column="createName" property="createName" />
<result column="createAccount" property="createAccount" />
<result column="createTime" property="createTime" />
<result column="updateUser" property="updateUser" />
<result column="updateTime" property="updateTime" />
<result column="updateName" property="updateName" />
</resultMap>
<select id="pageFormData" resultMap="BaseResultMap">
select
tfd.id,
tfd.form_id formId,
tfd.form_data formData,
tfd.instance_id instanceId,
tfd.instance_stage stage,
tfd.instance_checker checkers,
tfd.instance_node nodes,
tfd.deleted,
tfd.create_user createUser,
tfd.create_account createAccount,
tfd.create_time createTime,
tfd.create_name createName,
tfd.update_user updateUser,
tfd.update_time updateTime,
tfd.update_user_name updateName
from t_form_data tfd
${ew.customSqlSegment}
</select>
</mapper>

30
dk-common/common-workflow/src/main/java/org/dromara/dataManager/param/ActiveDataParams.java

@ -1,30 +0,0 @@
package org.dromara.dataManager.param;
import lombok.Data;
import java.util.LinkedHashMap;
/**
* 激活实例
*/
@Data
public class ActiveDataParams extends UpdateDataParams {
/**
* 激活的节点 id
*/
private String activeNodeId;
public ActiveDataParams(){}
public ActiveDataParams(String activeNodeId){
this.activeNodeId = activeNodeId;
}
public ActiveDataParams(String activeNodeId, String formCode, Long docId, LinkedHashMap<String, Object> data){
super.setFormCode(formCode);
super.setDataId(docId);
super.setData(data);
this.activeNodeId = activeNodeId;
}
}

109
dk-common/common-workflow/src/main/java/org/dromara/dataManager/param/DataParams.java

@ -1,109 +0,0 @@
package org.dromara.dataManager.param;
import lombok.Data;
import lombok.Getter;
import org.dromara.system.domain.SysDept;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* 数据传参
*/
@Data
public class DataParams implements Serializable {
private static final long serialVersionUID = 8682927139425739121L;
/**
* 表单id
*/
private Long formId;
/**
* 表单code
*/
private String formCode;
/**
* 权限组group id
*/
private Long permissionGroupId;
/**
* 操作用户信息
*/
private Long userId;
private String userAccount;
private String userName;
private List<Long> userDepartIds;
private List<Long> userGroupIds;
private List<SysDept> departs;
/**
* 操作时间
*/
private Date handleTime = new Date();
/**
* 外链更新方式 data
*/
private AccessType accessType;
/**
* 外链更新token
*/
private String accessToken;
@Getter
public enum AccessType{
form("form","表单"),
data("data","数据");
private String type;
private String name;
AccessType(String type,String name){
this.type = type;
this.name = name;
}
}
public void setUser(Long userId, String userAccount, String userName, List<Long> departIds, List<Long> groupIds){
this.userId = userId;
this.userAccount = userAccount;
this.userName = userName;
this.userDepartIds = departIds;
this.userGroupIds = groupIds;
}
public void setUser(Long userId, String userAccount, String userName, List<Long> departIds, List<Long> groupIds, List<SysDept> departs){
this.userId = userId;
this.userAccount = userAccount;
this.userName = userName;
this.userDepartIds = departIds;
this.userGroupIds = groupIds;
this.departs = departs;
}
public void setUser(Long userId, String userAccount, String userName){
this.userId = userId;
this.userAccount = userAccount;
this.userName = userName;
}
public void setUser(DataParams dataParams){
if(dataParams != null){
this.userId = dataParams.getUserId();
this.userAccount = dataParams.getUserAccount();
this.userName = dataParams.getUserName();
}
}
}

33
dk-common/common-workflow/src/main/java/org/dromara/dataManager/param/DownloadDataParams.java

@ -1,33 +0,0 @@
package org.dromara.dataManager.param;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import org.dromara.common.param.WorkflowBaseParam;
import java.util.List;
/**
* 数据导出
*/
@Data
public class DownloadDataParams extends DataParams {
@NotNull(message = "表单代码不能为空", groups = WorkflowBaseParam.export.class)
private String formCode;
@NotNull(message = "导出字段不能为空")
private List<String> exportFields;
private Long permissionId;
/**
* 是否导出ID
*/
private boolean includeId = false;
/**
* 导出文件名如果为空则使用表单名称作为文件名
*/
private String exportName;
}

71
dk-common/common-workflow/src/main/java/org/dromara/dataManager/param/FormDataModifyMessage.java

@ -1,71 +0,0 @@
package org.dromara.dataManager.param;
import org.dromara.dataManager.enums.DataAspectEnum;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* 表单数据更新message
*/
@Data
public class FormDataModifyMessage implements Serializable {
private static final long serialVersionUID = -1603895080729468809L;
/**
* 数据操作
*/
private DataAspectEnum action;
/**
* 表单id
*/
private Long formId;
/**
* 表单code
*/
private String formCode;
/**
* 操作时间
*/
private Date handleTime;
/**
* 操作人id
*/
private Long handleUserId;
/**
* 操作人账号
*/
private String handleUserAccount;
/**
* 操作人姓名
*/
private String handleUserName;
/**
* 修改前数据
*/
private List<Map<String, Object>> before = null;
/**
* 修改后数据
*/
private List<Map<String, Object>> after;
/**
* 批量修改的表单字段
*/
private String updateWidget;
}

41
dk-common/common-workflow/src/main/java/org/dromara/dataManager/param/FormDataParam.java

@ -1,41 +0,0 @@
package org.dromara.dataManager.param;
import cn.hutool.json.JSONArray;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import org.dromara.common.param.WorkflowBaseParam;
import org.dromara.workflow.engine.enums.InstanceStage;
import java.util.LinkedHashMap;
/**
* 表单数据
*
*/
@Data
public class FormDataParam extends WorkflowBaseParam {
private static final long serialVersionUID = 1L;
@NotNull(groups = {edit.class},message = "表单数据id不能为空")
private Long dataId;
@NotNull(groups = {add.class},message = "表单id不能为空")
private Long formId;
@NotNull(groups = {add.class},message = "表单数据不能为空")
private LinkedHashMap<String,Object> formData;
private Long instanceId;
private InstanceStage instanceStage;
private JSONArray instanceChecker;
private JSONArray instanceNode;
private Integer deleted;
private String app;
}

36
dk-common/common-workflow/src/main/java/org/dromara/dataManager/param/ImportDataParams.java

@ -1,36 +0,0 @@
package org.dromara.dataManager.param;
import org.dromara.dataManager.service.impt.enums.ImportMode;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.web.multipart.MultipartFile;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Data
@EqualsAndHashCode(callSuper = true)
public class ImportDataParams extends DataParams {
private static final long serialVersionUID = 5013388461809737003L;
private Integer sheetIndex;
private String mapping;
private Map<Integer, String> objMapping;
private List<String> exportFields = new ArrayList<>();
private ImportMode mode;
private String primaryKey;
private MultipartFile file;
private String validationConfigStr;
private ValidationConfig validationConfig;
@Data
public static class ValidationConfig {
private boolean required;
private boolean memberRequired;
private boolean departRequired;
private boolean optionRequired;
private boolean numberRequired;
private boolean dateRequired;
}
}

38
dk-common/common-workflow/src/main/java/org/dromara/dataManager/param/TransferDataParams.java

@ -1,38 +0,0 @@
package org.dromara.dataManager.param;
import lombok.Data;
import java.util.LinkedHashMap;
import java.util.List;
/**
* 调整实例节点负责人
*/
@Data
public class TransferDataParams extends UpdateDataParams {
/**
* 调整实例节点id
*/
private String transferNodeId;
/**
* 调整节点负责人
*/
private List<Long> checkers;
public TransferDataParams(){}
public TransferDataParams(String transferNodeId){
this.transferNodeId = transferNodeId;
}
public TransferDataParams(String transferNodeId, List<Long> checkers,
String formCode, Long dataId,
LinkedHashMap<String, Object> data){
super.setFormCode(formCode);
super.setDataId(dataId);
super.setData(data);
this.transferNodeId = transferNodeId;
this.checkers = checkers;
}
}

77
dk-common/common-workflow/src/main/java/org/dromara/dataManager/param/UpdateDataParams.java

@ -1,77 +0,0 @@
package org.dromara.dataManager.param;
import org.dromara.workflow.engine.enums.ESDefaultFieldConst;
import lombok.Data;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* 更新表单数据
*/
@Data
public class UpdateDataParams extends DataParams {
/**
* 数据doc id
*/
private Long dataId;
/**
* 表单数据
*/
private LinkedHashMap<String, Object> data;
/**
* 更新之前的表单数据
*/
private Map<String,Object> before;
public UpdateDataParams(){}
public UpdateDataParams(String formCode, Long docId, LinkedHashMap<String, Object> data){
this.setFormCode(formCode);
this.dataId = docId;
this.data = data;
}
/**
* 转ES数据
* @return
*/
public LinkedHashMap<String, Object> convertESData(){
if(data != null){
data.remove(ESDefaultFieldConst.OWNER);
data.remove(ESDefaultFieldConst.CREATOR);
data.remove(ESDefaultFieldConst.CREATOR_ACCOUNT);
data.remove(ESDefaultFieldConst.CREATE_TIME);
data.remove(ESDefaultFieldConst.DID);
data.remove(ESDefaultFieldConst.DELETED);
//设置更新时间
data.put(ESDefaultFieldConst.UPDATE_TIME, this.getHandleTime());
data.put(ESDefaultFieldConst.UPDATOR_NAME, this.getUserName());
}
return data;
}
/**
* 添加ES基础字段
* @return
*/
public LinkedHashMap<String, Object> addESData(){
if(data == null){
data = new LinkedHashMap<String, Object>();
}
data.put(ESDefaultFieldConst.OWNER, this.getUserId());
data.put(ESDefaultFieldConst.CREATOR, this.getUserName());
data.put(ESDefaultFieldConst.CREATOR_ACCOUNT, this.getUserAccount());
data.put(ESDefaultFieldConst.CREATE_TIME, this.getHandleTime());
data.put(ESDefaultFieldConst.UPDATE_TIME, this.getHandleTime());
data.put(ESDefaultFieldConst.UPDATOR_NAME, this.getUserName());
data.put(ESDefaultFieldConst.DID, this.getFormCode());
data.put(ESDefaultFieldConst.DELETED, false);
return data;
}
}

55
dk-common/common-workflow/src/main/java/org/dromara/dataManager/result/FormDataResult.java

@ -1,55 +0,0 @@
package org.dromara.dataManager.result;
import cn.hutool.json.JSONArray;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
import java.util.Map;
/**
* 表单数据
*
*/
@Data
public class FormDataResult implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private Long formId;
private Map<String,Object> formData;
private Long instanceId;
private String stage;
private String flowStage;
private String checkerName;
private String nodeTitle;
private Integer deleted;
private Long createUser;
private Date createTime;
private String createName;
private String createAccount;
private Long updateUser;
private Date updateTime;
private String updateName;
private JSONArray nodes = new JSONArray();
private JSONArray checkers = new JSONArray();
}

87
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/FormDataService.java

@ -1,87 +0,0 @@
package org.dromara.dataManager.service;
import java.util.List;
import java.util.Map;
import org.dromara.common.page.WorkflowPageResult;
import org.dromara.dataManager.param.UpdateDataParams;
import org.dromara.formMaking.results.FormSourceResult;
import com.baomidou.mybatisplus.extension.service.IService;
import org.dromara.dataManager.domain.FormData;
import org.dromara.dataManager.param.FormDataParam;
/**
* 表单数据 服务类
*
*/
public interface FormDataService extends IService<FormData> {
/**
* 分页
* @param param
* @return
*/
WorkflowPageResult<Map<String,Object>> pageFormData(FormDataParam param);
/**
* 查询表单数据
* @param dataId
* @return
*/
FormData getFormData(Long dataId);
/**
* 查询数据全部字段数据
* @param dataId
* @return
*/
Map<String,Object> getFormDataById(Long formId,Long dataId);
/**
* 查询表单中指定的字段的数据
* @param dataId
* @param includeFields
* @return
*/
Map<String,Object> getFormDataById(Long formId,Long dataId,String [] includeFields);
/**
* 查询指定的data
* @param dataIds
* @return
*/
List<Map<String, Object>> list(Long formId, String[] dataIds);
/**
* 查询表单数据的完整信息
* @param formId
* @param dataId
* @return
*/
FormSourceResult getFormDataFullInfo(Long formId,Long dataId);
/**
* 新增表单数据
* @param param
* @return
*/
FormData addFormData(FormDataParam param);
/**
* 编辑表单数据
* @param param
* @return
*/
FormData editFormData(UpdateDataParams param);
/**
* 删除表单数据
* @param id
* @return
*/
boolean deleteFormData(Long id);
}

278
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impl/FormDataServiceImpl.java

@ -1,278 +0,0 @@
package org.dromara.dataManager.service.impl;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.Exception.ServiceException;
import org.dromara.common.consts.ExceptionCodeConstant;
import org.dromara.common.page.WorkflowPageFactory;
import org.dromara.common.page.WorkflowPageResult;
import org.dromara.common.response.WorkflowResultCode;
import org.dromara.dataManager.param.UpdateDataParams;
import org.dromara.dataManager.result.FormDataResult;
import org.dromara.formMaking.domain.FormSource;
import org.dromara.formMaking.results.FormSourceResult;
import org.dromara.formMaking.service.FormSourceService;
import org.dromara.taskCenter.param.TaskFlowParam;
import org.dromara.taskCenter.param.TaskUpdateParam;
import org.dromara.taskCenter.service.action.impl.CreateHandler;
import org.dromara.workflow.engine.enums.InstanceStage;
import org.dromara.workflow.engine.enums.OperateType;
import org.dromara.workflow.param.model.FlowUser;
import org.dromara.workflow.result.engine.ActionNodeSubmitResult;
import org.dromara.workflow.result.engine.EngineDataResult;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collectors;
import org.dromara.dataManager.domain.FormData;
import org.dromara.dataManager.mapper.FormDataMapper;
import org.dromara.dataManager.param.FormDataParam;
import org.dromara.dataManager.service.FormDataService;
import org.springframework.transaction.annotation.Transactional;
/**
* 表单数据实现层
*
*/
@Service
@Slf4j
public class FormDataServiceImpl extends ServiceImpl<FormDataMapper, FormData> implements FormDataService {
@Autowired
private CreateHandler actionService;
@Autowired
private FormSourceService formSourceService;
@Override
public WorkflowPageResult<Map<String,Object>> pageFormData(FormDataParam param) {
if (ObjectUtil.isEmpty(param.getFormId())){
throw new ServiceException(ExceptionCodeConstant.Service.VALUE_INVALID,"参数[formId]不能为空");
}
Page<FormDataResult> pageFormData = this.baseMapper.pageFormData(WorkflowPageFactory.defaultPage(),generateWrapper(param));
List<Map<String,Object>> formDataList = new ArrayList<>();
pageFormData.getRecords().forEach(p->{
if(p.getInstanceId() != null){
p.getFormData().put("nodeTitle",p.getNodeTitle());
p.getFormData().put("checkerName",p.getCheckerName());
p.getFormData().put("flowStage",p.getStage());
}
p.getFormData().put("createName",p.getCreateName());
p.getFormData().put("createTime",p.getCreateTime());
p.getFormData().put("updateName",p.getUpdateName());
p.getFormData().put("updateTime",p.getUpdateTime());
p.getFormData().put("instanceId",p.getInstanceId());
p.getFormData().put("dataId",p.getId());
formDataList.add(p.getFormData());
});
return new WorkflowPageResult<>(pageFormData,formDataList);
}
@Override
public FormData getFormData(Long dataId) {
return this.baseMapper.selectById(dataId);
}
@Override
public Map<String, Object> getFormDataById(Long formId,Long dataId) {
if (ObjectUtil.isEmpty(formId)){
throw new ServiceException(ExceptionCodeConstant.Service.VALUE_INVALID,"参数[formId]不能为空");
}
if (ObjectUtil.isEmpty(dataId)){
throw new ServiceException(ExceptionCodeConstant.Service.VALUE_INVALID,"参数[dataId]不能为空");
}
List<FormData> formDataList = this.getFormDataByFormId(formId);
List<FormData> dataList = formDataList.stream().filter(p -> p.getId().equals(dataId)).collect(Collectors.toList());
if (CollUtil.isNotEmpty(dataList)){
FormData formData = dataList.stream().findFirst().get();
LinkedHashMap<String, Object> data = formData.getFormData();
data.put("instanceId",formData.getInstanceId());
data.put("instanceStage",formData.getInstanceStage());
data.put("instanceChecker",formData.getInstanceChecker());
data.put("instanceNode",formData.getInstanceNode());
data.put("dataId",dataId);
return data;
}
return new HashMap<>();
}
@Override
public Map<String, Object> getFormDataById(Long formId,Long dataId, String[] includeFields) {
Map<String, Object> formDataMap = this.getFormDataById(formId, dataId);
Map<String,Object> resultMap = new HashMap<>();
if (ObjectUtil.isEmpty(formDataMap)){
return resultMap;
}
List<String> keyList = formDataMap.keySet().stream().filter(key -> Arrays.asList(includeFields).contains(key)).collect(Collectors.toList());
keyList.forEach(key ->{
resultMap.put(key,formDataMap.get(key));
});
return resultMap;
}
@Override
public List<Map<String, Object>> list(Long formId, String[] dataIds) {
List<Map<String, Object>> resultList = new ArrayList<>();
List<FormData> formDataList = this.getFormDataByFormId(formId);
if (CollUtil.isEmpty(formDataList)){
return resultList;
}
List<FormData> resultFormData = formDataList.stream().
filter(formData -> Arrays.asList(dataIds).contains(String.valueOf(formData.getId()))).collect(Collectors.toList());
resultFormData.forEach(formData -> {
LinkedHashMap<String, Object> data = formData.getFormData();
data.put("instanceId",formData.getInstanceId());
data.put("instanceStage",formData.getInstanceStage());
data.put("instanceChecker",formData.getInstanceChecker());
data.put("instanceNode",formData.getInstanceNode());
data.put("dataId",formData.getId());
resultList.add(data);
});
return resultList;
}
@Override
public FormSourceResult getFormDataFullInfo(Long formId,Long dataId) {
FormSourceResult formSourceResult =formSourceService.getFormSourceById(formId);
if (ObjectUtil.isEmpty(formSourceResult)){
throw new ServiceException(WorkflowResultCode.FORM_NOT_EXIST);
}
formSourceResult.setFormData(this.getFormDataById(formSourceResult.getId(), dataId));
return formSourceResult;
}
@Override
@Transactional(rollbackFor = Exception.class)
public FormData addFormData(FormDataParam param) {
FormData item = new FormData();
BeanUtils.copyProperties(param,item);
item.setFormData(param.getFormData());
item.setDeleted(false);
item.setCreateAccount(LoginHelper.getUsername());
item.setCreateName(LoginHelper.getLoginUser().getNickname());
this.save(item);
//应用表单提交 + 表单启用流程 => 触发流程引擎
FormSource formSource = formSourceService.getFormSource(param.getFormId());
TaskFlowParam wfParam = new TaskFlowParam(
new TaskUpdateParam(OperateType.create, formSource, item.getId(),false,item.getFormData(),item.getCreateTime()),
new FlowUser(LoginHelper.getUserId(),
LoginHelper.getLoginUser().getNickname(),
LoginHelper.getUsername(),
Arrays.asList(LoginHelper.getDeptId()))
);
ActionNodeSubmitResult flowRsp = actionService.action(wfParam);
if(!flowRsp.getSuccess() || flowRsp.getData() == null){
throw new ServiceException(flowRsp.getCode(),flowRsp.getMessage());
}
EngineDataResult flowData = flowRsp.getData();
Long instanceId = flowData.getInstanceId();
item.setInstanceId(instanceId);
item.setInstanceStage(flowData.getFlowStage());
if(InstanceStage.processing.name().equals(flowData.getFlowStage())){
item.setInstanceNode(flowData.getNodeTitle());
item.setInstanceChecker(flowData.getCheckerName());
}else{
item.setInstanceNode("结束节点");
item.setInstanceChecker("");
}
this.updateById(item);
return item;
}
@Override
public FormData editFormData(UpdateDataParams param) {
FormData item = this.queryItem(param.getDataId());
item.setFormData(param.getData());
if(param.getData().containsKey("instanceStage")){
item.setInstanceStage((String) param.getData().get("instanceStage"));
}
if(param.getData().containsKey("instanceChecker")){
item.setInstanceChecker((String) param.getData().get("instanceChecker"));
}
if(param.getData().containsKey("instanceNode")){
item.setInstanceNode((String) param.getData().get("instanceNode"));
}
this.baseMapper.updateById(item);
return item;
}
@Override
public boolean deleteFormData(Long id) {
return this.baseMapper.deleteById(id) > 0;
}
private QueryWrapper<FormData> generateWrapper(FormDataParam param){
QueryWrapper<FormData> wrapper = new QueryWrapper<>();
if (ObjectUtil.isNotEmpty(param.getFormId())){
wrapper.eq("tfd.form_id",param.getFormId());
}
if (StringUtils.isNotEmpty(param.getStartTime()) && StringUtils.isNotEmpty(param.getEndTime())){
wrapper.ge("tfd.create_time",param.getStartTime() + " 00:00:00");
wrapper.le("tfd.create_time",param.getEndTime() + " 23:59:59");
}
wrapper.orderByDesc("tfd.update_time","tfd.create_time");
return wrapper;
}
private FormData queryItem(Long id) {
FormData item = this.getById(id);
if (ObjectUtil.isNull(item)) {
throw new ServiceException(4004,"未找到表单数据");
}
return item;
}
private List<FormData> getFormDataByFormId(Long formId) {
if (ObjectUtil.isEmpty(formId)){
throw new ServiceException(ExceptionCodeConstant.Service.VALUE_INVALID,"参数[formId]不能为空");
}
LambdaQueryWrapper<FormData> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(FormData::getFormId,formId);
return this.baseMapper.selectList(wrapper);
}
}

60
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/common/HeaderMergeStrategiesGenerator.java

@ -1,60 +0,0 @@
package org.dromara.dataManager.service.impt.common;
import org.dromara.taskCenter.model.FormWidget;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.excel.write.merge.OnceAbsoluteMergeStrategy;
import java.util.*;
public class HeaderMergeStrategiesGenerator {
public static List<OnceAbsoluteMergeStrategy> generate(List<FormWidget> formColumns, List<String> exportFields) {
List<OnceAbsoluteMergeStrategy> strategyList = new ArrayList<>();
if (formColumns == null) {
return strategyList;
}
Map<String, FormWidget> tableColumnsMap = new HashMap<>();
List<String> allColumns = new ArrayList<>();
if (exportFields == null) {
exportFields = allColumns;
}
List<String> finalExportFields = exportFields;
formColumns.stream().filter(col -> finalExportFields.contains(col.getModel())).forEach(col -> {
if (CollectionUtil.isNotEmpty(col.getTableColumns())) {
tableColumnsMap.put(col.getModel(), col);
}
allColumns.add(col.getModel());
});
if (tableColumnsMap.size() <= 0) {
return strategyList;
}
int colIndex = 0;
Set<String> tableColumns = tableColumnsMap.keySet();
for (String field : exportFields) {
if (tableColumns.contains(field)) {
int colSpan = tableColumnsMap.get(field).getTableColumns().size();
if (colSpan == 1) {
colIndex++;
continue;
}
strategyList.add(new OnceAbsoluteMergeStrategy(0, 0, colIndex, colIndex + colSpan - 1));
colIndex += colSpan;
} else {
strategyList.add(new OnceAbsoluteMergeStrategy(0, 1, colIndex, colIndex));
colIndex++;
}
}
return strategyList;
}
}

22
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/convert/BaseConverter.java

@ -1,22 +0,0 @@
package org.dromara.dataManager.service.impt.convert;
import org.dromara.system.domain.SysDept;
import org.dromara.system.domain.SysUser;
import org.dromara.taskCenter.model.FormWidget;
import lombok.Data;
import java.util.HashMap;
import java.util.Map;
@Data
public abstract class BaseConverter {
private FormWidget formWidget;
private Map<String, SysUser> accountUserMapping = new HashMap<>();
private Map<String, SysDept> pathDepartMapping = new HashMap<>();
public Object convert(String value) {
return null;
};
}

14
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/convert/BooleanConverter.java

@ -1,14 +0,0 @@
package org.dromara.dataManager.service.impt.convert;
public class BooleanConverter extends BaseConverter {
@Override
public Object convert(String value) {
if ("是".equals(value)) {
return true;
} else if ("否".equals(value)){
return false;
} else {
return null;
}
}
}

11
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/convert/CheckboxConverter.java

@ -1,11 +0,0 @@
package org.dromara.dataManager.service.impt.convert;
public class CheckboxConverter extends BaseConverter {
@Override
public Object convert(String value) {
if (value == null) {
return null;
}
return value.split(",");
}
}

13
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/convert/ConverterBuilder.java

@ -1,13 +0,0 @@
package org.dromara.dataManager.service.impt.convert;
import org.dromara.dataManager.service.impt.model.StringConverter;
import org.dromara.taskCenter.model.widget.WidgetModel;
public class ConverterBuilder {
public static WidgetConverter getConverter(String type, WidgetModel widgetModel){
WidgetConverter converter = new StringConverter(widgetModel);
return converter;
}
}

20
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/convert/CoordinateConverter.java

@ -1,20 +0,0 @@
package org.dromara.dataManager.service.impt.convert;
import cn.hutool.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
public class CoordinateConverter extends BaseConverter {
@Override
public Object convert(String value) {
if (StringUtils.isNotBlank(value)) {
JSONObject coordinate = new JSONObject();
coordinate.set("address", value);
coordinate.set("geopoint", null);
return coordinate;
} else {
return null;
}
}
}

70
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/convert/DateConverter.java

@ -1,70 +0,0 @@
package org.dromara.dataManager.service.impt.convert;
import com.alibaba.excel.util.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import java.text.ParseException;
import java.util.Date;
@Slf4j
public class DateConverter extends BaseConverter {
@Override
public Object convert(String value) {
if (StringUtils.isNotBlank(value)) {
try {
String format = (String) getFormWidget().getOptions().get("format");
// 使用规定格式转换数据
return DateUtils.parseDate(value, format);
} catch (Exception e) {
try {
// 如果转换报错,则尝试自动转换数据
return DateUtils.parseDate(value);
} catch (Exception parseException) {
// 自动识别格式失败则尝试自动识别常用格式
return convert2Date(value);
}
}
} else {
return null;
}
}
private Date convert2Date(String dateString) {
// 自动识别格式失败则尝试自动识别常用格式
String separator = null;
if (dateString.contains("-")) {
separator = "-";
} else if (dateString.contains("/")) {
separator = "/";
}
if (separator != null) {
String ymd = String.format("yyyy%sMM%sdd", separator, separator);
String[] formats = new String[]{String.format("%s HH:mm:ss", ymd), String.format("%s HH:mm", ymd), String.format("%s HH", ymd), ymd};
Date result = null;
for (String format: formats) {
try {
result = DateUtils.parseDate(dateString, format);
break;
} catch (ParseException parseException) {
log.error(String.format("转换为%s格式日期失败", format));
}
}
if (result != null) {
return result;
}
}
return null;
}
}

10
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/convert/EmptyArrayValueConverter.java

@ -1,10 +0,0 @@
package org.dromara.dataManager.service.impt.convert;
import java.util.ArrayList;
public class EmptyArrayValueConverter extends BaseConverter {
@Override
public Object convert(String value) {
return new ArrayList<>();
}
}

68
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/convert/FormatNumberConverter.java

@ -1,68 +0,0 @@
package org.dromara.dataManager.service.impt.convert;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
public class FormatNumberConverter extends BaseConverter {
@Override
public Object convert(String value) {
if (value == null) {
return null;
}
String numberWithoutSymbols = value.replaceAll(",", "").replaceAll("%", "");
// 将字符串转为数字
BigDecimal number = new BigDecimal(numberWithoutSymbols);
try {
// 开启小数位数
boolean isFloatChecked = (boolean) getFormWidget().getOptions().get("isFloatChecked");
// 小数位数
int numberDigit = getFormWidget().getOptions().get("numberDigit") == null ? 0 : (int) getFormWidget().getOptions().get("numberDigit");
DecimalFormat df;
// 开启了保留小数位
if (isFloatChecked) {
if (numberDigit > 0 ) {
StringBuilder digitPattern = new StringBuilder();
for (int index = 0; index < numberDigit; index++) {
digitPattern.append("#");
}
df = new DecimalFormat("#." + digitPattern);
} else {
df = new DecimalFormat("#");
}
// 如果是百分比字符串,再除以100
if (value.contains("%")) {
number = number.divide(new BigDecimal(100), RoundingMode.HALF_UP);
}
}
// 没开启保留小数位,则最多保留6位
else {
df = new DecimalFormat("###.######");
// 如果是百分比字符串,再除以100
if (value.contains("%")) {
number = number.divide(new BigDecimal(100), RoundingMode.HALF_UP);
}
}
df.setRoundingMode(RoundingMode.HALF_UP);
number = new BigDecimal(df.format(number));
} catch (Exception e) {
number = null;
}
return number == null ? null : number.doubleValue();
}
}

8
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/convert/GeneralConverter.java

@ -1,8 +0,0 @@
package org.dromara.dataManager.service.impt.convert;
public class GeneralConverter extends BaseConverter {
@Override
public Object convert(String value) {
return value;
}
}

34
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/convert/InputConverter.java

@ -1,34 +0,0 @@
package org.dromara.dataManager.service.impt.convert;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
public class InputConverter extends BaseConverter {
private static final List<String> NUMBER_TYPES = Arrays.asList("number", "integer", "float");
@Override
public Object convert(String value) {
if (value == null) {
return null;
}
Map<String, Object> options = getFormWidget().getOptions();
String dataType = (String) options.get("dataType");
if (NUMBER_TYPES.contains(dataType)) {
try {
if ("integer".equals(dataType)) {
return Double.valueOf(value).intValue();
} else {
return Float.valueOf(value);
}
} catch (Exception e) {
return null;
}
}
return value;
}
}

38
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/convert/LocationConverter.java

@ -1,38 +0,0 @@
package org.dromara.dataManager.service.impt.convert;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
public class LocationConverter extends BaseConverter {
@Override
public Object convert(String value) {
if (value == null) {
return getDefaultValue();
}
String[] location = value.split(",", -1);
Map<String, String> result = new HashMap<>();
if (location.length > 0) {
result.put("province", location[0]);
}
if (location.length > 1) {
result.put("city", location[1]);
}
if (location.length > 2) {
result.put("area", location[2]);
}
if (location.length > 3) {
result.put("address", String.join(",", Arrays.asList(location).subList(3, location.length)));
}
return result;
}
private Map<String, String> getDefaultValue() {
Map<String, String> location = new HashMap<>();
location.put("province", null);
location.put("city", null);
location.put("area", null);
location.put("address", null);
return location;
}
}

30
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/convert/MultipleDepartmentsConverter.java

@ -1,30 +0,0 @@
package org.dromara.dataManager.service.impt.convert;
import org.dromara.system.domain.SysDept;
import java.util.*;
public class MultipleDepartmentsConverter extends BaseConverter {
@Override
public Object convert(String value) {
List<Map<String, Object>> infoList = new ArrayList<>();
if (value == null) {
return infoList;
}
String[] pathList = value.split(",");
Arrays.stream(pathList).forEach(path -> {
SysDept org = getPathDepartMapping().get(path);
Map<String, Object> info = new HashMap<>();
info.put("key", String.valueOf(org.getDeptId()));
info.put("title", org.getDeptName());
info.put("code", org.getDeptId());
// info.put("path", org.getNamePath());
infoList.add(info);
});
return infoList;
}
}

30
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/convert/MultipleMemberConverter.java

@ -1,30 +0,0 @@
package org.dromara.dataManager.service.impt.convert;
import org.dromara.system.domain.SysUser;
import java.util.*;
public class MultipleMemberConverter extends BaseConverter {
@Override
public Object convert(String value) {
List<Map<String, Object>> infoList = new ArrayList<>();
if (value == null) {
return infoList;
}
String[] accounts = value.split(",");
Arrays.stream(accounts).forEach(account -> {
SysUser user = getAccountUserMapping().get(account);
Map<String, Object> info = new HashMap<>();
info.put("key", String.valueOf(user.getUserId()));
info.put("title", user.getNickName());
info.put("code", user.getUserName());
infoList.add(info);
});
return infoList;
}
}

11
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/convert/MultipleSelectConverter.java

@ -1,11 +0,0 @@
package org.dromara.dataManager.service.impt.convert;
public class MultipleSelectConverter extends BaseConverter {
@Override
public Object convert(String value) {
if (value == null) {
return null;
}
return value.split(",");
}
}

8
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/convert/NullValueConverter.java

@ -1,8 +0,0 @@
package org.dromara.dataManager.service.impt.convert;
public class NullValueConverter extends BaseConverter {
@Override
public Object convert(String value) {
return null;
}
}

17
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/convert/PhoneConverter.java

@ -1,17 +0,0 @@
package org.dromara.dataManager.service.impt.convert;
import java.util.HashMap;
import java.util.Map;
public class PhoneConverter extends BaseConverter {
@Override
public Object convert(String value) {
if (value == null) {
return null;
}
Map<String, Object> result = new HashMap<>();
result.put("phoneNumber", value);
result.put("status", 0);
return result;
}
}

28
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/convert/SingleDepartmentConverter.java

@ -1,28 +0,0 @@
package org.dromara.dataManager.service.impt.convert;
import org.dromara.system.domain.SysDept;
import java.util.HashMap;
import java.util.Map;
public class SingleDepartmentConverter extends BaseConverter {
@Override
public Object convert(String value) {
if (value == null) {
return null;
}
SysDept sysDepartment = getPathDepartMapping().get(value);
if (sysDepartment != null) {
Map<String, Object> info = new HashMap<>();
info.put("key", String.valueOf(sysDepartment.getDeptId()));
info.put("title", sysDepartment.getDeptName());
info.put("code", sysDepartment.getDeptId());
// info.put("path", sysDepartment.getNamePath());
return info;
}
return null;
}
}

30
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/convert/SingleMemberConverter.java

@ -1,30 +0,0 @@
package org.dromara.dataManager.service.impt.convert;
import org.dromara.system.domain.SysUser;
import java.util.HashMap;
import java.util.Map;
public class SingleMemberConverter extends BaseConverter {
public SingleMemberConverter() {
}
@Override
public Object convert(String value) {
if (value == null) {
return null;
}
SysUser sysUser = getAccountUserMapping().get(value);
if (sysUser != null) {
Map<String, Object> info = new HashMap<>();
info.put("key", String.valueOf(sysUser.getUserId()));
info.put("title", sysUser.getNickName());
info.put("code", sysUser.getUserName());
// info.put("type", UserDepartDataTypeEnum.USER.getCode());
return info;
}
return null;
}
}

69
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/convert/WidgetConverter.java

@ -1,69 +0,0 @@
package org.dromara.dataManager.service.impt.convert;
import org.dromara.dataManager.param.ImportDataParams;
import org.dromara.taskCenter.model.widget.WidgetModel;
import cn.hutool.core.util.ObjectUtil;
import lombok.Data;
/**
* 表单字段值转换
*/
@Data
public abstract class WidgetConverter {
protected static final String BLANK_MESSAGE = "'%s'字段不能为空值";
protected static final String IS_NOT_NUMBER = "'%s'不是数字";
protected static final String IS_NOT_DATE = "'%s'不是日期";
protected static final String IS_NOT_SYSTEM_ACCOUNT = "'%s'不是系统内的账号";
protected static final String IS_NOT_SYSTEM_DEPARTMENT = "'%s'不是系统内的部门";
protected static final String IS_NOT_VALID_OPTION = "'%s'不是合法的选项";
protected WidgetModel widget;
private ImportDataParams.ValidationConfig validationConfig;
public WidgetConverter() {
}
public WidgetConverter(WidgetModel widget){
this.widget = widget;
}
public void validate(String value, ConvertCallBack callback){
if (isRequiredButEmpty(value)) {
callback.fail(String.format(BLANK_MESSAGE, this.widget.getName()));
return;
}
callback.success(this.valueOf(value));
}
public Object valueOf(String value){
return value;
}
/**
* 是否必填但是数据为空
* @param value
* @return
*/
protected boolean isRequiredButEmpty(Object value) {
if (!validationConfig.isRequired()) {
return false;
}
boolean required = this.widget.getOptions().getBool("required", false);
return required && ObjectUtil.isEmpty(value);
}
/**
* 回调接口
*/
public interface ConvertCallBack{
/**
* 转换成功
* @param convertValue
*/
void success(Object convertValue);
/**
* 转换失败
* @param message
*/
void fail(String message);
}
}

75
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/convert/WidgetConverterFactory.java

@ -1,75 +0,0 @@
package org.dromara.dataManager.service.impt.convert;
import org.dromara.dataManager.enums.WidgetType;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@Component
public class WidgetConverterFactory implements CommandLineRunner {
private static final Map<WidgetType, BaseConverter> converterMap = new HashMap<>();
public static BaseConverter getConverter(String type) {
WidgetType widgetType = WidgetType.getByCode(type);
if (widgetType == null) {
widgetType = WidgetType.GENERAL;
}
BaseConverter baseConverter;
switch (widgetType) {
case SWITCH: baseConverter = new BooleanConverter();break;
case DATE: baseConverter = new DateConverter();break;
case CHECKBOX: baseConverter = new CheckboxConverter();break;
case MULTIPLE_SELECT: baseConverter = new MultipleSelectConverter();break;
case IMG_UPLOAD:
case FILE_UPLOAD:
case UNIQ_KEY:
case DATA_LINK:
baseConverter = new NullValueConverter();break;
case SINGLE_MEMBER: baseConverter = new SingleMemberConverter();break;
case SINGLE_DEPARTMENT: baseConverter = new SingleDepartmentConverter();break;
case MULTIPLE_MEMBERS: baseConverter = new MultipleMemberConverter();break;
case LOCATION: baseConverter = new LocationConverter();break;
// case INPUT: baseConverter = new InputConverter();break;
case PHONE: baseConverter = new PhoneConverter();break;
case MULTIPLE_DEPARTMENTS: baseConverter = new MultipleDepartmentsConverter();break;
case FORMAT_NUMBER: baseConverter = new FormatNumberConverter();break;
case COORDINATES: baseConverter = new CoordinateConverter();break;
default:baseConverter = new GeneralConverter();
}
return baseConverter;
}
@Override
public void run(String... args) throws Exception {
converterMap.put(WidgetType.GENERAL, new GeneralConverter());
converterMap.put(WidgetType.SWITCH, new BooleanConverter());
converterMap.put(WidgetType.DATE, new DateConverter());
converterMap.put(WidgetType.CHECKBOX, new CheckboxConverter());
converterMap.put(WidgetType.IMG_UPLOAD, new EmptyArrayValueConverter());
converterMap.put(WidgetType.FILE_UPLOAD, new EmptyArrayValueConverter());
converterMap.put(WidgetType.UNIQ_KEY, new NullValueConverter());
converterMap.put(WidgetType.DATA_LINK, new NullValueConverter());
converterMap.put(WidgetType.SINGLE_MEMBER, new SingleMemberConverter());
converterMap.put(WidgetType.SINGLE_DEPARTMENT, new SingleDepartmentConverter());
converterMap.put(WidgetType.MULTIPLE_MEMBERS, new MultipleMemberConverter());
converterMap.put(WidgetType.LOCATION, new LocationConverter());
converterMap.put(WidgetType.INPUT, new InputConverter());
converterMap.put(WidgetType.PHONE, new PhoneConverter());
converterMap.put(WidgetType.MULTIPLE_DEPARTMENTS, new MultipleDepartmentsConverter());
converterMap.put(WidgetType.FORMAT_NUMBER, new FormatNumberConverter());
converterMap.put(WidgetType.COORDINATES, new CoordinateConverter());
converterMap.put(WidgetType.MULTIPLE_SELECT, new MultipleSelectConverter());
}
}

17
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/enums/ImportMode.java

@ -1,17 +0,0 @@
package org.dromara.dataManager.service.impt.enums;
public enum ImportMode {
CREATE("create"),
UPDATE("update"),
CREATE_AND_UPDATE("createAndUpdate");
private final String mode;
public String getMode() {
return mode;
}
ImportMode(String mode) {
this.mode = mode;
}
}

15
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/exception/ImportDataInvalidException.java

@ -1,15 +0,0 @@
package org.dromara.dataManager.service.impt.exception;
import lombok.Data;
import java.util.List;
@Data
public class ImportDataInvalidException extends Exception{
private List<String> invalidRows;
public ImportDataInvalidException(String message, List<String> invalidRows) {
super(message);
this.invalidRows = invalidRows;
}
}

14
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/exception/ImportValidationException.java

@ -1,14 +0,0 @@
package org.dromara.dataManager.service.impt.exception;
import org.dromara.dataManager.service.impt.model.InvalidColumnResult;
import lombok.Data;
@Data
public class ImportValidationException extends Exception{
private InvalidColumnResult result;
public ImportValidationException(String message, InvalidColumnResult result) {
super(message);
this.result = result;
}
}

11
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/model/CellSpanInfo.java

@ -1,11 +0,0 @@
package org.dromara.dataManager.service.impt.model;
import lombok.Data;
@Data
public class CellSpanInfo {
private int rowIndex;
private int columnIndex;
private int colSpan;
private int rowSpan;
}

44
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/model/ColumnsNeedValidate.java

@ -1,44 +0,0 @@
package org.dromara.dataManager.service.impt.model;
import org.dromara.dataManager.enums.WidgetType;
import org.dromara.taskCenter.model.FormWidget;
import cn.hutool.core.util.BooleanUtil;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
public class ColumnsNeedValidate {
private List<FormWidget> requiredWidgets = new ArrayList<>();
private List<FormWidget> dateWidgets = new ArrayList<>();
private List<FormWidget> numberWidgets = new ArrayList<>();
private List<FormWidget> memberWidgets = new ArrayList<>();
private List<FormWidget> departWidgets = new ArrayList<>();
private List<FormWidget> widgets;
public ColumnsNeedValidate(List<FormWidget> widgets) {
this.widgets = widgets;
analyse();
}
private void analyse() {
widgets.forEach(w -> {
Object requiredObj = w.getOptions().get("required");
if (requiredObj != null && BooleanUtil.isTrue((Boolean) requiredObj)) {
requiredWidgets.add(w);
}
if (WidgetType.DATE.getCode().equals(w.getType())) {
dateWidgets.add(w);
}
if (WidgetType.FORMAT_NUMBER.getCode().equals(w.getType())) {
numberWidgets.add(w);
}
});
}
}

19
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/model/DataAnalysisParams.java

@ -1,19 +0,0 @@
package org.dromara.dataManager.service.impt.model;
import org.dromara.dataManager.param.ImportDataParams;
import org.dromara.taskCenter.model.widget.WidgetModel;
import lombok.Data;
import java.util.List;
import java.util.Map;
@Data
public class DataAnalysisParams {
private Long formId;
private String formCode;
private int headerNumber;
private String primaryKey;
private List<WidgetModel> formWidgets;
private Map<Integer, String> mappings;
private ImportDataParams.ValidationConfig validationConfig;
}

11
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/model/DownloadTemplateParams.java

@ -1,11 +0,0 @@
package org.dromara.dataManager.service.impt.model;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
public class DownloadTemplateParams {
private List<String> exportFields = new ArrayList<>();
}

40
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/model/ExtraMergeInfoListener.java

@ -1,40 +0,0 @@
package org.dromara.dataManager.service.impt.model;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.enums.CellExtraTypeEnum;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.metadata.CellExtra;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class ExtraMergeInfoListener extends AnalysisEventListener<Map<Integer, String>> {
private final List<CellExtra> extraMergeInfoList = new ArrayList<>();
private int rowCount = 0;
@Override
public void invoke(Map<Integer, String> data, AnalysisContext analysisContext) {
rowCount += 1;
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
}
@Override
public void extra(CellExtra extra, AnalysisContext context) {
if (CellExtraTypeEnum.MERGE.equals(extra.getType())) {
extraMergeInfoList.add(extra);
}
}
public List<CellExtra> getExtraMergeInfoList() {
return extraMergeInfoList;
}
public int getRowCount() {
return rowCount;
}
}

384
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/model/ImportValidatorListener.java

@ -1,384 +0,0 @@
package org.dromara.dataManager.service.impt.model;
import org.dromara.dataManager.enums.WidgetType;
import org.dromara.dataManager.service.impt.validator.ValueValidator;
import org.dromara.taskCenter.model.FormWidget;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.metadata.CellExtra;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
public class ImportValidatorListener extends AnalysisEventListener<Map<Integer, Object>> {
private static final int BATCH_COUNT = 2000;
private static final List<String> NOT_IMPORTABLE_TYPES = Arrays.asList(WidgetType.FILE_UPLOAD.getCode(), WidgetType.IMG_UPLOAD.getCode());
private final List<CellExtra> extraMergeInfoList;
private final Map<Integer, String> mapping;
private final Map<String, FormWidget> widgetMap;
private final int headRows;
private List<Map<String, Object>> list = new ArrayList<>();
private final InvalidColumnResult invalidColumnResult = new InvalidColumnResult();
// 子表单外的必填、日期、数字字段
private ColumnsNeedValidate widgetsOutOfTable2Validate;
// 子表单及其内的必填、日期、数字字段
private final Map<String, ColumnsNeedValidate> widgetsInTable2Validate = new HashMap<>();
// 用于标记字段的校验状态,初始都是true
Map<String, Boolean> columnValidMap = new HashMap<>();
// 成员字段及其值的集合
Map<String, Set<String>> memberValueMap = new HashMap<>();
// 部门字段及其值的集合
Map<String, Set<String>> departValueMap = new HashMap<>();
public ImportValidatorListener(List<CellExtra> extraMergeInfoList, Map<Integer, String> mapping, Map<String, FormWidget> widgetMap, int headRows) {
this.extraMergeInfoList = extraMergeInfoList;
this.mapping = mapping;
this.widgetMap = widgetMap;
this.headRows = headRows;
}
@Override
public void invoke(Map<Integer, Object> data, AnalysisContext analysisContext) {
Map<String, Object> row = new HashMap<>();
mapping.forEach((colIndex, model) -> row.put(model, data.get(colIndex)));
list.add(row);
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
generateWidgetsNeedValidate();
initValidateWidgetsStatus();
mergeRowAndValidate();
}
public boolean hasInvalidData() {
return columnValidMap.containsValue(false);
}
public InvalidColumnResult getValidationResult() {
return invalidColumnResult;
}
private Map<String, List<String>> getTableColumns() {
Map<String, List<String>> tableColumns = new HashMap<>();
widgetMap.forEach((model, widget) -> {
if (WidgetType.TABLE.getCode().equals(widget.getType())) {
tableColumns.put(model, widget.getTableColumns().stream().map(FormWidget::getModel).collect(Collectors.toList()));
}
});
return tableColumns;
}
private void mergeRowAndValidate() {
Map<String, List<String>> tableColumns = getTableColumns();
Set<String> tableColumnNames = new HashSet<>();
tableColumns.forEach((tc, columns) -> tableColumnNames.addAll(columns));
List<Map<String, Object>> dataSave2ES = new ArrayList<>();
if (CollectionUtil.isNotEmpty(tableColumns)) {
// 有子表单字段,需要处理合并单元格的数据后再导入
AtomicInteger rowIndex = new AtomicInteger();
while (rowIndex.get() < list.size()) {
Map<String, Object> thisRow = list.get(rowIndex.get());
Map<String, Object> newRow = new HashMap<>();
// 被合并行数,也是距离下一条数据的行数
AtomicInteger mostMergeRows = new AtomicInteger(1);
thisRow.forEach((field, value) -> {
// 子表单字段
if (tableColumnNames.contains(field)) {
// 查找这行是否有纵向合并单元格
Optional<CellExtra> optional = extraMergeInfoList.stream().filter(info -> info.getFirstRowIndex().equals(rowIndex.get() + headRows) && info.getLastRowIndex() - info.getFirstRowIndex() > 0).findFirst();
// 有多条数据
if (optional.isPresent()) {
mostMergeRows.set(optional.get().getLastRowIndex() - optional.get().getFirstRowIndex() + 1);
// 遍历子表单字段,并收集子表单字段的数据
tableColumns.forEach((table, columns) -> {
List<Map<String, Object>> tableData = new ArrayList<>();
for (int index = 0; index < mostMergeRows.get(); index++) {
Map<String, Object> rowData = new HashMap<>();
int finalIndex = index;
columns.forEach(colName -> {
rowData.put(colName, list.get(rowIndex.get() + finalIndex).get(colName));
});
tableData.add(rowData);
}
newRow.put(table, tableData);
});
}
// 只有一条数据
else {
// 遍历子表单字段,并收集子表单字段的数据
tableColumns.forEach((table, columns) -> {
List<Map<String, Object>> tableData = new ArrayList<>();
Map<String, Object> rowData = new HashMap<>();
columns.forEach(colName -> {
rowData.put(colName, thisRow.get(colName));
});
tableData.add(rowData);
newRow.put(table, tableData);
});
}
}
// 非子表单字段
else {
newRow.put(field, value);
}
});
// 数据索引往后移
rowIndex.addAndGet(mostMergeRows.get());
dataSave2ES.add(newRow);
// 批量保存,以免内存中存在大量临时数据
if (dataSave2ES.size() >= BATCH_COUNT) {
validate(dataSave2ES, null);
// validateMemberDepart();
// 清空,使其被GC
dataSave2ES.clear();
}
// 如果所有需要校验的字段都不合法,那就终止,没必要后续数据的校验了
if (validationFinished()) {
break;
}
}
} else {
// 没有子表单字段,无需处理合并单元格的数据,直接导入
dataSave2ES = list;
}
validate(dataSave2ES, null);
// validateMemberDepart();
}
private void generateWidgetsNeedValidate() {
// 归类子表单外的必填、日期、数字字段, 且已有不合法数据的字段就不再校验了
List<FormWidget> notTableWidgets = widgetMap.values().stream()
.filter(widget -> !WidgetType.TABLE.getCode().equals(widget.getType()))
.collect(Collectors.toList());
widgetsOutOfTable2Validate = new ColumnsNeedValidate(notTableWidgets);
// 归类子表单内的必填、日期、数字字段
widgetMap.values().stream().filter(widget -> WidgetType.TABLE.getCode().equals(widget.getType())).forEach(widget -> {
// 重命名子表单内的字段
ColumnsNeedValidate cnv = new ColumnsNeedValidate(widget.getTableColumns().stream()
.filter(tc -> !NOT_IMPORTABLE_TYPES.contains(tc.getType()) && mapping.containsValue(tc.getModel()))
.peek(tc -> tc.setName(String.format("%s.%s", widget.getName(), tc.getName())))
.collect(Collectors.toList()));
widgetsInTable2Validate.put(widget.getModel(), cnv);
});
// 初始化
widgetMap.values().forEach(widget -> {
if (WidgetType.SINGLE_MEMBER.getCode().equals(widget.getType()) || WidgetType.MULTIPLE_MEMBERS.getCode().equals(widget.getType())) {
memberValueMap.put(widget.getModel(), new HashSet<>());
widgetsOutOfTable2Validate.getMemberWidgets().add(widget);
} else if (WidgetType.SINGLE_DEPARTMENT.getCode().equals(widget.getType()) || WidgetType.MULTIPLE_DEPARTMENTS.getCode().equals(widget.getType())) {
departValueMap.put(widget.getModel(), new HashSet<>());
widgetsOutOfTable2Validate.getDepartWidgets().add(widget);
} else if (WidgetType.TABLE.getCode().equals(widget.getType())) {
widget.getTableColumns().forEach(tc -> {
if (WidgetType.SINGLE_MEMBER.getCode().equals(tc.getType()) || WidgetType.MULTIPLE_MEMBERS.getCode().equals(tc.getType())) {
memberValueMap.put(tc.getModel(), new HashSet<>());
widgetsInTable2Validate.get(widget.getModel()).getMemberWidgets().add(tc);
} else if (WidgetType.SINGLE_DEPARTMENT.getCode().equals(tc.getType()) || WidgetType.MULTIPLE_DEPARTMENTS.getCode().equals(tc.getType())) {
departValueMap.put(tc.getModel(), new HashSet<>());
widgetsInTable2Validate.get(widget.getModel()).getDepartWidgets().add(tc);
}
});
}
});
}
private void initValidateWidgetsStatus() {
widgetsOutOfTable2Validate.getRequiredWidgets().forEach(widget -> columnValidMap.put(widget.getModel(), true));
widgetsOutOfTable2Validate.getDateWidgets().forEach(widget -> columnValidMap.put(widget.getModel(), true));
widgetsOutOfTable2Validate.getNumberWidgets().forEach(widget -> columnValidMap.put(widget.getModel(), true));
widgetsInTable2Validate.forEach((table, cnv) -> {
cnv.getRequiredWidgets().forEach(tc -> columnValidMap.put(tc.getModel(), true));
cnv.getDateWidgets().forEach(tc -> columnValidMap.put(tc.getModel(), true));
cnv.getNumberWidgets().forEach(tc -> columnValidMap.put(tc.getModel(), true));
});
memberValueMap.keySet().forEach(member -> columnValidMap.put(member, true));
departValueMap.keySet().forEach(depart -> columnValidMap.put(depart, true));
}
private void validate(List<Map<String, Object>> dataSave2ES, ColumnsNeedValidate cnv) {
Set<String> tableFields = widgetsInTable2Validate.keySet();
for (Map<String, Object> row: dataSave2ES) {
// 如果所有需要校验的字段都不合法,那就终止,没必要后续数据的校验了
if (validationFinished()) {
break;
}
row.forEach((fieldName, fieldValue) -> {
if (tableFields.contains(fieldName)) {
if (fieldValue != null) {
ColumnsNeedValidate tableCnv = widgetsInTable2Validate.get(fieldName);
List<Map<String, Object>> tableData = (List<Map<String, Object>>) fieldValue;
validate(tableData, tableCnv);
}
} else {
ColumnsNeedValidate workingCnv = cnv == null ? widgetsOutOfTable2Validate : cnv;
validateFieldValue(fieldName, fieldValue, workingCnv);
}
});
}
}
private void validateFieldValue(String fieldName, Object fieldValue, ColumnsNeedValidate cnv) {
List<FormWidget> requiredWidgets = cnv.getRequiredWidgets().stream().filter(w -> columnValidMap.get(w.getModel())).collect(Collectors.toList());
List<FormWidget> dateWidgets = cnv.getDateWidgets().stream().filter(w -> columnValidMap.get(w.getModel())).collect(Collectors.toList());
List<FormWidget> numberWidgets = cnv.getNumberWidgets().stream().filter(w -> columnValidMap.get(w.getModel())).collect(Collectors.toList());
List<FormWidget> memberWidgets = cnv.getMemberWidgets().stream().filter(w -> columnValidMap.get(w.getModel())).collect(Collectors.toList());
List<FormWidget> departWidgets = cnv.getDepartWidgets().stream().filter(w -> columnValidMap.get(w.getModel())).collect(Collectors.toList());
List<String> requiredModels = requiredWidgets.stream().map(FormWidget::getModel).collect(Collectors.toList());
List<String> dateModels = dateWidgets.stream().map(FormWidget::getModel).collect(Collectors.toList());
List<String> numberModels = numberWidgets.stream().map(FormWidget::getModel).collect(Collectors.toList());
List<String> memberModels = memberWidgets.stream().map(FormWidget::getModel).collect(Collectors.toList());
List<String> departModels = departWidgets.stream().map(FormWidget::getModel).collect(Collectors.toList());
if (requiredModels.contains(fieldName) && ValueValidator.isEmpty(fieldValue)) {
Optional<FormWidget> optional = requiredWidgets.stream().filter(w -> w.getModel().equals(fieldName)).findFirst();
String name = optional.isPresent() ? optional.get().getName() : "";
invalidColumnResult.add(fieldName, String.format("导入「%s」字段的值存在空值数据", name));
columnValidMap.put(fieldName, false);
return;
}
if (dateModels.contains(fieldName) && !ValueValidator.isEmpty(fieldValue) && !ValueValidator.isDate(fieldValue, widgetMap.get(fieldName))) {
Optional<FormWidget> optional = dateWidgets.stream().filter(w -> w.getModel().equals(fieldName)).findFirst();
String name = optional.isPresent() ? optional.get().getName() : "";
invalidColumnResult.add(fieldName, String.format("导入「%s」字段的值存在不是日期的数据,请检查格式,错误数据:%s", name, fieldValue));
columnValidMap.put(fieldName, false);
return;
}
if (numberModels.contains(fieldName) && !ValueValidator.isEmpty(fieldValue) && !ValueValidator.isNumber(fieldValue)) {
Optional<FormWidget> optional = numberWidgets.stream().filter(w -> w.getModel().equals(fieldName)).findFirst();
String name = optional.isPresent() ? optional.get().getName() : "";
invalidColumnResult.add(fieldName, String.format("导入「%s」字段的值存在不是数字的数据,错误数据:%s", name, fieldValue));
columnValidMap.put(fieldName, false);
}
if (memberModels.contains(fieldName) && columnValidMap.get(fieldName)) {
if (ObjectUtil.isNotEmpty(fieldValue)) {
memberValueMap.get(fieldName).addAll(Arrays.asList(fieldValue.toString().split(",")));
}
}
if (departModels.contains(fieldName) && columnValidMap.get(fieldName)) {
if (ObjectUtil.isNotEmpty(fieldValue)) {
departValueMap.get(fieldName).addAll(Arrays.asList(fieldValue.toString().split(",")));
}
}
}
// private void validateMemberDepart() {
// // 校验账号合法性
// Set<String> mAccounts = new HashSet<>();
// memberValueMap.keySet().stream().filter(key -> columnValidMap.get(key)).forEach(member -> {
// mAccounts.addAll(memberValueMap.get(member));
// });
//
// Map<String, SysUser> aNameMapping = SpringUtil.getBean(ISysUserService.class).getAccountNameMapping(mAccounts);
// Set<String> validAccounts = aNameMapping.keySet();
// memberValueMap.keySet().stream().filter(key -> columnValidMap.get(key)).forEach(member -> {
//
// List<String> iva = memberValueMap.get(member).stream().filter(acc -> !validAccounts.contains(acc)).collect(Collectors.toList());
//
// if (CollectionUtil.isNotEmpty(iva)) {
// columnValidMap.put(member, false);
// invalidColumnResult.add(member, String.format("导入数据中存在非系统内用户的账号,非法账号:%s", String.join(", ", iva)));
// }
// });
//
// // 校验部门路径合法性
// Set<String> dPaths = new HashSet<>();
// departValueMap.keySet().stream().filter(key -> columnValidMap.get(key)).forEach(depart -> {
// dPaths.addAll(departValueMap.get(depart));
// });
// Map<String, SysDepartment> pDMapping = SpringUtil.getBean(DepartmentService.class).getPathDepartMapping(dPaths);
// Set<String> validPaths = pDMapping.keySet();
//
// departValueMap.keySet().stream().filter(key -> columnValidMap.get(key)).forEach(depart -> {
// List<String> ivp = departValueMap.get(depart).stream().filter(dp -> !validPaths.contains(dp)).collect(Collectors.toList());
// if (CollectionUtil.isNotEmpty(ivp)) {
// columnValidMap.put(depart, false);
// invalidColumnResult.add(depart, String.format("导入数据中存在非系统内的部门路径,非法部门路径:%s", String.join(", ", ivp)));
// }
// });
// }
private boolean validationFinished() {
// 如果所有需要校验的字段都不合法,那就终止,没必要后续数据的校验了
return !columnValidMap.containsValue(true);
}
}

27
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/model/InvalidColumnResult.java

@ -1,27 +0,0 @@
package org.dromara.dataManager.service.impt.model;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
public class InvalidColumnResult {
private List<InvalidColumn> invalidColumns = new ArrayList<>();
public void add(String column, String message) {
invalidColumns.add(new InvalidColumn(column, message));
}
@Data
public static class InvalidColumn {
private String column;
private String message;
public InvalidColumn(String column, String message) {
this.column = column;
this.message = message;
}
}
}

30
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/model/PreviewResult.java

@ -1,30 +0,0 @@
package org.dromara.dataManager.service.impt.model;
import lombok.Data;
import java.util.List;
@Data
public class PreviewResult {
private List<PreviewTableHeader> headers;
private List<Object> data;
private List<String> sheets;
private String sheetName;
private List<CellSpanInfo> spanInfoList;
public PreviewResult() {
}
public PreviewResult(List<PreviewTableHeader> headers, List<Object> data, List<String> sheets) {
this.headers = headers;
this.data = data;
this.sheets = sheets;
}
public PreviewResult(List<PreviewTableHeader> headers, List<Object> data, List<String> sheets, String sheetName) {
this.headers = headers;
this.data = data;
this.sheets = sheets;
this.sheetName = sheetName;
}
}

18
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/model/PreviewTableHeader.java

@ -1,18 +0,0 @@
package org.dromara.dataManager.service.impt.model;
import cn.hutool.core.util.StrUtil;
import lombok.Data;
import java.util.List;
@Data
public class PreviewTableHeader {
private String title;
private List<PreviewTableHeader> children;
private int columnIndex;
public PreviewTableHeader(String title, int columnIndex) {
this.title = StrUtil.isBlank(title) ? "" : title;
this.columnIndex = columnIndex;
}
}

19
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/model/StringConverter.java

@ -1,19 +0,0 @@
package org.dromara.dataManager.service.impt.model;
import org.dromara.dataManager.service.impt.convert.WidgetConverter;
import org.dromara.taskCenter.model.widget.WidgetModel;
/**
* 单行文本
*/
public class StringConverter extends WidgetConverter {
public StringConverter(WidgetModel widget) {
super(widget);
}
@Override
public Object valueOf(String value) {
return value == null ? null : value.replaceAll("\n", "");
}
}

116
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/service/ImportFromExcelHelper.java

@ -1,116 +0,0 @@
//package org.dromara.dataManager.service.impt.service;
//
//import cn.hutool.core.collection.CollUtil;
//import cn.hutool.core.collection.CollectionUtil;
//import cn.hutool.json.JSONArray;
//import cn.hutool.json.JSONObject;
//import cn.hutool.json.JSONUtil;
//import org.apache.commons.lang3.StringUtils;
//import org.elasticsearch.action.search.SearchRequest;
//import org.elasticsearch.index.query.QueryBuilders;
//import org.elasticsearch.search.builder.SearchSourceBuilder;
//import org.elasticsearch.search.sort.SortOrder;
//import org.springframework.stereotype.Component;
//
//import java.io.IOException;
//import java.util.List;
//import java.util.Map;
//
//@Component
//public class ImportFromExcelHelper {
//
// // @Autowired
// // private ElasticsearchClient elasticsearchClient;
//
// public List<String> getNotExistIds(String index, String query, List<String> ids) throws IOException {
// if(CollUtil.isNotEmpty(ids)){
// return ids;
// }
// SearchRequest searchRequest = new SearchRequest(index);
//
// SearchSourceBuilder sb = SearchSourceBuilder.searchSource();
//
// JSONObject queryObj;
// if (StringUtils.isNotBlank(query)) {
// queryObj = JSONUtil.parseObj(query);
// } else {
// queryObj = new JSONObject();
// }
//
// if (CollectionUtil.isNotEmpty(ids)) {
// queryObj.getByPath("query.bool.must", JSONArray.class).add(JSONUtil.parseObj(QueryBuilders.idsQuery().addIds(ids.toArray(new String[0])).toString()));
// }
//
// JSONObject query4Req = new JSONObject();
// query4Req.putOpt("bool", queryObj.getByPath("query.bool"));
// if (queryObj.get("query.filter") != null && !queryObj.getByPath("query.filter", JSONObject.class).isEmpty()) {
// query4Req.putOpt("filter", queryObj.getByPath("query.filter"));
// }
//
// sb.query(QueryBuilders.wrapperQuery(query4Req.toString()));
// sb.fetchSource(new String[]{"_id"}, new String[]{});
// // 最大只能处理3万条数据
// sb.size(Math.min(ids.size(), 30000));
//
// searchRequest.source(sb);
//
// // try (final RestHighLevelClient client = elasticsearchClient.getHighClient()) {
// //
// // SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// //
// // List<String> existedIds = Arrays.stream(response.getHits().getHits())
// // .map(SearchHit::getId)
// // .collect(Collectors.toList());
// //
// // return ids.stream().filter(id -> !existedIds.contains(id)).collect(Collectors.toList());
// //
// // }
// return ids;
// }
//
// public Map<String, String> getPKValueMapping(String index, String query, String pk, List<String> pkValues) throws IOException {
//
// SearchRequest searchRequest = new SearchRequest(index);
//
// SearchSourceBuilder sb = SearchSourceBuilder.searchSource();
// sb.fetchSource(new String[]{pk}, new String[]{});
// sb.sort("createTime", SortOrder.ASC);
// // 最多处理3万条
// sb.size(30000);
//
// JSONObject queryObj;
// if (StringUtils.isNotBlank(query)) {
// queryObj = JSONUtil.parseObj(query);
// } else {
// queryObj = new JSONObject();
// }
//
// if (CollectionUtil.isNotEmpty(pkValues)) {
// queryObj.getByPath("query.bool.must", JSONArray.class).add(JSONUtil.parseObj(QueryBuilders.termsQuery(pk, pkValues).toString()));
// }
//
// JSONObject query4Req = new JSONObject();
// query4Req.putOpt("bool", queryObj.getByPath("query.bool"));
// if (queryObj.get("query.filter") != null && !queryObj.getByPath("query.filter", JSONObject.class).isEmpty()) {
// query4Req.putOpt("filter", queryObj.getByPath("query.filter"));
// }
//
// sb.query(QueryBuilders.wrapperQuery(query4Req.toString()));
//
// searchRequest.source(sb);
// //
// // try (final RestHighLevelClient client = elasticsearchClient.getHighClient()) {
// //
// // SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// //
// // Map<String, String> map = new HashMap<>();
// // Arrays.stream(response.getHits().getHits())
// // .forEach(hit -> map.put(JSONUtil.parseObj(hit.getSourceAsString()).getByPath(pk, String.class), hit.getId()));
// //
// // return map;
// //
// // }
//
// return null;
// }
//}

20
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/service/ImportFromExcelService.java

@ -1,20 +0,0 @@
package org.dromara.dataManager.service.impt.service;
import jakarta.servlet.http.HttpServletResponse;
import org.dromara.dataManager.param.ImportDataParams;
import org.dromara.dataManager.service.impt.exception.ImportDataInvalidException;
import org.dromara.dataManager.service.impt.model.PreviewResult;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.List;
import java.util.Map;
public interface ImportFromExcelService{
PreviewResult previewExcel(MultipartFile file,Integer sheetIndex) throws IOException;
void generateImportTemplate(HttpServletResponse response, Long formId, List<String> exportFields) throws IOException;
List<Map<String, Object>> importV2(ImportDataParams params) throws IOException, ImportDataInvalidException;
}

621
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/service/impl/ImportFromExcelServiceImpl.java

@ -1,621 +0,0 @@
package org.dromara.dataManager.service.impt.service.impl;
import cn.hutool.core.collection.CollUtil;
import jakarta.servlet.http.HttpServletResponse;
import org.dromara.common.util.JsonUtil;
import org.dromara.dataManager.enums.WidgetType;
import org.dromara.dataManager.param.ImportDataParams;
import org.dromara.dataManager.service.FormDataService;
import org.dromara.dataManager.service.impt.common.HeaderMergeStrategiesGenerator;
import org.dromara.dataManager.service.impt.enums.ImportMode;
import org.dromara.dataManager.service.impt.exception.ImportDataInvalidException;
import org.dromara.dataManager.service.impt.model.*;
import org.dromara.dataManager.service.impt.service.ImportFromExcelService;
import org.dromara.dataManager.service.impt.service.impl.excel.listener.DataAnalysisEventListener;
import org.dromara.formMaking.results.FormSourceResult;
import org.dromara.formMaking.service.FormSourceService;
import org.dromara.taskCenter.model.FormWidget;
import org.dromara.taskCenter.model.widget.WidgetModel;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.enums.CellExtraTypeEnum;
import com.alibaba.excel.metadata.CellExtra;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.alibaba.excel.util.DateUtils;
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
@Slf4j
@Service
public class ImportFromExcelServiceImpl implements ImportFromExcelService {
@Resource
private FormSourceService sourceQueryService;
@Resource
private FormDataService formDataService;
// @Resource
// private ImportFromExcelHelper importFromExcelHelper;
@Override
public PreviewResult previewExcel(MultipartFile file, Integer sheetIndex) throws IOException {
// FormSource form = this.sourceQueryService.getFormSourceById(formId);
// 是否有合并表头,有的话表头有两行,没有的话表头只有一行
/*boolean hasMergedHeaders = false;
List<FormColumn> formColumns = JsonUtil.jsonToList(formDetail.getColumns(), FormColumn.class);
if (formColumns != null) {
if (formColumns.stream().anyMatch(formColumn -> WidgetType.TABLE.getCode().equals(formColumn.getEleType()) && CollectionUtil.isNotEmpty(formColumn.getSubColumns()))) {
hasMergedHeaders = true;
}
}*/
// 获取Excel中的sheet索引
List<String> sheets = EasyExcel.read(file.getInputStream())
.build()
.excelExecutor()
.sheetList()
.stream()
.map(ReadSheet::getSheetName)
.collect(Collectors.toList());
sheetIndex = sheetIndex == null ? 0 : sheetIndex;
// 获取Excel中所有的数据
ExtraMergeInfoListener mergeInfoListener = new ExtraMergeInfoListener();
List<Object> sheetData = EasyExcel.read(file.getInputStream(), mergeInfoListener)
.extraRead(CellExtraTypeEnum.MERGE)
.sheet(sheetIndex)
.headRowNumber(0)
.doReadSync()
.stream()
.limit(30000)
.collect(Collectors.toList());
if (CollectionUtil.isEmpty(sheetData)) {
return new PreviewResult(new ArrayList<>(), new ArrayList<>(), sheets, sheets.get(sheetIndex));
}
boolean hasMergedHeaders = mergeInfoListener.getExtraMergeInfoList().stream().anyMatch(em -> em.getFirstRowIndex() == 0);
int howManyHeaders = hasMergedHeaders ? 2 : 1;
List<PreviewTableHeader> headers = generatePreviewTableHeaders(sheetData, mergeInfoListener.getExtraMergeInfoList(), howManyHeaders);
List<Object> data = new ArrayList<>();
// 解析出数据
if (sheetData.size() > howManyHeaders) {
data = sheetData.subList(howManyHeaders, sheetData.size());
}
PreviewResult previewResult = new PreviewResult(headers, data, sheets);
previewResult.setSheetName(sheets.get(sheetIndex));
previewResult.setSpanInfoList(generateMergeInfo(mergeInfoListener.getExtraMergeInfoList(), headers, howManyHeaders));
return previewResult;
}
@Override
public void generateImportTemplate(HttpServletResponse response, Long formId, List<String> exportFields) throws IOException {
FormSourceResult formInfo = sourceQueryService.getFormSourceById(formId);
List<List<String>> headers = new ArrayList<>();
String widgetStr = JSONUtil.parseObj(formInfo.getFormJson()).getStr("list");
List<FormWidget> formColumns = JsonUtil.jsonToList(widgetStr, FormWidget.class);
List<String> exportableFields = new ArrayList<>();
if (formColumns != null) {
formColumns.stream()
.filter(column -> {
// 过滤掉文件、图片、流水号字段
if (WidgetType.FILE_UPLOAD.getCode().equals(column.getType()) || WidgetType.IMG_UPLOAD.getCode().equals(column.getType())
|| WidgetType.UNIQ_KEY.getCode().equals(column.getType()) || WidgetType.TEXT.getCode().equals(column.getType())
|| WidgetType.COORDINATES.getCode().equals(column.getType())|| WidgetType.DATA_LINK.getCode().equals(column.getType())
|| WidgetType.DIVIDER.getCode().equals(column.getType())) {
return false;
} else if (CollectionUtil.isNotEmpty(column.getTableColumns())){
List<FormWidget> validCols = column.getTableColumns().stream()
.filter(col -> !WidgetType.FILE_UPLOAD.getCode().equals(col.getType())
&& !WidgetType.IMG_UPLOAD.getCode().equals(col.getType())
&& !WidgetType.UNIQ_KEY.getCode().equals(col.getType())
&& !WidgetType.COORDINATES.getCode().equals(col.getType())
&& exportFields.contains(col.getModel()))
.collect(Collectors.toList());
column.setTableColumns(validCols);
return validCols.size() > 0;
} else {
return exportFields.contains(column.getModel());
}
})
.forEach(column -> {
if (CollectionUtil.isNotEmpty(column.getTableColumns())) {
column.getTableColumns().forEach(col -> {
List<String> header = new ArrayList<>();
header.add(column.getName());
header.add(col.getName());
headers.add(header);
});
} else {
List<String> header = new ArrayList<>();
header.add(column.getName());
headers.add(header);
}
exportableFields.add(column.getModel());
});
}
String fileName = URLEncoder.encode(String.format("%s-数据导入模版%s.xlsx", formInfo.getTitle(), DateUtils.format(new Date(), "yyyyMMddHHmmss")), "UTF-8").replaceAll("\\+", "%20");
response.setHeader("Content-Disposition", String.format("attachment;filename=%s", fileName));
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
ExcelWriterSheetBuilder sheetBuilder = EasyExcel.write(response.getOutputStream()).sheet("sheet1");
HeaderMergeStrategiesGenerator.generate(formColumns, exportableFields).forEach(sheetBuilder::registerWriteHandler);
sheetBuilder.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
.automaticMergeHead(false)
.head(headers)
.doWrite(new ArrayList<>());
}
@Override
public List<Map<String, Object>> importV2(ImportDataParams params) throws IOException, ImportDataInvalidException {
MultipartFile file = params.getFile();
Long formId = params.getFormId();
Integer sheetIndex = params.getSheetIndex();
Map<Integer, String> mappings = params.getObjMapping();
FormSourceResult form = sourceQueryService.getFormSourceById(formId);
// 是否有合并表头
boolean hasMergedHeaders = hasMergedHeaders(file, sheetIndex);
// 导入数据的表单字段
List<WidgetModel> formWidgets = new ArrayList<>();
if (form.getFormJson() != null) {
Map<String, Object> formJson = JsonUtil.jsonToMap(form.getFormJson());
assert formJson != null;
formWidgets = JsonUtil.jsonToList(JsonUtil.toJson(formJson.get("list")), WidgetModel.class);
}
int headerNumber = hasMergedHeaders ? 2 : 1;
// 导入数据量校验
// 获取Excel中所有的数据
ExtraMergeInfoListener countListener = new ExtraMergeInfoListener();
EasyExcel.read(file.getInputStream(), countListener)
.sheet(sheetIndex)
.headRowNumber(headerNumber)
.doRead();
int rowCount = countListener.getRowCount();
// 有成员部门字段限制到一万条,否则最大三万条
boolean thereAreDMC = thereAreDMColumns(formWidgets, mappings.values());
long maxCount = thereAreDMC ? DataAnalysisEventListener.MAX_DM_DATA_COUNT : DataAnalysisEventListener.MAX_DATA_COUNT;
if (rowCount > maxCount) {
int dataCount = headerNumber == 1 ? rowCount - headerNumber : rowCount - headerNumber + 1;
String message = thereAreDMC ? String.format("文件有%d条数据,有成员部门字段时导入数据不能超过%d条", dataCount, maxCount) : String.format("文件有%d条数据,导入数据不能超过%d条", dataCount, maxCount);
throw new ImportDataInvalidException(message, null);
}
// String primaryKey = params.getObjMapping().containsValue(DataAnalysisEventListener.DATA_ID) ? DataAnalysisEventListener.DATA_ID : params.getPrimaryKey();
String primaryKey = params.getPrimaryKey();
// 开始导入
DataAnalysisParams dap = new DataAnalysisParams();
dap.setFormId(form.getId());
dap.setFormCode(form.getCode());
dap.setHeaderNumber(headerNumber);
dap.setPrimaryKey(primaryKey);
dap.setFormWidgets(formWidgets);
dap.setMappings(mappings);
dap.setValidationConfig(params.getValidationConfig());
DataAnalysisEventListener listener = new DataAnalysisEventListener(dap);
EasyExcel.read( file.getInputStream(), listener)
.extraRead(CellExtraTypeEnum.MERGE)
.headRowNumber(headerNumber)
.autoCloseStream(true)
.sheet(sheetIndex)
.doRead();
if (!listener.getInvalidRows().isEmpty()) {
throw new ImportDataInvalidException("导入文件中有不合法数据", listener.getInvalidRows());
}
List<Map<String, Object>> convertedData = generateData4Save(listener.getConvertedData(), params, form.getFormJson());
if (convertedData.size() > 0) {
// formDataService.batchSave(formCode, LoginContextHolder.me().getSysLoginUserId(), convertedData);
}
return convertedData;
}
private boolean hasMergedHeaders(MultipartFile file, int sheetIndex) {
ExtraMergeInfoListener mergeInfoListener = new ExtraMergeInfoListener();
try {
List<Object> sheetData = EasyExcel.read(file.getInputStream(), mergeInfoListener)
.extraRead(CellExtraTypeEnum.MERGE)
.sheet(sheetIndex)
.headRowNumber(0)
.doReadSync()
.stream()
.limit(1)
.collect(Collectors.toList());
return mergeInfoListener.getExtraMergeInfoList().stream().anyMatch(em -> em.getFirstRowIndex() == 0);
} catch (IOException e) {
return true;
}
}
private boolean thereAreDMColumns(List<WidgetModel> formWidgets, Collection<String> importFields) {
List<String> tc = new ArrayList<>();
formWidgets.forEach(fc -> {
if (isDMColumn(fc)) {
tc.add(fc.getModel());
} else if (CollectionUtil.isNotEmpty(fc.getTableColumns())) {
tc.addAll(fc.getTableColumns().stream().filter(this::isDMColumn).map(WidgetModel::getModel).collect(Collectors.toList()));
}
});
return importFields.stream().anyMatch(tc::contains);
}
private boolean isDMColumn(WidgetModel wm) {
return wm.getType().equals(WidgetType.SINGLE_MEMBER.getCode()) || wm.getType().equals(WidgetType.SINGLE_DEPARTMENT.getCode())
|| wm.getType().equals(WidgetType.MULTIPLE_DEPARTMENTS.getCode()) || wm.getType().equals(WidgetType.MULTIPLE_MEMBERS.getCode());
}
/**
* 生成可保存数据
* @param rawData
* @param params
* @return
*/
private List<Map<String, Object>> generateData4Save(List<Map<String, Object>> rawData, ImportDataParams params, String formJson) {
if (ImportMode.CREATE.equals(params.getMode())) {
return generateCreateData(rawData, params.getFormId(), formJson);
}
if (StrUtil.isNotBlank(params.getPrimaryKey())) {
if (DataAnalysisEventListener.DATA_ID.equals(params.getPrimaryKey())) {
return generateUpsertData4IDMode(rawData, params);
} else {
return generateUpsertData4PKMode(rawData, params);
}
} else if (params.getObjMapping().containsValue(DataAnalysisEventListener.DATA_ID)) {
return generateUpsertData4IDMode(rawData, params);
}
return new ArrayList<>();
}
/**
* 根据匹配字段生成可保存数据
* @param rawData
* @param params
* @return
*/
private List<Map<String, Object>> generateUpsertData4PKMode(List<Map<String, Object>> rawData, ImportDataParams params) {
// eg: singlemember_1641965976117.code, input_1641965973461
String primaryKey = params.getPrimaryKey().contains(WidgetType.SINGLE_MEMBER.getCode()) ? String.format("%s.code", params.getPrimaryKey()) : params.getPrimaryKey();
List<String> pks = new ArrayList<>();
// 收集导入的主键
rawData.forEach(cd -> {
if (ObjectUtil.isNotEmpty(cd.get(primaryKey))) {
JSONObject jo = JSONUtil.parseObj(JSONUtil.toJsonStr(cd));
pks.add(jo.getByPath(primaryKey, String.class));
}
});
try {
// Map<String, String> pkvMapping = importFromExcelHelper.getPKValueMapping(params.getFormCode(), params.toElasticsearchQuery(), params.getPrimaryKey(), pks);
// Map<String, String> pkvMapping = importFromExcelHelper.getPKValueMapping(params.getFormCode(), null,
// params.getPrimaryKey(), pks);
Map<String, String> pkvMapping = new HashMap<>();
Set<String> validPK = pkvMapping.keySet();
rawData = rawData.stream()
.filter(cd -> {
JSONObject row = JSONUtil.parseObj(cd);
// 仅更新模式仅返回有数据ID且数据ID是合法的数据
if (ImportMode.UPDATE.equals(params.getMode())) {
return ObjectUtil.isNotEmpty(row.getByPath(primaryKey, String.class)) && validPK.contains(row.getByPath(primaryKey, String.class));
}
// 新增和更新数据模式,返回没有匹配字段或者匹配字段是合法的数据
else {
String rowPK = row.getByPath(primaryKey, String.class);
// 若匹配字段是空的,这条数据是有效的
if (StrUtil.isBlank(rowPK)) {
return true;
} else {
// 若匹配字段不是空的,则判断是否可以找到数据ID,找得到则是有效的,找不到则是无效的数据
return StrUtil.isNotBlank(pkvMapping.get(rowPK));
}
}
})
.peek(cd -> {
JSONObject row = JSONUtil.parseObj(cd);
String rowPK = row.getByPath(primaryKey, String.class);
cd.put("updateTime", new Date());
if (StrUtil.isNotBlank(rowPK)) {
// 根据主键查找到对应的数据ID
cd.put(DataAnalysisEventListener.DATA_ID, pkvMapping.get(rowPK));
} else {
// 为没有ID的数据创建ID
cd.put(DataAnalysisEventListener.DATA_ID, UUID.randomUUID().toString().replaceAll("-",""));
}
})
.collect(Collectors.toList());
} catch (Exception e) {
e.printStackTrace();
}
return rawData;
}
/**
* 为创建模式下生成可保存的数据
* @param rawData 原始数据
* @return 转换后的数据
*/
private List<Map<String, Object>> generateCreateData(List<Map<String, Object>> rawData, Long formId, String formJson) {
AtomicInteger count = new AtomicInteger();
rawData.forEach(row -> {
row.put(DataAnalysisEventListener.DATA_ID, UUID.randomUUID().toString().replaceAll("-",""));
Date date = new Date(System.currentTimeMillis() + count.getAndAdd(500));
row.put("createTime", date);
row.put("updateTime", date);
});
return rawData;
}
/**
* 根据数据ID生成可保存数据
* @param rawData 转换前的数据
* @param params 转换参数
* @return 转换后的数据
*/
private List<Map<String, Object>> generateUpsertData4IDMode(List<Map<String, Object>> rawData, ImportDataParams params) {
List<String> ids = new ArrayList<>();
ImportMode mode = params.getMode();
String formCode = params.getFormCode();
// String query = params.toElasticsearchQuery();
String query = null;
// 收集导入的ID
rawData.forEach(cd -> {
if (ObjectUtil.isNotEmpty(cd.get(DataAnalysisEventListener.DATA_ID))) {
ids.add((String) cd.get(DataAnalysisEventListener.DATA_ID));
}
});
// 过滤掉非法ID
try {
// List<String> invalidIds = importFromExcelHelper.getNotExistIds(formCode, query, ids);
List<String> invalidIds = CollUtil.newArrayList();
rawData = rawData.stream()
.filter(cd -> {
// 仅更新模式仅返回有数据ID且数据ID是合法的数据
if (ImportMode.UPDATE.equals(mode)) {
return ObjectUtil.isNotEmpty(cd.get(DataAnalysisEventListener.DATA_ID)) && !invalidIds.contains((String) cd.get(DataAnalysisEventListener.DATA_ID));
}
// 新增和更新数据模式,返回没有数据ID或者数据ID是合法的数据
else {
return ObjectUtil.isEmpty(cd.get(DataAnalysisEventListener.DATA_ID)) || !invalidIds.contains((String) cd.get(DataAnalysisEventListener.DATA_ID));
}
})
.peek(cd -> {
// 为没有ID的数据创建ID
if (ObjectUtil.isEmpty(cd.get(DataAnalysisEventListener.DATA_ID))) {
cd.put(DataAnalysisEventListener.DATA_ID, UUID.randomUUID().toString().replaceAll("-",""));
}
cd.put("updateTime", new Date());
})
.collect(Collectors.toList());
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return rawData;
}
/**
* 生成预览表头
* @param sheetData
* @param extraMergeInfoList
* @param howManyHeaders
* @return
*/
private List<PreviewTableHeader> generatePreviewTableHeaders(List<Object> sheetData, List<CellExtra> extraMergeInfoList, int howManyHeaders) {
List<PreviewTableHeader> headers = new ArrayList<>();
// 解析出表头
List<Map<String, Object>> headerRows = sheetData.stream()
.limit(howManyHeaders)
.map(JsonUtil::toJson)
.map(JsonUtil::jsonToMap)
.collect(Collectors.toList());
Map<String, Object> firstRow = headerRows.get(0);
Map<String, Object> secondRow = headerRows.size() > 1 ? headerRows.get(1) : null;
// 查看表头是否有合并单元格
List<CellExtra> mergedHeaderCells = extraMergeInfoList.stream()
.filter(extra -> extra.getFirstRowIndex() == 0 && extra.getLastRowIndex() == 0)
.collect(Collectors.toList());
List<String> existedColumns = new ArrayList<>();
AtomicInteger currentColumnIndex = new AtomicInteger();
firstRow.forEach((col, value) -> {
if (col.equals(currentColumnIndex.toString())) {
// 判断是否是合并单元格
Integer colIndex = Integer.parseInt(col);
Optional<CellExtra> optional = mergedHeaderCells.stream().filter(cellExtra -> colIndex.equals(cellExtra.getFirstColumnIndex())).findFirst();
String strValue = ObjectUtil.isEmpty(value) ? "" : String.valueOf(value);
if (optional.isPresent() && secondRow != null) {
// 有合并单元格
CellExtra extra = optional.get();
PreviewTableHeader header = new PreviewTableHeader(strValue, new Random().nextInt() * 100);
List<PreviewTableHeader> children = new ArrayList<>();
for (int cellColIndex = extra.getFirstColumnIndex(); cellColIndex <= extra.getLastColumnIndex(); cellColIndex++) {
PreviewTableHeader subHeader = new PreviewTableHeader((String) secondRow.get(String.valueOf(cellColIndex)), currentColumnIndex.get());
children.add(subHeader);
currentColumnIndex.getAndIncrement();
}
header.setChildren(children);
headers.add(header);
existedColumns.add(strValue);
} else if (!existedColumns.contains(strValue)){
// 没有合并单元格
PreviewTableHeader header = new PreviewTableHeader(strValue, currentColumnIndex.get());
if (secondRow != null && secondRow.get(col) != null && !strValue.equals(secondRow.get(col))) {
PreviewTableHeader subHeader = new PreviewTableHeader((String) secondRow.get(col), currentColumnIndex.get());
List<PreviewTableHeader> children = new ArrayList<>();
children.add(subHeader);
header.setChildren(children);
}
headers.add(header);
currentColumnIndex.getAndIncrement();
}
}
});
return headers;
}
/**
* 生成合并单元格信息
* @param extraMergeInfoList
* @param howManyHeaders
* @return
*/
private List<CellSpanInfo> generateMergeInfo(List<CellExtra> extraMergeInfoList, List<PreviewTableHeader> tableHeaders, int howManyHeaders) {
List<CellSpanInfo> spanInfoList = new ArrayList<>();
extraMergeInfoList.stream().filter(cellExtra -> cellExtra.getFirstRowIndex() >= howManyHeaders).forEach(cellExtra -> {
int firstRowIndex = cellExtra.getFirstRowIndex();
int firstColIndex = cellExtra.getFirstColumnIndex();
for (int rowIndex = cellExtra.getFirstRowIndex(); rowIndex <= cellExtra.getLastRowIndex(); rowIndex++) {
for (int colIndex = cellExtra.getFirstColumnIndex(); colIndex <= cellExtra.getLastColumnIndex(); colIndex++) {
if (rowIndex == firstRowIndex && colIndex == firstColIndex) {
// 第一个合并单元格
CellSpanInfo firstMergeCell = new CellSpanInfo();
firstMergeCell.setRowIndex(rowIndex - howManyHeaders);
firstMergeCell.setColumnIndex(getPreviewColumnIndex(tableHeaders, colIndex));
firstMergeCell.setRowSpan(cellExtra.getLastRowIndex() - cellExtra.getFirstRowIndex() + 1);
firstMergeCell.setColSpan(cellExtra.getLastColumnIndex() - cellExtra.getFirstColumnIndex() + 1);
spanInfoList.add(firstMergeCell);
} else {
// 处理被合并的单元格(只处理了纵向被合并的单元格)
CellSpanInfo noSpanCell = new CellSpanInfo();
noSpanCell.setRowIndex(rowIndex - howManyHeaders);
noSpanCell.setColumnIndex(getPreviewColumnIndex(tableHeaders, colIndex));
noSpanCell.setRowSpan(0);
noSpanCell.setColSpan(0);
spanInfoList.add(noSpanCell);
}
}
}
});
return spanInfoList;
}
/**
* 计算并获得列的实际索引
* @param tableHeaders
* @param columnIndex
* @return
*/
private int getPreviewColumnIndex(List<PreviewTableHeader> tableHeaders, int columnIndex) {
int columnCount = 0;
int mergeCellCount = 0;
for (PreviewTableHeader header : tableHeaders) {
if (columnCount >= columnIndex) {
break;
}
if (CollectionUtil.isNotEmpty(header.getChildren())) {
columnCount += header.getChildren().size();
mergeCellCount += header.getChildren().size();
} else {
columnCount++;
}
}
return columnIndex - mergeCellCount + (mergeCellCount > 0 ? 1 : 0);
}
}

63
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/service/impl/excel/ImportDemo.java

File diff suppressed because one or more lines are too long

35
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/service/impl/excel/handler/CommentWriteHandler.java

@ -1,35 +0,0 @@
package org.dromara.dataManager.service.impt.service.impl.excel.handler;
import org.dromara.dataManager.service.impt.service.impl.excel.model.CellModel;
import com.alibaba.excel.write.handler.RowWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Row;
import java.util.LinkedList;
import java.util.List;
/**
* 插入批注
*/
@Slf4j
public class CommentWriteHandler implements RowWriteHandler {
private List<CellModel> errors = new LinkedList<CellModel>();
public CommentWriteHandler(List<CellModel> errors){
this.errors = errors;
}
@Override
public void beforeRowCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Integer integer, Integer integer1, Boolean aBoolean) {
}
@Override
public void afterRowCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Integer integer, Boolean aBoolean) {
}
@Override
public void afterRowDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Integer integer, Boolean aBoolean) {
}
}

433
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/service/impl/excel/listener/DataAnalysisEventListener.java

@ -1,433 +0,0 @@
package org.dromara.dataManager.service.impt.service.impl.excel.listener;
import org.dromara.system.domain.SysDept;
import org.dromara.system.domain.SysUser;
import org.dromara.common.Exception.ServiceException;
import org.dromara.common.response.WorkflowResultCode;
import org.dromara.dataManager.enums.WidgetType;
import org.dromara.dataManager.param.ImportDataParams;
import org.dromara.dataManager.service.impt.convert.ConverterBuilder;
import org.dromara.dataManager.service.impt.convert.WidgetConverter;
import org.dromara.dataManager.service.impt.model.DataAnalysisParams;
import org.dromara.dataManager.service.impt.service.impl.excel.model.CellModel;
import org.dromara.dataManager.service.impt.service.impl.excel.model.RecordModel;
import org.dromara.dataManager.service.impt.service.impl.excel.model.RowModel;
import org.dromara.taskCenter.model.widget.WidgetModel;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.enums.CellExtraTypeEnum;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.metadata.CellExtra;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import java.util.*;
import java.util.stream.Collectors;
@Slf4j
@Data
public class DataAnalysisEventListener extends AnalysisEventListener<Map<Integer, String>> {
private static final List<String> DATE_COLUMNS = Arrays.asList("createTime", "updateTime");
public static final String DATA_ID = "id";
// 没有成员部门字段时的最大导入数据量
public static final Long MAX_DATA_COUNT = 30000L;
// 有成员部门字段时的最大导入数据量
public static final Long MAX_DM_DATA_COUNT = 10000L;
/**
* 表单ID
*/
private Long formId;
/**
* 表单code
*/
private String formCode;
/**
* 主键匹配字段
*/
private String primaryKey;
/**
* 表头行数
*/
private int headerNumber;
/**
* 要导入的表单字段
*/
private List<WidgetModel> importWidgets;
/**
* 表单的所有字段
*/
private List<WidgetModel> formWidgets;
/**
* 字段与列的映射关系
*/
private Map<Integer, String> mappings;
/**
* 表单字段值converter
*/
private Map<Integer, WidgetConverter> converts = new HashMap<Integer, WidgetConverter>();
/**
* excel 行信息
*/
private List<RowModel> rows = new LinkedList<RowModel>();
/**
* 合并单元格信息
*/
private List<CellExtra> extraList = new ArrayList<>();
/**
* 表单记录
*/
private LinkedList<RecordModel> records = new LinkedList<RecordModel>();
/**
* 行错误信息
*/
private List<String> invalidRows = new ArrayList<>();
/**
* excel中的成员账号
*/
private Set<String> importMembers = new HashSet<>();
private Map<String, SysUser> accountUserMapping = new HashMap<>();
/**
* excel中的部门路径
*/
private Set<String> importDeparts = new HashSet<>();
private Map<String, SysDept> pathDepartMapping = new HashMap<>();
public DataAnalysisEventListener(DataAnalysisParams params){
Long formId = params.getFormId();
String formCode = params.getFormCode();
int headerNumber = params.getHeaderNumber();
String primaryKey = params.getPrimaryKey();
List<WidgetModel> formWidgets = params.getFormWidgets();
Map<Integer, String> mappings = params.getMappings();
ImportDataParams.ValidationConfig validationConfig = params.getValidationConfig();
if(mappings == null || mappings.isEmpty() || formWidgets == null || formWidgets.isEmpty()){
throw new ServiceException(WorkflowResultCode.FAIL);
}
List<WidgetModel> widgets = buildImportWidgets(formWidgets, mappings);
Map<String, WidgetModel> widgetMap = new HashMap<>();
widgets.forEach(w ->{
if(w.getType().equalsIgnoreCase(WidgetType.TABLE.getCode())){
w.getTableColumns().forEach(sw ->{
widgetMap.put(sw.getModel(), sw);
});
}else {
widgetMap.put(w.getModel(), w);
}
});
mappings.keySet().forEach(i ->{
String type = widgetMap.get(mappings.get(i)) == null ? null : widgetMap.get(mappings.get(i)).getType();
WidgetConverter converter;
if (DATE_COLUMNS.contains(mappings.get(i))) {
WidgetModel widget = new WidgetModel(WidgetType.DATE.getCode(), mappings.get(i), mappings.get(i));
converter = ConverterBuilder.getConverter(WidgetType.DATE.getCode(), widget);
widgets.add(widget);
} else if ("creatorAccount".equals(mappings.get(i)) || DATA_ID.equals(mappings.get(i))) {
WidgetModel widget = new WidgetModel(WidgetType.GENERAL.getCode(), mappings.get(i), mappings.get(i));
converter = ConverterBuilder.getConverter(type, widget);
widgets.add(widget);
} else {
converter = ConverterBuilder.getConverter(type, widgetMap.get(mappings.get(i)));
// setAccountsDepartsMapping(type, converter);
}
converter.setValidationConfig(validationConfig);
this.converts.put(i, converter);
});
this.importWidgets = widgets;
this.formWidgets = formWidgets;
this.mappings = mappings;
this.formId = formId;
this.formCode = formCode;
this.headerNumber = headerNumber;
this.primaryKey = primaryKey;
}
@Override
public void invoke(Map<Integer, String> data, AnalysisContext analysisContext) {
// 封装 excel 行信息,此时不做数据校验
RowModel row = new RowModel(analysisContext.readRowHolder().getRowIndex());
mappings.forEach((ci, model) -> {
row.addCell(new CellModel(converts.get(ci), row.getRowIndex(), ci, data.get(ci)));
// 收集成员账号与部门路径
WidgetModel widget = getWidgetByModel(model);
collectMembersAndDeparts(widget, data.get(ci));
});
this.rows.add(row);
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
//
// this.accountUserMapping.putAll(SpringUtil.getBean(UserService.class).getAccountNameMapping(importMembers));
//
// this.pathDepartMapping.putAll(SpringUtil.getBean(DepartmentService.class).getPathDepartMapping(importDeparts));
//
// // 数据从第几行开始
// int rowIndex = headerNumber;
//
// // 临时的 form json
// JSONObject fjObj = new JSONObject();
// fjObj.putOpt("config", new JSONObject());
// fjObj.putOpt("list", formWidgets);
// String fj = fjObj.toString();
//
// // 是否有creatorAccount字段
// boolean hasAccountField = mappings.containsValue("creatorAccount");
// List<String> importAccounts = new ArrayList<>();
//
// // 是否有子表单字段
// List<WidgetModel> tableWidgets = importWidgets.stream().filter(w -> WidgetType.TABLE.getCode().equals(w.getType())).collect(Collectors.toList());
//
// for (int ri = 0; ri < rows.size() && rowIndex - headerNumber < rows.size(); ri ++) {
//
// int finalRowIndex = rowIndex;
// Optional<CellExtra> optional = tableWidgets.size() > 0 ? extraList.stream().filter(extra -> extra.getFirstRowIndex() == finalRowIndex).findFirst() : Optional.empty();
//
// RecordModel record;
// int thisRowIndex = rowIndex;
// // 有合并单元格的数据,且有子表单字段
// if (tableWidgets.size() > 0 && optional.isPresent()) {
//
// CellExtra merge = optional.get();
// record = new RecordModel(merge.getRowIndex());
// for(int index = merge.getFirstRowIndex(); index <= merge.getLastRowIndex(); index ++) {
//
// int fri = rowIndex;
// Optional<RowModel> rmo = this.rows.stream().filter(row -> row.getRowIndex().equals(fri)).findFirst();
// rmo.ifPresent(rowModel -> record.addRow(this.importWidgets, rowModel));
//
// // 行数加1
// rowIndex++;
// }
//
// if (ObjectUtil.isNotEmpty(record.getData().get(DATA_ID))) {
// // 移除子表单字段,更新模式不支持子表单字段
// tableWidgets.forEach(tw -> record.getData().remove(tw.getModel()));
// }
//
// }
// // 没有合并单元格的数据
// else {
// record = new RecordModel(rowIndex);
//
// int fri = rowIndex;
// Optional<RowModel> rmo = this.rows.stream().filter(row -> row.getRowIndex().equals(fri)).findFirst();
// rmo.ifPresent(rowModel -> record.addRow(this.importWidgets, rowModel));
//
// // 行数加1
// rowIndex++;
//
// }
//
// // 记录错误信息
// if (record.hasError()) {
// invalidRows.add(formatErrorMessage(thisRowIndex, record.getErrorCells()));
// }
//
// // 如有流水号字段则生成流水号
// // addSerialNumberFields(record.getData(), fj);
// this.records.add(record);
//
// // 收集导入的创建人账号信息
// if (hasAccountField && ObjectUtil.isNotEmpty(record.getData().containsKey("creatorAccount"))) {
// importAccounts.add((String) record.getData().get("creatorAccount"));
// }
// }
//
// // 添加系统字段
// addSystemFields(hasAccountField, importAccounts);
}
@Override
public void extra(CellExtra extra, AnalysisContext context) {
if(extra.getType() == CellExtraTypeEnum.MERGE) {
extraList.add(extra);
}
}
/**
* 获取处理后的数据
* @return 处理后的数据
*/
public List<Map<String, Object>> getConvertedData() {
return this.records.stream().map(RecordModel::getData).collect(Collectors.toList());
}
/**
* 添加系统字段
* @param hasAccountField 导入字段中是否有提交人账号字段
* @param importAccounts excel中的账号字段
*/
private void addSystemFields(boolean hasAccountField, List<String> importAccounts) {
//
// Map<String, SysUser> accountNameMap = getAccountNameMapping(importAccounts);
//
// this.records.forEach(item -> {
// Map<String, Object> row = item.getData();
// if (hasAccountField) {
//
// if (ObjectUtil.isNotEmpty(row.get("creatorAccount"))) {
// String account = (String) row.get("creatorAccount");
//
// SysUser user = accountNameMap.get(account);
// if (ObjectUtil.isNotNull(user)) {
// row.put("owner", user.getId());
// row.put("creator", user.getName());
// row.put("creatorAccount", user.getAccount());
// } else {
// row.put("owner", LoginContextHolder.me().getSysLoginUserId());
// row.put("creator", LoginContextHolder.me().getSysLoginUser().getName());
// row.put("creatorAccount", LoginContextHolder.me().getSysLoginUserAccount());
// }
// }
//
// }
//
// // 没有匹配字段说明这是一条新增的数据
// if (primaryKey != null) {
// if (ObjectUtil.isEmpty(item.getData().get(primaryKey))) {
// row.putIfAbsent("owner", LoginContextHolder.me().getSysLoginUserId());
// row.putIfAbsent("creator", LoginContextHolder.me().getSysLoginUser().getName());
// row.putIfAbsent("creatorAccount", LoginContextHolder.me().getSysLoginUserAccount());
// row.putIfAbsent("createTime", new Date());
// }
// } else {
// row.putIfAbsent("owner", LoginContextHolder.me().getSysLoginUserId());
// row.putIfAbsent("creator", LoginContextHolder.me().getSysLoginUser().getName());
// row.putIfAbsent("creatorAccount", LoginContextHolder.me().getSysLoginUserAccount());
// row.putIfAbsent("createTime", new Date());
// }
//
// });
}
private Map<String, SysUser> getAccountNameMapping(List<String> accounts) {
// if (CollUtil.isEmpty(accounts)) {
// return new HashMap<>();
// }
// UserService userService = SpringUtil.getBean(UserService.class);
// return userService.getAccountNameMapping(accounts);
return new HashMap<>();
}
/**
* 收集excel中的成员账号与部门路径
* @param widget 字段信息
* @param value excel中的值
*/
private void collectMembersAndDeparts(WidgetModel widget, String value) {
if (StringUtils.isNotBlank(value) && widget != null) {
if (WidgetType.SINGLE_MEMBER.getCode().equals(widget.getType()) || WidgetType.MULTIPLE_MEMBERS.getCode().equals(widget.getType())) {
importMembers.addAll(Arrays.asList(value.split(",")));
}
if (WidgetType.SINGLE_DEPARTMENT.getCode().equals(widget.getType()) || WidgetType.MULTIPLE_DEPARTMENTS.getCode().equals(widget.getType())) {
importDeparts.addAll(Arrays.asList(value.split(",")));
}
}
}
/**
* 格式化错误信息
* @param rowIndex 行索引
* @param errorCells 有错误数据的单元格
* @return 错误信息
*/
private String formatErrorMessage(int rowIndex, List<CellModel> errorCells) {
List<String> errors = new ArrayList<>();
errors.add(String.format("第%d行", rowIndex + 1));
errorCells.forEach(ec -> {
errors.add(String.format("%s(%d列)", ec.getValidate().getMessage(), ec.getColIndex() + 1));
});
return String.join(",", errors);
}
/**
* 根据字段唯一标识符获取字段配置信息
* @param model 字段唯一标识符
* @return 字段配置信息
*/
private WidgetModel getWidgetByModel(String model) {
WidgetModel matched = null;
for(WidgetModel wm: importWidgets) {
if (WidgetType.TABLE.getCode().equals(wm.getType())) {
Optional<WidgetModel> optional = wm.getTableColumns().stream().filter(tc -> tc.getModel().equals(model)).findFirst();
if (optional.isPresent()) {
matched = optional.get();
break;
}
} else if (wm.getModel().equals(model)){
matched = wm;
break;
}
}
return matched;
}
private List<WidgetModel> buildImportWidgets(List<WidgetModel> formWidgets, Map<Integer, String> mappings) {
List<WidgetModel> widgets = new ArrayList<>();
formWidgets.forEach(fc -> {
if (mappings.containsValue(fc.getModel())) {
widgets.add(fc);
} else if (CollectionUtil.isNotEmpty(fc.getTableColumns())) {
List<WidgetModel> tcList = fc.getTableColumns().stream()
.filter(tc -> mappings.containsValue(tc.getModel()))
.collect(Collectors.toList());
if (CollectionUtil.isNotEmpty(tcList)) {
fc.setTableColumns(tcList);
widgets.add(fc);
}
}
});
return widgets;
}
}

52
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/service/impl/excel/model/CellModel.java

@ -1,52 +0,0 @@
package org.dromara.dataManager.service.impt.service.impl.excel.model;
import org.dromara.dataManager.service.impt.convert.WidgetConverter;
import lombok.Data;
import java.io.Serializable;
/**
* excel单元格model
*/
@Data
public class CellModel implements Serializable {
private static final long serialVersionUID = -1027380204378668428L;
/**
* 表单字段值converter
*/
private WidgetConverter converter;
private Integer rowIndex;
private Integer colIndex;
private String excelValue;
private Validate validate;
public CellModel(WidgetConverter converter, Integer rowIndex, Integer colIndex, String excelValue){
this.converter = converter;
this.rowIndex = rowIndex;
this.colIndex = colIndex;
this.excelValue = excelValue;
}
public void validateFail(String message){
this.validate = new Validate(false, message);
}
public void validateSucc(){
this.validate = new Validate(true);
}
@Data
static
public class Validate implements Serializable{
private Boolean success = true;
private String message;
public Validate(Boolean success){
this.success = success;
}
public Validate(Boolean success, String message){
this.success = success;
this.message = message;
}
}
}

119
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/service/impl/excel/model/RecordModel.java

@ -1,119 +0,0 @@
package org.dromara.dataManager.service.impt.service.impl.excel.model;
import org.dromara.dataManager.enums.WidgetType;
import org.dromara.dataManager.service.impt.convert.WidgetConverter;
import org.dromara.taskCenter.model.widget.WidgetModel;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import lombok.Data;
import java.io.Serializable;
import java.util.*;
/**
* 数据记录
*/
@Data
public class RecordModel implements Serializable {
private static final long serialVersionUID = 8553281834023196024L;
/**
* excel 合并行
*/
private Integer rowIndex;
/**
* 表单数据
*/
private Map<String, Object> data = new HashMap<>();
/**
* 验证错误的单元格
*/
public List<CellModel> errorCells = new LinkedList<CellModel>();
public RecordModel(Integer rowIndex){
this.rowIndex = rowIndex;
}
public void addRow(List<WidgetModel> widgets, RowModel row){
if(widgets != null){
Map<String, CellModel> cellMap = row.getCells();
widgets.forEach(w -> {
if(!w.getType().equalsIgnoreCase(WidgetType.TABLE.getCode())){
this.putData(w.getModel(), cellMap.get(w.getModel()));
} else if (CollectionUtil.isNotEmpty(w.getTableColumns())){
w.getTableColumns().forEach(sw -> {
this.putTableData(w.getModel(), sw.getModel(), cellMap.get(sw.getModel()));
});
}
});
}
}
public boolean hasError(){
return errorCells.size() > 0;
}
/**
* 设置子表单数据
* @param tableModel
* @param model
* @param cell
*/
private void putTableData(String tableModel, String model, CellModel cell){
if (cell == null) {
return;
}
if(!data.containsKey(tableModel)){
data.put(tableModel, new LinkedList<Map<String, Object>>());
}
List<Map<String, Object>> table = (List<Map<String, Object>>) data.get(tableModel);
if(cell.getRowIndex() - this.rowIndex > table.size() -1){
table.add(new HashMap<>());
table.get(table.size() - 1).put("_id", UUID.randomUUID().toString());
}
Map<String, Object> map = table.get(cell.getRowIndex() - this.rowIndex);
cell.getConverter().validate(cell.getExcelValue(), new WidgetConverter.ConvertCallBack() {
@Override
public void success(Object convertValue) {
// 如果是空的数据则忽略掉这个字段
if (ObjectUtil.isNotEmpty(convertValue)) {
map.put(model, convertValue);
}
cell.validateSucc();
}
@Override
public void fail(String message) {
cell.validateFail(message);
errorCells.add(cell);
}
});
}
/**
* 设置数据
* @param model
* @param cell
*/
private void putData(String model, CellModel cell){
if(!this.data.containsKey(model)){
cell.getConverter().validate(cell.getExcelValue(), new WidgetConverter.ConvertCallBack() {
@Override
public void success(Object convertValue) {
// 如果是空的数据则忽略掉这个字段
if (ObjectUtil.isNotEmpty(convertValue)) {
data.put(model, convertValue);
}
cell.validateSucc();
}
@Override
public void fail(String message) {
cell.validateFail(message);
errorCells.add(cell);
}
});
}
}
}

30
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/service/impl/excel/model/RowMerge.java

@ -1,30 +0,0 @@
package org.dromara.dataManager.service.impt.service.impl.excel.model;
import lombok.Data;
import java.io.Serializable;
/**
* excel行合并信息
*/
@Data
public class RowMerge implements Serializable {
private Integer rowIndex;
private Integer firstRowIndex;
private Integer lastRowIndex;
public RowMerge(Integer rowIndex, Integer firstRowIndex, Integer lastRowIndex){
this.rowIndex = rowIndex;
this.firstRowIndex = firstRowIndex;
this.lastRowIndex = lastRowIndex;
}
public void update(Integer firstRowIndex, Integer lastRowIndex) {
if (firstRowIndex != null && firstRowIndex.intValue() < this.firstRowIndex.intValue()) {
this.firstRowIndex = firstRowIndex;
}
if (lastRowIndex != null && lastRowIndex.intValue() > this.lastRowIndex.intValue()) {
this.lastRowIndex = lastRowIndex;
}
}
}

34
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/service/impl/excel/model/RowModel.java

@ -1,34 +0,0 @@
package org.dromara.dataManager.service.impt.service.impl.excel.model;
import lombok.Data;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
/**
* excel 行model
*/
@Data
public class RowModel implements Serializable {
private static final long serialVersionUID = 3100643744741570508L;
/**
* 行号
*/
private Integer rowIndex;
/**
* key = 表单model
* value = CellModel
*/
private Map<String, CellModel> cells = new HashMap<>();
public RowModel(Integer rowIndex){
this.rowIndex = rowIndex;
}
public void addCell(CellModel cell){
this.cells.put(cell.getConverter().getWidget().getModel(), cell);
}
}

84
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/impt/validator/ValueValidator.java

@ -1,84 +0,0 @@
package org.dromara.dataManager.service.impt.validator;
import org.dromara.taskCenter.model.FormWidget;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.util.DateUtils;
import lombok.extern.slf4j.Slf4j;
import java.text.ParseException;
@Slf4j
public class ValueValidator {
public static boolean isEmpty(Object value) {
return ObjectUtil.isEmpty(value);
}
public static boolean isNumber(Object value) {
if (value == null) {
return false;
} else {
String numberStr = (String) value;
numberStr = numberStr.replaceAll(",", "").replaceAll("%", "");
return NumberUtil.isNumber(numberStr);
}
}
public static boolean isDate(Object value, FormWidget formWidget) {
if (value != null) {
String dateObj = (String) value;
try {
String format = (String) formWidget.getOptions().get("format");
// 使用规定格式转换数据,转换不报错就说明是日期格式数据
DateUtils.parseDate(dateObj, format);
return true;
} catch (Exception e) {
try {
// 如果转换报错,则尝试自动转换日期格式,转换不报错就说明是日期格式数据
DateUtils.parseDate(dateObj);
return true;
} catch (Exception parseException) {
// 自动识别格式失败则尝试自动识别常用格式,转换不报错就说明是日期格式数据
try {
if (dateObj.contains("/") || dateObj.contains("-")) {
convert2Date(dateObj);
} else {
return false;
}
} catch (ParseException exception) {
return false;
}
return true;
}
}
} else {
return false;
}
}
private static void convert2Date(String dateString) throws ParseException {
// 自动识别格式失败则尝试自动识别常用格式
String separator = null;
if (dateString.contains("-")) {
separator = "-";
} else if (dateString.contains("/")) {
separator = "/";
}
if (separator != null) {
String ymd = String.format("yyyy%sMM%sdd", separator, separator);
String[] formats = new String[]{ymd, String.format("%s HH:mm:ss", ymd), String.format("%s HH:mm", ymd), String.format("%s HH", ymd)};
for (String format: formats) {
DateUtils.parseDate(dateString, format);
break;
}
}
}
}

20
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/log/DataLogActionService.java

@ -1,20 +0,0 @@
package org.dromara.dataManager.service.log;
import org.dromara.dataManager.domain.FormDataLog;
import org.dromara.dataManager.param.FormDataModifyMessage;
import java.util.List;
/**
* @Description: server
**/
public interface DataLogActionService {
/**
* 封装数据日志对象集合
* @return
*/
List<FormDataLog> transformDataLogs(FormDataModifyMessage data);
}

37
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/log/FormDataLogService.java

@ -1,37 +0,0 @@
package org.dromara.dataManager.service.log;
import org.dromara.dataManager.domain.FormDataLog;
import org.dromara.dataManager.param.FormDataModifyMessage;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* 数据日志service
*/
public interface FormDataLogService extends IService<FormDataLog> {
/**
* 添加数据日志
* @param param
*/
void addDataLog(FormDataModifyMessage param);
/**
* 查询某数据的详细数据日志
* @param dataId
* @return
*/
List<FormDataLog> listDataLog(Long formId,Long dataId);
/**
* 清空表单填报数据
* @param formId
*/
void deleteByForm(Long formId);
/**
* 批量删除
* @param docIds
*/
void deleteByDataIds(String[] docIds);
}

53
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/log/impl/DataLogDeleteService.java

@ -1,53 +0,0 @@
package org.dromara.dataManager.service.log.impl;
import org.dromara.dataManager.domain.FormDataLog;
import org.dromara.dataManager.param.FormDataModifyMessage;
import org.dromara.dataManager.service.FormDataService;
import org.dromara.dataManager.service.log.DataLogActionService;
import org.dromara.workflow.engine.enums.ESDefaultFieldConst;
import cn.hutool.core.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @Description: 删除操作 记录数据日志
**/
@Slf4j
@Component("deleteDataLog")
public class DataLogDeleteService implements DataLogActionService {
@Autowired
private FormDataService formDataService;
@Override
public List<FormDataLog> transformDataLogs(FormDataModifyMessage data) {
List<FormDataLog> formDataLogs = new ArrayList<>();
data.getBefore().forEach(p -> {
Map<String, Object> afterDataMap = formDataService.getFormDataById(data.getFormId(), (Long) p.get("dataId"));
formDataLogs.add(transformLog(data, (Long) p.get("dataId"),afterDataMap));
});
return formDataLogs;
}
private FormDataLog transformLog(FormDataModifyMessage param, Long dataId, Map<String,Object> dataMap) {
if(ObjectUtil.isNotEmpty(dataId)){
FormDataLog formDataLog = new FormDataLog(param.getFormId(),param.getFormCode());
formDataLog.fillData(param.getAction().getCode(),dataId,null,dataMap);
dataMap.put(ESDefaultFieldConst.DELETED,false);
formDataLog.fillOldData(dataMap);
formDataLog.setUser(param.getHandleUserId(),param.getHandleUserName(),param.getHandleUserAccount(), param.getHandleTime());
formDataLog.setChanges(null);
return formDataLog;
}
return null;
}
}

42
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/log/impl/DataLogSaveService.java

@ -1,42 +0,0 @@
package org.dromara.dataManager.service.log.impl;
import org.dromara.dataManager.domain.FormDataLog;
import org.dromara.dataManager.param.FormDataModifyMessage;
import org.dromara.dataManager.service.log.DataLogActionService;
import cn.hutool.core.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @Description: 新增操作 记录数据日志
**/
@Slf4j
@Component("saveDataLog")
public class DataLogSaveService implements DataLogActionService {
@Override
public List<FormDataLog> transformDataLogs(FormDataModifyMessage data) {
return data.getAfter().stream().map(p -> transformLog(data,(Long) p.get("dataId"),p))
.collect(Collectors.toList());
}
private FormDataLog transformLog(FormDataModifyMessage param, Long dataId,Map<String,Object> after
) {
if(ObjectUtil.isNotEmpty(dataId)){
FormDataLog formDataLog = new FormDataLog(param.getFormId(),param.getFormCode());
formDataLog.fillData(param.getAction().getCode(),dataId,null,after);
formDataLog.setUser(param.getHandleUserId(),param.getHandleUserName(),param.getHandleUserAccount(), param.getHandleTime());
formDataLog.setChanges(null);
return formDataLog;
}
return null;
}
}

85
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/log/impl/DataLogUpdateService.java

@ -1,85 +0,0 @@
package org.dromara.dataManager.service.log.impl;
import org.dromara.common.Exception.ServiceException;
import org.dromara.common.response.WorkflowResultCode;
import org.dromara.common.util.JsonUtil;
import org.dromara.dataManager.domain.FormDataLog;
import org.dromara.dataManager.param.FormDataModifyMessage;
import org.dromara.dataManager.service.log.DataLogActionService;
import org.dromara.dataManager.service.validate.FormDataValidateService;
import org.dromara.formMaking.results.FormSourceResult;
import org.dromara.formMaking.service.FormSourceService;
import org.dromara.taskCenter.model.FormWidget;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
* @Description: 单条数据修改操作 记录数据日志
**/
@Slf4j
@Component("updateDataLog")
public class DataLogUpdateService implements DataLogActionService {
@Autowired
private FormDataValidateService dataValidateService;
@Autowired
private FormSourceService formSourceService;
@Override
public List<FormDataLog> transformDataLogs(FormDataModifyMessage data) {
if(ObjectUtil.hasEmpty(data.getBefore(),data.getAfter())){
throw new ServiceException(WorkflowResultCode.PARAM_IS_BLANK);
}
List<FormWidget> configs = getFormWidgets(data);
if(CollUtil.isEmpty(configs)){
throw new ServiceException(WorkflowResultCode.FORM_DETAIL_NOT_EXIST);
}
List<FormDataLog.UpdateWidgetResult> updateWidgets = dataValidateService.listUpdateWidgets(configs,data.getBefore().get(0), data.getAfter().get(0));
if(CollUtil.isNotEmpty(updateWidgets)){
return Arrays.asList(generateLogEntity(data, data.getBefore().get(0), data.getAfter().get(0),updateWidgets));
}
return null;
}
private FormDataLog generateLogEntity(FormDataModifyMessage param,Map<String,Object> before,
Map<String,Object> after,
List<FormDataLog.UpdateWidgetResult> updateWidgetResults
) {
Long dataId = (Long)before.get("dataId");
FormDataLog formDataLog = new FormDataLog(param.getFormId(),param.getFormCode());
formDataLog.fillData(param.getAction().getCode(),dataId,before,after);
formDataLog.setUser(param.getHandleUserId(),param.getHandleUserName(),param.getHandleUserAccount(), param.getHandleTime());
formDataLog.setChanges(JsonUtil.toJson(updateWidgetResults));
return formDataLog;
}
private List<FormWidget> getFormWidgets(FormDataModifyMessage data){
FormSourceResult formDetail = this.formSourceService.getFormSourceById(data.getFormId());
Map<String, Object> formJson = JsonUtil.jsonToMap(formDetail.getFormJson());
assert formJson != null;
List<FormWidget> columnWidgetList = JsonUtil.jsonToList(JsonUtil.toJson(formJson.get("list")), FormWidget.class);
if(CollUtil.isEmpty(columnWidgetList)){
log.error("###### 数据日志 update field widget not exist ######");
return null;
}
return columnWidgetList;
}
}

76
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/log/impl/FormDataLogServiceImpl.java

@ -1,76 +0,0 @@
package org.dromara.dataManager.service.log.impl;
import org.dromara.common.Exception.ServiceException;
import org.dromara.common.response.WorkflowResultCode;
import org.dromara.common.util.JsonUtil;
import org.dromara.dataManager.domain.FormDataLog;
import org.dromara.dataManager.mapper.FormDataLogMapper;
import org.dromara.dataManager.param.FormDataModifyMessage;
import org.dromara.dataManager.service.log.DataLogActionService;
import org.dromara.dataManager.service.log.FormDataLogService;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Slf4j
@Service
public class FormDataLogServiceImpl extends ServiceImpl<FormDataLogMapper, FormDataLog> implements FormDataLogService {
@Autowired
private final Map<String, DataLogActionService> dataActionService = new ConcurrentHashMap<String, DataLogActionService>();
@Autowired
private FormDataLogMapper formDataLogMapper;
@Override
public List<FormDataLog> listDataLog(Long formId,Long dataId) {
if(ObjectUtil.hasEmpty(formId,dataId)){
throw new ServiceException(WorkflowResultCode.PARAM_MISSING);
}
return this.formDataLogMapper.listDataLog(formId,dataId);
}
@Override
public void addDataLog(FormDataModifyMessage param) {
DataLogActionService dataLogActionService = dataActionService.get(param.getAction().getCode()+"DataLog");
if(dataLogActionService != null){
List<FormDataLog> formDataLogList = dataLogActionService.transformDataLogs(param);
if(CollUtil.isEmpty(formDataLogList)){
if(log.isDebugEnabled()){
log.error("###### data log empty {} ######", JsonUtil.toJson(param));
}
return;
}
this.formDataLogMapper.batchSaveDataLog(formDataLogList);
}
}
@Override
public void deleteByForm(Long formId) {
this.formDataLogMapper.delete(new LambdaQueryWrapper<FormDataLog>().eq(FormDataLog::getFormId,formId));
}
/**
* 删除数据日志
* @param dataIds
*/
@Override
public void deleteByDataIds(String... dataIds){
if(dataIds != null && dataIds.length > 0 && dataIds[0] != null){
this.formDataLogMapper.deleteByDataIds(dataIds);
}
}
}

67
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/validate/FormDataValidateService.java

@ -1,67 +0,0 @@
package org.dromara.dataManager.service.validate;
import org.dromara.dataManager.domain.FormDataLog;
import org.dromara.taskCenter.model.FormWidget;
import java.util.List;
import java.util.Map;
/**
* 表单数据校验/对比
*/
public interface FormDataValidateService {
/**
* 校验字段值是否发生变化
* @param widgetId
* @param before
* @param after
* @return
*/
boolean checkWidgetUpdated(String widgetId,Object before, Object after);
/**
* 查询发生变化的表单字段的值
*/
List<FormDataLog.UpdateWidgetResult> listUpdateWidgets(Long formId, Map<String,Object> before, Map<String, Object> after);
/**
* 查询发生变化的表单字段的值
*/
List<FormDataLog.UpdateWidgetResult> listUpdateWidgets(List<FormWidget> configs, Map<String,Object> before, Map<String, Object> after);
/**
* 查询主字段值的变化
* @param before
* @param after
* @param model
* @return
*/
FormDataLog.UpdateWidgetResult getUpdateWidget(FormWidget model,String widgetId,Map<String,Object> before,Map<String,Object> after);
/**
* 查询子表单子字段值的变化
* @param before
* @param after
* @param tableId
* @return
*/
FormDataLog.UpdateWidgetResult getTableColumnUpdateWidget(List<FormWidget> configs,
String tableId,
String subColumnId,
List<Map<String,Object>> before,
List<Map<String,Object>> after);
/**
* 查询数据变动情况数据补偿已废弃
* @param before
* @param after
* @return
*/
List<FormDataLog.UpdateWidgetResult> listUpdatedData(Map<String,Object> before,Map<String, Object> after);
}

265
dk-common/common-workflow/src/main/java/org/dromara/dataManager/service/validate/impl/FormDataValidateServiceImpl.java

@ -1,265 +0,0 @@
package org.dromara.dataManager.service.validate.impl;
import org.dromara.common.Exception.ServiceException;
import org.dromara.common.response.WorkflowResultCode;
import org.dromara.common.util.JsonUtil;
import org.dromara.dataManager.domain.FormDataLog;
import org.dromara.dataManager.enums.WidgetType;
import org.dromara.dataManager.service.validate.FormDataValidateService;
import org.dromara.dataManager.widget.convert.base.BaseFormFieldConverter;
import org.dromara.dataManager.widget.convert.base.FormFieldFactory;
import org.dromara.dataManager.widget.convert.column.DefaultConverter;
import org.dromara.dataManager.widget.convert.column.TableConverter;
import org.dromara.formMaking.results.FormSourceResult;
import org.dromara.formMaking.service.FormSourceService;
import org.dromara.taskCenter.model.FormWidget;
import org.dromara.workflow.engine.enums.ESDefaultFieldConst;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
@Slf4j
@Service
public class FormDataValidateServiceImpl implements FormDataValidateService {
public static final List<String> flowChangedFields = Arrays.asList(ESDefaultFieldConst.FLOW_STAGE);
@Autowired
private FormSourceService formSourceService;
@Override
public boolean checkWidgetUpdated(String widgetId,Object before, Object after){
BaseFormFieldConverter converter = FormFieldFactory.getConverter(widgetId.contains(WidgetType.TABLE.getCode()) ? StrUtil.subBefore(widgetId,".", true) : widgetId);
if (converter != null) {
return converter.checkChange(before, after);
}
throw new ServiceException(WorkflowResultCode.FORM_WIDGET_NOT_ALLOWED);
}
@Override
public List<FormDataLog.UpdateWidgetResult> listUpdateWidgets(Long formId, Map<String, Object> before, Map<String, Object> after) {
List<FormWidget> configs = getFormWidgets(formId);
if(CollUtil.isNotEmpty(configs)){
return listUpdateWidgets(configs,before,after);
}
return Lists.newArrayList();
}
@Override
public List<FormDataLog.UpdateWidgetResult> listUpdateWidgets(List<FormWidget> configs,Map<String, Object> before,Map<String, Object> after) {
List<FormDataLog.UpdateWidgetResult> results = new ArrayList<>();
if(ObjectUtil.isAllNotEmpty(before,after)) {
Sets.SetView<String> unionKeys = Sets.union(after.keySet(), before.keySet());
LinkedHashSet<String> sortKeys = new LinkedHashSet<>();
configs.stream().map(FormWidget::getModel)
.filter(unionKeys::contains)
.forEach(sortKeys::add);
if(CollUtil.isNotEmpty(unionKeys)){
unionKeys.stream().filter(key -> !sortKeys.contains(key)).forEach(sortKeys::add);
sortKeys.forEach(key -> {
FormWidget config =configs.stream().filter(p -> StrUtil.equals(p.getModel(),key)).findAny().orElse(null);
if(config != null) {
String tableId = key.contains(WidgetType.TABLE.getCode()) ? StrUtil.subBefore(key, ".", true) : null;
if (tableId != null) {
List<Map<String,Object>> tableBeforeData = (List<Map<String,Object>>)before.get(tableId);
List<Map<String,Object>> tableAfterData = (List<Map<String,Object>>)after.get(tableId);
FormDataLog.UpdateWidgetResult tableUpdateResult =
getTableColumnUpdateWidget(config.getTableColumns(),tableId,null,tableBeforeData,tableAfterData);
if(tableUpdateResult != null) {
results.add(tableUpdateResult);
}
} else {
FormDataLog.UpdateWidgetResult updateResult = getUpdateWidget(config, key, before, after);
if(updateResult != null) {
results.add(getUpdateWidget(config, key, before, after));
}
}
}
});
}
}
return results;
}
@Override
public FormDataLog.UpdateWidgetResult getUpdateWidget(FormWidget config,String widgetId,Map<String,Object> before,Map<String,Object> after) {
if(ObjectUtil.hasEmpty(config,widgetId) || ObjectUtil.isAllEmpty(before,after)){
return null;
}
if (flowChangedFields.contains(widgetId)) {
FormDataLog.UpdateWidgetResult result = new FormDataLog.UpdateWidgetResult(widgetId);
DefaultConverter converter = new DefaultConverter();
if (converter.checkChange(before.get(widgetId), after.get(widgetId))) {
String bef = new DefaultConverter().convert(before.get(widgetId), null);
String aft = new DefaultConverter().convert(after.get(widgetId), null);
result.setBef(bef);
result.setAft(aft);
return result;
}
}
BaseFormFieldConverter converter = FormFieldFactory.getConverter(config.getModel());
if(converter != null) {
FormDataLog.UpdateWidgetResult result = new FormDataLog.UpdateWidgetResult( config.getModel());
if(converter.checkChange(before.get(widgetId), after.get(widgetId))) {
String bData = converter.convert(before.get(widgetId), config);
String aData = converter.convert(after.get(widgetId), config);
result.setBef(bData);
result.setAft(aData);
return result;
}
}
return null;
}
@Override
public FormDataLog.UpdateWidgetResult getTableColumnUpdateWidget(List<FormWidget> config,
String tableId,
String subColumnId,
List<Map<String,Object>> before,
List<Map<String,Object>> after
) {
if(ObjectUtil.hasEmpty(config,tableId) || ObjectUtil.isAllEmpty(before,after)){
return null;
}
TableConverter tableConverter = new TableConverter(config);
FormDataLog.UpdateWidgetResult result = new FormDataLog.UpdateWidgetResult(tableId);
Map<String,List<Map<String,Object>>> updatedTableData = tableConverter.listUpdateData(subColumnId,before,after);
List<Map<String,Object>> befData = updatedTableData.get("before");
List<Map<String,Object>> afterData = updatedTableData.get("after");
if(CollUtil.isEmpty(befData) && CollUtil.isEmpty(afterData)){
return null;
}
if(CollUtil.isNotEmpty(befData)){
result.setBef(JsonUtil.toJson(befData));
}
if(CollUtil.isNotEmpty(afterData)){
result.setAft(JsonUtil.toJson(afterData));
}
return result;
}
private List<FormWidget> getFormWidgets(Long formId){
FormSourceResult formDetail = this.formSourceService.getFormSourceById(formId);
Map<String, Object> formJson = JsonUtil.jsonToMap(formDetail.getFormJson());
assert formJson != null;
List<FormWidget> columnWidgetList = JsonUtil.jsonToList(JsonUtil.toJson(formJson.get("list")), FormWidget.class);
if(CollUtil.isEmpty(columnWidgetList)){
log.error("###### 数据日志 update field widget not exist ######");
return null;
}
return columnWidgetList;
}
/**
* 历史数据修复专用方法后续会废弃
* @param before
* @param after
* @return
*/
@Override
public List<FormDataLog.UpdateWidgetResult> listUpdatedData(Map<String, Object> before, Map<String, Object> after) {
if(ObjectUtil.isAllNotEmpty(before,after)) {
List<FormDataLog.UpdateWidgetResult> results = new ArrayList<>();
after.keySet().forEach(widgetId -> {
FormDataLog.UpdateWidgetResult updateWidget = new FormDataLog.UpdateWidgetResult(widgetId);
if(flowChangedFields.contains(widgetId)){
DefaultConverter converter = new DefaultConverter();
if(converter.checkChange(before.get(widgetId),after.get(widgetId))) {
String bef = new DefaultConverter().convert(before.get(widgetId), null);
String aft = new DefaultConverter().convert(after.get(widgetId), null);
updateWidget.setBef(bef);
updateWidget.setAft(aft);
results.add(updateWidget);
}
}else{
BaseFormFieldConverter converter = FormFieldFactory.getConverter(widgetId);
if (converter != null) {
if(converter.checkChange(before.get(widgetId),after.get(widgetId))){
if(!StrUtil.contains(widgetId,WidgetType.TABLE.getCode())){
String bData = converter.convert(before.get(widgetId), null);
String aData = converter.convert(after.get(widgetId), null);
updateWidget.setBef(bData);
updateWidget.setAft(aData);
}else{
TableConverter tableConverter = (TableConverter)converter;
tableConverter.setFormWidgets(null);
Map<String,List<Map<String,Object>>> updatedTableData = tableConverter.listUpdateData(null,( List<Map<String,Object>>)before.get(widgetId),( List<Map<String,Object>>)after.get(widgetId));
List<Map<String,Object>> befData = updatedTableData.get("before");
List<Map<String,Object>> afterData = updatedTableData.get("after");
if(CollUtil.isNotEmpty(befData)){
updateWidget.setBef(JsonUtil.toJson(befData));
}
if(CollUtil.isNotEmpty(afterData)){
updateWidget.setAft(JsonUtil.toJson(afterData));
}
}
results.add(updateWidget);
}
}
}
});
return results;
}
return null;
}
public static void main(String[] args) {
System.out.println(" = " +JsonUtil.toJson(null) );
}
}

49
dk-common/common-workflow/src/main/java/org/dromara/dataManager/widget/convert/base/BaseFormFieldConverter.java

@ -1,49 +0,0 @@
package org.dromara.dataManager.widget.convert.base;
import cn.hutool.core.util.ObjectUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.dromara.taskCenter.model.FormWidget;
import java.util.Comparator;
import java.util.List;
/**
* @Description: 表单数据转化器基类
**/
@Slf4j
@Data
public abstract class BaseFormFieldConverter {
private FormWidget formWidget;
public String convert(Object data, FormWidget formWidget){
return "";
};
public Boolean checkChange(Object oldValue,Object newValue) {
return false;
}
/**
* 不相同时返回true
* @param oldSetData
* @param newSetData
* @return
*/
public static boolean comparingList(List<String> oldSetData, List<String> newSetData) {
List<String> oldData = ObjectUtil.cloneByStream(oldSetData);
List<String> newData = ObjectUtil.cloneByStream(newSetData);
oldData.sort(Comparator.comparing(String::hashCode));
newData.sort(Comparator.comparing(String::hashCode));
return !newData.toString().equals(oldData.toString());
}
}

82
dk-common/common-workflow/src/main/java/org/dromara/dataManager/widget/convert/base/FormFieldFactory.java

@ -1,82 +0,0 @@
package org.dromara.dataManager.widget.convert.base;
import org.dromara.dataManager.widget.convert.column.DefaultConverter;
import org.dromara.dataManager.widget.convert.enums.FormColumnType;
import org.dromara.workflow.engine.enums.ESDefaultFieldConst;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import java.util.Arrays;
import java.util.List;
@Slf4j
public class FormFieldFactory {
private static final String packageName = "org.dromara.dataManager.convert.column.{}";
public static final List<String> defaultFieldConst = Arrays.asList(ESDefaultFieldConst._ID,ESDefaultFieldConst.DID,
ESDefaultFieldConst.ID,
ESDefaultFieldConst.OWNER,ESDefaultFieldConst.CREATOR,ESDefaultFieldConst.CREATOR_ACCOUNT,ESDefaultFieldConst.CREATE_TIME,
ESDefaultFieldConst.UPDATE_TIME,ESDefaultFieldConst.UPDATOR_NAME,ESDefaultFieldConst.DELETED,
ESDefaultFieldConst.FLOW_INSTANCE_ID, ESDefaultFieldConst.FLOW_STAGE,
ESDefaultFieldConst.FLOW_TASK_ID, ESDefaultFieldConst.FLOW_NODE_TITLE, ESDefaultFieldConst.FLOW_CHECKER_NAME
);
public static BaseFormFieldConverter create(String columnType) throws InstantiationException,
IllegalAccessException {
FormColumnType formColumnType = FormColumnType.getByType(columnType);
if (formColumnType == null) {
return new DefaultConverter();
}
String columnName = columnType.substring(0, 1).toUpperCase() + columnType.substring(1)+"Converter";
try {
Class<?> clz = Class.forName(StrUtil.format(packageName, columnName));
return (BaseFormFieldConverter)clz.newInstance();
}catch (ClassNotFoundException e){
return new DefaultConverter();
}
}
public static BaseFormFieldConverter getConverter(String model){
if(!model.contains("_") || defaultFieldConst.contains(model)){
return null;
}
String filePrefix = model.substring(0, model.lastIndexOf("_"));
if(filePrefix.contains(".")){
filePrefix = StrUtil.subAfter(filePrefix,".",true);
}
FormColumnType formColumnType = FormColumnType.getByType(filePrefix);
if (formColumnType != null) {
try{
String columnName = filePrefix.substring(0, 1).toUpperCase() + filePrefix.substring(1)+"Converter";
try {
Class<?> clz = Class.forName(StrUtil.format(packageName, columnName));
return (BaseFormFieldConverter)clz.newInstance();
}catch (ClassNotFoundException e){
return new DefaultConverter();
}
}catch (Exception e){
}
}
return null;
}
}

41
dk-common/common-workflow/src/main/java/org/dromara/dataManager/widget/convert/column/CheckboxConverter.java

@ -1,41 +0,0 @@
package org.dromara.dataManager.widget.convert.column;
import org.dromara.dataManager.widget.convert.base.BaseFormFieldConverter;
import org.dromara.taskCenter.model.FormWidget;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.google.common.base.Joiner;
import java.util.List;
public class CheckboxConverter extends BaseFormFieldConverter {
@Override
public String convert(Object value, FormWidget widget) {
if (ObjectUtil.isEmpty(value)) {
return "";
}
List<String> checkBoxValue = (List<String>)value;
if(CollUtil.isNotEmpty(checkBoxValue)){
return Joiner.on("、").skipNulls().join(checkBoxValue);
}
return "";
}
@Override
public Boolean checkChange(Object oldValue,Object newValue) {
if(ObjectUtil.isEmpty(oldValue)){
return ObjectUtil.isNotEmpty(newValue);
}
if (!ObjectUtil.equal(oldValue,newValue) ) {
return true;
}
return comparingList((List<String>)oldValue,(List<String>)newValue);
}
}

96
dk-common/common-workflow/src/main/java/org/dromara/dataManager/widget/convert/column/CoordinatesConverter.java

@ -1,96 +0,0 @@
package org.dromara.dataManager.widget.convert.column;
import org.dromara.dataManager.widget.convert.base.BaseFormFieldConverter;
import org.dromara.taskCenter.model.FormWidget;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import java.util.Map;
public class CoordinatesConverter extends BaseFormFieldConverter {
@Override
public String convert(Object value, FormWidget widget) {
if (ObjectUtil.isEmpty(value)) {
return "";
}
if(value instanceof JSONObject) {
JSONObject data = (JSONObject)value;
if(ObjectUtil.isNotNull(data.get("address"))){
return (String) data.get("address");
}
}
if(value instanceof Map) {
Map<String, Object> data = (Map<String, Object>)value;
if(ObjectUtil.isNotNull(data.get("address"))){
return (String) data.get("address");
}
}
return "";
}
@Override
public Boolean checkChange(Object oldValue,Object newValue) {
if(ObjectUtil.isAllEmpty(oldValue,newValue)){
return false;
}
if (ObjectUtil.isEmpty(oldValue) && ObjectUtil.isNotEmpty(newValue)) {
return true;
}
if (ObjectUtil.isNotEmpty(oldValue) && ObjectUtil.isEmpty(newValue)) {
return true;
}
if(oldValue instanceof JSONObject){
JSONObject bef = (JSONObject)oldValue;
JSONObject aft = (JSONObject)newValue;
JSONObject befGeoPoint = (JSONObject)bef.get("geopoint");
JSONObject aftGeoPoint = (JSONObject)aft.get("geopoint");
if(!ObjectUtil.equal(befGeoPoint,aftGeoPoint) || !ObjectUtil.equal(bef.get("address"),aft.get("address"))){
return true;
}
if(befGeoPoint != null && aftGeoPoint != null){
return !(ObjectUtil.equal(bef.get("address"),aft.get("address"))
&& ObjectUtil.equal(befGeoPoint.get("lon"),aftGeoPoint.get("lon"))
&& ObjectUtil.equal(befGeoPoint.get("lat"),aftGeoPoint.get("lat")));
}
}
if(oldValue instanceof Map){
Map<String, Object> bef = (Map<String, Object>)oldValue;
Map<String, Object> aft = (Map<String, Object>)newValue;
Map<String, Object> befGeoPoint = (Map<String, Object>)bef.get("geopoint");
Map<String, Object> aftGeoPoint = (Map<String, Object>)aft.get("geopoint");
if(!ObjectUtil.equal(befGeoPoint,aftGeoPoint) || !ObjectUtil.equal(bef.get("address"),aft.get("address"))){
return true;
}
if(befGeoPoint != null && aftGeoPoint != null){
return ObjectUtil.equal(bef.get("address"),aft.get("address"))
&& ObjectUtil.equal(befGeoPoint.get("lon"),aftGeoPoint.get("lon"))
&& ObjectUtil.equal(befGeoPoint.get("lat"),aftGeoPoint.get("lat"));
}
}
return false;
}
}

35
dk-common/common-workflow/src/main/java/org/dromara/dataManager/widget/convert/column/DatalinkConverter.java

@ -1,35 +0,0 @@
package org.dromara.dataManager.widget.convert.column;
import org.dromara.dataManager.widget.convert.base.BaseFormFieldConverter;
import org.dromara.taskCenter.model.FormWidget;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import java.util.HashMap;
public class DatalinkConverter extends BaseFormFieldConverter {
@Override
public String convert(Object value, FormWidget widget) {
if (ObjectUtil.isEmpty(value)) {
return "";
}
return value.toString();
}
@Override
public Boolean checkChange(Object oldValue,Object newValue) {
if(ObjectUtil.isAllEmpty(oldValue,newValue)){
return false;
}
if(oldValue == null && ObjectUtil.isNotEmpty(newValue)){
HashMap<String, Object> dataMap = (HashMap<String, Object>) newValue;
return StrUtil.isNotEmpty((String)dataMap.get("id"));
}
return !ObjectUtil.equal(oldValue,newValue);
}
}

150
dk-common/common-workflow/src/main/java/org/dromara/dataManager/widget/convert/column/DateConverter.java

@ -1,150 +0,0 @@
package org.dromara.dataManager.widget.convert.column;
import org.dromara.dataManager.widget.convert.base.BaseFormFieldConverter;
import org.dromara.taskCenter.model.FormWidget;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
@Slf4j
public class DateConverter extends BaseFormFieldConverter {
@Override
public String convert(Object value, FormWidget widget) {
if (ObjectUtil.isEmpty(value) || StrUtil.equals("null",value.toString())) {
return "";
}
String formatOption = "yyyy-MM-dd HH:mm:ss";
if(widget != null){
formatOption = (String) widget.getOptions().get("format");
}
SimpleDateFormat defaultFormat = new SimpleDateFormat(formatOption);
try {
String dateTime = value.toString();
if(StrUtil.equals("0",dateTime) || dateTime.length() == 10){
return dateTime;
}
return convertTime2GMT08(dateTime,defaultFormat);
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
public Date converts(Object value, FormWidget widget){
if (ObjectUtil.isEmpty(value)) {
return null;
}
String dateTime = (String)value;
dateTime = dateTime.replace("Z", " UTC");
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS Z");
try {
return format.parse(dateTime);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
public Boolean checkChange(Object oldValue,Object newValue) {
if (!ObjectUtil.equal(oldValue,newValue) ) {
return true;
}
try{
String oldTimeValue = this.convert(oldValue,null);
String newTimeValue = this.convert(newValue,null);
return !StrUtil.equals(oldTimeValue,newTimeValue);
}catch (Exception e){
e.printStackTrace();
return false;
}
}
/**
* @description: 将带有0时区的字符串时间2021-09-22T03:00:00.000Z转换为东八区默认时间yyyy-MM-dd HH:mm:ss
*/
public static String convertTime2GMT08(String time,SimpleDateFormat sdf) throws ParseException {
//时间格式自己定义
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:sszzz");
TimeZone tz;
// 设置时区为"GMT+08:00"(需要输出时间的时区 )
tz = TimeZone.getTimeZone("GMT+08:00");
time = time.replace("+00:00","Z");
String msStr = StrUtil.subBetween(time,".","Z");
if(StrUtil.isNotEmpty(msStr)){
time = time.replace(StrUtil.format(".{}Z",msStr), "");
}
// 后面的+0000为国际时间,其它时区请自行更换 (如GMT+08:00 为+0800)
Date date = df.parse(time.replace("T"," ") + "+0000");
// 获取默认的DateFormat,用于格式化Date
if(sdf == null){
sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
}
// 设置时区为tz
sdf.setTimeZone(tz);
// 获取格式化后的字符串
return sdf.format(date);
}
public static String convertStr(Object date) {
String formatOption = "yyyy-MM-dd";
SimpleDateFormat defaultFormat = new SimpleDateFormat(formatOption);
if(date instanceof String){
String dateTime = (String)date;
dateTime = dateTime.replace("Z", " UTC");
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS Z");
try {
Date time = format.parse(dateTime);
return defaultFormat.format(time);
} catch (Exception e) {
e.printStackTrace();
}
}
if(date instanceof Date){
Date dateTime = (Date)date;
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
try {
return format.format(dateTime);
} catch (Exception e) {
}
}
return null;
}
public static void main(String[] args) {
try{
// "2022-02-13T16:00:00.000+00:00"
System.out.println(" = " + convertTime2GMT08("2022-02-13T16:00:00.123+00:00",null));
}catch (Exception e){
e.printStackTrace();
}
}
}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save