feat(REQ-3340) - 处理表单多种业务组件的保存和回显逻辑
This commit is contained in:
parent
4d39265ecd
commit
568bb07e31
@ -18,6 +18,10 @@ public enum FormInstanceRespCode implements IModuleRespCode {
|
||||
FORM_FIELD_VALIDATOR_ERROR("003", "表单字段校验不通过"),
|
||||
FORM_INSTANCE_PARSE_ERROR("004", "表单实例数据解析错误"),
|
||||
FORM_INSTANCE_DATA_NOT_FOUND("005", "未找到指定实例【{}】的表单数据"),
|
||||
FORM_DATA_PARSE_ERROR("006", "表单数据解析异常"),
|
||||
FORM_DATA_PARSE_ERROR_BY_UPLOAD("007", "表单上传组件的数据解析异常"),
|
||||
FORM_DATA_PARSE_ERROR_BY_IMAGE("008", "表单图片组件的数据解析异常"),
|
||||
|
||||
;
|
||||
|
||||
private final String code;
|
||||
|
||||
@ -17,4 +17,12 @@ public interface FormConstants {
|
||||
String FIELD_PROPERTY_HIDDEN = "hidden";
|
||||
|
||||
String FIELD_PROPERTY_DEFAULT_VALUE= "defaultValue";
|
||||
|
||||
String FORM_FIELD_TYPE_TEXTAREA = "textarea";
|
||||
String FORM_FIELD_TYPE_IMAGE = "image";
|
||||
String FORM_FIELD_TYPE_CUSTOM_COMPONENT = "customComponent";
|
||||
String FORM_FIELD_TYPE_TASK_ORDER = "taskOrder";
|
||||
String FORM_FIELD_TYPE_RECTIFY_ORDER = "rectifyOrder";
|
||||
String FORM_FIELD_TYPE_CHANGE_SIGNATURE_ORDER = "changeSignatureOrder";
|
||||
|
||||
}
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
package cn.axzo.workflow.common.model.dto;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
@ -14,7 +13,6 @@ import lombok.NoArgsConstructor;
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Deprecated // 这个类型不应该产生,建议后面迭代替换为 AttachmentDTO
|
||||
public class UploadFieldDTO {
|
||||
|
||||
/**
|
||||
@ -25,24 +23,11 @@ public class UploadFieldDTO {
|
||||
/**
|
||||
* 文件类型
|
||||
*/
|
||||
private String fileType;
|
||||
private String fileUrl;
|
||||
|
||||
/**
|
||||
* 文件 oss 的 key
|
||||
*/
|
||||
private String fileKey;
|
||||
|
||||
public String toString() {
|
||||
return JSON.toJSONString(this);
|
||||
}
|
||||
|
||||
public String toSpecString() {
|
||||
return this.toString().replaceAll(",", "|");
|
||||
}
|
||||
|
||||
public static UploadFieldDTO toObject(String str) {
|
||||
str = str.trim().replaceAll("\\|",",");
|
||||
return JSON.parseObject(str, UploadFieldDTO.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -3,10 +3,7 @@ package cn.axzo.workflow.common.model.request.bpmn.process;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@ -19,8 +16,11 @@ import java.util.Map;
|
||||
@Data
|
||||
public class BpmnProcessInstanceCreateWithFormDTO {
|
||||
|
||||
/**
|
||||
* todo 需要补充各种组件传入的模型文档
|
||||
*/
|
||||
@ApiModelProperty(value = "通过表单创建流程时传入的初始表单数据")
|
||||
private Map<String, Object> startFormVariables = new HashMap<>();
|
||||
private Map<String, Object> startFormVariables;
|
||||
/**
|
||||
* 工作流实例集成表单后,可以通过表单 key 组装成的变量存入该变量的值,可用于后续流程的流转
|
||||
* <p>
|
||||
|
||||
@ -65,4 +65,10 @@ public class AttachmentDTO implements Serializable {
|
||||
@IndexField(fieldType = FieldType.KEYWORD)
|
||||
private String url;
|
||||
|
||||
/**
|
||||
* 文件 OSS 的 fileKey
|
||||
*/
|
||||
@ApiModelProperty(value = "附件 oss 的 fileKey")
|
||||
private String fileKey;
|
||||
|
||||
}
|
||||
|
||||
@ -51,7 +51,7 @@ public class FormFieldDTO {
|
||||
* 部分组件是多值,比如日期区间,多选, 多附件
|
||||
*/
|
||||
@ApiModelProperty(value = "表单字段默认值", example = "account")
|
||||
private List<String> value;
|
||||
private Object value;
|
||||
|
||||
/**
|
||||
* 表单占位提示
|
||||
|
||||
@ -3,6 +3,7 @@ package cn.axzo.workflow.core.conf;
|
||||
import cn.axzo.workflow.core.common.utils.SpringContextUtils;
|
||||
import cn.axzo.workflow.core.engine.behavior.CustomActivityBehaviorFactory;
|
||||
import cn.axzo.workflow.core.engine.cmd.CustomCommandContextFactory;
|
||||
import cn.axzo.workflow.core.engine.formhandler.CustomFormFieldHandler;
|
||||
import cn.axzo.workflow.core.engine.id.BasedNacosSnowflakeIdGenerator;
|
||||
import cn.axzo.workflow.core.engine.interceptor.CustomRetryInterceptor;
|
||||
import cn.axzo.workflow.core.engine.job.AsyncAbortProcessInstanceJobHandler;
|
||||
@ -36,7 +37,6 @@ import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.common.engine.api.delegate.event.FlowableEventListener;
|
||||
import org.flowable.common.engine.impl.history.HistoryLevel;
|
||||
import org.flowable.form.engine.configurator.FormEngineConfigurator;
|
||||
import org.flowable.job.service.JobProcessor;
|
||||
import org.flowable.spring.SpringProcessEngineConfiguration;
|
||||
import org.flowable.spring.boot.EngineConfigurationConfigurer;
|
||||
@ -132,6 +132,9 @@ public class FlowableConfiguration {
|
||||
configuration.setCustomPreCommandInterceptors(Lists.newArrayList(
|
||||
new CustomRetryInterceptor()
|
||||
));
|
||||
// form configuration
|
||||
configuration.setFormFieldValidationEnabled(true);
|
||||
configuration.setFormFieldHandler(new CustomFormFieldHandler());
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -2,7 +2,6 @@ package cn.axzo.workflow.core.engine.cmd;
|
||||
|
||||
import cn.axzo.workflow.common.enums.BpmnFlowNodeType;
|
||||
import cn.axzo.workflow.common.exception.WorkflowEngineException;
|
||||
import cn.axzo.workflow.common.model.dto.UploadFieldDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.AttachmentDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditWithFormDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
|
||||
@ -13,7 +12,6 @@ import cn.axzo.workflow.core.repository.entity.ExtAxProcessLog;
|
||||
import cn.axzo.workflow.core.service.ExtAxBpmnFormRelationService;
|
||||
import cn.axzo.workflow.core.service.ExtAxProcessLogService;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.flowable.common.engine.impl.identity.Authentication;
|
||||
import org.flowable.common.engine.impl.interceptor.CommandContext;
|
||||
import org.flowable.engine.RuntimeService;
|
||||
@ -33,7 +31,6 @@ import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -211,19 +208,19 @@ public class CustomApproveTaskWithFormCmd extends AbstractCommand<Void> implemen
|
||||
.deploymentId(relation.getFormDeploymentId())
|
||||
.singleResult();
|
||||
Authentication.setAuthenticatedUserId(approver.buildAssigneeId());
|
||||
formVariables.entrySet().forEach(e -> {
|
||||
if (e.getValue() instanceof Collection) {
|
||||
List<String> convertUploads = ((Collection<?>) e.getValue()).stream().map(i -> {
|
||||
if (i instanceof String) {
|
||||
return UploadFieldDTO.toObject(String.valueOf(i)).toSpecString();
|
||||
} else {
|
||||
ObjectMapper objectMapper = SpringContextUtils.getBean(ObjectMapper.class);
|
||||
return objectMapper.convertValue(i, UploadFieldDTO.class).toSpecString();
|
||||
}
|
||||
}).collect(Collectors.toList());
|
||||
e.setValue(StringUtils.collectionToCommaDelimitedString(convertUploads));
|
||||
}
|
||||
});
|
||||
// formVariables.entrySet().forEach(e -> {
|
||||
// if (e.getValue() instanceof Collection) {
|
||||
// List<String> convertUploads = ((Collection<?>) e.getValue()).stream().map(i -> {
|
||||
// if (i instanceof String) {
|
||||
// return UploadFieldDTO.toObject(String.valueOf(i)).toSpecString();
|
||||
// } else {
|
||||
// ObjectMapper objectMapper = SpringContextUtils.getBean(ObjectMapper.class);
|
||||
// return objectMapper.convertValue(i, UploadFieldDTO.class).toSpecString();
|
||||
// }
|
||||
// }).collect(Collectors.toList());
|
||||
// e.setValue(StringUtils.collectionToCommaDelimitedString(convertUploads));
|
||||
// }
|
||||
// });
|
||||
taskService.completeTaskWithForm(taskId, formDefinition.getId(), null, formVariables);
|
||||
Authentication.setAuthenticatedUserId(null);
|
||||
} else {
|
||||
|
||||
@ -1,19 +1,44 @@
|
||||
package cn.axzo.workflow.core.engine.cmd;
|
||||
|
||||
import cn.axzo.workflow.common.model.dto.UploadFieldDTO;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.flowable.common.engine.api.FlowableException;
|
||||
import org.flowable.common.engine.api.delegate.Expression;
|
||||
import org.flowable.common.engine.impl.el.VariableContainerWrapper;
|
||||
import org.flowable.common.engine.impl.interceptor.CommandContext;
|
||||
import org.flowable.form.api.FormInstance;
|
||||
import org.flowable.form.api.FormInstanceInfo;
|
||||
import org.flowable.form.api.FormInstanceQuery;
|
||||
import org.flowable.form.engine.FormEngineConfiguration;
|
||||
import org.flowable.form.engine.impl.cmd.GetFormInstanceModelCmd;
|
||||
import org.flowable.form.engine.impl.util.CommandContextUtil;
|
||||
import org.flowable.form.model.ExpressionFormField;
|
||||
import org.flowable.form.model.FormField;
|
||||
import org.flowable.form.model.FormFieldTypes;
|
||||
import org.flowable.form.model.Option;
|
||||
import org.flowable.form.model.OptionFormField;
|
||||
import org.flowable.form.model.SimpleFormModel;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static cn.axzo.workflow.common.constant.FormConstants.FORM_FIELD_TYPE_CHANGE_SIGNATURE_ORDER;
|
||||
import static cn.axzo.workflow.common.constant.FormConstants.FORM_FIELD_TYPE_CUSTOM_COMPONENT;
|
||||
import static cn.axzo.workflow.common.constant.FormConstants.FORM_FIELD_TYPE_IMAGE;
|
||||
import static cn.axzo.workflow.common.constant.FormConstants.FORM_FIELD_TYPE_RECTIFY_ORDER;
|
||||
import static cn.axzo.workflow.common.constant.FormConstants.FORM_FIELD_TYPE_TASK_ORDER;
|
||||
|
||||
/**
|
||||
* 自定义的获取表单模型和最新表单内容的命令实现
|
||||
*
|
||||
@ -78,4 +103,208 @@ public class CustomGetFormInstanceModelCmd extends GetFormInstanceModelCmd {
|
||||
log.info("未查询到流程实例关联的表单实例数据");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillVariablesWithFormValues(Map<String, JsonNode> submittedFormFieldMap, List<FormField> allFields) {
|
||||
for (FormField field : allFields) {
|
||||
|
||||
JsonNode fieldValueNode = submittedFormFieldMap.get(field.getId());
|
||||
|
||||
if (fieldValueNode == null || fieldValueNode.isNull()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String fieldType = field.getType();
|
||||
String fieldValue = fieldValueNode.asText();
|
||||
|
||||
if (FormFieldTypes.DATE.equals(fieldType)) {
|
||||
try {
|
||||
if (org.apache.commons.lang3.StringUtils.isNotEmpty(fieldValue)) {
|
||||
LocalDate dateValue = LocalDate.parse(fieldValue);
|
||||
variables.put(field.getId(), dateValue.toString("d-M-yyyy"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Error parsing form date value for process instance {} and task {} with value {}", processInstanceId, taskId, fieldValue, e);
|
||||
}
|
||||
// } else if (FormFieldTypes.UPLOAD.equals(fieldType) || FormConstants.FORM_FIELD_TYPE_IMAGE.equals(fieldType)) {
|
||||
// FormEngineConfiguration formEngineConfiguration = CommandContextUtil.getFormEngineConfiguration();
|
||||
// ObjectMapper objectMapper = formEngineConfiguration.getObjectMapper();
|
||||
// try {
|
||||
// List<UploadFieldDTO> uploadFiles = objectMapper.readValue(fieldValue, new TypeReference<List<UploadFieldDTO>>() {
|
||||
// });
|
||||
// variables.put(field.getId(), uploadFiles);
|
||||
// } catch (JsonProcessingException e) {
|
||||
// throw new WorkflowEngineException(FORM_DATA_PARSE_ERROR_BY_UPLOAD);
|
||||
// }
|
||||
} else if (fieldValueNode.isBoolean()) {
|
||||
variables.put(field.getId(), fieldValueNode.asBoolean());
|
||||
|
||||
} else if (fieldValueNode.isLong()) {
|
||||
variables.put(field.getId(), fieldValueNode.asLong());
|
||||
|
||||
} else if (fieldValueNode.isDouble()) {
|
||||
variables.put(field.getId(), fieldValueNode.asDouble());
|
||||
|
||||
} else {
|
||||
variables.put(field.getId(), fieldValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fillFormInstanceValues(FormInstanceInfo formInstanceModel, FormInstance formInstance, Map<String, JsonNode> formInstanceFieldMap, ObjectMapper objectMapper) {
|
||||
try {
|
||||
JsonNode submittedNode = objectMapper.readTree(formInstance.getFormValueBytes());
|
||||
if (submittedNode == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (submittedNode.get("values") != null) {
|
||||
JsonNode valuesNode = submittedNode.get("values");
|
||||
Iterator<String> fieldIdIterator = valuesNode.fieldNames();
|
||||
while (fieldIdIterator.hasNext()) {
|
||||
String fieldId = fieldIdIterator.next();
|
||||
JsonNode valueNode = valuesNode.get(fieldId);
|
||||
formInstanceFieldMap.put(fieldId, valueNode);
|
||||
}
|
||||
}
|
||||
|
||||
if (submittedNode.get("flowable_form_outcome") != null) {
|
||||
JsonNode outcomeNode = submittedNode.get("flowable_form_outcome");
|
||||
if (!outcomeNode.isNull() && org.apache.commons.lang3.StringUtils.isNotEmpty(outcomeNode.asText())) {
|
||||
formInstanceModel.setSelectedOutcome(outcomeNode.asText());
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new FlowableException("Error parsing form instance " + formInstance.getId(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fillFormFieldValues(FormInstance formInstance, FormInstanceInfo formInstanceModel, CommandContext commandContext) {
|
||||
FormEngineConfiguration formEngineConfiguration = CommandContextUtil.getFormEngineConfiguration();
|
||||
SimpleFormModel formModel = (SimpleFormModel) formInstanceModel.getFormModel();
|
||||
List<FormField> allFields = formModel.listAllFields();
|
||||
if (allFields != null) {
|
||||
|
||||
Map<String, JsonNode> formInstanceFieldMap = new HashMap<>();
|
||||
if (formInstance != null) {
|
||||
fillFormInstanceValues(formInstanceModel, formInstance, formInstanceFieldMap, formEngineConfiguration.getObjectMapper());
|
||||
fillVariablesWithFormValues(formInstanceFieldMap, allFields);
|
||||
}
|
||||
|
||||
for (FormField field : allFields) {
|
||||
if (field instanceof OptionFormField) {
|
||||
OptionFormField optionFormField = (OptionFormField) field;
|
||||
if (optionFormField.getOptionsExpression() != null) {
|
||||
// Drop down options to be populated from an expression
|
||||
Expression optionsExpression = formEngineConfiguration.getExpressionManager().createExpression(optionFormField.getOptionsExpression());
|
||||
Object value = null;
|
||||
try {
|
||||
value = optionsExpression.getValue(new VariableContainerWrapper(variables));
|
||||
} catch (Exception e) {
|
||||
throw new FlowableException("Error getting value for optionsExpression: " + optionFormField.getOptionsExpression(), e);
|
||||
}
|
||||
if (value instanceof List) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Option> options = (List<Option>) value;
|
||||
optionFormField.setOptions(options);
|
||||
} else if (value instanceof String) {
|
||||
String json = (String) value;
|
||||
try {
|
||||
List<Option> options = formEngineConfiguration.getObjectMapper().readValue(json, new TypeReference<List<Option>>() {
|
||||
});
|
||||
optionFormField.setOptions(options);
|
||||
} catch (Exception e) {
|
||||
throw new FlowableException("Error parsing optionsExpression json value: " + json, e);
|
||||
}
|
||||
} else {
|
||||
throw new FlowableException("Invalid type from evaluated expression for optionsExpression: " + optionFormField.getOptionsExpression() + ", resulting type:" + value.getClass().getName());
|
||||
}
|
||||
}
|
||||
Object variableValue = variables.get(field.getId());
|
||||
optionFormField.setValue(variableValue);
|
||||
|
||||
} else if (FormFieldTypes.HYPERLINK.equals(field.getType())) {
|
||||
Object variableValue = variables.get(field.getId());
|
||||
// process expression if there is no value, otherwise keep it
|
||||
if (variableValue != null) {
|
||||
field.setValue(variableValue);
|
||||
} else {
|
||||
// No value set, process as expression
|
||||
if (field.getParam("hyperlinkUrl") != null) {
|
||||
String hyperlinkUrl = field.getParam("hyperlinkUrl").toString();
|
||||
Expression formExpression = formEngineConfiguration.getExpressionManager().createExpression(hyperlinkUrl);
|
||||
try {
|
||||
field.setValue(formExpression.getValue(new VariableContainerWrapper(variables)));
|
||||
} catch (Exception e) {
|
||||
log.error("Error getting value for hyperlink expression {} {}", hyperlinkUrl, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if (field instanceof ExpressionFormField) {
|
||||
ExpressionFormField expressionField = (ExpressionFormField) field;
|
||||
Expression formExpression = formEngineConfiguration.getExpressionManager().createExpression(expressionField.getExpression());
|
||||
try {
|
||||
field.setValue(formExpression.getValue(new VariableContainerWrapper(variables)));
|
||||
} catch (Exception e) {
|
||||
log.error("Error getting value for expression {} {}", expressionField.getExpression(), e.getMessage());
|
||||
}
|
||||
|
||||
} else if (FormFieldTypes.UPLOAD.equals(field.getType())
|
||||
|| FORM_FIELD_TYPE_IMAGE.equals(field.getType())) {
|
||||
|
||||
// Multiple docs are stored as comma-separated string ids,
|
||||
// explicitly storing them as an array so they're serialized properly
|
||||
if (variables.containsKey(field.getId())) {
|
||||
String uploadValue = (String) variables.get(field.getId());
|
||||
if (uploadValue != null) {
|
||||
try {
|
||||
List<UploadFieldDTO> uploadFiles = formEngineConfiguration.getObjectMapper()
|
||||
.readValue(uploadValue, new TypeReference<List<UploadFieldDTO>>() {
|
||||
});
|
||||
field.setValue(uploadFiles);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new FlowableException("Error parsing upload files json value: " + uploadValue, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (FORM_FIELD_TYPE_TASK_ORDER.equals(field.getType())
|
||||
|| FORM_FIELD_TYPE_RECTIFY_ORDER.equals(field.getType())
|
||||
|| FORM_FIELD_TYPE_CHANGE_SIGNATURE_ORDER.equals(field.getType())) {
|
||||
if (variables.containsKey(field.getId())) {
|
||||
String listValue = (String) variables.get(field.getId());
|
||||
if (listValue != null) {
|
||||
try {
|
||||
List<String> ids = formEngineConfiguration.getObjectMapper()
|
||||
.readValue(listValue, new TypeReference<List<String>>() {
|
||||
});
|
||||
field.setValue(ids);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new FlowableException("Error parsing business component ids json value: " + listValue, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (FORM_FIELD_TYPE_CUSTOM_COMPONENT.equals(field.getType())) {
|
||||
|
||||
} else {
|
||||
Object variableValue = variables.get(field.getId());
|
||||
if (variableValue != null) {
|
||||
|
||||
if (variableValue instanceof LocalDate) {
|
||||
field.setValue(((LocalDate) variableValue).toString("d-M-yyyy"));
|
||||
} else if (variableValue instanceof Date) {
|
||||
field.setValue(DATE_FORMAT.format(((Date) variableValue).toInstant()));
|
||||
} else {
|
||||
field.setValue(variableValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
field.setReadOnly(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,36 @@
|
||||
package cn.axzo.workflow.core.engine.formhandler;
|
||||
|
||||
import org.flowable.content.api.ContentService;
|
||||
import org.flowable.engine.impl.formhandler.DefaultFormFieldHandler;
|
||||
import org.flowable.engine.impl.util.CommandContextUtil;
|
||||
import org.flowable.form.api.FormFieldHandler;
|
||||
import org.flowable.form.api.FormInfo;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 自定义的具体的表单组件类型处理器
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2025-01-22 13:58
|
||||
*/
|
||||
public class CustomFormFieldHandler extends DefaultFormFieldHandler implements FormFieldHandler {
|
||||
@Override
|
||||
public void handleFormFieldsOnSubmit(FormInfo formInfo,
|
||||
String taskId,
|
||||
String processInstanceId,
|
||||
String scopeId,
|
||||
String scopeType,
|
||||
Map<String, Object> variables,
|
||||
String tenantId) {
|
||||
ContentService contentService = CommandContextUtil.getContentService();
|
||||
if (contentService == null || formInfo == null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enrichFormFields(FormInfo formInfo) {
|
||||
super.enrichFormFields(formInfo);
|
||||
}
|
||||
}
|
||||
@ -8,7 +8,6 @@ import cn.axzo.workflow.common.enums.BpmnFlowNodeType;
|
||||
import cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum;
|
||||
import cn.axzo.workflow.common.enums.WorkspaceType;
|
||||
import cn.axzo.workflow.common.exception.WorkflowEngineException;
|
||||
import cn.axzo.workflow.common.model.dto.UploadFieldDTO;
|
||||
import cn.axzo.workflow.common.model.request.BpmnApproveConf;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.BpmnButtonConf;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.BpmnButtonMetaInfo;
|
||||
@ -115,7 +114,6 @@ import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.validation.Valid;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
@ -422,25 +420,29 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
|
||||
|
||||
ExtAxBpmnFormRelation relation = bpmnFormRelationService.queryByBpmnDefinitionId(definition.getId());
|
||||
if (Objects.isNull(relation)) {
|
||||
// 如果模型没有绑定表单,则强制情况表单相关属性,避免报错
|
||||
// 如果模型没有绑定表单,则强制清空表单相关属性,避免异常
|
||||
instanceBuilder.outcome(null);
|
||||
} else {
|
||||
// TODO 可以使用 cn.axzo.workflow.core.service.impl.BpmnProcessDefinitionServiceImpl.getProcessDefinition 接口拉取模型后进行表单数据转型,字段验证的扩展实现
|
||||
// 关于表单目前只有两类组件,由于研发资源限制,暂不做扩展性设计
|
||||
dto.getStartFormVariables().entrySet().forEach(e -> {
|
||||
if (e.getValue() instanceof Collection) {
|
||||
List<String> convertUploads = ((Collection<?>) e.getValue()).stream().map(i -> {
|
||||
if (i instanceof String) {
|
||||
return UploadFieldDTO.toObject(String.valueOf(i)).toSpecString();
|
||||
} else {
|
||||
return objectMapper.convertValue(i, UploadFieldDTO.class).toSpecString();
|
||||
}
|
||||
}).collect(Collectors.toList());
|
||||
e.setValue(StringUtils.collectionToCommaDelimitedString(convertUploads));
|
||||
}
|
||||
});
|
||||
instanceBuilder.startFormVariables(dto.getStartFormVariables())
|
||||
.outcome(dto.getOutcome());
|
||||
// // TODO 可以使用 cn.axzo.workflow.core.service.impl.BpmnProcessDefinitionServiceImpl.getProcessDefinition 接口拉取模型后进行表单数据转型,字段验证的扩展实现
|
||||
// // 关于表单目前只有两类组件,由于研发资源限制,暂不做扩展性设计
|
||||
// dto.getStartFormVariables().entrySet().forEach(e -> {
|
||||
// if (e.getValue() instanceof Collection) {
|
||||
// List<String> convertUploads = ((Collection<?>) e.getValue()).stream().map(i -> {
|
||||
// if (i instanceof String) {
|
||||
// return UploadFieldDTO.toObject(String.valueOf(i)).toSpecString();
|
||||
// } else {
|
||||
// return objectMapper.convertValue(i, UploadFieldDTO.class).toSpecString();
|
||||
// }
|
||||
// }).collect(Collectors.toList());
|
||||
// e.setValue(StringUtils.collectionToCommaDelimitedString(convertUploads));
|
||||
// }
|
||||
// });
|
||||
if (!CollectionUtils.isEmpty(dto.getStartFormVariables())) {
|
||||
instanceBuilder.startFormVariables(dto.getStartFormVariables());
|
||||
}
|
||||
if (StringUtils.hasText(dto.getOutcome())) {
|
||||
instanceBuilder.outcome(dto.getOutcome());
|
||||
}
|
||||
}
|
||||
dto.getVariables().put(CREATE_INSTANCE_PARAMS, JSONUtil.toJsonStr(dto));
|
||||
instanceBuilder.variables(dto.getVariables());
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package cn.axzo.workflow.form.conf;
|
||||
|
||||
import cn.axzo.workflow.form.engine.api.CustomFormServiceImpl;
|
||||
import org.flowable.form.spring.SpringFormEngineConfiguration;
|
||||
import org.flowable.spring.boot.EngineConfigurationConfigurer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@ -18,6 +19,9 @@ public class FormFlowableConfiguration {
|
||||
|
||||
@Bean
|
||||
public EngineConfigurationConfigurer<SpringFormEngineConfiguration> formEngineConfigurer() {
|
||||
return configuration -> configuration.setDatabaseSchemaUpdate(DB_SCHEMA_UPDATE_TRUE);
|
||||
return configuration -> {
|
||||
configuration.setDatabaseSchemaUpdate(DB_SCHEMA_UPDATE_TRUE);
|
||||
configuration.setFormService(new CustomFormServiceImpl(configuration));
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,43 @@
|
||||
package cn.axzo.workflow.form.engine.api;
|
||||
|
||||
import cn.axzo.workflow.form.engine.cmd.CustomCreateFormInstanceCmd;
|
||||
import cn.axzo.workflow.form.engine.cmd.CustomGetVariablesFromFormSubmissionCmd;
|
||||
import org.flowable.form.api.FormInfo;
|
||||
import org.flowable.form.api.FormInstance;
|
||||
import org.flowable.form.engine.FormEngineConfiguration;
|
||||
import org.flowable.form.engine.impl.FormServiceImpl;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 自定义扩展表单引擎中的 FormService
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2025-01-22 11:19
|
||||
*/
|
||||
public class CustomFormServiceImpl extends FormServiceImpl {
|
||||
public CustomFormServiceImpl(FormEngineConfiguration engineConfiguration) {
|
||||
super(engineConfiguration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateFormFields(FormInfo formInfo, Map<String, Object> values) {
|
||||
// StartEvent Form Fields Validation
|
||||
super.validateFormFields(formInfo, values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FormInstance createFormInstance(Map<String, Object> variables, FormInfo formInfo, String taskId, String processInstanceId, String processDefinitionId, String tenantId, String outcome) {
|
||||
return commandExecutor.execute(new CustomCreateFormInstanceCmd(formInfo, variables, taskId, processInstanceId, processDefinitionId, tenantId, outcome));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getVariablesFromFormSubmission(FormInfo formInfo, Map<String, Object> values) {
|
||||
return commandExecutor.execute(new CustomGetVariablesFromFormSubmissionCmd(formInfo, values));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getVariablesFromFormSubmission(FormInfo formInfo, Map<String, Object> values, String outcome) {
|
||||
return commandExecutor.execute(new CustomGetVariablesFromFormSubmissionCmd(formInfo, values, outcome));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,158 @@
|
||||
package cn.axzo.workflow.form.engine.cmd;
|
||||
|
||||
import cn.axzo.workflow.common.exception.WorkflowEngineException;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import org.flowable.common.engine.api.FlowableException;
|
||||
import org.flowable.common.engine.impl.identity.Authentication;
|
||||
import org.flowable.common.engine.impl.interceptor.CommandContext;
|
||||
import org.flowable.form.api.FormInfo;
|
||||
import org.flowable.form.api.FormInstance;
|
||||
import org.flowable.form.engine.FormEngineConfiguration;
|
||||
import org.flowable.form.engine.impl.cmd.CreateFormInstanceCmd;
|
||||
import org.flowable.form.engine.impl.persistence.entity.FormInstanceEntity;
|
||||
import org.flowable.form.engine.impl.persistence.entity.FormInstanceEntityManager;
|
||||
import org.flowable.form.engine.impl.util.CommandContextUtil;
|
||||
import org.flowable.form.model.FormField;
|
||||
import org.flowable.form.model.FormFieldTypes;
|
||||
import org.flowable.form.model.SimpleFormModel;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.axzo.workflow.common.code.FormInstanceRespCode.FORM_DATA_PARSE_ERROR_BY_UPLOAD;
|
||||
|
||||
/**
|
||||
* 覆盖表单引擎的创建表单实例的命令
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2025-01-22 16:52
|
||||
*/
|
||||
public class CustomCreateFormInstanceCmd extends CreateFormInstanceCmd {
|
||||
public CustomCreateFormInstanceCmd(FormInfo formInfo, Map<String, Object> variables, String taskId, String processInstanceId, String processDefinitionId, String tenantId, String outcome) {
|
||||
super(formInfo, variables, taskId, processInstanceId, processDefinitionId, tenantId, outcome);
|
||||
}
|
||||
|
||||
public CustomCreateFormInstanceCmd(String formModelId, Map<String, Object> variables, String taskId, String processInstanceId, String processDefinitionId, String tenantId, String outcome) {
|
||||
super(formModelId, variables, taskId, processInstanceId, processDefinitionId, tenantId, outcome);
|
||||
}
|
||||
|
||||
public CustomCreateFormInstanceCmd(FormInfo formInfo, Map<String, Object> variables, String taskId, String scopeId, String scopeType, String scopeDefinitionId, String tenantId, String outcome) {
|
||||
super(formInfo, variables, taskId, scopeId, scopeType, scopeDefinitionId, tenantId, outcome);
|
||||
}
|
||||
|
||||
public CustomCreateFormInstanceCmd(String formModelId, Map<String, Object> variables, String taskId, String scopeId, String scopeType, String scopeDefinitionId, String tenantId, String outcome) {
|
||||
super(formModelId, variables, taskId, scopeId, scopeType, scopeDefinitionId, tenantId, outcome);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FormInstance execute(CommandContext commandContext) {
|
||||
FormEngineConfiguration formEngineConfiguration = CommandContextUtil.getFormEngineConfiguration();
|
||||
if (formInfo == null) {
|
||||
if (formModelId == null) {
|
||||
throw new FlowableException("Invalid form model and no form model Id provided");
|
||||
}
|
||||
formInfo = CommandContextUtil.getFormEngineConfiguration().getFormRepositoryService().getFormModelById(formModelId);
|
||||
}
|
||||
|
||||
if (formInfo == null || formInfo.getId() == null) {
|
||||
throw new FlowableException("Invalid form model provided");
|
||||
}
|
||||
|
||||
ObjectMapper objectMapper = formEngineConfiguration.getObjectMapper();
|
||||
ObjectNode submittedFormValuesJson = objectMapper.createObjectNode();
|
||||
|
||||
ObjectNode valuesNode = submittedFormValuesJson.putObject("values");
|
||||
|
||||
// Loop over all form fields and see if a value was provided
|
||||
|
||||
SimpleFormModel formModel = (SimpleFormModel) formInfo.getFormModel();
|
||||
Map<String, FormField> fieldMap = formModel.allFieldsAsMap();
|
||||
for (String fieldId : fieldMap.keySet()) {
|
||||
FormField formField = fieldMap.get(fieldId);
|
||||
|
||||
if (FormFieldTypes.EXPRESSION.equals(formField.getType()) || FormFieldTypes.CONTAINER.equals(formField.getType())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (variables != null && variables.containsKey(fieldId)) {
|
||||
Object variableValue = variables.get(fieldId);
|
||||
if (variableValue == null) {
|
||||
valuesNode.putNull(fieldId);
|
||||
} else if (variableValue instanceof Long) {
|
||||
valuesNode.put(fieldId, (Long) variables.get(fieldId));
|
||||
|
||||
} else if (variableValue instanceof Double) {
|
||||
valuesNode.put(fieldId, (Double) variables.get(fieldId));
|
||||
|
||||
} else if (variableValue instanceof Boolean) {
|
||||
valuesNode.put(fieldId, (Boolean) variables.get(fieldId));
|
||||
|
||||
} else if (variableValue instanceof LocalDate) {
|
||||
valuesNode.put(fieldId, ((LocalDate) variableValue).toString());
|
||||
} else if (variableValue instanceof Collection) {
|
||||
if (CollectionUtils.isEmpty((Collection<?>) variableValue)) {
|
||||
variableValue = Collections.emptyList();
|
||||
}
|
||||
try {
|
||||
valuesNode.put(fieldId, objectMapper.writeValueAsString(variableValue));
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new WorkflowEngineException(FORM_DATA_PARSE_ERROR_BY_UPLOAD);
|
||||
}
|
||||
} else {
|
||||
valuesNode.put(fieldId, variableValue.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (outcome != null) {
|
||||
submittedFormValuesJson.put("flowable_form_outcome", outcome);
|
||||
}
|
||||
|
||||
FormInstanceEntityManager formInstanceEntityManager = CommandContextUtil.getFormInstanceEntityManager(commandContext);
|
||||
FormInstanceEntity formInstanceEntity = findExistingFormInstance(formEngineConfiguration);
|
||||
|
||||
if (formInstanceEntity == null) {
|
||||
formInstanceEntity = formInstanceEntityManager.create();
|
||||
}
|
||||
|
||||
formInstanceEntity.setFormDefinitionId(formInfo.getId());
|
||||
formInstanceEntity.setTaskId(taskId);
|
||||
|
||||
if (processInstanceId != null) {
|
||||
formInstanceEntity.setProcessInstanceId(processInstanceId);
|
||||
formInstanceEntity.setProcessDefinitionId(processDefinitionId);
|
||||
|
||||
} else {
|
||||
formInstanceEntity.setScopeId(scopeId);
|
||||
formInstanceEntity.setScopeType(scopeType);
|
||||
formInstanceEntity.setScopeDefinitionId(scopeDefinitionId);
|
||||
}
|
||||
|
||||
formInstanceEntity.setSubmittedDate(formEngineConfiguration.getClock().getCurrentTime());
|
||||
formInstanceEntity.setSubmittedBy(Authentication.getAuthenticatedUserId());
|
||||
|
||||
if (tenantId != null) {
|
||||
formInstanceEntity.setTenantId(tenantId);
|
||||
}
|
||||
|
||||
try {
|
||||
formInstanceEntity.setFormValueBytes(objectMapper.writeValueAsBytes(submittedFormValuesJson));
|
||||
} catch (Exception e) {
|
||||
throw new FlowableException("Error setting form values JSON", e);
|
||||
}
|
||||
|
||||
if (formInstanceEntity.getId() == null) {
|
||||
formInstanceEntityManager.insert(formInstanceEntity);
|
||||
} else {
|
||||
formInstanceEntityManager.update(formInstanceEntity);
|
||||
}
|
||||
|
||||
|
||||
return formInstanceEntity;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,113 @@
|
||||
package cn.axzo.workflow.form.engine.cmd;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.math.NumberUtils;
|
||||
import org.flowable.common.engine.impl.interceptor.CommandContext;
|
||||
import org.flowable.form.api.FormInfo;
|
||||
import org.flowable.form.engine.FormEngineConfiguration;
|
||||
import org.flowable.form.engine.impl.cmd.GetVariablesFromFormSubmissionCmd;
|
||||
import org.flowable.form.engine.impl.util.CommandContextUtil;
|
||||
import org.flowable.form.model.FormField;
|
||||
import org.flowable.form.model.FormFieldTypes;
|
||||
import org.joda.time.LocalDate;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 覆盖表单引擎自带的表单提交处理命令
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2025-01-22 15:20
|
||||
*/
|
||||
public class CustomGetVariablesFromFormSubmissionCmd extends GetVariablesFromFormSubmissionCmd {
|
||||
|
||||
public CustomGetVariablesFromFormSubmissionCmd(FormInfo formInfo, Map<String, Object> values) {
|
||||
super(formInfo, values);
|
||||
}
|
||||
|
||||
public CustomGetVariablesFromFormSubmissionCmd(FormInfo formInfo, Map<String, Object> values, String outcome) {
|
||||
super(formInfo, values, outcome);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> execute(CommandContext commandContext) {
|
||||
return super.execute(commandContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object transformFormFieldValueToVariableValue(FormField formField, Object formFieldValue) {
|
||||
Object result = formFieldValue;
|
||||
if (formField.getType().equals(FormFieldTypes.DATE) && formFieldValue instanceof String) {
|
||||
if (StringUtils.isNotEmpty((String) formFieldValue)) {
|
||||
try {
|
||||
result = LocalDate.parse((String) formFieldValue);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
result = null;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (formField.getType().equals(FormFieldTypes.DATE) && formFieldValue instanceof Date) {
|
||||
result = new LocalDate(formFieldValue);
|
||||
} else if (formField.getType().equals(FormFieldTypes.INTEGER) && formFieldValue instanceof String) {
|
||||
String strFieldValue = (String) formFieldValue;
|
||||
if (StringUtils.isNotEmpty(strFieldValue) && NumberUtils.isCreatable(strFieldValue)) {
|
||||
result = Long.valueOf(strFieldValue);
|
||||
|
||||
} else {
|
||||
result = null;
|
||||
}
|
||||
|
||||
} else if (formField.getType().equals(FormFieldTypes.DECIMAL) && formFieldValue instanceof String) {
|
||||
String strFieldValue = (String) formFieldValue;
|
||||
if (StringUtils.isNotEmpty(strFieldValue) && NumberUtils.isCreatable(strFieldValue)) {
|
||||
result = Double.valueOf(strFieldValue);
|
||||
|
||||
} else {
|
||||
result = null;
|
||||
}
|
||||
|
||||
} else if (formField.getType().equals(FormFieldTypes.AMOUNT) && formFieldValue instanceof String) {
|
||||
try {
|
||||
result = Double.parseDouble((String) formFieldValue);
|
||||
|
||||
} catch (NumberFormatException e) {
|
||||
result = null;
|
||||
}
|
||||
|
||||
} else if (formField.getType().equals(FormFieldTypes.DROPDOWN) || formField.getType().equals(FormFieldTypes.RADIO_BUTTONS)) {
|
||||
if (formFieldValue instanceof Map<?, ?>) {
|
||||
result = ((Map<?, ?>) formFieldValue).get("id");
|
||||
if (result == null) {
|
||||
// fallback to name for manual config options
|
||||
result = ((Map<?, ?>) formFieldValue).get("name");
|
||||
}
|
||||
}
|
||||
|
||||
} else if (formField.getType().equals(FormFieldTypes.UPLOAD)) {
|
||||
FormEngineConfiguration formEngineConfiguration = CommandContextUtil.getFormEngineConfiguration();
|
||||
try {
|
||||
String json = formEngineConfiguration.getObjectMapper().writeValueAsString(formFieldValue);
|
||||
result = json;
|
||||
} catch (JsonProcessingException e) {
|
||||
result = null;
|
||||
}
|
||||
|
||||
} else if (formField.getType().equals(FormFieldTypes.PEOPLE) || formField.getType().equals(FormFieldTypes.FUNCTIONAL_GROUP)) {
|
||||
if (formFieldValue instanceof Map<?, ?>) {
|
||||
Map<String, Object> value = (Map<String, Object>) formFieldValue;
|
||||
result = value.get("id").toString();
|
||||
|
||||
} else {
|
||||
// Incorrect or empty map, ignore
|
||||
result = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Default: no processing needs to be done, can be stored as-is
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,5 @@
|
||||
package cn.axzo.workflow.form.service.converter;
|
||||
|
||||
import cn.axzo.workflow.common.model.dto.UploadFieldDTO;
|
||||
import cn.axzo.workflow.common.model.request.form.definition.FormFieldDTO;
|
||||
import cn.axzo.workflow.common.model.response.form.instance.FormInstanceVO;
|
||||
import cn.axzo.workflow.common.model.response.form.model.FormModelVO;
|
||||
@ -8,17 +7,13 @@ import org.flowable.form.api.FormInstanceInfo;
|
||||
import org.flowable.form.api.FormModel;
|
||||
import org.flowable.form.model.FormContainer;
|
||||
import org.flowable.form.model.FormField;
|
||||
import org.flowable.form.model.FormFieldTypes;
|
||||
import org.flowable.form.model.SimpleFormModel;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.mapstruct.NullValueCheckStrategy.ALWAYS;
|
||||
@ -78,24 +73,10 @@ public interface FormInstanceConverter extends EntityConverter<FormInstanceVO, F
|
||||
return formFieldDTO;
|
||||
}
|
||||
|
||||
default List<String> castList(FormField field) {
|
||||
List<String> values = new ArrayList<>();
|
||||
default List<Object> castList(FormField field) {
|
||||
List<Object> values = new ArrayList<>();
|
||||
Object value = field.getValue();
|
||||
if (Objects.isNull(value)) {
|
||||
return values;
|
||||
}
|
||||
if (Objects.equals(field.getType(), FormFieldTypes.UPLOAD)) {
|
||||
return ((Collection<String>) field.getValue()).stream()
|
||||
.filter(StringUtils::hasText)
|
||||
.map(i -> UploadFieldDTO.toObject(i).toString())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
if (value instanceof Collection) {
|
||||
return (List<String>) value;
|
||||
}
|
||||
if (value instanceof String) {
|
||||
values.add((String) value);
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user