refactor(bpm): 重构流程附件功能
- 新增 resolveEntityType 方法动态解析实体类型 -优化 updateAttachment 方法,增加日志记录和异常处理 - 移除 BpmProcessInstanceController 中的静态实体类型映射 - 使用服务层方法统一处理实体类型解析和附件更新
This commit is contained in:
parent
b8339c9056
commit
a71cd74ecc
@ -1,10 +1,8 @@
|
||||
package cn.iocoder.yudao.module.bpm.controller.admin.task;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.exception.ServiceException;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.oa.BpmOALeaveController;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.attachment.BpmOAAttachmentReqVO;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.print.BpmProcessInstancePrintDataReqVO;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.print.BpmProcessInstancePrintDataRespVO;
|
||||
@ -12,16 +10,7 @@ import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO;
|
||||
import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert;
|
||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.financialpayment.FinancialPaymentDO;
|
||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOALeaveDO;
|
||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAPetitionDO;
|
||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAReimbursementDO;
|
||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOASealDO;
|
||||
import cn.iocoder.yudao.module.bpm.dal.mysql.oa.BpmOALeaveMapper;
|
||||
import cn.iocoder.yudao.module.bpm.dal.mysql.oa.BpmOAPetitionMapper;
|
||||
import cn.iocoder.yudao.module.bpm.dal.mysql.oa.BpmOAReimbursementMapper;
|
||||
import cn.iocoder.yudao.module.bpm.dal.mysql.oa.BpmOASealMapper;
|
||||
import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
|
||||
import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum;
|
||||
import cn.iocoder.yudao.module.bpm.service.financialpayment.FinancialPaymentService;
|
||||
import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService;
|
||||
import cn.iocoder.yudao.module.bpm.service.oa.BpmOAAttachmentService;
|
||||
@ -36,26 +25,21 @@ import org.flowable.engine.runtime.ProcessInstance;
|
||||
import org.flowable.task.api.Task;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
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.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
@Tag(name = "管理后台 - 流程实例") // 流程实例,通过流程定义创建的一次“申请”
|
||||
@Tag(name = "管理后台 - 流程实例") // 流程实例,通过流程定义创建的一次"申请"
|
||||
@RestController
|
||||
@RequestMapping("/bpm/process-instance")
|
||||
@Validated
|
||||
@ -78,6 +62,9 @@ public class BpmProcessInstanceController {
|
||||
@Resource
|
||||
private FinancialPaymentService financialPaymentService;
|
||||
|
||||
@Resource
|
||||
private BpmOAAttachmentService bpmOAAttachmentService;
|
||||
|
||||
@GetMapping("/my-page")
|
||||
@Operation(summary = "获得我的实例分页列表", description = "在【我的流程】菜单中,进行调用")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:process-instance:query')")
|
||||
@ -210,69 +197,14 @@ public class BpmProcessInstanceController {
|
||||
return success(processInstanceService.getOAReportPrintData(reqVO));
|
||||
}
|
||||
|
||||
private final Map<String, List> entityTypeMap = new ConcurrentHashMap<>();
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
// 注册支持的实体类型
|
||||
entityTypeMap.put("oa_reimbursement", new ArrayList<Class<?>>(Arrays.asList(BpmOAReimbursementDO.class, BpmOAReimbursementMapper.class)));
|
||||
entityTypeMap.put("oa_seal", new ArrayList<Class<?>>(Arrays.asList(BpmOASealDO.class, BpmOASealMapper.class)));
|
||||
entityTypeMap.put("oa_contract", new ArrayList<Class<?>>(Arrays.asList(BpmOASealDO.class, BpmOASealMapper.class)));
|
||||
entityTypeMap.put("oa_leave", new ArrayList<Class<?>>(Arrays.asList(BpmOALeaveDO.class, BpmOALeaveMapper.class)));
|
||||
entityTypeMap.put("oa_cash", new ArrayList<Class<?>>(Arrays.asList(BpmOAPetitionDO.class, BpmOAPetitionMapper.class)));
|
||||
entityTypeMap.put("oa_overtime", new ArrayList<Class<?>>(Arrays.asList(BpmOAPetitionDO.class, BpmOAPetitionMapper.class)));
|
||||
entityTypeMap.put("oa_regular", new ArrayList<Class<?>>(Arrays.asList(BpmOAPetitionDO.class, BpmOAPetitionMapper.class)));
|
||||
entityTypeMap.put("oa_shiftjobs", new ArrayList<Class<?>>(Arrays.asList(BpmOAPetitionDO.class, BpmOAPetitionMapper.class)));
|
||||
|
||||
entityTypeMap.put("oa_second", new ArrayList<Class<?>>(Arrays.asList(BpmOAPetitionDO.class, BpmOAPetitionMapper.class)));
|
||||
entityTypeMap.put("oa_evection", new ArrayList<Class<?>>(Arrays.asList(BpmOAPetitionDO.class, BpmOAPetitionMapper.class)));
|
||||
entityTypeMap.put("oa_procure", new ArrayList<Class<?>>(Arrays.asList(BpmOAPetitionDO.class, BpmOAPetitionMapper.class)));
|
||||
entityTypeMap.put("oa_procure_pay", new ArrayList<Class<?>>(Arrays.asList(BpmOAPetitionDO.class, BpmOAPetitionMapper.class)));
|
||||
entityTypeMap.put("oa_imprest", new ArrayList<Class<?>>(Arrays.asList(BpmOAPetitionDO.class, BpmOAPetitionMapper.class)));
|
||||
entityTypeMap.put("oa_incentive", new ArrayList<Class<?>>(Arrays.asList(BpmOAPetitionDO.class, BpmOAPetitionMapper.class)));
|
||||
entityTypeMap.put("work_task", new ArrayList<Class<?>>(Arrays.asList(BpmOAPetitionDO.class, BpmOAPetitionMapper.class)));
|
||||
entityTypeMap.put("oa_entry", new ArrayList<Class<?>>(Arrays.asList(BpmOAPetitionDO.class, BpmOAPetitionMapper.class)));
|
||||
entityTypeMap.put("oa_overtime", new ArrayList<Class<?>>(Arrays.asList(BpmOAPetitionDO.class, BpmOAPetitionMapper.class)));
|
||||
|
||||
entityTypeMap.put("oa_regular", new ArrayList<Class<?>>(Arrays.asList(BpmOAPetitionDO.class, BpmOAPetitionMapper.class)));
|
||||
entityTypeMap.put("oa_incentive", new ArrayList<Class<?>>(Arrays.asList(BpmOAPetitionDO.class, BpmOAPetitionMapper.class)));
|
||||
entityTypeMap.put("oa_salary", new ArrayList<Class<?>>(Arrays.asList(BpmOAPetitionDO.class, BpmOAPetitionMapper.class)));
|
||||
entityTypeMap.put("oa_go_out", new ArrayList<Class<?>>(Arrays.asList(BpmOAPetitionDO.class, BpmOAPetitionMapper.class)));
|
||||
entityTypeMap.put("oa_salary_adjustment", new ArrayList<Class<?>>(Arrays.asList(BpmOAPetitionDO.class, BpmOAPetitionMapper.class)));
|
||||
entityTypeMap.put("oa_petition", new ArrayList<Class<?>>(Arrays.asList(BpmOAPetitionDO.class, BpmOAPetitionMapper.class)));
|
||||
entityTypeMap.put("oa_business_card", new ArrayList<Class<?>>(Arrays.asList(BpmOAPetitionDO.class, BpmOAPetitionMapper.class)));
|
||||
entityTypeMap.put("oa_hire", new ArrayList<Class<?>>(Arrays.asList(BpmOAPetitionDO.class, BpmOAPetitionMapper.class)));
|
||||
entityTypeMap.put("oa_business_card", new ArrayList<Class<?>>(Arrays.asList(BpmOAPetitionDO.class, BpmOAPetitionMapper.class)));
|
||||
entityTypeMap.put("oa_business_hospitality", new ArrayList<Class<?>>(Arrays.asList(BpmOAPetitionDO.class, BpmOAPetitionMapper.class)));
|
||||
entityTypeMap.put("oa_finance", new ArrayList<Class<?>>(Arrays.asList(BpmOAPetitionDO.class, BpmOAPetitionMapper.class)));
|
||||
entityTypeMap.put("oa_invoice", new ArrayList<Class<?>>(Arrays.asList(BpmOAPetitionDO.class, BpmOAPetitionMapper.class)));
|
||||
entityTypeMap.put("oa_replacementCard", new ArrayList<Class<?>>(Arrays.asList(BpmOAPetitionDO.class, BpmOAPetitionMapper.class)));
|
||||
entityTypeMap.put("oa_project", new ArrayList<Class<?>>(Arrays.asList(BpmOAPetitionDO.class, BpmOAPetitionMapper.class)));
|
||||
entityTypeMap.put("oa_payment", new ArrayList<Class<?>>(Arrays.asList(BpmOAPetitionDO.class, BpmOAPetitionMapper.class)));
|
||||
entityTypeMap.put("oa_expenses", new ArrayList<Class<?>>(Arrays.asList(BpmOAPetitionDO.class, BpmOAPetitionMapper.class)));
|
||||
entityTypeMap.put("oa_loan", new ArrayList<Class<?>>(Arrays.asList(BpmOAPetitionDO.class, BpmOAPetitionMapper.class)));
|
||||
entityTypeMap.put("oa_receipt", new ArrayList<Class<?>>(Arrays.asList(BpmOAPetitionDO.class, BpmOAPetitionMapper.class)));
|
||||
entityTypeMap.put("oa_refund", new ArrayList<Class<?>>(Arrays.asList(BpmOAPetitionDO.class, BpmOAPetitionMapper.class)));
|
||||
}
|
||||
|
||||
@Resource
|
||||
private BpmOAAttachmentService bpmOAAttachmentService;
|
||||
@PostMapping("/uploadAttachment")
|
||||
@Operation(summary = "更新流程附件")
|
||||
@DataPermission(enable = false)
|
||||
public CommonResult<?> uploadAttachment(@Valid @RequestBody BpmOAAttachmentReqVO reqVO) {
|
||||
// 解析实体类型
|
||||
List<Class<?>> entityClazzs = resolveEntityType(reqVO.getProcessType());
|
||||
// 调用通用服务
|
||||
// 通过服务层解析实体类型
|
||||
List<Class<?>> entityClazzs = bpmOAAttachmentService.resolveEntityType(reqVO.getProcessType());
|
||||
// 调用服务层更新附件
|
||||
bpmOAAttachmentService.updateAttachment(entityClazzs, reqVO.getProcessBusinessId(), reqVO.getFileItems());
|
||||
return success("附件更新成功");
|
||||
}
|
||||
|
||||
private List<Class<?>> resolveEntityType(String typeName) {
|
||||
List<Class<?>> entityClazzs = entityTypeMap.get(typeName);
|
||||
if (entityClazzs == null) {
|
||||
// 添加日志记录以便更好地调试
|
||||
log.error("不支持的流程类型: {}", typeName);
|
||||
throw new ServiceException(500, "不支持的流程类型: " + typeName);
|
||||
}
|
||||
return entityClazzs;
|
||||
}
|
||||
}
|
||||
|
@ -4,15 +4,23 @@ import cn.iocoder.yudao.framework.common.pojo.UploadUserFile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* BPM OA 附件服务接口
|
||||
*/
|
||||
public interface BpmOAAttachmentService {
|
||||
|
||||
/**
|
||||
* 更新业务实体的附件信息
|
||||
* @param entityClazzs 业务实体
|
||||
* @param entityClazzs 业务实体类列表
|
||||
* @param entityId 业务ID
|
||||
* @param fileItems 附件数据
|
||||
*/
|
||||
void updateAttachment(List<Class<?>> entityClazzs, Long entityId, List<UploadUserFile> fileItems);
|
||||
|
||||
|
||||
/**
|
||||
* 通过流程代码解析实体类型
|
||||
* @param processCode 流程标识码
|
||||
* @return 实体类和Mapper类的列表
|
||||
*/
|
||||
List<Class<?>> resolveEntityType(String processCode);
|
||||
}
|
||||
|
@ -1,47 +1,98 @@
|
||||
package cn.iocoder.yudao.module.bpm.service.oa;
|
||||
|
||||
import cn.hutool.core.util.ClassUtil;
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import cn.iocoder.yudao.framework.common.exception.ServiceException;
|
||||
import cn.iocoder.yudao.framework.common.pojo.UploadUserFile;
|
||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.processmapping.BpmProcessMappingConfigDO;
|
||||
import cn.iocoder.yudao.module.bpm.framework.core.util.ReflectionInvoker;
|
||||
import cn.iocoder.yudao.module.bpm.service.processmapping.ProcessMappingConfigService;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import liquibase.pro.packaged.T;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.common.engine.impl.persistence.entity.EntityManager;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_MAPPING_CONFIG_NOT_EXISTS;
|
||||
|
||||
@Service
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class BpmOAAttachmentServiceImpl implements BpmOAAttachmentService {
|
||||
|
||||
@Resource
|
||||
private ProcessMappingConfigService processMappingConfigService;
|
||||
|
||||
/**
|
||||
* 更新业务实体的附件信息
|
||||
* @param entityClazzs 业务实体
|
||||
* @param entityClazzs 业务实体类列表
|
||||
* @param entityId 业务ID
|
||||
* @param fileItems 附件数据
|
||||
*/
|
||||
@Override
|
||||
public void updateAttachment(List<Class<?>> entityClazzs, Long entityId, List<UploadUserFile> fileItems) {
|
||||
try {
|
||||
// 1. 获取实体, 赋值实体类
|
||||
Class doClass = entityClazzs.get(0) ;
|
||||
// 1. 获取实体类并创建实例
|
||||
Class<?> doClass = entityClazzs.get(0);
|
||||
Object entity = doClass.getDeclaredConstructor().newInstance();
|
||||
Method setIdMethod = doClass.getMethod("setId", Long.class) ;
|
||||
|
||||
// 2. 使用反射设置实体属性
|
||||
Method setIdMethod = doClass.getMethod("setId", Long.class);
|
||||
setIdMethod.invoke(entity, entityId);
|
||||
Method setFileItems = doClass.getMethod("setFileItems", List.class) ;
|
||||
Method setFileItems = doClass.getMethod("setFileItems", List.class);
|
||||
setFileItems.invoke(entity, fileItems);
|
||||
//获取MyBatist的操作类实体
|
||||
Class mapperClass = entityClazzs.get(1) ;
|
||||
BaseMapper mapper = (BaseMapper) SpringUtil.getBean(mapperClass);
|
||||
mapper.updateById(entity);
|
||||
|
||||
// 3. 获取Mapper实例并调用updateById方法
|
||||
Class<?> mapperClass = entityClazzs.get(1);
|
||||
Object mapperBean = SpringUtil.getBean(mapperClass);
|
||||
|
||||
// 4. 使用ReflectionInvoker调用updateById方法
|
||||
ReflectionInvoker.invokeMapperMethod(mapperBean, "updateById", Object.class, entity);
|
||||
|
||||
log.debug("[updateAttachment][附件更新成功] entityClass={}, entityId={}, fileCount={}",
|
||||
doClass.getSimpleName(), entityId, fileItems != null ? fileItems.size() : 0);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage());
|
||||
throw new ServiceException(500, "系统异常,请联系管理员");
|
||||
log.error("[updateAttachment][附件更新失败] entityId={}, error={}", entityId, e.getMessage(), e);
|
||||
throw new ServiceException(500, "附件更新失败,请联系管理员");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过流程代码动态解析实体类型
|
||||
* @param processCode 流程标识码
|
||||
* @return 实体类和Mapper类的列表
|
||||
*/
|
||||
@Override
|
||||
public List<Class<?>> resolveEntityType(String processCode) {
|
||||
try {
|
||||
// 1. 获取流程映射配置
|
||||
BpmProcessMappingConfigDO config = processMappingConfigService.getProcessMappingConfigByCode(processCode);
|
||||
if (config == null) {
|
||||
log.error("[resolveEntityType][流程映射配置不存在] processCode={}", processCode);
|
||||
throw exception(PROCESS_MAPPING_CONFIG_NOT_EXISTS);
|
||||
}
|
||||
|
||||
// 2. 动态加载实体类和Mapper类
|
||||
Class<?> entityClass = ClassUtil.loadClass(config.getEntityClass());
|
||||
Class<?> mapperClass = ClassUtil.loadClass(config.getMapperClass());
|
||||
|
||||
// 3. 验证Mapper类是否可获取Bean实例
|
||||
SpringUtil.getBean(mapperClass);
|
||||
|
||||
log.debug("[resolveEntityType][成功解析流程类型] processCode={}, entityClass={}, mapperClass={}",
|
||||
processCode, config.getEntityClass(), config.getMapperClass());
|
||||
|
||||
return Arrays.asList(entityClass, mapperClass);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("[resolveEntityType][解析流程类型失败] processCode={}", processCode, e);
|
||||
throw new ServiceException(500, String.format("不支持的流程类型: %s, 错误信息: %s", processCode, e.getMessage()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user