feat(bpm): 增加项目编号和名称字段,并优化报销功能

- 在 BpmOACash 和 BpmOAReimbursement 模型中添加项目编号字段
- 在 API 接口中增加项目名称的获取和展示
- 新增 BpmOAReimbursementItem 模型和相关 Mapper- 优化报销申请创建逻辑,支持明细数据插入
-调整抄送人处理逻辑,使用事务提交后执行
-重构领导审批规则计算方法,提高灵活性和准确性
This commit is contained in:
furongxin 2024-11-29 17:05:42 +08:00
parent a12e01992f
commit c51c46262c
16 changed files with 262 additions and 60 deletions

View File

@ -5,9 +5,12 @@ import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.cash.BpmOACashCreateRe
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.cash.BpmOACashRespVO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOACashDO;
import cn.iocoder.yudao.module.bpm.service.oa.BpmOACashService;
import cn.iocoder.yudao.module.system.api.project.ProjectApi;
import cn.iocoder.yudao.module.system.api.project.dto.ProjectDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.mapstruct.ap.internal.util.Strings;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@ -32,6 +35,9 @@ public class BpmOACashController {
@Resource
private BpmOACashService cashService;
@Resource
private ProjectApi projectApi;
@PostMapping("/create")
@Operation(summary = "创建请求申请")
public CommonResult<Long> createCash(@Valid @RequestBody BpmOACashCreateReqVO createReqVO) {
@ -45,8 +51,13 @@ public class BpmOACashController {
public CommonResult<BpmOACashRespVO> getCash(@RequestParam("id") Long id) {
BpmOACashDO cashDO = cashService.getCash(id);
BpmOACashRespVO respVO = cashService.convertCash(cashDO);
if (respVO != null && Strings.isNotEmpty(respVO.getProjectNo())) {
ProjectDTO projectDTO = projectApi.getProject(respVO.getProjectNo()).getCheckedData();
respVO.setProjectName(projectDTO.getName());
}
return success(cashService.convertCash(cashDO));
return success(respVO);
}
@GetMapping("/getByProcessInstanceId")
@ -55,7 +66,12 @@ public class BpmOACashController {
public CommonResult<BpmOACashRespVO> getCashByProcessInstanceId(@RequestParam("processInstanceId") String processInstanceId) {
BpmOACashDO cashDO = cashService.getByProcessInstanceId(processInstanceId);
BpmOACashRespVO respVO = cashService.convertCash(cashDO);
if (respVO != null && Strings.isNotEmpty(respVO.getProjectNo())) {
ProjectDTO projectDTO = projectApi.getProject(respVO.getProjectNo()).getCheckedData();
respVO.setProjectName(projectDTO.getName());
}
return success(cashService.convertCash(cashDO));
return success(respVO);
}
}

View File

@ -5,9 +5,12 @@ import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.reimbursement.BpmOARei
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.reimbursement.BpmOAReimbursementRespVO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAReimbursementDO;
import cn.iocoder.yudao.module.bpm.service.oa.BpmOAReimbursementService;
import cn.iocoder.yudao.module.system.api.project.ProjectApi;
import cn.iocoder.yudao.module.system.api.project.dto.ProjectDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.mapstruct.ap.internal.util.Strings;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@ -31,6 +34,9 @@ public class BpmOAReimbursementController {
@Resource
private BpmOAReimbursementService service;
@Resource
private ProjectApi projectApi;
@PostMapping("/create")
// @PreAuthorize("@ss.hasPermission('bpm:oa-reimbursement:create')")
@Operation(summary = "创建请求申请")
@ -45,7 +51,13 @@ public class BpmOAReimbursementController {
public CommonResult<BpmOAReimbursementRespVO> getReimbursement(@RequestParam("id") Long id) {
BpmOAReimbursementDO reimbursement = service.getReimbursement(id);
return success(service.convert(reimbursement));
BpmOAReimbursementRespVO respVO = service.convert(reimbursement);
if (respVO != null && Strings.isNotEmpty(respVO.getProjectNo())) {
// 设置项目名称
ProjectDTO projectDTO = projectApi.getProject(respVO.getProjectNo()).getCheckedData();
respVO.setProjectName(projectDTO.getName());
}
return success(respVO);
}
// @GetMapping("/page")
@ -62,6 +74,12 @@ public class BpmOAReimbursementController {
public CommonResult<BpmOAReimbursementRespVO> getByProcessInstanceId(@RequestParam("processInstanceId") String processInstanceId) {
BpmOAReimbursementDO reimbursement = service.getByProcessInstanceId(processInstanceId);
return success(service.convert(reimbursement));
BpmOAReimbursementRespVO respVO = service.convert(reimbursement);
if (respVO != null && Strings.isNotEmpty(respVO.getProjectNo())) {
// 设置项目名称
ProjectDTO projectDTO = projectApi.getProject(respVO.getProjectNo()).getCheckedData();
respVO.setProjectName(projectDTO.getName());
}
return success(respVO);
}
}

View File

@ -31,6 +31,9 @@ public class BpmOACashCreateReqVO {
@NotNull(message = "报销总金额不能为空")
private BigDecimal totalMoney;
@Schema(description = "项目编号")
private String projectNo;
@Schema(description = "备用金申请编号")
private Long imprestId;

View File

@ -37,6 +37,12 @@ public class BpmOACashRespVO extends BpmOABaseRespVO {
@Schema(description = "报销总金额")
private BigDecimal totalMoney;
@Schema(description = "项目编号")
private String projectNo;
@Schema(description = "项目名称")
private String projectName;
@Schema(description = "备用金申请编号")
private Long imprestId;

View File

@ -36,9 +36,12 @@ public class BpmOAReimbursementCreateReqVO {
@NotNull(message = "报销总金额中文大写不能为空")
private String totalMoneyChinese ;
@Schema(description = "报销类型", requiredMode = Schema.RequiredMode.REQUIRED)
@Schema(description = "报销类型 | 1正常报销 2备用金报销", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "报销类型不能为空")
private BigDecimal reimbursementType ;
private BigDecimal reimbursementType;
@Schema(description = "项目编号")
private String projectNo;
@Schema(description = "备用金ID")
private Long imprestId;

View File

@ -43,6 +43,12 @@ public class BpmOAReimbursementRespVO extends BpmOABaseRespVO {
@NotNull(message = "报销类型不能为空")
private BigDecimal reimbursementType ;
@Schema(description = "项目编号")
private String projectNo;
@Schema(description = "项目名称")
private String projectName;
@Schema(description = "备用金金额", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private BigDecimal amount;

View File

@ -15,6 +15,9 @@ import java.util.Date;
@Data
public class Reimbursement {
@Schema(description = "主键ID")
private Long id;
@Schema(description = "所属部门ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "128")
private Long deptId;

View File

@ -50,6 +50,11 @@ public class BpmOACashDO extends BaseDO {
*/
private BigDecimal totalMoney;
/**
* 项目编号
*/
private String projectNo;
/**
* 备用金申请编号
*/

View File

@ -29,7 +29,7 @@ import java.util.List;
public class BpmOAReimbursementDO extends BaseDO {
/**
* 1: 自费
* 1: 办公报销
*/
public static final Integer EXPENSE_TYPE = 1;
/**
@ -79,6 +79,11 @@ public class BpmOAReimbursementDO extends BaseDO {
*/
private String totalMoneyChinese;
/**
* 项目编号
*/
private String projectNo;
/**
* 报销类型
*/

View File

@ -0,0 +1,71 @@
package cn.iocoder.yudao.module.bpm.dal.dataobject.oa;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
import java.math.BigDecimal;
import java.util.Date;
/**
* OA 报销明细 DO
*
* @author 姚君
*
*/
@TableName(value ="bpm_oa_reimbursement_item", autoResultMap = true)
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class BpmOAReimbursementItemDO extends BaseDO {
/**
* 报销明细表单主键
*/
@TableId
private Long id;
/**
* 报销编号
*/
private Long reimbursementId;
/**
* 费用产生部门编号
*/
private Long deptId;
/**
* 报销金额
*/
private BigDecimal money;
/**
* 费用类型 | 字典值 参考bpm_oa_reimbursement_type
*/
private String type;
/**
* 发生时间
*/
private Date happenTime;
/**
* 发票张数
*/
private Integer quantity ;
/**
* 费用明细
*/
private String detail ;
/**
* 采购申请编号
*/
private Long procureId;
}

View File

@ -0,0 +1,9 @@
package cn.iocoder.yudao.module.bpm.dal.mysql.oa;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAReimbursementItemDO;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface BpmOAReimbursementItemMapper extends BaseMapperX<BpmOAReimbursementItemDO> {
}

View File

@ -9,10 +9,12 @@ import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.runtime.ProcessInstance;
import org.omg.CORBA.IRObject;
import org.springframework.context.annotation.Lazy;
import org.springframework.util.Assert;
import javax.annotation.Resource;
import java.util.Objects;
import java.util.Set;
import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
@ -39,32 +41,59 @@ public abstract class BpmTaskAssignLeaderAbstractScript implements BpmTaskAssign
// 获得发起人
ProcessInstance processInstance = bpmProcessInstanceService.getProcessInstance(execution.getProcessInstanceId());
Long startUserId = NumberUtils.parseLong(processInstance.getStartUserId());
// 获得对应 leve 的部门
DeptRespDTO dept = null;
for (int i = 0; i < level; i++) {
// 获得 level 对应的部门
if (dept == null) {
dept = getStartUserDept(startUserId);
if (dept == null) { // 找不到发起人的部门所以无法使用该规则
return emptySet();
}
} else {
DeptRespDTO parentDept = deptApi.getDept(dept.getParentId()).getCheckedData();
if (parentDept == null) { // 找不到父级部门所以只好结束寻找原因是例如说级别比较高的人所在部门层级比较少
break;
}
dept = parentDept;
}
// 获得发起人部门信息
DeptRespDTO startUserDept = getStartUserDept(startUserId);
// 如果发起人部门为空则直接返回空
if (startUserDept == null) {
return emptySet();
}
Long leaderUserId = dept.getLeaderUserId() ;
if( leaderUserId !=null && !startUserId.toString().equals(leaderUserId.toString()) ) {
return asSet(dept.getLeaderUserId()) ;
}else if( leaderUserId !=null && startUserId.toString().equals(leaderUserId.toString()) ) {
// 如果发起人部门层级 小于等于 level则直接返回发起人的部门负责人
if (startUserDept.getLevel() <= level) {
return startUserDept.getLeaderUserId() == null ? emptySet() : asSet(startUserDept.getLeaderUserId());
}
// 获取发起人部门flag
String [] flag = startUserDept.getFlag().split("-");
// 获取指定层级部门信息
DeptRespDTO dept = deptApi.getDept(Long.valueOf(flag[level])).getCheckedData();
Long leaderUserId = dept.getLeaderUserId();
if(leaderUserId == null) {
return emptySet();
}
if (Objects.equals(leaderUserId, startUserId)) {
//如果领导ID和发起人ID一致那么需要再往上级机构寻找
return calculateTaskCandidateUsers(execution, level+1) ;
return calculateTaskCandidateUsers(execution, level+1);
}else {
return emptySet() ;
return asSet(dept.getLeaderUserId());
}
// // 获得对应 leve 的部门
// DeptRespDTO dept = null;
// for (int i = 0; i < level; i++) {
// // 获得 level 对应的部门
// if (dept == null) {
// dept = getStartUserDept(startUserId);
// if (dept == null) { // 找不到发起人的部门所以无法使用该规则
// return emptySet();
// }
// } else {
// DeptRespDTO parentDept = deptApi.getDept(dept.getParentId()).getCheckedData();
// if (parentDept == null) { // 找不到父级部门所以只好结束寻找原因是例如说级别比较高的人所在部门层级比较少
// break;
// }
// dept = parentDept;
// }
// }
// Long leaderUserId = dept.getLeaderUserId() ;
// if( leaderUserId !=null && !startUserId.toString().equals(leaderUserId.toString()) ) {
// return asSet(dept.getLeaderUserId()) ;
// }else if( leaderUserId !=null && startUserId.toString().equals(leaderUserId.toString()) ) {
// //如果领导ID和发起人ID一致那么需要再往上级机构寻找
// return calculateTaskCandidateUsers(execution, level+1) ;
// }else {
// return emptySet() ;
// }
//return dept.getLeaderUserId() != null ? asSet(dept.getLeaderUserId()) : emptySet();
}

View File

@ -83,6 +83,6 @@ public class BpmProcessCcServiceImpl implements BpmProcessCcService {
return processCcMapper.selectList(new LambdaQueryWrapperX<BpmProcessCcDO>()
.likeIfPresent(BpmProcessCcDO::getName, name)
.eqIfPresent(BpmProcessCcDO::getCompanyDeptId, dto.getId()));
.likeIfPresent(BpmProcessCcDO::getCompanyDeptId, String.valueOf(dto.getId())));
}
}

View File

@ -3,9 +3,12 @@ package cn.iocoder.yudao.module.bpm.service.oa;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.reimbursement.BpmOAReimbursementCreateReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.reimbursement.BpmOAReimbursementRespVO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOACashItemDO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAReimbursementDO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAReimbursementItemDO;
import javax.validation.Valid;
import java.util.List;
/**
* 报销申请 Service 接口
@ -40,6 +43,14 @@ public interface BpmOAReimbursementService {
*/
BpmOAReimbursementDO getReimbursement(Long id);
/**
* 获得指定得报销明细
*
* @param reimbursementId 报销主表编号
* @return 明细列表
*/
List<BpmOAReimbursementItemDO> getReimbursementItem(Long reimbursementId);
BpmOAReimbursementRespVO convert(BpmOAReimbursementDO bpmOAReimbursementDO);
/**

View File

@ -15,11 +15,10 @@ import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.reimbursement.Reimburs
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.reimbursement.ReimbursementDTO;
import cn.iocoder.yudao.module.bpm.convert.oa.BpmOAReimbursementConvert;
import cn.iocoder.yudao.module.bpm.dal.dataobject.financialpayment.FinancialPaymentDO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAImprestDO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAProcureDO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAReimbursementDO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.*;
import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO;
import cn.iocoder.yudao.module.bpm.dal.mysql.oa.BpmOAImprestMapper;
import cn.iocoder.yudao.module.bpm.dal.mysql.oa.BpmOAReimbursementItemMapper;
import cn.iocoder.yudao.module.bpm.dal.mysql.oa.BpmOAReimbursementMapper;
import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
import cn.iocoder.yudao.module.bpm.service.financialpayment.FinancialPaymentService;
@ -80,6 +79,9 @@ public class BpmOAReimbursementServiceImpl extends BpmOABaseService implements B
@Resource
private BpmOAImprestMapper bpmOAImprestMapper;
@Resource
private BpmOAReimbursementItemMapper reimbursementItemMapper;
@Resource
private BpmOAProcureService bpmOAProcureService;
@ -102,6 +104,11 @@ public class BpmOAReimbursementServiceImpl extends BpmOABaseService implements B
.setResult(BpmProcessInstanceResultEnum.PROCESS.getResult());
reimbursementMapper.insert(reimbursement);
// 同步插入明细数据
List<BpmOAReimbursementItemDO> createDO = BeanUtils.toBean(createReqVO.getReimbursements(), BpmOAReimbursementItemDO.class);
createDO.forEach(item -> item.setReimbursementId(reimbursement.getId()));
reimbursementItemMapper.insertBatch(createDO);
// 发起 BPM 流程
Map<String, Object> processInstanceVariables = new HashMap<>();
String processInstanceId = processInstanceApi.createProcessInstance(userId,
@ -125,7 +132,7 @@ public class BpmOAReimbursementServiceImpl extends BpmOABaseService implements B
//判断是否有 采购报销
List<Long> procureIds = new ArrayList<>();
for (Reimbursement data : reimbursement.getReimbursements()) {
for (BpmOAReimbursementItemDO data : createDO) {
//报销类别为 采购费时
if ("4".equals(data.getType())) {
@ -158,7 +165,8 @@ public class BpmOAReimbursementServiceImpl extends BpmOABaseService implements B
BpmOAReimbursementDO bpmOAReimbursementDO = validateLeaveExists(id);
reimbursementMapper.updateById(new BpmOAReimbursementDO().setId(id).setResult(result));
// 获取明细数据
List<BpmOAReimbursementItemDO> reimbursements = getReimbursementItem(id);
//审核通过 最后节点
if (BpmProcessInstanceResultEnum.APPROVE.getResult().equals(result)) {
@ -169,13 +177,13 @@ public class BpmOAReimbursementServiceImpl extends BpmOABaseService implements B
//判断是否有采购报销
List<Long> procureIds = new ArrayList<>();
List<Reimbursement> reimbursements = bpmOAReimbursementDO.getReimbursements();
//直接从数据库取出来的List<Reimbursement> 实际上是List<LinkedHashMap>类型 所以不能直接遍历
//将list再次转为json串然后由json串再转为list
String json = JsonUtils.toJsonString(reimbursements);
reimbursements = JsonUtils.parseArray(json, Reimbursement.class);
for (Reimbursement reimbursement : reimbursements) {
// List<Reimbursement> reimbursements = bpmOAReimbursementDO.getReimbursements();
//
// //直接从数据库取出来的List<Reimbursement> 实际上是List<LinkedHashMap>类型 所以不能直接遍历
// //将list再次转为json串然后由json串再转为list
// String json = JsonUtils.toJsonString(reimbursements);
// reimbursements = JsonUtils.parseArray(json, Reimbursement.class);
for (BpmOAReimbursementItemDO reimbursement : reimbursements) {
//报销类别为 采购费时
if ("4".equals(reimbursement.getType())) {
procureIds.add(reimbursement.getProcureId());
@ -219,7 +227,7 @@ public class BpmOAReimbursementServiceImpl extends BpmOABaseService implements B
}
}
String reason = reimbursements.stream().map(Reimbursement::getDetail)
String reason = reimbursements.stream().map(BpmOAReimbursementItemDO::getDetail)
.filter(StrUtil::isNotEmpty)
.collect(Collectors.joining(","));
@ -264,14 +272,14 @@ public class BpmOAReimbursementServiceImpl extends BpmOABaseService implements B
//判断是否有采购报销
List<Long> procureIds = new ArrayList<>();
List<Reimbursement> reimbursements = bpmOAReimbursementDO.getReimbursements();
// List<Reimbursement> reimbursements = bpmOAReimbursementDO.getReimbursements();
//
// //直接从数据库取出来的List<Reimbursement> 实际上是List<LinkedHashMap>类型 所以不能直接遍历
// //将list再次转为json串然后由json串再转为list
// String json = JsonUtils.toJsonString(reimbursements);
// reimbursements = JsonUtils.parseArray(json, Reimbursement.class);
//直接从数据库取出来的List<Reimbursement> 实际上是List<LinkedHashMap>类型 所以不能直接遍历
//将list再次转为json串然后由json串再转为list
String json = JsonUtils.toJsonString(reimbursements);
reimbursements = JsonUtils.parseArray(json, Reimbursement.class);
for (Reimbursement reimbursement : reimbursements) {
for (BpmOAReimbursementItemDO reimbursement : reimbursements) {
//报销类别为 采购费时
if ("4".equals(reimbursement.getType())) {
@ -294,7 +302,7 @@ public class BpmOAReimbursementServiceImpl extends BpmOABaseService implements B
);
}
}
reimbursementMapper.updateById(new BpmOAReimbursementDO().setId(id).setResult(result));
}
private BpmOAReimbursementDO validateLeaveExists(Long id) {
@ -311,19 +319,28 @@ public class BpmOAReimbursementServiceImpl extends BpmOABaseService implements B
return reimbursementMapper.selectById(id);
}
@Override
public List<BpmOAReimbursementItemDO> getReimbursementItem(Long reimbursementId) {
return reimbursementItemMapper.selectList(BpmOAReimbursementItemDO::getReimbursementId, reimbursementId);
}
@Override
public BpmOAReimbursementRespVO convert(BpmOAReimbursementDO reimbursementDO) {
List<Reimbursement> reimbursement = reimbursementDO.getReimbursements();
// 获取明细数据
List<BpmOAReimbursementItemDO> reimbursements = getReimbursementItem(reimbursementDO.getId());
//直接从数据库取出来的List<Reimbursement> 实际上是List<LinkedHashMap>类型 所以不能直接遍历
//将list再次转为json串然后由json串再转为list
String json = JsonUtils.toJsonString(reimbursement);
reimbursement = JsonUtils.parseArray(json, Reimbursement.class);
// List<Reimbursement> reimbursement = reimbursementDO.getReimbursements();
//
// //直接从数据库取出来的List<Reimbursement> 实际上是List<LinkedHashMap>类型 所以不能直接遍历
// //将list再次转为json串然后由json串再转为list
// String json = JsonUtils.toJsonString(reimbursement);
// reimbursement = JsonUtils.parseArray(json, Reimbursement.class);
//针对之前的数据 没有设置明细所属部门的 手动设置发起人的部门编号
AdminUserRespDTO userRespDTO = userApi.getUser(reimbursementDO.getUserId()).getCheckedData();
for (Reimbursement data : reimbursement) {
for (BpmOAReimbursementItemDO data : reimbursements) {
if (data.getDeptId() != null) {
break;
@ -333,9 +350,9 @@ public class BpmOAReimbursementServiceImpl extends BpmOABaseService implements B
}
//获取部门信息map
Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(reimbursement, Reimbursement::getDeptId));
Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(reimbursements, BpmOAReimbursementItemDO::getDeptId));
List<ReimbursementDTO> reimbursementDTOS = BeanUtils.toBean(reimbursement, ReimbursementDTO.class);
List<ReimbursementDTO> reimbursementDTOS = BeanUtils.toBean(reimbursements, ReimbursementDTO.class);
BpmOAReimbursementRespVO bpmOAReimbursementRespVO = BeanUtils.toBean(reimbursementDO, BpmOAReimbursementRespVO.class);
bpmOAReimbursementRespVO.setReimbursements(BpmOAReimbursementConvert.INSTANCE.convertList(reimbursementDTOS, deptMap)); //拼接数据