【功能新增】工作流:流程模型修改时,校验是否为流程的管理员

This commit is contained in:
YunaiV 2024-10-03 20:16:32 +08:00
parent 90ced26b01
commit 9cc8e0d37f
5 changed files with 51 additions and 34 deletions

View File

@ -23,6 +23,7 @@ public interface ErrorCodeConstants {
"原因:用户任务({})未配置审批人,请点击【流程设计】按钮,选择该它的【任务(审批人)】进行配置"); "原因:用户任务({})未配置审批人,请点击【流程设计】按钮,选择该它的【任务(审批人)】进行配置");
ErrorCode MODEL_DEPLOY_FAIL_BPMN_START_EVENT_NOT_EXISTS = new ErrorCode(1_009_002_005, "部署流程失败原因BPMN 流程图中,没有开始事件"); ErrorCode MODEL_DEPLOY_FAIL_BPMN_START_EVENT_NOT_EXISTS = new ErrorCode(1_009_002_005, "部署流程失败原因BPMN 流程图中,没有开始事件");
ErrorCode MODEL_DEPLOY_FAIL_BPMN_USER_TASK_NAME_NOT_EXISTS = new ErrorCode(1_009_002_006, "部署流程失败原因BPMN 流程图中,用户任务({})的名字不存在"); ErrorCode MODEL_DEPLOY_FAIL_BPMN_USER_TASK_NAME_NOT_EXISTS = new ErrorCode(1_009_002_006, "部署流程失败原因BPMN 流程图中,用户任务({})的名字不存在");
ErrorCode MODEL_UPDATE_FAIL_NOT_MANAGER = new ErrorCode(1_009_002_007, "操作流程失败,原因:你不是该流程的管理员");
// ========== 流程定义 1-009-003-000 ========== // ========== 流程定义 1-009-003-000 ==========
ErrorCode PROCESS_DEFINITION_KEY_NOT_MATCH = new ErrorCode(1_009_003_000, "流程定义的标识期望是({}),当前是({}),请修改 BPMN 流程图"); ErrorCode PROCESS_DEFINITION_KEY_NOT_MATCH = new ErrorCode(1_009_003_000, "流程定义的标识期望是({}),当前是({}),请修改 BPMN 流程图");

View File

