mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2025-01-19 03:30:06 +08:00
仿钉钉流程设计- 流程表单字段权限测试
This commit is contained in:
parent
9456d461f9
commit
1e30e4851a
@ -0,0 +1,26 @@
|
||||
package cn.iocoder.yudao.module.bpm.enums.definition;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* BPM 表单权限的枚举
|
||||
*
|
||||
* @author jason
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum BpmFieldPermissionEnum {
|
||||
|
||||
EDITABLE(1, "可编辑"),
|
||||
READONLY(2, "只读"),
|
||||
HIDE(3, "隐藏");
|
||||
|
||||
private final Integer permission;
|
||||
private final String name;
|
||||
|
||||
public static BpmFieldPermissionEnum valueOf(Integer permission) {
|
||||
return ArrayUtil.firstMatch(item -> item.getPermission().equals(permission), values());
|
||||
}
|
||||
}
|
@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*;
|
||||
import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert;
|
||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
|
||||
import cn.iocoder.yudao.module.bpm.service.definition.BpmFormService;
|
||||
import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
|
||||
import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
|
||||
import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
|
||||
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
||||
@ -19,6 +20,7 @@ import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.flowable.bpmn.model.BpmnModel;
|
||||
import org.flowable.bpmn.model.UserTask;
|
||||
import org.flowable.engine.history.HistoricProcessInstance;
|
||||
import org.flowable.engine.runtime.ProcessInstance;
|
||||
@ -50,6 +52,8 @@ public class BpmTaskController {
|
||||
private BpmProcessInstanceService processInstanceService;
|
||||
@Resource
|
||||
private BpmFormService formService;
|
||||
@Resource
|
||||
private BpmProcessDefinitionService bpmProcessDefinitionService;
|
||||
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
@ -134,8 +138,10 @@ public class BpmTaskController {
|
||||
// 获得 Form Map
|
||||
Map<Long, BpmFormDO> formMap = formService.getFormMap(
|
||||
convertSet(taskList, task -> NumberUtils.parseLong(task.getFormKey())));
|
||||
// 获得 BpmnModel
|
||||
BpmnModel bpmnModel = bpmProcessDefinitionService.getProcessDefinitionBpmnModel(processInstance.getProcessDefinitionId());
|
||||
return success(BpmTaskConvert.INSTANCE.buildTaskListByProcessInstanceId(taskList, processInstance,
|
||||
formMap, userMap, deptMap));
|
||||
formMap, userMap, deptMap,bpmnModel));
|
||||
}
|
||||
|
||||
@PutMapping("/approve")
|
||||
|
@ -13,6 +13,7 @@ import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
|
||||
import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenTaskCreatedReqDTO;
|
||||
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import org.flowable.bpmn.model.BpmnModel;
|
||||
import org.flowable.engine.history.HistoricProcessInstance;
|
||||
import org.flowable.engine.runtime.ProcessInstance;
|
||||
import org.flowable.task.api.Task;
|
||||
@ -81,7 +82,8 @@ public interface BpmTaskConvert {
|
||||
HistoricProcessInstance processInstance,
|
||||
Map<Long, BpmFormDO> formMap,
|
||||
Map<Long, AdminUserRespDTO> userMap,
|
||||
Map<Long, DeptRespDTO> deptMap) {
|
||||
Map<Long, DeptRespDTO> deptMap,
|
||||
BpmnModel bpmnModel) {
|
||||
List<BpmTaskRespVO> taskVOList = CollectionUtils.convertList(taskList, task -> {
|
||||
BpmTaskRespVO taskVO = BeanUtils.toBean(task, BpmTaskRespVO.class);
|
||||
taskVO.setStatus(FlowableUtils.getTaskStatus(task)).setReason(FlowableUtils.getTaskReason(task));
|
||||
@ -92,6 +94,10 @@ public interface BpmTaskConvert {
|
||||
// 表单信息
|
||||
BpmFormDO form = MapUtil.get(formMap, NumberUtils.parseLong(task.getFormKey()), BpmFormDO.class);
|
||||
if (form != null) {
|
||||
// 测试一下权限处理
|
||||
// List<String> afterChangedFields = BpmnFormUtils.changeCreateFormFiledPermissionRule(form.getFields(),
|
||||
// BpmnModelUtils.parseFormFieldsPermission(bpmnModel, task.getTaskDefinitionKey()));
|
||||
|
||||
taskVO.setFormId(form.getId()).setFormName(form.getName()).setFormConf(form.getConf())
|
||||
.setFormFields(form.getFields()).setFormVariables(FlowableUtils.getTaskFormVariable(task));
|
||||
}
|
||||
|
@ -0,0 +1,24 @@
|
||||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.enums;
|
||||
|
||||
/**
|
||||
* 仿钉钉快搭 JSON 常量信息
|
||||
*
|
||||
* @author jason
|
||||
*/
|
||||
public interface SimpleModelConstants {
|
||||
|
||||
/**
|
||||
* 流程表单字段权限, 用于标记字段权限
|
||||
*/
|
||||
String FIELDS_PERMISSION = "fieldsPermission";
|
||||
|
||||
/**
|
||||
* 字段属性
|
||||
*/
|
||||
String FIELD_ATTRIBUTE = "field";
|
||||
|
||||
/**
|
||||
* 权限属性
|
||||
*/
|
||||
String PERMISSION_ATTRIBUTE = "permission";
|
||||
}
|
@ -1,9 +1,12 @@
|
||||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.util;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants;
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.SimpleModelConstants;
|
||||
import org.flowable.bpmn.converter.BpmnXMLConverter;
|
||||
import org.flowable.bpmn.model.Process;
|
||||
import org.flowable.bpmn.model.*;
|
||||
@ -11,6 +14,9 @@ import org.flowable.common.engine.impl.util.io.BytesStreamSource;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.SimpleModelConstants.FIELD_ATTRIBUTE;
|
||||
import static org.flowable.bpmn.constants.BpmnXMLConstants.FLOWABLE_EXTENSIONS_NAMESPACE;
|
||||
|
||||
/**
|
||||
* 流程模型转操作工具类
|
||||
*/
|
||||
@ -38,6 +44,23 @@ public class BpmnModelUtils {
|
||||
return candidateParam;
|
||||
}
|
||||
|
||||
public static Map<String,Integer> parseFormFieldsPermission(BpmnModel bpmnModel, String flowElementId) {
|
||||
FlowElement flowElement = getFlowElementById(bpmnModel, flowElementId);
|
||||
if (flowElement == null) {
|
||||
return null;
|
||||
}
|
||||
final HashMap<String, Integer> fieldsPermission = MapUtil.newHashMap();
|
||||
List<ExtensionElement> extensionElements = flowElement.getExtensionElements().get(SimpleModelConstants.FIELDS_PERMISSION);
|
||||
extensionElements.forEach(el -> {
|
||||
String field = el.getAttributeValue(FLOWABLE_EXTENSIONS_NAMESPACE, FIELD_ATTRIBUTE);
|
||||
String permission = el.getAttributeValue(FLOWABLE_EXTENSIONS_NAMESPACE, SimpleModelConstants.PERMISSION_ATTRIBUTE);
|
||||
if (StrUtil.isNotEmpty(field) && StrUtil.isNotEmpty(permission)) {
|
||||
fieldsPermission.put(field, Integer.parseInt(permission));
|
||||
}
|
||||
});
|
||||
return fieldsPermission;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据节点,获取入口连线
|
||||
*
|
||||
|
@ -1,6 +1,8 @@
|
||||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.util;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.lang.TypeReference;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
@ -8,11 +10,13 @@ import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.simple.BpmSimp
|
||||
import cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModelNodeType;
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants;
|
||||
import org.flowable.bpmn.BpmnAutoLayout;
|
||||
import org.flowable.bpmn.model.*;
|
||||
import org.flowable.bpmn.model.Process;
|
||||
import org.flowable.bpmn.model.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.SimpleModelConstants.FIELDS_PERMISSION;
|
||||
import static org.flowable.bpmn.constants.BpmnXMLConstants.FLOWABLE_EXTENSIONS_NAMESPACE;
|
||||
import static org.flowable.bpmn.constants.BpmnXMLConstants.FLOWABLE_EXTENSIONS_PREFIX;
|
||||
|
||||
@ -202,15 +206,20 @@ public class SimpleModelUtils {
|
||||
serviceTask.setName(node.getName());
|
||||
// TODO @jason:建议使用 ServiceTask,通过 executionListeners 实现;
|
||||
// @芋艿 ServiceTask 就可以了吧。 不需要 executionListeners
|
||||
addExtensionElement(node, serviceTask);
|
||||
addCandidateElements(node, serviceTask);
|
||||
|
||||
return serviceTask;
|
||||
}
|
||||
|
||||
private static void addExtensionElement(BpmSimpleModelNodeVO node, FlowElement flowElement) {
|
||||
|
||||
/**
|
||||
* 给节点添加候选人元素
|
||||
*/
|
||||
private static void addCandidateElements(BpmSimpleModelNodeVO node, FlowElement flowElement) {
|
||||
Integer candidateStrategy = MapUtil.getInt(node.getAttributes(), BpmnModelConstants.USER_TASK_CANDIDATE_STRATEGY);
|
||||
addExtensionElement(flowElement, FLOWABLE_EXTENSIONS_NAMESPACE, BpmnModelConstants.USER_TASK_CANDIDATE_STRATEGY,
|
||||
addExtensionElement(flowElement, BpmnModelConstants.USER_TASK_CANDIDATE_STRATEGY,
|
||||
candidateStrategy == null ? null : String.valueOf(candidateStrategy));
|
||||
addExtensionElement(flowElement, FLOWABLE_EXTENSIONS_NAMESPACE, BpmnModelConstants.USER_TASK_CANDIDATE_PARAM,
|
||||
addExtensionElement(flowElement, BpmnModelConstants.USER_TASK_CANDIDATE_PARAM,
|
||||
MapUtil.getStr(node.getAttributes(), BpmnModelConstants.USER_TASK_CANDIDATE_PARAM));
|
||||
}
|
||||
|
||||
@ -245,16 +254,48 @@ public class SimpleModelUtils {
|
||||
UserTask userTask = new UserTask();
|
||||
userTask.setId(node.getId());
|
||||
userTask.setName(node.getName());
|
||||
addExtensionElement(node, userTask);
|
||||
// TODO 暂时测试,后面去掉
|
||||
userTask.setFormKey("24");
|
||||
// 添加候选人元素
|
||||
addCandidateElements(node, userTask);
|
||||
// 添加表单字段权限属性元素
|
||||
addFormFieldsPermission(node, userTask);
|
||||
return userTask;
|
||||
}
|
||||
|
||||
private static void addExtensionElement(FlowElement element, String namespace, String name, String value) {
|
||||
/**
|
||||
* 给节点添加表单字段权限元素
|
||||
*/
|
||||
private static void addFormFieldsPermission(BpmSimpleModelNodeVO node, FlowElement flowElement) {
|
||||
List<Map<String, String>> fieldsPermissions = MapUtil.get(node.getAttributes(),
|
||||
FIELDS_PERMISSION, new TypeReference<>() {});
|
||||
if (CollUtil.isNotEmpty(fieldsPermissions)) {
|
||||
fieldsPermissions.forEach(item -> addExtensionElement(flowElement, FIELDS_PERMISSION, item));
|
||||
}
|
||||
}
|
||||
|
||||
private static void addExtensionElement(FlowElement element, String name, Map<String, String> attributes) {
|
||||
if (attributes == null) {
|
||||
return;
|
||||
}
|
||||
ExtensionElement extensionElement = new ExtensionElement();
|
||||
extensionElement.setNamespace(FLOWABLE_EXTENSIONS_NAMESPACE);
|
||||
extensionElement.setNamespacePrefix(FLOWABLE_EXTENSIONS_PREFIX);
|
||||
extensionElement.setName(name);
|
||||
attributes.forEach((key, value) -> {
|
||||
ExtensionAttribute extensionAttribute = new ExtensionAttribute(key, value);
|
||||
extensionAttribute.setNamespace(FLOWABLE_EXTENSIONS_NAMESPACE);
|
||||
extensionElement.addAttribute(extensionAttribute);
|
||||
});
|
||||
element.addExtensionElement(extensionElement);
|
||||
}
|
||||
|
||||
private static void addExtensionElement(FlowElement element, String name, String value) {
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
ExtensionElement extensionElement = new ExtensionElement();
|
||||
extensionElement.setNamespace(namespace);
|
||||
extensionElement.setNamespace(FLOWABLE_EXTENSIONS_NAMESPACE);
|
||||
extensionElement.setNamespacePrefix(FLOWABLE_EXTENSIONS_PREFIX);
|
||||
extensionElement.setElementText(value);
|
||||
extensionElement.setName(name);
|
||||
|
@ -0,0 +1,68 @@
|
||||
package cn.iocoder.yudao.module.bpm.service.util;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||
import cn.iocoder.yudao.module.bpm.enums.definition.BpmFieldPermissionEnum;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.SimpleModelConstants.FIELD_ATTRIBUTE;
|
||||
|
||||
/**
|
||||
* Bpmn 流程表单相关工具方法
|
||||
*
|
||||
* @author jason
|
||||
*/
|
||||
public class BpmnFormUtils {
|
||||
private static final String CREATE_FORM_DISPLAY_ATTRIBUTE = "display";
|
||||
private static final String CREATE_FORM_DISABLED_ATTRIBUTE = "disabled";
|
||||
|
||||
/**
|
||||
* 修改 form-create 表单组件字段权限规则: 包括可编辑、只读、隐藏规则
|
||||
* @param fields 字段规则
|
||||
* @param fieldsPermission 字段权限
|
||||
* @return 修改权限后的字段规则
|
||||
*/
|
||||
public static List<String> changeCreateFormFiledPermissionRule(List<String> fields, Map<String,Integer> fieldsPermission) {
|
||||
if ( CollUtil.isEmpty(fields) || MapUtil.isEmpty(fieldsPermission)) {
|
||||
return fields;
|
||||
}
|
||||
List<String> afterChangedFields = new ArrayList<>(fields.size());
|
||||
fields.forEach( f-> {
|
||||
Map<String, Object> fieldMap = JsonUtils.parseObject(f, new TypeReference<>() {});
|
||||
String field = ObjUtil.defaultIfNull(fieldMap.get(FIELD_ATTRIBUTE), Object::toString, "");
|
||||
if (StrUtil.isEmpty(field) || !fieldsPermission.containsKey(field)) {
|
||||
afterChangedFields.add(f);
|
||||
return;
|
||||
}
|
||||
BpmFieldPermissionEnum fieldPermission = BpmFieldPermissionEnum.valueOf(fieldsPermission.get(field));
|
||||
Assert.notNull(fieldPermission, "字段权限不匹配");
|
||||
if (BpmFieldPermissionEnum.HIDE == fieldPermission) {
|
||||
fieldMap.put(CREATE_FORM_DISPLAY_ATTRIBUTE, Boolean.FALSE);
|
||||
} else if (BpmFieldPermissionEnum.EDITABLE == fieldPermission){
|
||||
Map<String, Object> props = MapUtil.get(fieldMap, "props", new cn.hutool.core.lang.TypeReference<>() {});
|
||||
if (props == null) {
|
||||
props = MapUtil.newHashMap();
|
||||
fieldMap.put("props", props);
|
||||
}
|
||||
props.put(CREATE_FORM_DISABLED_ATTRIBUTE, Boolean.FALSE);
|
||||
} else if (BpmFieldPermissionEnum.READONLY == fieldPermission) {
|
||||
Map<String, Object> props = MapUtil.get(fieldMap, "props", new cn.hutool.core.lang.TypeReference<>() {});
|
||||
if (props == null) {
|
||||
props = MapUtil.newHashMap();
|
||||
fieldMap.put("props", props);
|
||||
}
|
||||
props.put(CREATE_FORM_DISABLED_ATTRIBUTE, Boolean.TRUE);
|
||||
}
|
||||
afterChangedFields.add(JsonUtils.toJsonString(fieldMap));
|
||||
});
|
||||
return afterChangedFields;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user