diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/DeptTypeEnum.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/DeptTypeEnum.java index 753944f3..66abddc8 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/DeptTypeEnum.java +++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/DeptTypeEnum.java @@ -10,6 +10,7 @@ import lombok.Getter; @Getter public enum DeptTypeEnum { + HEAD_COMPANY("HEAD_COMPANY", "总公司"), COMPANY("COMPANY", "公司"), SALE_DEPT("SALE_DEPT", "销售部门"), DEVELOPMENT_DEPT("DEVELOPMENT_DEPT", "开发部门"), diff --git a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java index 122939d2..0afec317 100644 --- a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java +++ b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java @@ -62,6 +62,7 @@ public interface ErrorCodeConstants { ErrorCode OA_CONTRACT_INVOICE_AMOUNT_LACK = new ErrorCode(1_009_001_125, "该合同的开票余额不足!"); ErrorCode OA_PAYMENT_NOT_EXISTS = new ErrorCode(1_009_001_126, "付款申请不存在"); ErrorCode OA_RECEIPT_NOT_EXISTS = new ErrorCode(1_009_001_127, "回款申请不存在"); + ErrorCode OA_PAYMENT_FILES_NOT_NULL = new ErrorCode(1_009_001_128, "后补发票不能为空!"); // ========== 流程模型 1-009-002-000 ========== ErrorCode MODEL_KEY_EXISTS = new ErrorCode(1_009_002_000, "已经存在流程标识为【{}】的流程"); diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmProcessCcController.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmProcessCcController.java index 65078ee1..6d33ed2f 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmProcessCcController.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmProcessCcController.java @@ -103,7 +103,7 @@ public class BpmProcessCcController { .collect(Collectors.joining("、"))); // 设置公司名称 data.setCompanyName(data.getCompanyDeptId().stream() - .map(item -> deptMap.get(item).getName()) + .map(item -> deptMap.get(item) != null ? deptMap.get(item).getName() : "") .collect(Collectors.joining("、"))); }); return success(respVOPageResult); diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOAPaymentController.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOAPaymentController.java index df8698a8..e8258487 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOAPaymentController.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOAPaymentController.java @@ -1,37 +1,32 @@ package cn.iocoder.yudao.module.bpm.controller.admin.oa; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollectionUtil; +import cn.iocoder.yudao.framework.common.enums.DeptTypeEnum; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; -import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.contract.BpmOAContractPageReqVO; -import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.contract.BpmOAContractRespVO; -import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.payment.BpmOAPaymentCreateReqVO; -import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.payment.BpmOAPaymentPageReqVO; -import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.payment.BpmOAPaymentRespVO; -import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.payment.FactoryDetailVO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.payment.*; import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAPaymentDO; import cn.iocoder.yudao.module.bpm.service.oa.BpmOAPaymentService; -import cn.iocoder.yudao.module.system.api.bank.BankApi; -import cn.iocoder.yudao.module.system.api.bank.dto.BankRespDTO; import cn.iocoder.yudao.module.system.api.dept.DeptApi; import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; -import cn.iocoder.yudao.module.system.api.project.ProjectApi; -import cn.iocoder.yudao.module.system.api.project.dto.ProjectDTO; +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; -import org.apache.commons.lang3.StringUtils; -import org.apache.logging.log4j.util.Strings; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.validation.Valid; import java.util.*; +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.convertList; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; /** @@ -50,14 +45,11 @@ public class BpmOAPaymentController { private BpmOAPaymentService paymentService; @Resource - private ProjectApi projectApi; + private AdminUserApi userApi; @Resource private DeptApi deptApi; - @Resource - private BankApi bankApi; - @PostMapping("/create") @Operation(summary = "创建付款申请") public CommonResult createPayment(@Valid @RequestBody BpmOAPaymentCreateReqVO createReqVO) { @@ -71,44 +63,7 @@ public class BpmOAPaymentController { public CommonResult getPayment(@RequestParam("id") Long id) { BpmOAPaymentDO payment = paymentService.getPayment(id); - BpmOAPaymentRespVO respVO = BeanUtils.toBean(payment, BpmOAPaymentRespVO.class); - if (respVO != null) { - - // 获取部门信息Map - List deptIds = new ArrayList<>(); - if (CollectionUtil.isNotEmpty(respVO.getFactoryDetail())) { - deptIds.addAll(convertList(respVO.getFactoryDetail(), FactoryDetailVO::getDeptId)); - }else { - deptIds.add(payment.getDeptId()); - } - deptIds.add(payment.getPaymentCompany()); - Map dtoMap = deptApi.getDeptMap(new HashSet<>(deptIds)); - - // 设置部门名称 - respVO.setDeptName(dtoMap.get(payment.getDeptId()) != null ? dtoMap.get(payment.getDeptId()).getName() : null); - // 设置付款公司名称 - respVO.setPaymentCompanyName(dtoMap.get(payment.getPaymentCompany()).getName()); - // 设置工厂名称 - respVO.getFactoryDetail().forEach(item -> { - item.setFactoryName(dtoMap.get(item.getDeptId()).getName()); - }); - - if (StringUtils.isNotEmpty(payment.getProjectNo())) { - // 获取项目信息 - ProjectDTO project = projectApi.getProject(payment.getProjectNo()).getCheckedData(); - // 设置项目名称 - respVO.setProjectName(project.getName()); - } - - if (payment.getBankId() != null) { - // 获取银行卡信息 - BankRespDTO bankResp = bankApi.getBank(payment.getBankId()).getCheckedData(); - // 设置银行卡信息 - respVO.setBankName(bankResp.getBankName()); - respVO.setBankNo(bankResp.getBankNo()); - respVO.setNickname(bankResp.getNickname()); - } - } + BpmOAPaymentRespVO respVO = paymentService.convertPayment(payment); return success(respVO); } @@ -119,43 +74,7 @@ public class BpmOAPaymentController { public CommonResult getByProcessInstanceId(@RequestParam("processInstanceId") String processInstanceId) { BpmOAPaymentDO payment = paymentService.getByProcessInstanceId(processInstanceId); - BpmOAPaymentRespVO respVO = BeanUtils.toBean(payment, BpmOAPaymentRespVO.class); - if (respVO != null) { - // 获取部门信息Map - List deptIds = new ArrayList<>(); - if (CollectionUtil.isNotEmpty(respVO.getFactoryDetail())) { - deptIds.addAll(convertList(respVO.getFactoryDetail(), FactoryDetailVO::getDeptId)); - }else { - deptIds.add(payment.getDeptId()); - } - deptIds.add(payment.getPaymentCompany()); - Map dtoMap = deptApi.getDeptMap(new HashSet<>(deptIds)); - - // 设置部门名称 - respVO.setDeptName(dtoMap.get(payment.getDeptId()) != null ? dtoMap.get(payment.getDeptId()).getName() : null); - // 设置付款公司名称 - respVO.setPaymentCompanyName(dtoMap.get(payment.getPaymentCompany()).getName()); - // 设置工厂名称 - respVO.getFactoryDetail().forEach(item -> { - item.setFactoryName(dtoMap.get(item.getDeptId()).getName()); - }); - - if (payment.getProjectNo() != null) { - // 获取项目信息 - ProjectDTO project = projectApi.getProject(payment.getProjectNo()).getCheckedData(); - // 设置项目名称 - respVO.setProjectName(project.getName()); - } - - if (payment.getBankId() != null) { - // 获取银行卡信息 - BankRespDTO bankResp = bankApi.getBank(payment.getBankId()).getCheckedData(); - // 设置银行卡信息 - respVO.setBankName(bankResp.getBankName()); - respVO.setBankNo(bankResp.getBankNo()); - respVO.setNickname(bankResp.getNickname()); - } - } + BpmOAPaymentRespVO respVO = paymentService.convertPayment(payment); return success(respVO); } @@ -172,6 +91,80 @@ public class BpmOAPaymentController { @Operation(summary = "获得 后补票的付款申请分页列表") public CommonResult> getPage(@Valid BpmOAPaymentPageReqVO pageReqVO) { - return success(paymentService.getPaymentPage(pageReqVO)); + // 获取所有 财务部门信息 + List deptRespDTOS = deptApi.getDeptListByType(DeptTypeEnum.FINANCE_DEPT.getValue()).getCheckedData(); + // 筛选 所属总公司的财务部门 + List dto = deptApi.getDeptListByType(DeptTypeEnum.HEAD_COMPANY.getValue()).getCheckedData(); + Long headCompanyId = dto.get(0).getId(); + deptRespDTOS = deptRespDTOS.stream() + .filter(item -> item.getFlag().contains(headCompanyId.toString())) + .collect(Collectors.toList()); + + // 获取财务部门下 所有用户信息 + List userRespDTOS = userApi.getUserListByDeptIds(convertSet(deptRespDTOS, DeptRespDTO::getId)).getCheckedData(); + List userIds = convertList(userRespDTOS, AdminUserRespDTO::getId); + + // 判断当前登录用户是否属于财务部 + pageReqVO.setIsMy(!userIds.contains(getLoginUserId())); + + PageResult pageResult = BeanUtils.toBean(paymentService.getPaymentPage(pageReqVO, getLoginUserId()), BpmOAPaymentRespVO.class); + if (CollUtil.isNotEmpty(pageResult.getList())) { + + // 获取发起人用户信息 + Set startUserIds = convertSet(pageResult.getList(), BpmOAPaymentRespVO::getUserId); + Map userMap = userApi.getUserMap(startUserIds); + + // 获取部门信息Map + List deptIds = new ArrayList<>(); + // 获取工厂详情 + List> factoryDetailList = convertList(pageResult.getList(), BpmOAPaymentRespVO::getFactoryDetail); + List factoryDetailVOS = factoryDetailList.stream().flatMap(List::stream).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(factoryDetailVOS)) { + deptIds.addAll(convertList(factoryDetailVOS, FactoryDetailVO::getDeptId)); + }else { + deptIds.addAll(convertList(pageResult.getList(), BpmOAPaymentRespVO::getDeptId)); + } + // 添加公司集合 + deptIds.addAll(convertList(pageResult.getList(), BpmOAPaymentRespVO::getPaymentCompany)); + Map dtoMap = deptApi.getDeptMap(new HashSet<>(deptIds)); + + pageResult.getList().forEach(item -> { + item.setUserName(userMap.get(item.getUserId()).getNickname()); + // 设置部门名称 + item.setDeptName(dtoMap.get(item.getDeptId()) != null ? dtoMap.get(item.getDeptId()).getName() : null); + // 设置付款公司名称 + item.setPaymentCompanyName(dtoMap.get(item.getPaymentCompany()).getName()); + // 设置工厂名称 + item.getFactoryDetail().forEach(detail -> { + detail.setFactoryName(dtoMap.get(detail.getDeptId()).getName()); + }); + }); + } + + return success(pageResult); + } + + @PutMapping("update-files") + @Operation(summary = "继续上传附件") + public CommonResult updateFiles(@Valid @RequestBody BpmOAPaymentUpdateReqVO updateReqVO) { + paymentService.updateFiles(updateReqVO); + return success(true); + } + + @PutMapping("update-status") + @Operation(summary = "修改付款申请的补票状态") + public CommonResult updateStatus(@Valid @RequestBody BpmOAPaymentUpdateReqVO updateReqVO) { + paymentService.updateStatus(updateReqVO); + return success(true); + } + + @PutMapping("/delete-files") + @Operation(summary = "删除后补附件") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @Parameter(name = "url", description = "url", required = true, example = "1024") + public CommonResult deleteUser(@RequestParam("id") Long id, + @RequestParam("url") String url) { + paymentService.deleteFiles(id, url); + return success(true); } } \ No newline at end of file diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/payment/BpmOAPaymentCreateReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/payment/BpmOAPaymentCreateReqVO.java index 5d5ac688..9a417e32 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/payment/BpmOAPaymentCreateReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/payment/BpmOAPaymentCreateReqVO.java @@ -63,6 +63,9 @@ public class BpmOAPaymentCreateReqVO { @Schema(description = "后补票批注", requiredMode = Schema.RequiredMode.NOT_REQUIRED) private String annotations; + @Schema(description = "补票状态 | 0待补票 1已补票 2已确认", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private Integer status; + @Schema(description = "父级审批编号", requiredMode = Schema.RequiredMode.NOT_REQUIRED) private Long parentId; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/payment/BpmOAPaymentPageReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/payment/BpmOAPaymentPageReqVO.java index f29f08d6..ec408e27 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/payment/BpmOAPaymentPageReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/payment/BpmOAPaymentPageReqVO.java @@ -6,6 +6,9 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; +import org.springframework.format.annotation.DateTimeFormat; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; @Schema(description = "管理后台 - 付款申请分页 Request VO") @Data @@ -16,4 +19,11 @@ public class BpmOAPaymentPageReqVO extends PageParam { @Schema(description = "补票状态 | 0待补票 1已补票 2已确认") private Integer status; + + @Schema(description = "是否我的申请") + private Boolean isMy; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private String[] createTime; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/payment/BpmOAPaymentRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/payment/BpmOAPaymentRespVO.java index c6e06ab1..8e59d39d 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/payment/BpmOAPaymentRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/payment/BpmOAPaymentRespVO.java @@ -19,6 +19,12 @@ import java.util.List; @ToString(callSuper = true) public class BpmOAPaymentRespVO extends BpmOABaseRespVO { + @Schema(description = "申请人编号") + private Long userId; + + @Schema(description = "申请人名称") + private String userName; + @Schema(description = "申请事由") private String reason; @@ -79,6 +85,9 @@ public class BpmOAPaymentRespVO extends BpmOABaseRespVO { @Schema(description = "后补票批注", requiredMode = Schema.RequiredMode.NOT_REQUIRED) private String annotations; + @Schema(description = "补票状态 | 0待补票 1已补票 2已确认", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private Integer status; + @Schema(description = "父级审批编号") private Long parentId; @@ -87,4 +96,7 @@ public class BpmOAPaymentRespVO extends BpmOABaseRespVO { @Schema(description = "上传文件") private List fileItems; + + @Schema(description = "后补文件") + private List laterFileItems; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/payment/BpmOAPaymentUpdateReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/payment/BpmOAPaymentUpdateReqVO.java new file mode 100644 index 00000000..9ebb795b --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/payment/BpmOAPaymentUpdateReqVO.java @@ -0,0 +1,29 @@ +package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.payment; + +import cn.iocoder.yudao.framework.common.pojo.UploadUserFile; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +/** + * 付款申请 创建 Request VO + * + * @author 符溶馨 + */ +@Schema(description = "管理后台 - 付款申请创建 Request VO") +@Data +public class BpmOAPaymentUpdateReqVO { + + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED) + private Long id; + + @Schema(description = "后补票批注", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private String annotations; + + @Schema(description = "补票状态 | 0待补票 1已补票 2重新补票 3已确认", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private Integer status; + + @Schema(description = "上传文件", requiredMode = Schema.RequiredMode.REQUIRED) + private List fileItems; +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/print/BpmOAReimbursementPrintDataRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/print/BpmOAPrintDataRespVO.java similarity index 72% rename from yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/print/BpmOAReimbursementPrintDataRespVO.java rename to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/print/BpmOAPrintDataRespVO.java index 4949b7d2..9e6c9b67 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/print/BpmOAReimbursementPrintDataRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/print/BpmOAPrintDataRespVO.java @@ -1,6 +1,8 @@ package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.print; import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.BpmOABaseRespVO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.cash.BpmOACashRespVO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.payment.BpmOAPaymentRespVO; import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.reimbursement.BpmOAReimbursementRespVO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO; import io.swagger.v3.oas.annotations.media.Schema; @@ -14,12 +16,18 @@ import java.util.List; @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) -public class BpmOAReimbursementPrintDataRespVO extends BpmOABaseRespVO { +public class BpmOAPrintDataRespVO extends BpmOABaseRespVO { - @Schema(description = "报销业务数据", requiredMode = Schema.RequiredMode.REQUIRED) + @Schema(description = "报销业务数据") private BpmOAReimbursementRespVO bpmOAReimbursementRespVO ; - @Schema(description = "流程审批节点信息【包含人员签名地址】", requiredMode = Schema.RequiredMode.REQUIRED) + @Schema(description = "现金支出业务数据") + private BpmOACashRespVO bpmOACashRespVO; + + @Schema(description = "付款业务数据") + private BpmOAPaymentRespVO bpmOAPaymentRespVO; + + @Schema(description = "流程审批节点信息【包含人员签名地址】") List processTasks ; /** diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/print/BpmProcessInstancePrintDataRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/print/BpmProcessInstancePrintDataRespVO.java index 1f130cd9..151578c2 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/print/BpmProcessInstancePrintDataRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/print/BpmProcessInstancePrintDataRespVO.java @@ -15,9 +15,9 @@ public class BpmProcessInstancePrintDataRespVO { @Schema(description = "流程标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "oa_reimbursement") private String key; - @Schema(description = "报销业务打印数据", requiredMode = Schema.RequiredMode.REQUIRED) - private BpmOAReimbursementPrintDataRespVO bpmOAReimbursementPrintDataRespVO ; + @Schema(description = "业务打印数据", requiredMode = Schema.RequiredMode.REQUIRED) + private BpmOAPrintDataRespVO printDataRespVO ; - @Schema(description = "现金支出业务打印数据", requiredMode = Schema.RequiredMode.REQUIRED) - private BpmOACashPrintDataRespVO bpmOACashPrintDataRespVO; +// @Schema(description = "现金支出业务打印数据", requiredMode = Schema.RequiredMode.REQUIRED) +// private BpmOACashPrintDataRespVO bpmOACashPrintDataRespVO; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/BpmOAPaymentDO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/BpmOAPaymentDO.java index 1f0936b6..3459fc56 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/BpmOAPaymentDO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/BpmOAPaymentDO.java @@ -112,6 +112,11 @@ public class BpmOAPaymentDO extends BaseDO { */ private String annotations; + /** + * 补票状态 | 0待补票 1已补票 2重新补票 3已确认 + */ + private Integer status; + /** * 父级审批 */ @@ -135,4 +140,10 @@ public class BpmOAPaymentDO extends BaseDO { */ @TableField(typeHandler = JacksonTypeHandler.class) private List fileItems ; + + /** + * 后补附件基本信息 + */ + @TableField(typeHandler = JacksonTypeHandler.class) + private List laterFileItems; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/oa/BpmOAPaymentMapper.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/oa/BpmOAPaymentMapper.java index c09397d5..6bd17c2d 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/oa/BpmOAPaymentMapper.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/oa/BpmOAPaymentMapper.java @@ -1,8 +1,12 @@ package cn.iocoder.yudao.module.bpm.dal.mysql.oa; +import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.payment.BpmOAPaymentPageReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.payment.BpmOAPaymentRespVO; import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAPaymentDO; +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; @@ -12,4 +16,16 @@ import java.util.List; public interface BpmOAPaymentMapper extends BaseMapperX { List selectPaymentList(@Param("type") Integer type); + + default PageResult selectTicketsPage(BpmOAPaymentPageReqVO pageReqVO, Long userId) { + + return selectPage(pageReqVO, new LambdaQueryWrapperX() + .eq(BpmOAPaymentDO::getResult, BpmProcessInstanceResultEnum.APPROVE.getResult()) + .eq(BpmOAPaymentDO::getIsTickets, 1) + .eqIfPresent(BpmOAPaymentDO::getStatus, pageReqVO.getStatus()) + .betweenIfPresent(BpmOAPaymentDO::getCreateTime, pageReqVO.getCreateTime()) + .eq(pageReqVO.getIsMy(), BpmOAPaymentDO::getUserId, userId) + .orderByAsc(BpmOAPaymentDO::getStatus) + .orderByDesc(BpmOAPaymentDO::getId)); + } } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/task/BpmTaskExtMapper.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/task/BpmTaskExtMapper.java index 145d86ec..0666850b 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/task/BpmTaskExtMapper.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/task/BpmTaskExtMapper.java @@ -7,6 +7,7 @@ import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*; import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO; +import cn.iocoder.yudao.module.bpm.enums.task.BpmConstants; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; @@ -100,6 +101,7 @@ public interface BpmTaskExtMapper extends BaseMapperX { .eq(StringUtils.isNotEmpty(pageVO.getName()), BpmProcessInstanceExtDO::getName, pageVO.getName())); queryWrapperX.likeRight(BpmProcessInstanceExtDO::getProcessDefinitionId, "oa_"); queryWrapperX.eq(BpmTaskExtDO::getAssigneeUserId, userId); + queryWrapperX.ne(BpmTaskExtDO::getReason, BpmConstants.AUTO_APPRAVAL); queryWrapperX.betweenIfPresent(BpmTaskExtDO::getCreateTime, pageVO.getCreateTime()); queryWrapperX.orderByDesc(BpmTaskExtDO::getEndTime); diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAPaymentService.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAPaymentService.java index 6c2db11e..ecceaba6 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAPaymentService.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAPaymentService.java @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.payment.BpmOAPaymentCreateReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.payment.BpmOAPaymentPageReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.payment.BpmOAPaymentRespVO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.payment.BpmOAPaymentUpdateReqVO; import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAPaymentDO; import javax.validation.Valid; @@ -51,8 +52,31 @@ public interface BpmOAPaymentService { /** * 获得 后补票的付款申请分页列表 - * @param pageReqVO 分页条件 + * + * @param pageReqVO 分页条件 + * @param userId 用户编号 * @return 付款申请分页列表 */ - PageResult getPaymentPage(BpmOAPaymentPageReqVO pageReqVO); + PageResult getPaymentPage(BpmOAPaymentPageReqVO pageReqVO, Long userId); + + /** + * 更新付款申请附件 + * @param updateReqVO 更新信息 + */ + void updateFiles(BpmOAPaymentUpdateReqVO updateReqVO); + + /** + * 更新付款申请补票状态 + * @param updateReqVO 更新信息 + */ + void updateStatus(BpmOAPaymentUpdateReqVO updateReqVO); + + /** + * 删除后补附件信息 + * @param id 编号 + * @param url utl + */ + void deleteFiles(Long id, String url); + + BpmOAPaymentRespVO convertPayment(BpmOAPaymentDO payment); } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAPaymentServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAPaymentServiceImpl.java index 463c081d..2dfe3382 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAPaymentServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAPaymentServiceImpl.java @@ -1,36 +1,40 @@ package cn.iocoder.yudao.module.bpm.service.oa; -import cn.hutool.core.util.StrUtil; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.collection.CollectionUtil; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.UploadUserFile; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; -import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.payment.BpmOAPaymentCreateReqVO; -import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.payment.BpmOAPaymentPageReqVO; -import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.payment.BpmOAPaymentRespVO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.payment.*; import cn.iocoder.yudao.module.bpm.dal.dataobject.financialpayment.FinancialPaymentDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAPaymentDO; -import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAReimbursementItemDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO; import cn.iocoder.yudao.module.bpm.dal.mysql.oa.BpmOAPaymentMapper; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; import cn.iocoder.yudao.module.bpm.service.financialpayment.FinancialPaymentService; import cn.iocoder.yudao.module.bpm.service.task.BpmHistoryProcessInstanceService; import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService; +import cn.iocoder.yudao.module.system.api.bank.BankApi; +import cn.iocoder.yudao.module.system.api.bank.dto.BankRespDTO; +import cn.iocoder.yudao.module.system.api.dept.DeptApi; +import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; +import cn.iocoder.yudao.module.system.api.project.ProjectApi; +import cn.iocoder.yudao.module.system.api.project.dto.ProjectDTO; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; +import org.apache.commons.lang3.StringUtils; import org.flowable.engine.runtime.ProcessInstance; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; +import java.util.*; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.OA_PAYMENT_FILES_NOT_NULL; import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.OA_PAYMENT_NOT_EXISTS; /** @@ -62,12 +66,24 @@ public class BpmOAPaymentServiceImpl extends BpmOABaseService implements BpmOAPa @Resource private AdminUserApi userApi; + @Resource + private DeptApi deptApi; + + @Resource + private BankApi bankApi; + + @Resource + private ProjectApi projectApi; + @Override public Long createPayment(Long userId, BpmOAPaymentCreateReqVO createReqVO) { //插入OA 付款申请 BpmOAPaymentDO paymentDO = BeanUtils.toBean(createReqVO, BpmOAPaymentDO.class).setUserId(userId) .setResult(BpmProcessInstanceResultEnum.PROCESS.getResult()); + if (createReqVO.getIsTickets() == 1) { + paymentDO.setStatus(0); // 设置补票状态 为待补票 + } paymentMapper.insert(paymentDO); // 发起 BPM 流程 @@ -145,9 +161,103 @@ public class BpmOAPaymentServiceImpl extends BpmOABaseService implements BpmOAPa } @Override - public PageResult getPaymentPage(BpmOAPaymentPageReqVO pageReqVO) { + public PageResult getPaymentPage(BpmOAPaymentPageReqVO pageReqVO, Long userId) { - return null; + return paymentMapper.selectTicketsPage(pageReqVO, userId); + } + + @Override + public void updateFiles(BpmOAPaymentUpdateReqVO updateReqVO) { + // 校验付款申请是否存在 + BpmOAPaymentDO paymentDO = validateLeaveExists(updateReqVO.getId()); + + //这里的逻辑,如果fileItems不为空,且有数据,那么说明是上传了附件的,则需要更工作流文件表对应的实例Id + if (CollUtil.isNotEmpty(updateReqVO.getFileItems())) { + uploadBpmFileProcessInstanceId(paymentDO.getProcessInstanceId(), updateReqVO.getFileItems()) ; + }else { + throw exception(OA_PAYMENT_FILES_NOT_NULL); + } + + // 更新附件 + paymentMapper.updateById(new BpmOAPaymentDO() + .setId(paymentDO.getId()) + .setLaterFileItems(updateReqVO.getFileItems()) + .setStatus(updateReqVO.getStatus())); + } + + @Override + public void updateStatus(BpmOAPaymentUpdateReqVO updateReqVO) { + // 校验付款申请是否存在 + BpmOAPaymentDO paymentDO = validateLeaveExists(updateReqVO.getId()); + + BpmOAPaymentDO update = BeanUtils.toBean(updateReqVO, BpmOAPaymentDO.class); + if (update.getStatus() == 3) { + List fileItems = paymentDO.getFileItems() == null ? new ArrayList<>() : paymentDO.getFileItems(); + fileItems.addAll(paymentDO.getLaterFileItems()); + update.setFileItems(fileItems); + } + + paymentMapper.updateById(update); + } + + @Override + public void deleteFiles(Long id, String url) { + + // 校验付款申请是否存在 + BpmOAPaymentDO paymentDO = validateLeaveExists(id); + + List fileItems = paymentDO.getLaterFileItems(); + if (CollUtil.isNotEmpty(fileItems)) { + fileItems.removeIf(item -> item.getUrl().equals(url)); + + paymentMapper.updateById(new BpmOAPaymentDO() + .setId(id) + .setLaterFileItems(fileItems)); + } + } + + @Override + public BpmOAPaymentRespVO convertPayment(BpmOAPaymentDO payment) { + + BpmOAPaymentRespVO respVO = BeanUtils.toBean(payment, BpmOAPaymentRespVO.class); + if (respVO != null) { + + // 获取部门信息Map + List deptIds = new ArrayList<>(); + if (CollectionUtil.isNotEmpty(respVO.getFactoryDetail())) { + deptIds.addAll(convertList(respVO.getFactoryDetail(), FactoryDetailVO::getDeptId)); + }else { + deptIds.add(payment.getDeptId()); + } + deptIds.add(payment.getPaymentCompany()); + Map dtoMap = deptApi.getDeptMap(new HashSet<>(deptIds)); + + // 设置部门名称 + respVO.setDeptName(dtoMap.get(payment.getDeptId()) != null ? dtoMap.get(payment.getDeptId()).getName() : null); + // 设置付款公司名称 + respVO.setPaymentCompanyName(dtoMap.get(payment.getPaymentCompany()).getName()); + // 设置工厂名称 + respVO.getFactoryDetail().forEach(item -> { + item.setFactoryName(dtoMap.get(item.getDeptId()).getName()); + }); + + if (StringUtils.isNotEmpty(payment.getProjectNo())) { + // 获取项目信息 + ProjectDTO project = projectApi.getProject(payment.getProjectNo()).getCheckedData(); + // 设置项目名称 + respVO.setProjectName(project.getName()); + } + + if (payment.getBankId() != null) { + // 获取银行卡信息 + BankRespDTO bankResp = bankApi.getBank(payment.getBankId()).getCheckedData(); + // 设置银行卡信息 + respVO.setBankName(bankResp.getBankName()); + respVO.setBankNo(bankResp.getBankNo()); + respVO.setNickname(bankResp.getNickname()); + } + } + return respVO; } private BpmOAPaymentDO validateLeaveExists(Long id) { diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOASalaryService.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOASalaryService.java index a2f25bb7..586c4c14 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOASalaryService.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOASalaryService.java @@ -4,6 +4,7 @@ import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.salary.BpmOASalaryCrea import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOASalaryDO; import javax.validation.Valid; +import java.util.List; /** * 薪资付款申请 Service 接口 @@ -13,7 +14,7 @@ import javax.validation.Valid; public interface BpmOASalaryService { /** - * 创建用章申请 + * 创建薪资付款申请 * * @param userId 用户编号 * @param createReqVO 创建信息 @@ -22,7 +23,7 @@ public interface BpmOASalaryService { Long createSalary(Long userId, @Valid BpmOASalaryCreateReqVO createReqVO); /** - * 更新用章申请的状态 + * 更新薪资付款申请的状态 * * @param id 编号 * @param result 结果 @@ -30,17 +31,24 @@ public interface BpmOASalaryService { void updateSalaryResult(Long id, Integer result); /** - * 获得用章申请 + * 获得薪资付款申请 * * @param id 编号 - * @return 用章申请 + * @return 薪资付款申请 */ BpmOASalaryDO getSalary(Long id); /** - * 获得指定的用章申请 + * 获得指定的薪资付款申请 * @param processInstanceId 流程实例编号 - * @return 用章申请 + * @return 薪资付款申请 */ BpmOASalaryDO getByProcessInstanceId(String processInstanceId); + + /** + * 获得指定的薪资付款申请 + * @param processInstanceIds 流程实例编号 + * @return 薪资付款申请 + */ + List getListByProcessInstanceIds(List processInstanceIds); } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOASalaryServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOASalaryServiceImpl.java index 4efa97d9..d0862455 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOASalaryServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOASalaryServiceImpl.java @@ -107,4 +107,10 @@ public class BpmOASalaryServiceImpl extends BpmOABaseService implements BpmOASal return salaryMapper.selectOne(BpmOASalaryDO::getProcessInstanceId, processInstanceId); } + + @Override + public List getListByProcessInstanceIds(List processInstanceIds) { + + return salaryMapper.selectList(BpmOASalaryDO::getProcessInstanceId, processInstanceIds); + } } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java index e93f2f6a..6551ae1e 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java @@ -1 +1 @@ -package cn.iocoder.yudao.module.bpm.service.task; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.date.LocalDateTimeUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.date.DateUtils; import cn.iocoder.yudao.framework.common.util.number.NumberUtils; import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission; import cn.iocoder.yudao.framework.flowable.core.util.FlowableUtils; import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.cash.BpmOACashRespVO; import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.print.BpmOACashPrintDataRespVO; import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.print.BpmOAReimbursementPrintDataRespVO; import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.print.BpmProcessInstancePrintDataReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.print.BpmProcessInstancePrintDataRespVO; import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.reimbursement.BpmOAReimbursementRespVO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskApproveReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO; import cn.iocoder.yudao.module.bpm.convert.task.BpmProcessInstanceConvert; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessCcDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOACashDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAImprestDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAReimbursementDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO; import cn.iocoder.yudao.module.bpm.dal.mysql.DynamicMapper; import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmTaskAssignRuleMapper; import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmProcessInstanceExtMapper; import cn.iocoder.yudao.module.bpm.enums.task.BpmConstants; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceDeleteReasonEnum; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum; import cn.iocoder.yudao.module.bpm.framework.bpm.core.event.BpmProcessInstanceResultEventPublisher; import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessCcService; import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService; import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService; import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService; import cn.iocoder.yudao.module.bpm.service.oa.BpmOACashService; import cn.iocoder.yudao.module.bpm.service.oa.BpmOAImprestService; import cn.iocoder.yudao.module.bpm.service.oa.BpmOAProcureServiceImpl; import cn.iocoder.yudao.module.bpm.service.oa.BpmOAReimbursementService; import cn.iocoder.yudao.module.infra.api.config.ConfigApi; import cn.iocoder.yudao.module.infra.api.file.FileApi; import cn.iocoder.yudao.module.system.api.dept.DeptApi; import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; import cn.iocoder.yudao.module.system.api.permission.PermissionApi; import cn.iocoder.yudao.module.system.api.permission.dto.DeptDataPermissionRespDTO; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import jodd.util.StringUtil; import lombok.extern.slf4j.Slf4j; import org.flowable.engine.HistoryService; import org.flowable.engine.RuntimeService; import org.flowable.engine.TaskService; import org.flowable.engine.delegate.event.FlowableCancelledEvent; import org.flowable.engine.history.HistoricProcessInstance; import org.flowable.engine.repository.ProcessDefinition; import org.flowable.engine.runtime.ProcessInstance; import org.flowable.task.api.Task; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.support.TransactionSynchronization; import org.springframework.transaction.support.TransactionSynchronizationManager; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import javax.validation.Valid; import java.lang.reflect.Field; import java.text.DecimalFormat; import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId; import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; /** * 流程实例 Service 实现类 *

* ProcessDefinition & ProcessInstance & Execution & Task 的关系: * 1. *

* HistoricProcessInstance & ProcessInstance 的关系: * 1. *

* 简单来说,前者 = 历史 + 运行中的流程实例,后者仅是运行中的流程实例 */ @Service @Validated @Slf4j public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService { @Resource private TaskService engineTaskService; @Resource private BpmTaskAssignRuleMapper taskRuleMapper; @Resource private BpmUserGroupService userGroupService; @Resource private RuntimeService runtimeService; @Resource private BpmProcessInstanceExtMapper processInstanceExtMapper; @Resource @Lazy // 解决循环依赖 private BpmTaskService taskService; @Resource private BpmProcessDefinitionService processDefinitionService; @Resource private HistoryService historyService; @Resource private AdminUserApi adminUserApi; @Resource private DeptApi deptApi; @Resource private BpmProcessInstanceResultEventPublisher processInstanceResultEventPublisher; @Resource @Lazy // 解决循环依赖 private BpmMessageService messageService; @Resource private ConfigApi configApi; @Resource private DynamicMapper dynamicMapper ; @Resource private BpmProcessCcService processCcService; @Override public ProcessInstance getProcessInstance(String id) { return runtimeService.createProcessInstanceQuery().processInstanceId(id).singleResult(); } @Override public List getProcessInstances(Set ids) { return runtimeService.createProcessInstanceQuery().processInstanceIds(ids).list(); } public String transform(String input) { if(StringUtil.isNotEmpty(input)) { String[] parts = input.split(","); StringBuilder result = new StringBuilder(); for (String part : parts) { String[] keyValue = part.split(":"); if (keyValue.length > 1) { result.append(keyValue[1]).append(","); } } if (result.length() > 0) { return result.substring(0, result.length() - 1); } } return ""; } public String replaceValues(String input, Map map) { String[] parts = input.split(","); StringBuilder result = new StringBuilder(); for (String part : parts) { String[] keyValue = part.split(":"); if (keyValue.length > 1) { String key = keyValue[1].trim(); // 去除可能的空格 if (map.containsKey(key)) { Object value = map.get(key); String stringValue = (value != null) ? value.toString() : ""; // 将值转换为字符串 result.append(keyValue[0].trim()).append(":").append(stringValue).append(","); } else { //result.append(part).append(","); } } } if (result.length() > 0) { return result.substring(0, result.length() - 1); } return ""; } @Override @TenantIgnore public PageResult getMyProcessInstancePage(Long userId, BpmProcessInstanceMyPageReqVO pageReqVO) { // 通过 BpmProcessInstanceExtDO 表,先查询到对应的分页 PageResult pageResult = processInstanceExtMapper.selectPage(userId, pageReqVO); List bpmProcessInstanceExtDOList = pageResult.getList() ; for (int i = 0; i < bpmProcessInstanceExtDOList.size() ; i++) { BpmProcessInstanceExtDO bpmProcessInstanceExtDO = bpmProcessInstanceExtDOList.get(i) ; String input = bpmProcessInstanceExtDO.getFieldNames() ; if(StringUtil.isNotEmpty(input)) { String sql = "SELECT " + transform(bpmProcessInstanceExtDO.getFieldNames()) + " FROM " + bpmProcessInstanceExtDO.getTableName() + " WHERE id=" + bpmProcessInstanceExtDO.getBusinessKey(); log.info(sql); Map map = dynamicMapper.selectListByTableName(sql) ; String detailInfo = replaceValues(bpmProcessInstanceExtDO.getFieldNames(),map) ; bpmProcessInstanceExtDO.setDetailInfo(detailInfo); } } if (CollUtil.isEmpty(pageResult.getList())) { return new PageResult<>(pageResult.getTotal()); } // 获得流程 Task Map List processInstanceIds = convertList(pageResult.getList(), BpmProcessInstanceExtDO::getProcessInstanceId); Map> taskMap = taskService.getTaskMapByProcessInstanceIds(processInstanceIds); List ids = taskMap.values().stream() .flatMap(Collection::stream) .map(Task::getAssignee) .collect(Collectors.toList()); Iterator iterator = ids.iterator(); while (iterator.hasNext()) { String id = iterator.next(); if (id == null) { iterator.remove(); } } List longIds = ids.stream() .map(Long::valueOf) .collect(Collectors.toList()); // 获得 User Map Map userMap = adminUserApi.getUserMap(longIds); // 转换返回 return BpmProcessInstanceConvert.INSTANCE.convertPage(pageResult, taskMap, userMap); } @Override @Transactional(rollbackFor = Exception.class) public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqVO createReqVO) { // 获得流程定义 ProcessDefinition definition = processDefinitionService.getProcessDefinition(createReqVO.getProcessDefinitionId()); // 发起流程 return createProcessInstance0(userId, definition, createReqVO.getVariables(), null); } @Override @Transactional(rollbackFor = Exception.class) public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqDTO createReqDTO) { // 获得流程定义 ProcessDefinition definition = processDefinitionService.getActiveProcessDefinition(createReqDTO.getProcessDefinitionKey()); // 发起流程 return createProcessInstance0(userId, definition, createReqDTO.getVariables(), createReqDTO.getBusinessKey()); } @Override public BpmProcessInstanceRespVO getProcessInstanceVO(String id) { // 获得流程实例 HistoricProcessInstance processInstance = getHistoricProcessInstance(id); if (processInstance == null) { return null; } BpmProcessInstanceExtDO processInstanceExt = processInstanceExtMapper.selectByProcessInstanceId(id); Assert.notNull(processInstanceExt, "流程实例拓展({}) 不存在", id); // 获得流程定义 ProcessDefinition processDefinition = processDefinitionService .getProcessDefinition(processInstance.getProcessDefinitionId()); Assert.notNull(processDefinition, "流程定义({}) 不存在", processInstance.getProcessDefinitionId()); BpmProcessDefinitionExtDO processDefinitionExt = processDefinitionService.getProcessDefinitionExt( processInstance.getProcessDefinitionId()); Assert.notNull(processDefinitionExt, "流程定义拓展({}) 不存在", id); String bpmnXml = processDefinitionService.getProcessDefinitionBpmnXML(processInstance.getProcessDefinitionId()); // 获得 User AdminUserRespDTO startUser = adminUserApi.getUser(NumberUtils.parseLong(processInstance.getStartUserId())).getCheckedData(); DeptRespDTO dept = null; if (startUser != null) { dept = deptApi.getDept(startUser.getDeptId()).getCheckedData(); } // 拼接结果 return BpmProcessInstanceConvert.INSTANCE.convert2(processInstance, processInstanceExt, processDefinition, processDefinitionExt, bpmnXml, startUser, dept); } @Override public void cancelProcessInstance(Long userId, @Valid BpmProcessInstanceCancelReqVO cancelReqVO) { // 校验流程实例存在 ProcessInstance instance = getProcessInstance(cancelReqVO.getId()); if (instance == null) { throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS); } // 只能取消自己的 if (!Objects.equals(instance.getStartUserId(), String.valueOf(userId))) { throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF); } // 通过删除流程实例,实现流程实例的取消, // 删除流程实例,正则执行任务 ACT_RU_TASK. 任务会被删除。通过历史表查询 deleteProcessInstance(cancelReqVO.getId(), BpmProcessInstanceDeleteReasonEnum.CANCEL_TASK.format(cancelReqVO.getReason())); } /** * 获得历史的流程实例 * * @param id 流程实例的编号 * @return 历史的流程实例 */ @Override public HistoricProcessInstance getHistoricProcessInstance(String id) { return historyService.createHistoricProcessInstanceQuery().processInstanceId(id).singleResult(); } @Override public List getHistoricProcessInstances(Set ids) { return historyService.createHistoricProcessInstanceQuery().processInstanceIds(ids).list(); } @Override public void createProcessInstanceExt(ProcessInstance instance) { // 获得流程定义 ProcessDefinition definition = processDefinitionService.getProcessDefinition2(instance.getProcessDefinitionId()); // 插入 BpmProcessInstanceExtDO 对象 BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO() .setProcessInstanceId(instance.getId()) .setProcessDefinitionId(definition.getId()) .setName(instance.getProcessDefinitionName()) .setStartUserId(Long.valueOf(instance.getStartUserId())) .setCategory(definition.getCategory()) .setStatus(BpmProcessInstanceStatusEnum.RUNNING.getStatus()) .setResult(BpmProcessInstanceResultEnum.PROCESS.getResult()); processInstanceExtMapper.insert(instanceExtDO); } @Override @DataPermission(enable = false) public void updateProcessInstanceExtCancel(FlowableCancelledEvent event) { // 判断是否为 Reject 不通过。如果是,则不进行更新. // 因为,updateProcessInstanceExtReject 方法,已经进行更新了 if (BpmProcessInstanceDeleteReasonEnum.isRejectReason((String) event.getCause())) { return; } // 需要主动查询,因为 instance 只有 id 属性 // 另外,此时如果去查询 ProcessInstance 的话,字段是不全的,所以去查询了 HistoricProcessInstance HistoricProcessInstance processInstance = getHistoricProcessInstance(event.getProcessInstanceId()); // 更新拓展表 BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO() .setProcessInstanceId(event.getProcessInstanceId()) .setEndTime(LocalDateTime.now()) // 由于 ProcessInstance 里没有办法拿到 endTime,所以这里设置 .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus()) .setResult(BpmProcessInstanceResultEnum.CANCEL.getResult()); processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); // 发送流程实例的状态事件 processInstanceResultEventPublisher.sendProcessInstanceResultEvent( BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult())); } @Override @DataPermission(enable = false) public void updateProcessInstanceExtComplete(ProcessInstance instance) { // 需要主动查询,因为 instance 只有 id 属性 // 另外,此时如果去查询 ProcessInstance 的话,字段是不全的,所以去查询了 HistoricProcessInstance HistoricProcessInstance processInstance = getHistoricProcessInstance(instance.getId()); // 更新拓展表 BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO() .setProcessInstanceId(instance.getProcessInstanceId()) .setEndTime(LocalDateTime.now()) // 由于 ProcessInstance 里没有办法拿到 endTime,所以这里设置 .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus()) .setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()); // 如果正常完全,说明审批通过 processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); Map processVariables = runtimeService.getVariables(instance.getProcessInstanceId()); String reason = (String) processVariables.get("approve_reason"); // 发送流程被通过的消息 messageService.sendMessageWhenProcessInstanceApprove(BpmProcessInstanceConvert.INSTANCE.convert2ApprovedReq(instance, reason)); // 发送流程实例的状态事件 processInstanceResultEventPublisher.sendProcessInstanceResultEvent( BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult())); } @Override @Transactional(rollbackFor = Exception.class) @DataPermission(enable = false) public void updateProcessInstanceExtReject(String id, String reason) { // 需要主动查询,因为 instance 只有 id 属性 ProcessInstance processInstance = getProcessInstance(id); // 删除流程实例,以实现驳回任务时,取消整个审批流程 deleteProcessInstance(id, StrUtil.format(BpmProcessInstanceDeleteReasonEnum.REJECT_TASK.format(reason))); // 更新 status + result // 注意,不能和上面的逻辑更换位置。因为 deleteProcessInstance 会触发流程的取消,进而调用 updateProcessInstanceExtCancel 方法, // 设置 result 为 BpmProcessInstanceStatusEnum.CANCEL,显然和 result 不一定是一致的 BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO() .setProcessInstanceId(id) .setEndTime(LocalDateTime.now()) // 由于 ProcessInstance 里没有办法拿到 endTime,所以这里设置 .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus()) .setResult(BpmProcessInstanceResultEnum.REJECT.getResult()); processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); // 发送流程被不通过的消息 messageService.sendMessageWhenProcessInstanceReject(BpmProcessInstanceConvert.INSTANCE.convert2RejectReq(processInstance, reason)); // 发送流程实例的状态事件 processInstanceResultEventPublisher.sendProcessInstanceResultEvent( BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult())); } private void deleteProcessInstance(String id, String reason) { runtimeService.deleteProcessInstance(id, reason); } private String createProcessInstance0(Long userId, ProcessDefinition definition, Map variables, String businessKey) { // 校验流程定义 if (definition == null) { throw exception(PROCESS_DEFINITION_NOT_EXISTS); } if (definition.isSuspended()) { throw exception(PROCESS_DEFINITION_IS_SUSPENDED); } // 设置当前用户 FlowableUtils.setAuthenticatedUserId(userId); //获取流程发起人User AdminUserRespDTO startUser = adminUserApi.getUser(userId).getCheckedData(); //获取流程发起人部门信息 DeptRespDTO startDeptInfo = deptApi.getDept(startUser.getDeptId()).getCheckedData(); // 获取岗位信息 Set postIds = startUser.getPostIds(); ArrayList list = new ArrayList<>(postIds); //配置通用流程变量 variables.put("post_id", list.get(0).toString()); // 只获配置的首个岗位 variables.put("user_id", userId.toString()); // 配置发起人用户id variables.put("dept_id", startUser.getDeptId().toString()); // 配置发起人部门id variables.put("dept_flag", startDeptInfo.getFlag()); // 配置发起人部门flag // 创建流程实例 ProcessInstance instance = runtimeService.createProcessInstanceBuilder() .processDefinitionId(definition.getId()) .businessKey(businessKey) .name(definition.getName().trim()) .variables(variables) .start(); // 设置流程名字 runtimeService.setProcessInstanceName(instance.getId(), definition.getName()); // 发送通知。在事务提交时,批量执行操作,所以直接查询会无法查询到 ProcessInstance,所以这里是通过监听事务的提交来实现。 TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() { @Override public void afterCommit() { // 创建流程后,添加抄送人 processCCToUsers(instance, variables); } }); return instance.getId(); // // 补全流程实例的拓展表 // processInstanceExtMapper.updateByProcessInstanceId(new BpmProcessInstanceExtDO().setProcessInstanceId(instance.getId()) // .setFormVariables(variables)); // // /** 创建流程后,添加抄送人 End add by yj 2024.1.4 */ // processCCToUsers(definition, instance); // /** 通过自己发起的流程 */ // approveSelfTask(instance.getId()) ; } private void approveSelfTask(String processInstanceId) { List tasks = engineTaskService.createTaskQuery().processInstanceId(processInstanceId).list(); if (tasks != null && tasks.size() > 0) { Task task = tasks.get(0); String assigneeId = task.getAssignee(); //如果当前登陆用户是审批人,那么自动审批通过 if (assigneeId.equals(SecurityFrameworkUtils.getLoginUserId().toString())) { BpmTaskApproveReqVO reqVO = new BpmTaskApproveReqVO(); reqVO.setId(task.getId()); reqVO.setReason(BpmConstants.AUTO_APPRAVAL); taskService.approveTask(getLoginUserId(), reqVO); } } } /** * 获得抄送我的流程实例的分页 * * @param userId 用户编号 * @param pageReqVO 分页请求 * @return 流程实例的分页 */ public PageResult getMyCCProcessInstancePage(Long userId, BpmProcessInstanceMyPageReqVO pageReqVO) { // 通过 BpmProcessInstanceExtDO 表,先查询到对应的分页 PageResult pageResult = processInstanceExtMapper.selectCCPage(userId, pageReqVO); if (CollUtil.isEmpty(pageResult.getList())) { return new PageResult<>(pageResult.getTotal()); } // 获得流程 Task Map List processInstanceIds = convertList(pageResult.getList(), BpmProcessInstanceExtDO::getProcessInstanceId); Map> taskMap = taskService.getTaskMapByProcessInstanceIds(processInstanceIds); // 转换返回 return BpmProcessInstanceConvert.INSTANCE.convertPage(pageResult, taskMap, null); } public List getProcessInstancesGroupByModelName(BpmProcessInstanceStatisticsReqVO pageReqVO) { pageReqVO = getUserids(pageReqVO); return processInstanceExtMapper.getProcessInstancesGroupByModelName(pageReqVO); } public List getProcessInstancesGroupByResultStatus(BpmProcessInstanceStatisticsReqVO pageReqVO) { pageReqVO = getUserids(pageReqVO); return processInstanceExtMapper.getProcessInstancesGroupByResultStatus(pageReqVO); } public PageResult getStatisticsProcessInstancePage(@Valid BpmProcessInstanceMyPageReqVO pageReqVO) { // 通过 BpmProcessInstanceExtDO 表,先查询到对应的分页 PageResult pageResult = processInstanceExtMapper.selectStatisticePage(pageReqVO); if (CollUtil.isEmpty(pageResult.getList())) { return new PageResult<>(pageResult.getTotal()); } // 获得流程 Task Map List processInstanceIds = convertList(pageResult.getList(), BpmProcessInstanceExtDO::getProcessInstanceId); Map> taskMap = taskService.getTaskMapByProcessInstanceIds(processInstanceIds); List ids = taskMap.values().stream() .flatMap(Collection::stream) .map(Task::getAssignee) .collect(Collectors.toList()); Iterator iterator = ids.iterator(); while (iterator.hasNext()) { String id = iterator.next(); if (id == null) { iterator.remove(); } } List longIds = ids.stream() .map(Long::valueOf) .collect(Collectors.toList()); //获得 审批人 User Map Map assigneeUserMap = adminUserApi.getUserMap(longIds); //获得 发起人 User Map List bpieDOs = pageResult.getList(); longIds = new ArrayList<>(); for (BpmProcessInstanceExtDO bpieDO : bpieDOs) { longIds.add(bpieDO.getStartUserId()); } Map startUserMap = adminUserApi.getUserMap(longIds); // 转换返回 return BpmProcessInstanceConvert.INSTANCE.convertStatisticsPage(pageResult, taskMap, assigneeUserMap, startUserMap); } @Resource PermissionApi permissionApi; /** * 根据数据权限,查询关联操作的用户IDS * * @param pageReqVO * @param * @return */ private T getUserids(T pageReqVO) { try { Class clazz = (Class) pageReqVO.getClass(); Field idField = clazz.getDeclaredField("userIds"); idField.setAccessible(true); // 设置可访问性 Long[] userIds = null; Long userId = WebFrameworkUtils.getLoginUserId(); DeptDataPermissionRespDTO deptDataPermission = permissionApi.getDeptDataPermission(userId).getCheckedData(); //查询全部 if (deptDataPermission.getAll()) { //idField.set(pageReqVO, null); // 设置属性值 return pageReqVO; } // 情况二,即不能查看部门,又不能查看自己,则说明 100% 无权限 if (CollUtil.isEmpty(deptDataPermission.getDeptIds()) && Boolean.FALSE.equals(deptDataPermission.getSelf())) { //设置成0,一个不存在的用户Id,就查询不到数据了。 userIds = new Long[]{0L}; idField.set(pageReqVO, userIds); return pageReqVO; } //情况三 至查询自己 if (deptDataPermission.getSelf()) { userIds = new Long[]{userId}; idField.set(pageReqVO, userIds); return pageReqVO; } Set deptIds = deptDataPermission.getDeptIds(); //查询部门关联的用户Id List users = adminUserApi.getUserListByDeptIds(deptIds).getCheckedData(); List tempList = new ArrayList<>(); for (AdminUserRespDTO user : users) { Long id = user.getId(); tempList.add(id); } tempList.add(userId); userIds = tempList.stream().toArray(Long[]::new); //将临时的List集合转换成数组集合 idField.set(pageReqVO, userIds); return pageReqVO; } catch (Exception exception) { exception.printStackTrace(); throw exception(BPM_SYSTEM_BUG); } } /** * /创建流程后,添加抄送人 Begin add by yj 2024.1.4 * 在设计流程的时候,需要添加一个任务块 名字必须叫Activity_cc 分配权限的时候,需要选择用户组。 * * @param definition * @param instance */ private void processCCToUsers(ProcessDefinition definition, ProcessInstance instance) { //获取bpm_task_assign_reule (Bpm 任务规则表)的流程中有没有配置抄送节点 固定抄送名称为:Activity_cc String processDefinitionId = definition.getId(); List rules = taskRuleMapper.selectListByProcessDefinitionId(processDefinitionId, null); String BpmConstantsName = BpmConstants.CC_NAME; // 获取发起人信息 AdminUserRespDTO userRespDTO = adminUserApi.getUser(Long.valueOf(instance.getStartUserId())).getCheckedData(); DeptRespDTO deptRespDTO = deptApi.getDept(userRespDTO.getDeptId()).getCheckedData(); //发起人是深圳分公司 if (deptRespDTO.getFlag().contains("136")) { BpmConstantsName = BpmConstants.CCSZ_NAME; } for (BpmTaskAssignRuleDO rule : rules) { String key = rule.getTaskDefinitionKey(); //任务名称 Integer type = rule.getType(); if (!key.isEmpty() && key.equals(BpmConstantsName) && type == 40) { StringBuffer str = new StringBuffer(); Set options = rule.getOptions(); List list = new ArrayList(options); for (Long groupId : list) { //需要根据这个groupId,查询这个组中的用户id BpmUserGroupDO userGroup = userGroupService.getUserGroup(groupId); Set userIds = userGroup.getMemberUserIds(); List userIdList = new ArrayList(userIds); for (Long user_id : userIdList) { str.append("[").append(user_id).append("]"); } } //流程是采购计划时 if (definition.getKey().equals(BpmOAProcureServiceImpl.PROCESS_KEY)) { //发起人部门为 生产部及以下时 if (deptRespDTO.getFlag().contains("130")) { //添加 供应部抄送 BpmUserGroupDO userGroup = userGroupService.getUserGroup(121L); Set userIds = userGroup.getMemberUserIds(); List userIdList = new ArrayList(userIds); for (Long user_id : userIdList) { str.append("[").append(user_id).append("]"); } } } String ccids = str.toString(); //根据processDefinitionId 将ccids保存到bpm_process_instance_ext中的ccids字段 BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO().setProcessDefinitionId(processDefinitionId) .setCcids(ccids).setProcessInstanceId(instance.getProcessInstanceId()); processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); break; } } } /** * 创建流程后,添加抄送人 * @param instance 流程实例 */ private void processCCToUsers(ProcessInstance instance, Map variables) { // 根据流程名称、流程发起人 查询流程配置的抄送人信息 List processCcList = processCcService.getCCListByName(instance.getName(), Long.valueOf(instance.getStartUserId())); // 提取抄送信息用中对应的用户组编号 Set userGroupIds = processCcList.stream() .flatMap(data -> data.getUserGroupId().stream()) .collect(Collectors.toSet()); //根据processDefinitionId 将ccIds保存到bpm_process_instance_ext中的ccIds字段 BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO() .setProcessDefinitionId(instance.getProcessDefinitionId()) .setFormVariables(variables) .setProcessInstanceId(instance.getProcessInstanceId()); if (CollectionUtil.isNotEmpty(userGroupIds)) { // 获取用户组信息 List userGroups = userGroupService.getUserGroupList(userGroupIds); // 提取用户组中对应的用户ID Set userIds = userGroups.stream() .flatMap(data -> data.getMemberUserIds().stream()) .collect(Collectors.toSet()); // 将用户ID列表转换为字符串 String ccIds = userIds.stream() .map(id -> "[" + id + "]") // 每个值用方括号包裹 .collect(Collectors.joining()); //根据processDefinitionId 将ccIds保存到bpm_process_instance_ext中的ccIds字段 instanceExtDO.setCcids(ccIds); } processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); } @Override public List getUserProcessTpo10(BpmProcessInstanceStatisticsReqVO pageReqVO) { //按审核人分组查询,统计已完成流程数量及平均耗时间 List respVOS = processInstanceExtMapper.getUserProcessTpo10(pageReqVO); if (respVOS == null || respVOS.size() == 0) { return null; } List idList = respVOS.stream() .map(BpmProcessFinishStatisticsRespVO::getUserId) .collect(Collectors.toList()); //根据userId,查询UserMap Map userMap = adminUserApi.getUserMap(idList); Long[] idsArray = new Long[userMap.size()]; // 使用 map 的 keySet() 方法获取键集合 Set keys = userMap.keySet(); // 遍历键集合,将每个键添加到数组中 int index = 0; for (Long key : keys) { idsArray[index++] = key; } pageReqVO.setUserIds(idsArray); //按审核人分组查询,未审批完成的流程数量 List bpmTaskExtDOs = processInstanceExtMapper.selectUnfinishProcessCount(pageReqVO); //按审核人分组查询,未完成的记录数 Map unFinfishCountCountMap = new HashMap<>(); for (BpmProcessFinishStatisticsRespVO item : bpmTaskExtDOs) { unFinfishCountCountMap.put(item.getUserId(), item.getUnFinfishCount()); } respVOS.forEach(respVO -> respVO.setName(userMap.get(respVO.getUserId()).getNickname())); respVOS.forEach(respVO -> respVO.setUnFinfishCount(unFinfishCountCountMap.get(respVO.getUserId()))); //获取排行榜第一记录的耗时,作为基础数据 double num = Double.parseDouble(respVOS.get(0).getUserTime()); // 先将字符串转换为双精度浮点数 int baseNumber = (int) num; // 再通过类型转换操作符将其转换为整数 DecimalFormat df = new DecimalFormat("#.00"); respVOS.forEach(respVO -> { //格式化流程完成率 float finfishCount = (float) respVO.getFinfishCount(); float unFinfishCount = respVO.getUnFinfishCount() == null ? 0 : respVO.getUnFinfishCount(); float all = finfishCount + unFinfishCount; float result = finfishCount / all; float rate = result * 100; respVO.setCompletionRate(df.format(rate) + "%"); double dValue = Double.parseDouble(respVO.getUserTime()); // 将字符串转换为double类型 int roundedValue = (int) Math.round(dValue); // 使用Math.round()进行四舍五入,并转换为int类型 respVO.setUserTime(roundedValue + ""); //格式化进度百度比, 参照最高的数据进行百分比显示 double percentage = ((int) Double.parseDouble(respVO.getUserTime()) / (double) baseNumber) * 100; respVO.setPercentage((int) Math.round(percentage)); //设置未完成 respVO.setUnFinfishCount(Integer.valueOf((int) unFinfishCount)); }); return respVOS; } @Override @DataPermission(enable = false) public BpmProcessInstanceExtDO getProcessInstanceDO(String id) { return processInstanceExtMapper.selectByProcessInstanceId(id); } @Resource private FileApi fileApi; @Resource @Lazy // 解决循环依赖 private BpmOAReimbursementService reimbursementService; @Resource @Lazy // 解决循环依赖 private BpmOACashService cashService; @Resource @Lazy // 解决循环依赖 private BpmOAImprestService imprestService; @Override public BpmProcessInstancePrintDataRespVO getOAReportPrintData(BpmProcessInstancePrintDataReqVO reqVO) { BpmProcessInstancePrintDataRespVO bpmProcessInstancePrintDataRespVO = new BpmProcessInstancePrintDataRespVO(); String key = reqVO.getKey(); //流程标识 String processInstanceId = reqVO.getId(); //流程实例ID bpmProcessInstancePrintDataRespVO.setId(processInstanceId); bpmProcessInstancePrintDataRespVO.setKey(key); BpmProcessInstanceRespVO bpmProcessInstance = getProcessInstanceVO(processInstanceId); Long businessKey = Long.valueOf(bpmProcessInstance.getBusinessKey()); //流程业务表-主键ID // 判断是否可见外勤人员信息 List userIds = new ArrayList<>(); String type = configApi.getConfigKey("sys.user.type").getCheckedData(); if ("1".equals(type)) { //不可见时 // 获取所有外勤人员 用户编号 userIds = adminUserApi.getUserIdsByUserNature(4).getCheckedData(); } // 获得流程审批信息 List taskRespVOList = taskService.getTaskListByProcessInstanceId(processInstanceId); // 移除外勤人员信息 List finalUserIds = userIds; taskRespVOList.removeIf(data -> finalUserIds.contains(data.getAssigneeUser().getId())); //给User添加签名地址 taskRespVOList.forEach(taskRespVO -> taskRespVO.getAssigneeUser().setSignURL( fileApi.getUserSignImgPath( taskRespVO.getAssigneeUser().getId() ).getData() ) ); //获取流程抄送用户编号 BpmProcessInstanceExtDO processInstanceExtDO = getProcessInstanceDO(processInstanceId); //获取流程抄送用户信息 List ccUserIds = new ArrayList<>(); if (processInstanceExtDO.getCcids() != null && !processInstanceExtDO.getCcids().isEmpty()) { Pattern pattern = Pattern.compile("\\[(\\d+)]"); Matcher matcher = pattern.matcher(processInstanceExtDO.getCcids()); while (matcher.find()) { ccUserIds.add(Long.parseLong(matcher.group(1))); } // 移除 外勤人员信息 ccUserIds.removeAll(userIds); } List userRespDTOS = adminUserApi.getUserList(ccUserIds).getCheckedData(); //获取抄送用户部门信息 Map deptMapDTO = deptApi.getDeptMap(convertSet(userRespDTOS, AdminUserRespDTO::getDeptId)); if ("oa_reimbursement".equals(key)) { //报销流程 BpmOAReimbursementDO reimbursement = reimbursementService.getReimbursement(businessKey); BpmOAReimbursementRespVO bpmOAReimbursementRespVO = reimbursementService.convert(reimbursement); //报销业务数据 // 移除自己得审批节点 taskRespVOList.removeIf(data -> data.getAssigneeUser().getId().equals(reimbursement.getUserId())); //备用金信息查询 BpmOAImprestDO bpmOAImprestDO = imprestService.getImprest(reimbursement.getImprestId()); if (bpmOAImprestDO != null) { //设置备用金 金额 bpmOAReimbursementRespVO.setAmount(bpmOAImprestDO.getAmount()); // 设置备用金 剩余金额 bpmOAReimbursementRespVO.setRemainingAmount(bpmOAImprestDO.getAmount().subtract(bpmOAImprestDO.getReimbursedAmount())); } // 设置抄送人信息 List ccUsers = userRespDTOS.stream().map(user -> { BpmOAReimbursementPrintDataRespVO.CCUser cc = new BpmOAReimbursementPrintDataRespVO.CCUser(); cc.setCcUserId(user.getId()); cc.setCcUserName(user.getNickname()); cc.setCcDeptName(deptMapDTO.get(user.getDeptId()).getName()); return cc; }).collect(Collectors.toList()); BpmOAReimbursementPrintDataRespVO reimbursementPrintData = new BpmOAReimbursementPrintDataRespVO(); reimbursementPrintData.setBpmOAReimbursementRespVO(bpmOAReimbursementRespVO); reimbursementPrintData.setProcessTasks(taskRespVOList); reimbursementPrintData.setCcUsers(ccUsers); bpmProcessInstancePrintDataRespVO.setBpmOAReimbursementPrintDataRespVO(reimbursementPrintData); } if ("oa_cash".equals(key)) { BpmOACashDO cashDO = cashService.getCash(businessKey); BpmOACashRespVO cashRespVO = cashService.convertCash(cashDO); // 移除自己得审批节点 taskRespVOList.removeIf(data -> data.getAssigneeUser().getId().equals(cashDO.getUserId())); //备用金信息查询 BpmOAImprestDO bpmOAImprestDO = imprestService.getImprest(cashDO.getImprestId()); if (bpmOAImprestDO != null) { //设置备用金 金额 cashRespVO.setAmount(bpmOAImprestDO.getAmount()); // 设置备用金 剩余金额 cashRespVO.setRemainingAmount(bpmOAImprestDO.getAmount().subtract(bpmOAImprestDO.getReimbursedAmount())); } // 设置抄送人信息 List ccUsers = userRespDTOS.stream().map(user -> { BpmOACashPrintDataRespVO.CCUser cc = new BpmOACashPrintDataRespVO.CCUser(); cc.setCcUserId(user.getId()); cc.setCcUserName(user.getNickname()); cc.setCcDeptName(deptMapDTO.get(user.getDeptId()).getName()); return cc; }).collect(Collectors.toList()); BpmOACashPrintDataRespVO cashPrintData = new BpmOACashPrintDataRespVO(); cashPrintData.setBpmOACashRespVO(cashRespVO); cashPrintData.setProcessTasks(taskRespVOList); cashPrintData.setCcUsers(ccUsers); bpmProcessInstancePrintDataRespVO.setBpmOACashPrintDataRespVO(cashPrintData); } return bpmProcessInstancePrintDataRespVO; } @Override public Map> getProcessInstanceResultStatusStatisticsGroupTime(BpmProcessInstanceStatisticsReqVO pageReqVO) { pageReqVO = getUserids(pageReqVO); pageReqVO.setRecentDays(pageReqVO.getRecentDays() == null ? 7 : pageReqVO.getRecentDays()); List list = processInstanceExtMapper.getProcessInstanceResultStatusStatisticsGroupTime(pageReqVO); // -- 获取到日期列表 LocalDateTime now = LocalDateTimeUtil.now(); LocalDateTime offset = LocalDateTimeUtil.offset(LocalDateTimeUtil.now(), -1L * pageReqVO.getRecentDays(), ChronoUnit.DAYS); List dateList = DateUtils.betweenDayList(offset, now); //根据时间分组 Map> map = list.stream().collect(Collectors.groupingBy(BpmProcessInstanceResultStatusStatisticsGroupTimeVO::getTime)); List keys = new ArrayList<>(CollectionUtil.subtract(dateList, new ArrayList<>(map.keySet()))); if (CollectionUtil.isNotEmpty(keys)) { for (String key : keys) { map.put(key, new ArrayList<>()); } } List statusList = Arrays.asList(1, 2, 3, 4); for (Map.Entry> entry : map.entrySet()) { List items = entry.getValue(); List results = items.stream().map(BpmProcessInstanceResultStatusStatisticsGroupTimeVO::getResult).collect(Collectors.toList()); List saveList = new ArrayList<>(CollectionUtil.subtract(statusList, results)); // -- 如果没有的话组装上缺少的 if (CollectionUtil.isNotEmpty(saveList)) { for (Integer status : saveList) { items.add(new BpmProcessInstanceResultStatusStatisticsGroupTimeVO() .setTime(entry.getKey()) .setTotalCount(0) .setResult(status) .setName("")); } } } return map; } } \ No newline at end of file +package cn.iocoder.yudao.module.bpm.service.task; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.date.LocalDateTimeUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.date.DateUtils; import cn.iocoder.yudao.framework.common.util.number.NumberUtils; import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission; import cn.iocoder.yudao.framework.flowable.core.util.FlowableUtils; import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.cash.BpmOACashRespVO; import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.payment.BpmOAPaymentRespVO; import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.print.BpmOAPrintDataRespVO; import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.print.BpmProcessInstancePrintDataReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.print.BpmProcessInstancePrintDataRespVO; import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.reimbursement.BpmOAReimbursementRespVO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskApproveReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO; import cn.iocoder.yudao.module.bpm.convert.task.BpmProcessInstanceConvert; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessCcDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOACashDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAImprestDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAPaymentDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAReimbursementDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO; import cn.iocoder.yudao.module.bpm.dal.mysql.DynamicMapper; import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmTaskAssignRuleMapper; import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmProcessInstanceExtMapper; import cn.iocoder.yudao.module.bpm.enums.task.BpmConstants; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceDeleteReasonEnum; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum; import cn.iocoder.yudao.module.bpm.framework.bpm.core.event.BpmProcessInstanceResultEventPublisher; import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessCcService; import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService; import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService; import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService; import cn.iocoder.yudao.module.bpm.service.oa.*; import cn.iocoder.yudao.module.infra.api.config.ConfigApi; import cn.iocoder.yudao.module.infra.api.file.FileApi; import cn.iocoder.yudao.module.system.api.dept.DeptApi; import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; import cn.iocoder.yudao.module.system.api.permission.PermissionApi; import cn.iocoder.yudao.module.system.api.permission.dto.DeptDataPermissionRespDTO; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import jodd.util.StringUtil; import lombok.extern.slf4j.Slf4j; import org.flowable.engine.HistoryService; import org.flowable.engine.RuntimeService; import org.flowable.engine.TaskService; import org.flowable.engine.delegate.event.FlowableCancelledEvent; import org.flowable.engine.history.HistoricProcessInstance; import org.flowable.engine.repository.ProcessDefinition; import org.flowable.engine.runtime.ProcessInstance; import org.flowable.task.api.Task; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.support.TransactionSynchronization; import org.springframework.transaction.support.TransactionSynchronizationManager; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import javax.validation.Valid; import java.lang.reflect.Field; import java.text.DecimalFormat; import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId; import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; /** * 流程实例 Service 实现类 *

* ProcessDefinition & ProcessInstance & Execution & Task 的关系: * 1. *

* HistoricProcessInstance & ProcessInstance 的关系: * 1. *

* 简单来说,前者 = 历史 + 运行中的流程实例,后者仅是运行中的流程实例 */ @Service @Validated @Slf4j public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService { @Resource private TaskService engineTaskService; @Resource private BpmTaskAssignRuleMapper taskRuleMapper; @Resource private BpmUserGroupService userGroupService; @Resource private RuntimeService runtimeService; @Resource private BpmProcessInstanceExtMapper processInstanceExtMapper; @Resource @Lazy // 解决循环依赖 private BpmTaskService taskService; @Resource private BpmProcessDefinitionService processDefinitionService; @Resource private HistoryService historyService; @Resource private AdminUserApi adminUserApi; @Resource private DeptApi deptApi; @Resource private BpmProcessInstanceResultEventPublisher processInstanceResultEventPublisher; @Resource @Lazy // 解决循环依赖 private BpmMessageService messageService; @Resource private ConfigApi configApi; @Resource private DynamicMapper dynamicMapper ; @Resource private BpmProcessCcService processCcService; @Override public ProcessInstance getProcessInstance(String id) { return runtimeService.createProcessInstanceQuery().processInstanceId(id).singleResult(); } @Override public List getProcessInstances(Set ids) { return runtimeService.createProcessInstanceQuery().processInstanceIds(ids).list(); } public String transform(String input) { if(StringUtil.isNotEmpty(input)) { String[] parts = input.split(","); StringBuilder result = new StringBuilder(); for (String part : parts) { String[] keyValue = part.split(":"); if (keyValue.length > 1) { result.append(keyValue[1]).append(","); } } if (result.length() > 0) { return result.substring(0, result.length() - 1); } } return ""; } public String replaceValues(String input, Map map) { String[] parts = input.split(","); StringBuilder result = new StringBuilder(); for (String part : parts) { String[] keyValue = part.split(":"); if (keyValue.length > 1) { String key = keyValue[1].trim(); // 去除可能的空格 if (map.containsKey(key)) { Object value = map.get(key); String stringValue = (value != null) ? value.toString() : ""; // 将值转换为字符串 result.append(keyValue[0].trim()).append(":").append(stringValue).append(","); } else { //result.append(part).append(","); } } } if (result.length() > 0) { return result.substring(0, result.length() - 1); } return ""; } @Override @TenantIgnore public PageResult getMyProcessInstancePage(Long userId, BpmProcessInstanceMyPageReqVO pageReqVO) { // 通过 BpmProcessInstanceExtDO 表,先查询到对应的分页 PageResult pageResult = processInstanceExtMapper.selectPage(userId, pageReqVO); List bpmProcessInstanceExtDOList = pageResult.getList() ; for (int i = 0; i < bpmProcessInstanceExtDOList.size() ; i++) { BpmProcessInstanceExtDO bpmProcessInstanceExtDO = bpmProcessInstanceExtDOList.get(i) ; String input = bpmProcessInstanceExtDO.getFieldNames() ; if(StringUtil.isNotEmpty(input)) { String sql = "SELECT " + transform(bpmProcessInstanceExtDO.getFieldNames()) + " FROM " + bpmProcessInstanceExtDO.getTableName() + " WHERE id=" + bpmProcessInstanceExtDO.getBusinessKey(); log.info(sql); Map map = dynamicMapper.selectListByTableName(sql) ; String detailInfo = replaceValues(bpmProcessInstanceExtDO.getFieldNames(),map) ; bpmProcessInstanceExtDO.setDetailInfo(detailInfo); } } if (CollUtil.isEmpty(pageResult.getList())) { return new PageResult<>(pageResult.getTotal()); } // 获得流程 Task Map List processInstanceIds = convertList(pageResult.getList(), BpmProcessInstanceExtDO::getProcessInstanceId); Map> taskMap = taskService.getTaskMapByProcessInstanceIds(processInstanceIds); List ids = taskMap.values().stream() .flatMap(Collection::stream) .map(Task::getAssignee) .collect(Collectors.toList()); Iterator iterator = ids.iterator(); while (iterator.hasNext()) { String id = iterator.next(); if (id == null) { iterator.remove(); } } List longIds = ids.stream() .map(Long::valueOf) .collect(Collectors.toList()); // 获得 User Map Map userMap = adminUserApi.getUserMap(longIds); // 转换返回 return BpmProcessInstanceConvert.INSTANCE.convertPage(pageResult, taskMap, userMap); } @Override @Transactional(rollbackFor = Exception.class) public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqVO createReqVO) { // 获得流程定义 ProcessDefinition definition = processDefinitionService.getProcessDefinition(createReqVO.getProcessDefinitionId()); // 发起流程 return createProcessInstance0(userId, definition, createReqVO.getVariables(), null); } @Override @Transactional(rollbackFor = Exception.class) public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqDTO createReqDTO) { // 获得流程定义 ProcessDefinition definition = processDefinitionService.getActiveProcessDefinition(createReqDTO.getProcessDefinitionKey()); // 发起流程 return createProcessInstance0(userId, definition, createReqDTO.getVariables(), createReqDTO.getBusinessKey()); } @Override public BpmProcessInstanceRespVO getProcessInstanceVO(String id) { // 获得流程实例 HistoricProcessInstance processInstance = getHistoricProcessInstance(id); if (processInstance == null) { return null; } BpmProcessInstanceExtDO processInstanceExt = processInstanceExtMapper.selectByProcessInstanceId(id); Assert.notNull(processInstanceExt, "流程实例拓展({}) 不存在", id); // 获得流程定义 ProcessDefinition processDefinition = processDefinitionService .getProcessDefinition(processInstance.getProcessDefinitionId()); Assert.notNull(processDefinition, "流程定义({}) 不存在", processInstance.getProcessDefinitionId()); BpmProcessDefinitionExtDO processDefinitionExt = processDefinitionService.getProcessDefinitionExt( processInstance.getProcessDefinitionId()); Assert.notNull(processDefinitionExt, "流程定义拓展({}) 不存在", id); String bpmnXml = processDefinitionService.getProcessDefinitionBpmnXML(processInstance.getProcessDefinitionId()); // 获得 User AdminUserRespDTO startUser = adminUserApi.getUser(NumberUtils.parseLong(processInstance.getStartUserId())).getCheckedData(); DeptRespDTO dept = null; if (startUser != null) { dept = deptApi.getDept(startUser.getDeptId()).getCheckedData(); } // 拼接结果 return BpmProcessInstanceConvert.INSTANCE.convert2(processInstance, processInstanceExt, processDefinition, processDefinitionExt, bpmnXml, startUser, dept); } @Override public void cancelProcessInstance(Long userId, @Valid BpmProcessInstanceCancelReqVO cancelReqVO) { // 校验流程实例存在 ProcessInstance instance = getProcessInstance(cancelReqVO.getId()); if (instance == null) { throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS); } // 只能取消自己的 if (!Objects.equals(instance.getStartUserId(), String.valueOf(userId))) { throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF); } // 通过删除流程实例,实现流程实例的取消, // 删除流程实例,正则执行任务 ACT_RU_TASK. 任务会被删除。通过历史表查询 deleteProcessInstance(cancelReqVO.getId(), BpmProcessInstanceDeleteReasonEnum.CANCEL_TASK.format(cancelReqVO.getReason())); } /** * 获得历史的流程实例 * * @param id 流程实例的编号 * @return 历史的流程实例 */ @Override public HistoricProcessInstance getHistoricProcessInstance(String id) { return historyService.createHistoricProcessInstanceQuery().processInstanceId(id).singleResult(); } @Override public List getHistoricProcessInstances(Set ids) { return historyService.createHistoricProcessInstanceQuery().processInstanceIds(ids).list(); } @Override public void createProcessInstanceExt(ProcessInstance instance) { // 获得流程定义 ProcessDefinition definition = processDefinitionService.getProcessDefinition2(instance.getProcessDefinitionId()); // 插入 BpmProcessInstanceExtDO 对象 BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO() .setProcessInstanceId(instance.getId()) .setProcessDefinitionId(definition.getId()) .setName(instance.getProcessDefinitionName()) .setStartUserId(Long.valueOf(instance.getStartUserId())) .setCategory(definition.getCategory()) .setStatus(BpmProcessInstanceStatusEnum.RUNNING.getStatus()) .setResult(BpmProcessInstanceResultEnum.PROCESS.getResult()); processInstanceExtMapper.insert(instanceExtDO); } @Override @DataPermission(enable = false) public void updateProcessInstanceExtCancel(FlowableCancelledEvent event) { // 判断是否为 Reject 不通过。如果是,则不进行更新. // 因为,updateProcessInstanceExtReject 方法,已经进行更新了 if (BpmProcessInstanceDeleteReasonEnum.isRejectReason((String) event.getCause())) { return; } // 需要主动查询,因为 instance 只有 id 属性 // 另外,此时如果去查询 ProcessInstance 的话,字段是不全的,所以去查询了 HistoricProcessInstance HistoricProcessInstance processInstance = getHistoricProcessInstance(event.getProcessInstanceId()); // 更新拓展表 BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO() .setProcessInstanceId(event.getProcessInstanceId()) .setEndTime(LocalDateTime.now()) // 由于 ProcessInstance 里没有办法拿到 endTime,所以这里设置 .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus()) .setResult(BpmProcessInstanceResultEnum.CANCEL.getResult()); processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); // 发送流程实例的状态事件 processInstanceResultEventPublisher.sendProcessInstanceResultEvent( BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult())); } @Override @DataPermission(enable = false) public void updateProcessInstanceExtComplete(ProcessInstance instance) { // 需要主动查询,因为 instance 只有 id 属性 // 另外,此时如果去查询 ProcessInstance 的话,字段是不全的,所以去查询了 HistoricProcessInstance HistoricProcessInstance processInstance = getHistoricProcessInstance(instance.getId()); // 更新拓展表 BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO() .setProcessInstanceId(instance.getProcessInstanceId()) .setEndTime(LocalDateTime.now()) // 由于 ProcessInstance 里没有办法拿到 endTime,所以这里设置 .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus()) .setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()); // 如果正常完全,说明审批通过 processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); Map processVariables = runtimeService.getVariables(instance.getProcessInstanceId()); String reason = (String) processVariables.get("approve_reason"); // 发送流程被通过的消息 messageService.sendMessageWhenProcessInstanceApprove(BpmProcessInstanceConvert.INSTANCE.convert2ApprovedReq(instance, reason)); // 发送流程实例的状态事件 processInstanceResultEventPublisher.sendProcessInstanceResultEvent( BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult())); } @Override @Transactional(rollbackFor = Exception.class) @DataPermission(enable = false) public void updateProcessInstanceExtReject(String id, String reason) { // 需要主动查询,因为 instance 只有 id 属性 ProcessInstance processInstance = getProcessInstance(id); // 删除流程实例,以实现驳回任务时,取消整个审批流程 deleteProcessInstance(id, StrUtil.format(BpmProcessInstanceDeleteReasonEnum.REJECT_TASK.format(reason))); // 更新 status + result // 注意,不能和上面的逻辑更换位置。因为 deleteProcessInstance 会触发流程的取消,进而调用 updateProcessInstanceExtCancel 方法, // 设置 result 为 BpmProcessInstanceStatusEnum.CANCEL,显然和 result 不一定是一致的 BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO() .setProcessInstanceId(id) .setEndTime(LocalDateTime.now()) // 由于 ProcessInstance 里没有办法拿到 endTime,所以这里设置 .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus()) .setResult(BpmProcessInstanceResultEnum.REJECT.getResult()); processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); // 发送流程被不通过的消息 messageService.sendMessageWhenProcessInstanceReject(BpmProcessInstanceConvert.INSTANCE.convert2RejectReq(processInstance, reason)); // 发送流程实例的状态事件 processInstanceResultEventPublisher.sendProcessInstanceResultEvent( BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult())); } private void deleteProcessInstance(String id, String reason) { runtimeService.deleteProcessInstance(id, reason); } private String createProcessInstance0(Long userId, ProcessDefinition definition, Map variables, String businessKey) { // 校验流程定义 if (definition == null) { throw exception(PROCESS_DEFINITION_NOT_EXISTS); } if (definition.isSuspended()) { throw exception(PROCESS_DEFINITION_IS_SUSPENDED); } // 设置当前用户 FlowableUtils.setAuthenticatedUserId(userId); //获取流程发起人User AdminUserRespDTO startUser = adminUserApi.getUser(userId).getCheckedData(); //获取流程发起人部门信息 DeptRespDTO startDeptInfo = deptApi.getDept(startUser.getDeptId()).getCheckedData(); // 获取岗位信息 Set postIds = startUser.getPostIds(); ArrayList list = new ArrayList<>(postIds); //配置通用流程变量 variables.put("post_id", list.get(0).toString()); // 只获配置的首个岗位 variables.put("user_id", userId.toString()); // 配置发起人用户id variables.put("dept_id", startUser.getDeptId().toString()); // 配置发起人部门id variables.put("dept_flag", startDeptInfo.getFlag()); // 配置发起人部门flag // 创建流程实例 ProcessInstance instance = runtimeService.createProcessInstanceBuilder() .processDefinitionId(definition.getId()) .businessKey(businessKey) .name(definition.getName().trim()) .variables(variables) .start(); // 设置流程名字 runtimeService.setProcessInstanceName(instance.getId(), definition.getName()); // 发送通知。在事务提交时,批量执行操作,所以直接查询会无法查询到 ProcessInstance,所以这里是通过监听事务的提交来实现。 TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() { @Override public void afterCommit() { // 创建流程后,添加抄送人 processCCToUsers(instance, variables); } }); return instance.getId(); // // 补全流程实例的拓展表 // processInstanceExtMapper.updateByProcessInstanceId(new BpmProcessInstanceExtDO().setProcessInstanceId(instance.getId()) // .setFormVariables(variables)); // // /** 创建流程后,添加抄送人 End add by yj 2024.1.4 */ // processCCToUsers(definition, instance); // /** 通过自己发起的流程 */ // approveSelfTask(instance.getId()) ; } private void approveSelfTask(String processInstanceId) { List tasks = engineTaskService.createTaskQuery().processInstanceId(processInstanceId).list(); if (tasks != null && tasks.size() > 0) { Task task = tasks.get(0); String assigneeId = task.getAssignee(); //如果当前登陆用户是审批人,那么自动审批通过 if (assigneeId.equals(SecurityFrameworkUtils.getLoginUserId().toString())) { BpmTaskApproveReqVO reqVO = new BpmTaskApproveReqVO(); reqVO.setId(task.getId()); reqVO.setReason(BpmConstants.AUTO_APPRAVAL); taskService.approveTask(getLoginUserId(), reqVO); } } } /** * 获得抄送我的流程实例的分页 * * @param userId 用户编号 * @param pageReqVO 分页请求 * @return 流程实例的分页 */ public PageResult getMyCCProcessInstancePage(Long userId, BpmProcessInstanceMyPageReqVO pageReqVO) { // 通过 BpmProcessInstanceExtDO 表,先查询到对应的分页 PageResult pageResult = processInstanceExtMapper.selectCCPage(userId, pageReqVO); if (CollUtil.isEmpty(pageResult.getList())) { return new PageResult<>(pageResult.getTotal()); } // 获得流程 Task Map List processInstanceIds = convertList(pageResult.getList(), BpmProcessInstanceExtDO::getProcessInstanceId); Map> taskMap = taskService.getTaskMapByProcessInstanceIds(processInstanceIds); // 转换返回 return BpmProcessInstanceConvert.INSTANCE.convertPage(pageResult, taskMap, null); } public List getProcessInstancesGroupByModelName(BpmProcessInstanceStatisticsReqVO pageReqVO) { pageReqVO = getUserids(pageReqVO); return processInstanceExtMapper.getProcessInstancesGroupByModelName(pageReqVO); } public List getProcessInstancesGroupByResultStatus(BpmProcessInstanceStatisticsReqVO pageReqVO) { pageReqVO = getUserids(pageReqVO); return processInstanceExtMapper.getProcessInstancesGroupByResultStatus(pageReqVO); } public PageResult getStatisticsProcessInstancePage(@Valid BpmProcessInstanceMyPageReqVO pageReqVO) { // 通过 BpmProcessInstanceExtDO 表,先查询到对应的分页 PageResult pageResult = processInstanceExtMapper.selectStatisticePage(pageReqVO); if (CollUtil.isEmpty(pageResult.getList())) { return new PageResult<>(pageResult.getTotal()); } // 获得流程 Task Map List processInstanceIds = convertList(pageResult.getList(), BpmProcessInstanceExtDO::getProcessInstanceId); Map> taskMap = taskService.getTaskMapByProcessInstanceIds(processInstanceIds); List ids = taskMap.values().stream() .flatMap(Collection::stream) .map(Task::getAssignee) .collect(Collectors.toList()); Iterator iterator = ids.iterator(); while (iterator.hasNext()) { String id = iterator.next(); if (id == null) { iterator.remove(); } } List longIds = ids.stream() .map(Long::valueOf) .collect(Collectors.toList()); //获得 审批人 User Map Map assigneeUserMap = adminUserApi.getUserMap(longIds); //获得 发起人 User Map List bpieDOs = pageResult.getList(); longIds = new ArrayList<>(); for (BpmProcessInstanceExtDO bpieDO : bpieDOs) { longIds.add(bpieDO.getStartUserId()); } Map startUserMap = adminUserApi.getUserMap(longIds); // 转换返回 return BpmProcessInstanceConvert.INSTANCE.convertStatisticsPage(pageResult, taskMap, assigneeUserMap, startUserMap); } @Resource PermissionApi permissionApi; /** * 根据数据权限,查询关联操作的用户IDS * * @param pageReqVO * @param * @return */ private T getUserids(T pageReqVO) { try { Class clazz = (Class) pageReqVO.getClass(); Field idField = clazz.getDeclaredField("userIds"); idField.setAccessible(true); // 设置可访问性 Long[] userIds = null; Long userId = WebFrameworkUtils.getLoginUserId(); DeptDataPermissionRespDTO deptDataPermission = permissionApi.getDeptDataPermission(userId).getCheckedData(); //查询全部 if (deptDataPermission.getAll()) { //idField.set(pageReqVO, null); // 设置属性值 return pageReqVO; } // 情况二,即不能查看部门,又不能查看自己,则说明 100% 无权限 if (CollUtil.isEmpty(deptDataPermission.getDeptIds()) && Boolean.FALSE.equals(deptDataPermission.getSelf())) { //设置成0,一个不存在的用户Id,就查询不到数据了。 userIds = new Long[]{0L}; idField.set(pageReqVO, userIds); return pageReqVO; } //情况三 至查询自己 if (deptDataPermission.getSelf()) { userIds = new Long[]{userId}; idField.set(pageReqVO, userIds); return pageReqVO; } Set deptIds = deptDataPermission.getDeptIds(); //查询部门关联的用户Id List users = adminUserApi.getUserListByDeptIds(deptIds).getCheckedData(); List tempList = new ArrayList<>(); for (AdminUserRespDTO user : users) { Long id = user.getId(); tempList.add(id); } tempList.add(userId); userIds = tempList.stream().toArray(Long[]::new); //将临时的List集合转换成数组集合 idField.set(pageReqVO, userIds); return pageReqVO; } catch (Exception exception) { exception.printStackTrace(); throw exception(BPM_SYSTEM_BUG); } } /** * /创建流程后,添加抄送人 Begin add by yj 2024.1.4 * 在设计流程的时候,需要添加一个任务块 名字必须叫Activity_cc 分配权限的时候,需要选择用户组。 * * @param definition * @param instance */ private void processCCToUsers(ProcessDefinition definition, ProcessInstance instance) { //获取bpm_task_assign_reule (Bpm 任务规则表)的流程中有没有配置抄送节点 固定抄送名称为:Activity_cc String processDefinitionId = definition.getId(); List rules = taskRuleMapper.selectListByProcessDefinitionId(processDefinitionId, null); String BpmConstantsName = BpmConstants.CC_NAME; // 获取发起人信息 AdminUserRespDTO userRespDTO = adminUserApi.getUser(Long.valueOf(instance.getStartUserId())).getCheckedData(); DeptRespDTO deptRespDTO = deptApi.getDept(userRespDTO.getDeptId()).getCheckedData(); //发起人是深圳分公司 if (deptRespDTO.getFlag().contains("136")) { BpmConstantsName = BpmConstants.CCSZ_NAME; } for (BpmTaskAssignRuleDO rule : rules) { String key = rule.getTaskDefinitionKey(); //任务名称 Integer type = rule.getType(); if (!key.isEmpty() && key.equals(BpmConstantsName) && type == 40) { StringBuffer str = new StringBuffer(); Set options = rule.getOptions(); List list = new ArrayList(options); for (Long groupId : list) { //需要根据这个groupId,查询这个组中的用户id BpmUserGroupDO userGroup = userGroupService.getUserGroup(groupId); Set userIds = userGroup.getMemberUserIds(); List userIdList = new ArrayList(userIds); for (Long user_id : userIdList) { str.append("[").append(user_id).append("]"); } } //流程是采购计划时 if (definition.getKey().equals(BpmOAProcureServiceImpl.PROCESS_KEY)) { //发起人部门为 生产部及以下时 if (deptRespDTO.getFlag().contains("130")) { //添加 供应部抄送 BpmUserGroupDO userGroup = userGroupService.getUserGroup(121L); Set userIds = userGroup.getMemberUserIds(); List userIdList = new ArrayList(userIds); for (Long user_id : userIdList) { str.append("[").append(user_id).append("]"); } } } String ccids = str.toString(); //根据processDefinitionId 将ccids保存到bpm_process_instance_ext中的ccids字段 BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO().setProcessDefinitionId(processDefinitionId) .setCcids(ccids).setProcessInstanceId(instance.getProcessInstanceId()); processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); break; } } } /** * 创建流程后,添加抄送人 * @param instance 流程实例 */ private void processCCToUsers(ProcessInstance instance, Map variables) { // 根据流程名称、流程发起人 查询流程配置的抄送人信息 List processCcList = processCcService.getCCListByName(instance.getName(), Long.valueOf(instance.getStartUserId())); // 提取抄送信息用中对应的用户组编号 Set userGroupIds = processCcList.stream() .flatMap(data -> data.getUserGroupId().stream()) .collect(Collectors.toSet()); //根据processDefinitionId 将ccIds保存到bpm_process_instance_ext中的ccIds字段 BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO() .setProcessDefinitionId(instance.getProcessDefinitionId()) .setFormVariables(variables) .setProcessInstanceId(instance.getProcessInstanceId()); if (CollectionUtil.isNotEmpty(userGroupIds)) { // 获取用户组信息 List userGroups = userGroupService.getUserGroupList(userGroupIds); // 提取用户组中对应的用户ID Set userIds = userGroups.stream() .flatMap(data -> data.getMemberUserIds().stream()) .collect(Collectors.toSet()); // 将用户ID列表转换为字符串 String ccIds = userIds.stream() .map(id -> "[" + id + "]") // 每个值用方括号包裹 .collect(Collectors.joining()); //根据processDefinitionId 将ccIds保存到bpm_process_instance_ext中的ccIds字段 instanceExtDO.setCcids(ccIds); } processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); } @Override public List getUserProcessTpo10(BpmProcessInstanceStatisticsReqVO pageReqVO) { //按审核人分组查询,统计已完成流程数量及平均耗时间 List respVOS = processInstanceExtMapper.getUserProcessTpo10(pageReqVO); if (respVOS == null || respVOS.size() == 0) { return null; } List idList = respVOS.stream() .map(BpmProcessFinishStatisticsRespVO::getUserId) .collect(Collectors.toList()); //根据userId,查询UserMap Map userMap = adminUserApi.getUserMap(idList); Long[] idsArray = new Long[userMap.size()]; // 使用 map 的 keySet() 方法获取键集合 Set keys = userMap.keySet(); // 遍历键集合,将每个键添加到数组中 int index = 0; for (Long key : keys) { idsArray[index++] = key; } pageReqVO.setUserIds(idsArray); //按审核人分组查询,未审批完成的流程数量 List bpmTaskExtDOs = processInstanceExtMapper.selectUnfinishProcessCount(pageReqVO); //按审核人分组查询,未完成的记录数 Map unFinfishCountCountMap = new HashMap<>(); for (BpmProcessFinishStatisticsRespVO item : bpmTaskExtDOs) { unFinfishCountCountMap.put(item.getUserId(), item.getUnFinfishCount()); } respVOS.forEach(respVO -> respVO.setName(userMap.get(respVO.getUserId()).getNickname())); respVOS.forEach(respVO -> respVO.setUnFinfishCount(unFinfishCountCountMap.get(respVO.getUserId()))); //获取排行榜第一记录的耗时,作为基础数据 double num = Double.parseDouble(respVOS.get(0).getUserTime()); // 先将字符串转换为双精度浮点数 int baseNumber = (int) num; // 再通过类型转换操作符将其转换为整数 DecimalFormat df = new DecimalFormat("#.00"); respVOS.forEach(respVO -> { //格式化流程完成率 float finfishCount = (float) respVO.getFinfishCount(); float unFinfishCount = respVO.getUnFinfishCount() == null ? 0 : respVO.getUnFinfishCount(); float all = finfishCount + unFinfishCount; float result = finfishCount / all; float rate = result * 100; respVO.setCompletionRate(df.format(rate) + "%"); double dValue = Double.parseDouble(respVO.getUserTime()); // 将字符串转换为double类型 int roundedValue = (int) Math.round(dValue); // 使用Math.round()进行四舍五入,并转换为int类型 respVO.setUserTime(roundedValue + ""); //格式化进度百度比, 参照最高的数据进行百分比显示 double percentage = ((int) Double.parseDouble(respVO.getUserTime()) / (double) baseNumber) * 100; respVO.setPercentage((int) Math.round(percentage)); //设置未完成 respVO.setUnFinfishCount(Integer.valueOf((int) unFinfishCount)); }); return respVOS; } @Override @DataPermission(enable = false) public BpmProcessInstanceExtDO getProcessInstanceDO(String id) { return processInstanceExtMapper.selectByProcessInstanceId(id); } @Resource private FileApi fileApi; @Resource @Lazy // 解决循环依赖 private BpmOAReimbursementService reimbursementService; @Resource @Lazy // 解决循环依赖 private BpmOACashService cashService; @Resource @Lazy // 解决循环依赖 private BpmOAImprestService imprestService; @Resource @Lazy // 解决循环依赖 private BpmOAPaymentService paymentService; @Override public BpmProcessInstancePrintDataRespVO getOAReportPrintData(BpmProcessInstancePrintDataReqVO reqVO) { BpmProcessInstancePrintDataRespVO bpmProcessInstancePrintDataRespVO = new BpmProcessInstancePrintDataRespVO(); String key = reqVO.getKey(); //流程标识 String processInstanceId = reqVO.getId(); //流程实例ID bpmProcessInstancePrintDataRespVO.setId(processInstanceId); bpmProcessInstancePrintDataRespVO.setKey(key); BpmProcessInstanceRespVO bpmProcessInstance = getProcessInstanceVO(processInstanceId); Long businessKey = Long.valueOf(bpmProcessInstance.getBusinessKey()); //流程业务表-主键ID // 判断是否可见外勤人员信息 List userIds = new ArrayList<>(); String type = configApi.getConfigKey("sys.user.type").getCheckedData(); if ("1".equals(type)) { //不可见时 // 获取所有外勤人员 用户编号 userIds = adminUserApi.getUserIdsByUserNature(4).getCheckedData(); } // 获得流程审批信息 List taskRespVOList = taskService.getTaskListByProcessInstanceId(processInstanceId); // 移除外勤人员信息 List finalUserIds = userIds; taskRespVOList.removeIf(data -> finalUserIds.contains(data.getAssigneeUser().getId())); //给User添加签名地址 taskRespVOList.forEach(taskRespVO -> taskRespVO.getAssigneeUser().setSignURL( fileApi.getUserSignImgPath( taskRespVO.getAssigneeUser().getId() ).getData() ) ); //获取流程抄送用户编号 BpmProcessInstanceExtDO processInstanceExtDO = getProcessInstanceDO(processInstanceId); //获取流程抄送用户信息 List ccUserIds = new ArrayList<>(); if (processInstanceExtDO.getCcids() != null && !processInstanceExtDO.getCcids().isEmpty()) { Pattern pattern = Pattern.compile("\\[(\\d+)]"); Matcher matcher = pattern.matcher(processInstanceExtDO.getCcids()); while (matcher.find()) { ccUserIds.add(Long.parseLong(matcher.group(1))); } // 移除 外勤人员信息 ccUserIds.removeAll(userIds); } List userRespDTOS = adminUserApi.getUserList(ccUserIds).getCheckedData(); //获取抄送用户部门信息 Map deptMapDTO = deptApi.getDeptMap(convertSet(userRespDTOS, AdminUserRespDTO::getDeptId)); // 设置抄送人信息 List ccUsers = userRespDTOS.stream().map(user -> { BpmOAPrintDataRespVO.CCUser cc = new BpmOAPrintDataRespVO.CCUser(); cc.setCcUserId(user.getId()); cc.setCcUserName(user.getNickname()); cc.setCcDeptName(deptMapDTO.get(user.getDeptId()).getName()); return cc; }).collect(Collectors.toList()); BpmOAPrintDataRespVO printData = new BpmOAPrintDataRespVO(); // 设置抄送人 printData.setCcUsers(ccUsers); switch (key) { case "oa_reimbursement": BpmOAReimbursementDO reimbursement = reimbursementService.getReimbursement(businessKey); BpmOAReimbursementRespVO bpmOAReimbursementRespVO = reimbursementService.convert(reimbursement); //报销业务数据 // 移除自己得审批节点 taskRespVOList.removeIf(data -> data.getAssigneeUser().getId().equals(reimbursement.getUserId())); //备用金信息查询 BpmOAImprestDO bpmOAImprestDO = imprestService.getImprest(reimbursement.getImprestId()); if (bpmOAImprestDO != null) { //设置备用金 金额 bpmOAReimbursementRespVO.setAmount(bpmOAImprestDO.getAmount()); // 设置备用金 剩余金额 bpmOAReimbursementRespVO.setRemainingAmount(bpmOAImprestDO.getAmount().subtract(bpmOAImprestDO.getReimbursedAmount())); } printData.setBpmOAReimbursementRespVO(bpmOAReimbursementRespVO); printData.setProcessTasks(taskRespVOList); break; case "oa_cash": BpmOACashDO cashDO = cashService.getCash(businessKey); BpmOACashRespVO cashRespVO = cashService.convertCash(cashDO); // 移除自己得审批节点 taskRespVOList.removeIf(data -> data.getAssigneeUser().getId().equals(cashDO.getUserId())); //备用金信息查询 BpmOAImprestDO cashImprestDO = imprestService.getImprest(cashDO.getImprestId()); if (cashImprestDO != null) { //设置备用金 金额 cashRespVO.setAmount(cashImprestDO.getAmount()); // 设置备用金 剩余金额 cashRespVO.setRemainingAmount(cashImprestDO.getAmount().subtract(cashImprestDO.getReimbursedAmount())); } printData.setBpmOACashRespVO(cashRespVO); printData.setProcessTasks(taskRespVOList); break; case "oa_payment_2": BpmOAPaymentDO paymentDO = paymentService.getPayment(businessKey); BpmOAPaymentRespVO paymentRespVO = paymentService.convertPayment(paymentDO); // 移除自己得审批节点 taskRespVOList.removeIf(data -> data.getAssigneeUser().getId().equals(paymentDO.getUserId())); printData.setBpmOAPaymentRespVO(paymentRespVO); printData.setProcessTasks(taskRespVOList); break; } bpmProcessInstancePrintDataRespVO.setPrintDataRespVO(printData); return bpmProcessInstancePrintDataRespVO; } @Override public Map> getProcessInstanceResultStatusStatisticsGroupTime(BpmProcessInstanceStatisticsReqVO pageReqVO) { pageReqVO = getUserids(pageReqVO); pageReqVO.setRecentDays(pageReqVO.getRecentDays() == null ? 7 : pageReqVO.getRecentDays()); List list = processInstanceExtMapper.getProcessInstanceResultStatusStatisticsGroupTime(pageReqVO); // -- 获取到日期列表 LocalDateTime now = LocalDateTimeUtil.now(); LocalDateTime offset = LocalDateTimeUtil.offset(LocalDateTimeUtil.now(), -1L * pageReqVO.getRecentDays(), ChronoUnit.DAYS); List dateList = DateUtils.betweenDayList(offset, now); //根据时间分组 Map> map = list.stream().collect(Collectors.groupingBy(BpmProcessInstanceResultStatusStatisticsGroupTimeVO::getTime)); List keys = new ArrayList<>(CollectionUtil.subtract(dateList, new ArrayList<>(map.keySet()))); if (CollectionUtil.isNotEmpty(keys)) { for (String key : keys) { map.put(key, new ArrayList<>()); } } List statusList = Arrays.asList(1, 2, 3, 4); for (Map.Entry> entry : map.entrySet()) { List items = entry.getValue(); List results = items.stream().map(BpmProcessInstanceResultStatusStatisticsGroupTimeVO::getResult).collect(Collectors.toList()); List saveList = new ArrayList<>(CollectionUtil.subtract(statusList, results)); // -- 如果没有的话组装上缺少的 if (CollectionUtil.isNotEmpty(saveList)) { for (Integer status : saveList) { items.add(new BpmProcessInstanceResultStatusStatisticsGroupTimeVO() .setTime(entry.getKey()) .setTotalCount(0) .setResult(status) .setName("")); } } } return map; } } \ No newline at end of file diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java index a70455f4..0d027b59 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java @@ -17,6 +17,7 @@ import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceMyPageReqVO; 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.oa.BpmOASalaryDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO; import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmProcessInstanceExtMapper; @@ -25,6 +26,7 @@ import cn.iocoder.yudao.module.bpm.enums.task.*; import cn.iocoder.yudao.module.bpm.service.definition.BpmModelService; import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService; import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService; +import cn.iocoder.yudao.module.bpm.service.oa.BpmOASalaryService; import cn.iocoder.yudao.module.bpm.service.task.dto.ProcessInstanceVariablesDTO; import cn.iocoder.yudao.module.system.api.dept.DeptApi; import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; @@ -106,6 +108,9 @@ public class BpmTaskServiceImpl implements BpmTaskService { @Resource private BpmProcessInstanceExtMapper processInstanceExtMapper; + @Resource + private BpmOASalaryService salaryService; + @Override public PageResult getCCTaskPage(Long userId, BpmTaskDonePageReqVO pageVO) { // 查询被抄送的Task @@ -194,6 +199,32 @@ public class BpmTaskServiceImpl implements BpmTaskService { Page page = new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize()); IPage pageResp = taskExtMapper.selectTodoTaskPage(page, pageReqVO, userId); + + /* + 临时处理,列表中薪资付款 展示具体公司名称问题 + begin + */ + // 获取所有薪资付款的流程实例 + List processInstanceIds = pageResp.getRecords().stream() + .filter(item -> item.getProcessDefinitionId().contains("oa_salary")) + .map(BpmTaskTodoPageRespVO::getProcessInstanceId) + .collect(Collectors.toList()); + + // 获取薪资付款列表 + List salaryDOS = salaryService.getListByProcessInstanceIds(processInstanceIds); + Map salaryDeptMap = salaryDOS.stream() + .collect(Collectors.toMap(BpmOASalaryDO::getProcessInstanceId, BpmOASalaryDO::getCompanyDeptId)); + // 获取付款部门信息 + Map dtoMap = deptApi.getDeptMap(convertSet(salaryDOS, BpmOASalaryDO::getCompanyDeptId)); + pageResp.getRecords().forEach(item -> { + if (salaryDeptMap.containsKey(item.getProcessInstanceId())) { + item.setStartUserNickname(item.getStartUserNickname() + + "(" + + dtoMap.get(salaryDeptMap.get(item.getProcessInstanceId())).getName() + + ")"); + } + }); + return new PageResult<>(pageResp.getRecords(), pageResp.getTotal()); } @@ -202,7 +233,9 @@ public class BpmTaskServiceImpl implements BpmTaskService { // 判断搜索条件是否选择用户 List userIds = null; - if (pageVO.getDeptId() != null) { + if (pageVO.getUserId() != null) { + userIds = Collections.singletonList(pageVO.getUserId()); + }else if (pageVO.getDeptId() != null) { List users = adminUserApi.getUserByDeptIdAll(pageVO.getDeptId()).getCheckedData(); userIds = users.stream().map(AdminUserRespDTO::getId).collect(Collectors.toList()); @@ -217,8 +250,31 @@ public class BpmTaskServiceImpl implements BpmTaskService { // 获得 User Map Map userMap = adminUserApi.getUserMap(startUserIds); + /* + 临时处理,列表中薪资付款 展示具体公司名称问题 + begin + */ + // 获取所有薪资付款的流程实例 + List processInstanceIds = pageResult.getList().stream() + .filter(item -> item.getProcessDefinitionId().contains("oa_salary")) + .map(BpmTaskDonePageRespVO::getProcessInstanceId) + .collect(Collectors.toList()); + + // 获取薪资付款列表 + List salaryDOS = salaryService.getListByProcessInstanceIds(processInstanceIds); + Map salaryDeptMap = salaryDOS.stream() + .collect(Collectors.toMap(BpmOASalaryDO::getProcessInstanceId, BpmOASalaryDO::getCompanyDeptId)); + // 获取付款部门信息 + Map dtoMap = deptApi.getDeptMap(convertSet(salaryDOS, BpmOASalaryDO::getCompanyDeptId)); + pageResult.getList().forEach(item -> { item.setStartUserNickname(userMap.get(item.getStartUserId()).getNickname()); + if (salaryDeptMap.containsKey(item.getProcessInstanceId())) { + item.setStartUserNickname(item.getStartUserNickname() + + "(" + + dtoMap.get(salaryDeptMap.get(item.getProcessInstanceId())).getName() + + ")"); + } }); } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/mapper/oa/BpmOAProcureMapper.xml b/yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/mapper/oa/BpmOAProcureMapper.xml index c5bb5882..9d25ad57 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/mapper/oa/BpmOAProcureMapper.xml +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/mapper/oa/BpmOAProcureMapper.xml @@ -30,7 +30,7 @@ AND a.pay_flag = 0 AND a.deleted = 0 - AND a.procure_type = #{type} + AND (a.procure_type = #{type} or a.procure_type = 3) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/dept/DeptApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/dept/DeptApiImpl.java index d72b407f..f147139e 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/dept/DeptApiImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/dept/DeptApiImpl.java @@ -132,7 +132,7 @@ public class DeptApiImpl implements DeptApi { @Override @DataPermission(enable = false) public CommonResult> getCompanyDept() { - List deptDOS = deptService.getCompanyDept(); + List deptDOS = deptService.getCompanyDept(2); return success(BeanUtils.toBean(deptDOS, DeptRespDTO.class)); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/bank/UserBankController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/bank/UserBankController.java index 134bcb5a..30033bd0 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/bank/UserBankController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/bank/UserBankController.java @@ -7,7 +7,9 @@ import cn.iocoder.yudao.module.system.controller.admin.bank.vo.UserBankPageReqVO import cn.iocoder.yudao.module.system.controller.admin.bank.vo.UserBankRespVO; import cn.iocoder.yudao.module.system.controller.admin.bank.vo.UserBankSaveReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.bank.BankDO; +import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; import cn.iocoder.yudao.module.system.service.bank.UserBankService; +import cn.iocoder.yudao.module.system.service.user.AdminUserService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; @@ -18,6 +20,10 @@ import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.validation.Valid; import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; @@ -31,6 +37,9 @@ public class UserBankController { @Resource private UserBankService userBankService; + @Resource + private AdminUserService userService; + @PostMapping("/create") @Operation(summary = "创建银行卡信息") @PreAuthorize("@ss.hasPermission('system:user-bank:create')") @@ -107,15 +116,33 @@ public class UserBankController { @PreAuthorize("@ss.hasPermission('system:user-bank:query')") public CommonResult> getUserBankPage(@Valid UserBankPageReqVO pageReqVO) { - PageResult pageResult = new PageResult(); List bankIds = userBankService.getBankIds(getLoginUserId()); - if (!bankIds.isEmpty()) { + if (bankIds.isEmpty()) { - pageResult = userBankService.getBankPageIn(pageReqVO, bankIds); + return success(PageResult.empty()); } + PageResult pageResult = userBankService.getBankPageIn(pageReqVO, bankIds); - return success(BeanUtils.toBean(pageResult, UserBankRespVO.class)); + // 获取创建者信息 + Set userIds = pageResult.getList().stream() + .filter(Objects::nonNull) + .map(BankDO::getCreator) + .map(Long::valueOf) + .collect(Collectors.toSet()); + List userDOS = userService.getUserList(userIds); + Map userMap = userDOS.stream() + .collect(Collectors.toMap(user -> + String.valueOf(user.getId()), // 将 Long 类型的 id 转换为 String 类型 + v -> v)); + + PageResult respResult = BeanUtils.toBean(pageResult, UserBankRespVO.class); + respResult.getList().forEach(item -> { + // 设置创建者名称 + item.setCreateName(userMap.get(item.getCreator()) != null ? userMap.get(item.getCreator()).getNickname() : ""); + }); + + return success(respResult); } @GetMapping("/list") diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/bank/vo/UserBankRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/bank/vo/UserBankRespVO.java index a89cfae0..2fffedfb 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/bank/vo/UserBankRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/bank/vo/UserBankRespVO.java @@ -35,4 +35,10 @@ public class UserBankRespVO { @ExcelProperty("创建时间") private LocalDateTime createTime; + @Schema(description = "创建人", example = "1") + private String creator; + + @Schema(description = "创建人名称", example = "赵六") + private String createName; + } \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/DeptController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/DeptController.java index 2c542e1c..e8be097f 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/DeptController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/DeptController.java @@ -271,9 +271,10 @@ public class DeptController { @GetMapping("/getCompanyDept") @Operation(summary = "获取部门类型为公司的部门信息") + @Parameter(name = "method", description = "查询类型 | 1全部 2真实公司 3隐藏公司") @DataPermission(enable = false) - public CommonResult> getCompanyDept() { - List list = deptService.getCompanyDept(); + public CommonResult> getCompanyDept(@RequestParam(name = "method", required = false, defaultValue = "2") Integer method) { + List list = deptService.getCompanyDept(method); return success(BeanUtils.toBean(list, DeptSimpleRespVO.class)); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/punchrecord/AttendancePunchRecordController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/punchrecord/AttendancePunchRecordController.java index 7347835c..537f72b4 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/punchrecord/AttendancePunchRecordController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/punchrecord/AttendancePunchRecordController.java @@ -75,7 +75,7 @@ public class AttendancePunchRecordController { @GetMapping("/getMissingCardRecord") @Operation(summary = "获得本月用户缺卡记录") - @PreAuthorize("@ss.hasPermission('attendance:punch-record:query')") +// @PreAuthorize("@ss.hasPermission('attendance:punch-record:query')") public CommonResult> getPunchRecord() { // 获取当前用户已申请的补卡记录 diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java index cdf6a95d..16cbea78 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java @@ -40,10 +40,12 @@ import java.time.format.DateTimeFormatter; import java.util.*; import java.util.stream.Collectors; +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.error; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.TASK_OPERATE_FAIL_USER_NO_DEPT; @Tag(name = "管理后台 - 用户") @RestController @@ -332,6 +334,23 @@ public class UserController { return success(pageResult); } + @GetMapping("/getUserStatus") + @Operation(summary = "获得当前登录用户是否属于工厂人员") + @PreAuthorize("@ss.hasPermission('system:user:query')") + public CommonResult getUserStatus() { + + DeptDO deptDO = deptService.getDept(userService.getUser(getLoginUserId()).getDeptId()); + if (deptDO == null) { + return error(TASK_OPERATE_FAIL_USER_NO_DEPT); + } + + if (deptDO.getFactoryId() == null) { + return success(false); + }else { + return success(true); + } + } + @GetMapping("/export") @Operation(summary = "导出用户") @PreAuthorize("@ss.hasPermission('system:user:export')") diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/worklog/LogInstanceController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/worklog/LogInstanceController.java index 442ea62f..7fb6816f 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/worklog/LogInstanceController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/worklog/LogInstanceController.java @@ -178,7 +178,7 @@ public class LogInstanceController { public CommonResult> getReadCompanyDept() { // 获得公司编号列表 - List companyDeptDOs = deptService.getCompanyDept(); + List companyDeptDOs = deptService.getCompanyDept(2); // 获得用户角色 List userRoles = roleService.getRoleListFromCache(permissionService.getUserRoleIdListByUserId(getLoginUserId())); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/bank/UserBankServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/bank/UserBankServiceImpl.java index 2e6b80f3..7f1c7116 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/bank/UserBankServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/bank/UserBankServiceImpl.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.system.service.bank; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.system.controller.admin.bank.vo.UserBankPageReqVO; import cn.iocoder.yudao.module.system.controller.admin.bank.vo.UserBankSaveReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.bank.BankDO; @@ -45,7 +46,9 @@ public class UserBankServiceImpl implements UserBankService { public Long createBank(UserBankSaveReqVO createReqVO) { //校验银行卡号是否已存在 - Long count = bankMapper.selectCount(BankDO::getBankNo, createReqVO.getBankNo()); + Long count = bankMapper.selectCount(new LambdaQueryWrapperX() + .eq(BankDO::getBankNo, createReqVO.getBankNo()) + .eq(BankDO::getNickname, createReqVO.getNickname())); if (count > 0L) { throw exception(BANK_EXISTS); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dept/DeptService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dept/DeptService.java index 6a612c1b..53bd84dd 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dept/DeptService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dept/DeptService.java @@ -138,7 +138,7 @@ public interface DeptService { * * @return 部门信息列表 */ - List getCompanyDept(); + List getCompanyDept(Integer method); /** * 获取所有工厂部门 diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceImpl.java index fc84275c..5784c05a 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceImpl.java @@ -330,12 +330,16 @@ public class DeptServiceImpl implements DeptService { @Override @DataPermission(enable = false) - public List getCompanyDept() { + public List getCompanyDept(Integer method) { return deptMapper.selectList(new LambdaQueryWrapperX() + .eq(method == 2, DeptDO::getVirtuallyStatus, 0) + .eq(method == 3, DeptDO::getVirtuallyStatus, 1) + .eq(DeptDO::getStatus, CommonStatusEnum.ENABLE.getStatus()) .eq(DeptDO::getType, DeptTypeEnum.COMPANY.getValue()) - .eq(DeptDO::getVirtuallyStatus, 0) - .eq(DeptDO::getStatus, CommonStatusEnum.ENABLE.getStatus())); + .or() + .eq(DeptDO::getType, DeptTypeEnum.HEAD_COMPANY.getValue())); + } @Override diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/project/ProjectServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/project/ProjectServiceImpl.java index f88027af..f2b9fbc0 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/project/ProjectServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/project/ProjectServiceImpl.java @@ -80,9 +80,9 @@ public class ProjectServiceImpl implements ProjectService { @Override public List getMyProject(Long userId) { return projectMapper.selectList(new LambdaQueryWrapperX() - .eq(ProjectDO::getDirectorUserId, userId) - .or() - .like(ProjectDO::getStaff, userId) +// .eq(ProjectDO::getDirectorUserId, userId) +// .or() +// .like(ProjectDO::getStaff, userId) .eq(ProjectDO::getStatus, 1)); } diff --git a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/service/factoryinfo/FactoryInfoServiceImpl.java b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/service/factoryinfo/FactoryInfoServiceImpl.java index f7a92819..dd1c5775 100644 --- a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/service/factoryinfo/FactoryInfoServiceImpl.java +++ b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/service/factoryinfo/FactoryInfoServiceImpl.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.smartfactory.service.factoryinfo; import cn.hutool.core.collection.CollectionUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.enums.DeptTypeEnum; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.ip.core.Area; @@ -68,9 +69,11 @@ public class FactoryInfoServiceImpl implements FactoryInfoService { DeptRespDTO deptRespDTO = new DeptRespDTO(); deptRespDTO.setFactoryId(factoryInfo.getId()); deptRespDTO.setName(createReqVO.getShortName()); - deptRespDTO.setParentId(130L); //这里设置上级部门为 生产部 + deptRespDTO.setParentId(169L); //这里设置上级部门为 生产部 deptRespDTO.setLeaderUserId(createReqVO.getLeaderUserId()); deptRespDTO.setStatus(CommonStatusEnum.ENABLE.getStatus()); + deptRespDTO.setType(DeptTypeEnum.PRODUCTION_DEPT.getValue()); + deptRespDTO.setVirtuallyStatus(0); deptApi.createDept(deptRespDTO); }