@ -4,7 +4,6 @@ import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*;
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO;
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelUpdateReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelUpdateReqVO;
@ -36,8 +35,8 @@ import java.util.Set;
import java.util.stream.Stream; import java.util.stream.Stream;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
@Tag(name = "管理后台 - 流程模型") @Tag(name = "管理后台 - 流程模型")
@RestController @RestController
@ -68,7 +67,7 @@ public class BpmModelController {
// 拼接数据 // 拼接数据
// 获得 Form 表单 // 获得 Form 表单
Set<Long> formIds = convertSet(pageResult.getList(), model -> { Set<Long> formIds = convertSet(pageResult.getList(), model -> {
BpmModelMetaInfoVO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoVO.class); BpmModelMetaInfoVO metaInfo = BpmModelConvert.INSTANCE.parseMetaInfo(model);
return metaInfo != null ? metaInfo.getFormId() : null; return metaInfo != null ? metaInfo.getFormId() : null;
}); });
Map<Long, BpmFormDO> formMap = formService.getFormMap(formIds); Map<Long, BpmFormDO> formMap = formService.getFormMap(formIds);
@ -83,8 +82,8 @@ public class BpmModelController {
List<ProcessDefinition> processDefinitions = processDefinitionService.getProcessDefinitionListByDeploymentIds(deploymentIds); List<ProcessDefinition> processDefinitions = processDefinitionService.getProcessDefinitionListByDeploymentIds(deploymentIds);
Map<String, ProcessDefinition> processDefinitionMap = convertMap(processDefinitions, ProcessDefinition::getDeploymentId); Map<String, ProcessDefinition> processDefinitionMap = convertMap(processDefinitions, ProcessDefinition::getDeploymentId);
// 获得 User Map // 获得 User Map
Set<Long> userIds = CollectionUtils.convertSetByFlatMap(pageResult.getList(), model -> { Set<Long> userIds = convertSetByFlatMap(pageResult.getList(), model -> {
BpmModelMetaInfoVO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoVO.class); BpmModelMetaInfoVO metaInfo = BpmModelConvert.INSTANCE.parseMetaInfo(model);
return metaInfo != null ? metaInfo.getStartUserIds().stream() : Stream.empty(); return metaInfo != null ? metaInfo.getStartUserIds().stream() : Stream.empty();
}); });
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds); Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds);
@ -116,7 +115,7 @@ public class BpmModelController {
@Operation(summary = "修改模型") @Operation(summary = "修改模型")
@PreAuthorize("@ss.hasPermission('bpm:model:update')") @PreAuthorize("@ss.hasPermission('bpm:model:update')")
public CommonResult<Boolean> updateModel(@Valid @RequestBody BpmModelSaveReqVO modelVO) { public CommonResult<Boolean> updateModel(@Valid @RequestBody BpmModelSaveReqVO modelVO) {
modelService.updateModel(modelVO); modelService.updateModel(getLoginUserId(), modelVO);
return success(true); return success(true);
} }
@ -125,7 +124,7 @@ public class BpmModelController {
@Parameter(name = "id", description = "编号", required = true, example = "1024") @Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('bpm:model:deploy')") @PreAuthorize("@ss.hasPermission('bpm:model:deploy')")
public CommonResult<Boolean> deployModel(@RequestParam("id") String id) { public CommonResult<Boolean> deployModel(@RequestParam("id") String id) {
modelService.deployModel(id); modelService.deployModel(getLoginUserId(), id);
return success(true); return success(true);
} }
@ -133,7 +132,7 @@ public class BpmModelController {
@Operation(summary = "修改模型的状态", description = "实际更新的部署的流程定义的状态") @Operation(summary = "修改模型的状态", description = "实际更新的部署的流程定义的状态")
@PreAuthorize("@ss.hasPermission('bpm:model:update')") @PreAuthorize("@ss.hasPermission('bpm:model:update')")
public CommonResult<Boolean> updateModelState(@Valid @RequestBody BpmModelUpdateStateReqVO reqVO) { public CommonResult<Boolean> updateModelState(@Valid @RequestBody BpmModelUpdateStateReqVO reqVO) {
modelService.updateModelState(reqVO.getId(), reqVO.getState()); modelService.updateModelState(getLoginUserId(), reqVO.getId(), reqVO.getState());
return success(true); return success(true);
} }
@ -150,7 +149,7 @@ public class BpmModelController {
@Parameter(name = "id", description = "编号", required = true, example = "1024") @Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('bpm:model:delete')") @PreAuthorize("@ss.hasPermission('bpm:model:delete')")
public CommonResult<Boolean> deleteModel(@RequestParam("id") String id) { public CommonResult<Boolean> deleteModel(@RequestParam("id") String id) {
modelService.deleteModel(id); modelService.deleteModel(getLoginUserId(), id);
return success(true); return success(true);
} }
@ -167,7 +166,7 @@ public class BpmModelController {
@Operation(summary = "保存仿钉钉流程设计模型") @Operation(summary = "保存仿钉钉流程设计模型")
@PreAuthorize("@ss.hasPermission('bpm:model:update')") @PreAuthorize("@ss.hasPermission('bpm:model:update')")
public CommonResult<Boolean> updateSimpleModel(@Valid @RequestBody BpmSimpleModelUpdateReqVO reqVO) { public CommonResult<Boolean> updateSimpleModel(@Valid @RequestBody BpmSimpleModelUpdateReqVO reqVO) {
modelService.updateSimpleModel(reqVO); modelService.updateSimpleModel(getLoginUserId(), reqVO);
return success(Boolean.TRUE); return success(Boolean.TRUE);
} }

View File

@ -42,7 +42,7 @@ public interface BpmModelConvert {
Map<String, ProcessDefinition> processDefinitionMap, Map<String, ProcessDefinition> processDefinitionMap,
Map<Long, AdminUserRespDTO> userMap) { Map<Long, AdminUserRespDTO> userMap) {
List<BpmModelRespVO> list = convertList(pageResult.getList(), model -> { List<BpmModelRespVO> list = convertList(pageResult.getList(), model -> {
BpmModelMetaInfoVO metaInfo = buildMetaInfo(model); BpmModelMetaInfoVO metaInfo = parseMetaInfo(model);
BpmFormDO form = metaInfo != null ? formMap.get(metaInfo.getFormId()) : null; BpmFormDO form = metaInfo != null ? formMap.get(metaInfo.getFormId()) : null;
BpmCategoryDO category = categoryMap.get(model.getCategory()); BpmCategoryDO category = categoryMap.get(model.getCategory());
Deployment deployment = model.getDeploymentId() != null ? deploymentMap.get(model.getDeploymentId()) : null; Deployment deployment = model.getDeploymentId() != null ? deploymentMap.get(model.getDeploymentId()) : null;
@ -55,7 +55,7 @@ public interface BpmModelConvert {
default BpmModelRespVO buildModel(Model model, default BpmModelRespVO buildModel(Model model,
byte[] bpmnBytes) { byte[] bpmnBytes) {
BpmModelMetaInfoVO metaInfo = buildMetaInfo(model); BpmModelMetaInfoVO metaInfo = parseMetaInfo(model);
BpmModelRespVO modelVO = buildModel0(model, metaInfo, null, null, null, null, null); BpmModelRespVO modelVO = buildModel0(model, metaInfo, null, null, null, null, null);
if (ArrayUtil.isNotEmpty(bpmnBytes)) { if (ArrayUtil.isNotEmpty(bpmnBytes)) {
modelVO.setBpmnXml(BpmnModelUtils.getBpmnXml(bpmnBytes)); modelVO.setBpmnXml(BpmnModelUtils.getBpmnXml(bpmnBytes));
@ -100,7 +100,7 @@ public interface BpmModelConvert {
model.setMetaInfo(JsonUtils.toJsonString(BeanUtils.toBean(reqVO, BpmModelMetaInfoVO.class))); model.setMetaInfo(JsonUtils.toJsonString(BeanUtils.toBean(reqVO, BpmModelMetaInfoVO.class)));
} }
default BpmModelMetaInfoVO buildMetaInfo(Model model) { default BpmModelMetaInfoVO parseMetaInfo(Model model) {
return JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoVO.class); return JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoVO.class);
} }

View File

@ -59,31 +59,35 @@ public interface BpmModelService {
/** /**
* 修改流程模型 * 修改流程模型
* *
* @param userId 用户编号
* @param updateReqVO 更新信息 * @param updateReqVO 更新信息
*/ */
void updateModel(@Valid BpmModelSaveReqVO updateReqVO); void updateModel(Long userId, @Valid BpmModelSaveReqVO updateReqVO);
/** /**
* 将流程模型部署成一个流程定义 * 将流程模型部署成一个流程定义
* *
* @param userId 用户编号
* @param id 编号 * @param id 编号
*/ */
void deployModel(String id); void deployModel(Long userId, String id);
/** /**
* 删除模型 * 删除模型
* *
* @param userId 用户编号
* @param id 编号 * @param id 编号
*/ */
void deleteModel(String id); void deleteModel(Long userId, String id);
/** /**
* 修改模型的状态实际更新的部署的流程定义的状态 * 修改模型的状态实际更新的部署的流程定义的状态
* *
* @param userId 用户编号
* @param id 编号 * @param id 编号
* @param state 状态 * @param state 状态
*/ */
void updateModelState(String id, Integer state); void updateModelState(Long userId, String id, Integer state);
/** /**
* 获得流程定义编号对应的 BPMN Model * 获得流程定义编号对应的 BPMN Model
@ -106,10 +110,9 @@ public interface BpmModelService {
/** /**
* 更新仿钉钉流程设计模型 * 更新仿钉钉流程设计模型
* *
* @param userId 用户编号
* @param reqVO 请求信息 * @param reqVO 请求信息
*/ */
void updateSimpleModel(@Valid BpmSimpleModelUpdateReqVO reqVO); void updateSimpleModel(Long userId, @Valid BpmSimpleModelUpdateReqVO reqVO);
// TODO @jason另外个问题因为是存储到 modelExtra 那需要 deploy 存储出快照 bpmn xml 一样目前我想到的就是存储到 BpmProcessDefinitionInfoDO 加一个 simple_model 字段text 类型可以看看还有啥方案重要
} }

View File

@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.bpm.service.definition; package cn.iocoder.yudao.module.bpm.service.definition;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
@ -109,9 +110,9 @@ public class BpmModelServiceImpl implements BpmModelService {
@Override @Override
@Transactional(rollbackFor = Exception.class) // 因为进行多个操作所以开启事务 @Transactional(rollbackFor = Exception.class) // 因为进行多个操作所以开启事务
public void updateModel(@Valid BpmModelSaveReqVO updateReqVO) { public void updateModel(Long userId, @Valid BpmModelSaveReqVO updateReqVO) {
// 1. 校验流程模型存在 // 1. 校验流程模型存在
Model model = validateModelExists(updateReqVO.getId()); Model model = validateModelManager(updateReqVO.getId(), userId);
// 修改流程定义 // 修改流程定义
BpmModelConvert.INSTANCE.copyToModel(model, updateReqVO); BpmModelConvert.INSTANCE.copyToModel(model, updateReqVO);
@ -127,19 +128,32 @@ public class BpmModelServiceImpl implements BpmModelService {
return model; return model;
} }
// // 更新 BPMN XML /**
// saveModelBpmnXml(model.getId(), updateReqVO.getBpmnXml()); * 校验是否有流程模型的管理权限
*
* @param id 流程模型编号
* @param userId 用户编号
* @return 流程模型
*/
private Model validateModelManager(String id, Long userId) {
Model model = validateModelExists(id);
BpmModelMetaInfoVO metaInfo = BpmModelConvert.INSTANCE.parseMetaInfo(model);
if (metaInfo == null || !CollUtil.contains(metaInfo.getManagerUserIds(), userId)) {
throw exception(MODEL_UPDATE_FAIL_NOT_MANAGER);
}
return model;
}
@Override @Override
@Transactional(rollbackFor = Exception.class) // 因为进行多个操作所以开启事务 @Transactional(rollbackFor = Exception.class) // 因为进行多个操作所以开启事务
public void deployModel(String id) { public void deployModel(Long userId, String id) {
// 1.1 校验流程模型存在 // 1.1 校验流程模型存在
Model model = validateModelExists(id); Model model = validateModelManager(id, userId);
// 1.2 校验流程图 // 1.2 校验流程图
byte[] bpmnBytes = getModelBpmnXML(model.getId()); byte[] bpmnBytes = getModelBpmnXML(model.getId());
validateBpmnXml(bpmnBytes); validateBpmnXml(bpmnBytes);
// 1.3 校验表单已配 // 1.3 校验表单已配
BpmModelMetaInfoVO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoVO.class); BpmModelMetaInfoVO metaInfo = BpmModelConvert.INSTANCE.parseMetaInfo(model);
BpmFormDO form = validateFormConfig(metaInfo); BpmFormDO form = validateFormConfig(metaInfo);
// 1.4 校验任务分配规则已配置 // 1.4 校验任务分配规则已配置
taskCandidateInvoker.validateBpmnConfig(bpmnBytes); taskCandidateInvoker.validateBpmnConfig(bpmnBytes);
@ -179,9 +193,9 @@ public class BpmModelServiceImpl implements BpmModelService {
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void deleteModel(String id) { public void deleteModel(Long userId, String id) {
// 校验流程模型存在 // 校验流程模型存在
Model model = validateModelExists(id); Model model = validateModelManager(id, userId);
// 执行删除 // 执行删除
repositoryService.deleteModel(id); repositoryService.deleteModel(id);
@ -190,9 +204,9 @@ public class BpmModelServiceImpl implements BpmModelService {
} }
@Override @Override
public void updateModelState(String id, Integer state) { public void updateModelState(Long userId, String id, Integer state) {
// 1.1 校验流程模型存在 // 1.1 校验流程模型存在
Model model = validateModelExists(id); Model model = validateModelManager(id, userId);
// 1.2 校验流程定义存在 // 1.2 校验流程定义存在
ProcessDefinition definition = processDefinitionService.getProcessDefinitionByDeploymentId(model.getDeploymentId()); ProcessDefinition definition = processDefinitionService.getProcessDefinitionByDeploymentId(model.getDeploymentId());
if (definition == null) { if (definition == null) {
@ -217,9 +231,9 @@ public class BpmModelServiceImpl implements BpmModelService {
} }
@Override @Override
public void updateSimpleModel(BpmSimpleModelUpdateReqVO reqVO) { public void updateSimpleModel(Long userId, BpmSimpleModelUpdateReqVO reqVO) {
// 1. 校验流程模型存在 // 1. 校验流程模型存在
Model model = validateModelExists(reqVO.getId()); Model model = validateModelManager(reqVO.getId(), userId);
// 2.1 JSON 转换成 bpmnModel // 2.1 JSON 转换成 bpmnModel
BpmnModel bpmnModel = SimpleModelUtils.buildBpmnModel(model.getKey(), model.getName(), reqVO.getSimpleModel()); BpmnModel bpmnModel = SimpleModelUtils.buildBpmnModel(model.getKey(), model.getName(), reqVO.getSimpleModel());