diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOAReceiptApiImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOAReceiptApiImpl.java new file mode 100644 index 00000000..3707e4f4 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOAReceiptApiImpl.java @@ -0,0 +1,50 @@ +package cn.iocoder.yudao.module.bpm.api.oa; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.bpm.api.oa.vo.receipt.BpmOAReceiptDTO; +import cn.iocoder.yudao.module.bpm.api.oa.vo.receipt.BpmOAReceiptVO; +import cn.iocoder.yudao.module.bpm.api.oa.vo.receipt.ReceiptStatisticsDTO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.contract.ContractStatisticsRespVO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.receipt.ReceiptStatisticsVO; +import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAReceiptDO; +import cn.iocoder.yudao.module.bpm.service.oa.BpmOAReceiptService; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +import java.time.LocalDateTime; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; + +/** + * Flowable 流程实例 Api 实现类 + */ +@RestController +@Validated +public class BpmOAReceiptApiImpl implements BpmOAReceiptApi{ + + @Resource + private BpmOAReceiptService receiptService; + + @Override + public CommonResult getReceiptCount(String relation) { + ReceiptStatisticsVO respVO = receiptService.getStatistics(getLoginUserId(), relation); + return success(BeanUtils.toBean(respVO, ReceiptStatisticsDTO.class)); + } + + @Override + public CommonResult> getReceiptList(BpmOAReceiptVO respVO) { + List receiptDO = receiptService.getReceiptList(respVO); + return success(BeanUtils.toBean(receiptDO, BpmOAReceiptDTO.class)); + } + + @Override + public CommonResult> getContractStatistics(List userIds, LocalDateTime[] createTime) { + List respVOS = receiptService.getReceiptStatisticsListByUserIds(userIds, createTime); + return success(BeanUtils.toBean(respVOS, ReceiptStatisticsDTO.class)); + } +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOAReceiptController.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOAReceiptController.java new file mode 100644 index 00000000..615ae77f --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOAReceiptController.java @@ -0,0 +1,107 @@ +package cn.iocoder.yudao.module.bpm.controller.admin.oa; + +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.receipt.BpmOAReceiptCreateReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.receipt.BpmOAReceiptPageReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.receipt.BpmOAReceiptRespVO; +import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAContractDO; +import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAReceiptDO; +import cn.iocoder.yudao.module.bpm.service.oa.BpmOAContractService; +import cn.iocoder.yudao.module.bpm.service.oa.BpmOAReceiptService; +import cn.iocoder.yudao.module.hrm.api.crmcustomer.CrmCustomerApi; +import cn.iocoder.yudao.module.hrm.api.crmcustomer.dto.CrmCustomerDTO; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; + +/** + * OA 回款申请 Controller + * + * @author 符溶馨 + + */ +@Tag(name = "管理后台 - OA 回款申请") +@RestController +@RequestMapping("/bpm/oa/receipt") +@Validated +public class BpmOAReceiptController { + + @Resource + private BpmOAReceiptService receiptService; + + @Resource + private CrmCustomerApi customerApi; + + @Resource + private BpmOAContractService contractService; + + @PostMapping("/create") + @Operation(summary = "创建请求申请") + public CommonResult createReceipt(@Valid @RequestBody BpmOAReceiptCreateReqVO createReqVO) { + + return success(receiptService.createReceipt(getLoginUserId(), createReqVO)); + } + + @GetMapping("/get") + @Operation(summary = "获得回款申请") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + public CommonResult getReceipt(@RequestParam("id") Long id) { + + BpmOAReceiptDO receipt = receiptService.getReceipt(id); + BpmOAReceiptRespVO respVO = BeanUtils.toBean(receipt, BpmOAReceiptRespVO.class); + if (respVO != null) { + + // 获取客户信息 + CrmCustomerDTO crmCustomerDTO = customerApi.getCustomer(receipt.getCustomerId()).getCheckedData(); + // 获取合同信息 + BpmOAContractDO contractDO = contractService.getContract(receipt.getContractId()); + + // 设置客户名称 + respVO.setCustomerName(crmCustomerDTO != null ? crmCustomerDTO.getName() : null); + // 设置合同名称 + respVO.setContractName(contractDO != null ? contractDO.getContractName() : null); + } + + return success(respVO); + } + + @GetMapping("/getByProcessInstanceId") + @Operation(summary = "获得回款申请") + @Parameter(name = "processInstanceId", description = "流程实例编号", required = true, example = "1024") + public CommonResult getByProcessInstanceId(@RequestParam("processInstanceId") String processInstanceId) { + + BpmOAReceiptDO receipt = receiptService.getByProcessInstanceId(processInstanceId); + BpmOAReceiptRespVO respVO = BeanUtils.toBean(receipt, BpmOAReceiptRespVO.class); + if (respVO != null) { + + // 获取客户信息 + CrmCustomerDTO crmCustomerDTO = customerApi.getCustomer(receipt.getCustomerId()).getCheckedData(); + // 获取合同信息 + BpmOAContractDO contractDO = contractService.getContract(receipt.getContractId()); + + // 设置客户名称 + respVO.setCustomerName(crmCustomerDTO != null ? crmCustomerDTO.getName() : null); + // 设置合同名称 + respVO.setContractName(contractDO != null ? contractDO.getContractName() : null); + } + + return success(respVO); + } + + @GetMapping("/page") + @Operation(summary = "获得回款分页列表") + public CommonResult> getPage(@Valid BpmOAReceiptPageReqVO pageReqVO) { + + return success(receiptService.getReceiptPage(pageReqVO)); + } +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/receipt/BpmOAReceiptCreateReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/receipt/BpmOAReceiptCreateReqVO.java new file mode 100644 index 00000000..d3466147 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/receipt/BpmOAReceiptCreateReqVO.java @@ -0,0 +1,55 @@ +package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.receipt; + +import cn.iocoder.yudao.framework.common.pojo.UploadUserFile; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; + +import javax.validation.constraints.NotNull; +import java.math.BigDecimal; +import java.time.LocalDate; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY; + +/** + * 回款申请 创建 Request VO + * + * @author 符溶馨 + */ +@Schema(description = "管理后台 - 回款申请创建 Request VO") +@Data +@EqualsAndHashCode() +@ToString(callSuper = true) +public class BpmOAReceiptCreateReqVO { + + @Schema(description = "客户ID", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "客户ID不能为空") + private Long customerId; + + @Schema(description = "合同ID", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "合同ID不能为空") + private Long contractId; + + @Schema(description = "回款日期", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY) + private LocalDate returnTime; + + @Schema(description = "回款金额", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "回款金额不能为空") + private BigDecimal money; + + @Schema(description = "备注", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private String remark; + + @Schema(description = "流程实例编号") + private String processInstanceId; + + @Schema(description = "状态-参见 bpm_process_instance_result 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Integer result; + + @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/receipt/BpmOAReceiptPageReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/receipt/BpmOAReceiptPageReqVO.java new file mode 100644 index 00000000..39956594 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/receipt/BpmOAReceiptPageReqVO.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.receipt; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +@Schema(description = "管理后台 - 回款申请分页 Request VO") +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class BpmOAReceiptPageReqVO extends PageParam { + + @Schema(description = "客户名称,模糊匹配") + private String customerName; + + @Schema(description = "合同名称,模糊匹配") + private String contractName; + + @Schema(description = "审批结果") + private Integer result; + + @Schema(description = "创建人名称") + private String createName; + + @Schema(description = "查询模式") + private String relation; +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/receipt/BpmOAReceiptRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/receipt/BpmOAReceiptRespVO.java new file mode 100644 index 00000000..3cbeac76 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/receipt/BpmOAReceiptRespVO.java @@ -0,0 +1,56 @@ +package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.receipt; + +import cn.iocoder.yudao.framework.common.pojo.UploadUserFile; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.BpmOABaseRespVO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; + +import java.math.BigDecimal; +import java.time.LocalDate; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY; + +/** + * @author 符溶馨 + */ +@Schema(description = "管理后台 - 退款申请 请求Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class BpmOAReceiptRespVO extends BpmOABaseRespVO { + + @Schema(description = "客户ID") + private Long customerId; + + @Schema(description = "客户名称") + private String customerName; + + @Schema(description = "合同ID") + private Long contractId; + + @Schema(description = "合同编号") + private String contractNo; + + @Schema(description = "合同名称") + private String contractName; + + @Schema(description = "回款日期") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY) + private LocalDate returnTime; + + @Schema(description = "回款金额") + private BigDecimal money; + + @Schema(description = "备注") + private String remark; + + @Schema(description = "创建人") + private String createName; + + @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/receipt/ReceiptStatisticsVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/receipt/ReceiptStatisticsVO.java new file mode 100644 index 00000000..26717088 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/receipt/ReceiptStatisticsVO.java @@ -0,0 +1,26 @@ +package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.receipt; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + +@Schema(description = "管理后台 - 合同审批 请求Request VO") +@Data +public class ReceiptStatisticsVO { + + @Schema(description = "用户编号") + private Long userId; + + @Schema(description = "今日新增回款金额") + private BigDecimal todayAddMoney; + + @Schema(description = "昨日新增回款金额") + private BigDecimal yesterdayAddMoney; + + @Schema(description = "较昨日百分比 | 金额") + private BigDecimal moneyPercentage; + + @Schema(description = "回款总金额") + private BigDecimal money; +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/BpmOAReceiptDO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/BpmOAReceiptDO.java new file mode 100644 index 00000000..c8065dad --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/BpmOAReceiptDO.java @@ -0,0 +1,86 @@ +package cn.iocoder.yudao.module.bpm.dal.dataobject.oa; + +import cn.iocoder.yudao.framework.common.pojo.UploadUserFile; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.refund.BpmOARefundItems; +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import lombok.*; + +import java.math.BigDecimal; +import java.time.LocalDate; +import java.util.List; + +/** + * OA 回款申请 DO + * + * @author 符溶馨 + */ +@TableName(value ="bpm_oa_receipt", autoResultMap = true) +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class BpmOAReceiptDO extends BaseDO { + + /** + * 出差表单主键 + */ + @TableId + private Long id; + + /** + * 申请人的用户编号 + * 关联 AdminUserDO 的 id 属性 + */ + private Long userId; + + /** + * 客户ID + */ + private Long customerId; + + /** + * 合同ID + */ + private Long contractId; + + /** + * 回款日期 + */ + private LocalDate returnTime; + + /** + * 回款金额 + */ + private BigDecimal money; + + /** + * 备注 + */ + private String remark; + + /** + * 结果 + * 枚举 {@link BpmProcessInstanceResultEnum} + * 考虑到简单,所以直接复用了 BpmProcessInstanceResultEnum 枚举,也可以自己定义一个枚举哈 + */ + private Integer result; + + /** + * 对应的流程编号 + * 关联 ProcessInstance 的 id 属性 + */ + private String processInstanceId; + + /** + * 附件基本信息 + */ + @TableField(typeHandler = JacksonTypeHandler.class) + private List fileItems ; +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/oa/BpmOAReceiptMapper.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/oa/BpmOAReceiptMapper.java new file mode 100644 index 00000000..1571ccfd --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/oa/BpmOAReceiptMapper.java @@ -0,0 +1,64 @@ +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.MPJLambdaWrapperX; +import cn.iocoder.yudao.module.bpm.api.oa.vo.receipt.ReceiptStatisticsDTO; +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.receipt.BpmOAReceiptPageReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.receipt.BpmOAReceiptRespVO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.receipt.ReceiptStatisticsVO; +import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAContractDO; +import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAReceiptDO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Objects; + +@Mapper +public interface BpmOAReceiptMapper extends BaseMapperX { + default PageResult selectReceiptPage(BpmOAReceiptPageReqVO pageReqVO, Long userId) { + + MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); + query.selectAll(BpmOAReceiptDO.class); + query.selectAs(BpmOAContractDO::getContractName, BpmOAReceiptRespVO::getContractName); + query.selectAs(BpmOAContractDO::getCustomerName, BpmOAReceiptRespVO::getCustomerName); + query.selectAs(BpmOAContractDO::getContractNo, BpmOAReceiptRespVO::getContractNo); + query.selectAs("u.nickname", BpmOAReceiptRespVO::getCreateName); + query.leftJoin(BpmOAContractDO.class, "c", BpmOAContractDO::getId, BpmOAReceiptDO::getContractId); + query.leftJoin("system_users u on u.id = t.creator"); + query.eqIfPresent(BpmOAReceiptDO::getResult, pageReqVO.getResult()); + query.apply(Objects.nonNull(pageReqVO.getCustomerName()), "c.customer_name LIKE CONCAT('%', {0}, '%')", pageReqVO.getCustomerName()); + query.apply(Objects.nonNull(pageReqVO.getContractName()), "c.contract_name LIKE CONCAT('%', {0}, '%')", pageReqVO.getContractName()); + query.apply(Objects.nonNull(pageReqVO.getCreateName()),"u.nickname Like CONCAT('%', {0}, '%')", pageReqVO.getCreateName()); + if ("my".equals(pageReqVO.getRelation())) { + query.eq(BpmOAContractDO::getUserId, userId); + }else if ("sub".equals(pageReqVO.getRelation())){ + query.innerJoin("(" + + "\tSELECT DISTINCT\n" + + "\t\tu.id \n" + + "\tFROM\n" + + "\t\tsystem_users u\n" + + "\t\tINNER JOIN system_dept d ON d.leader_user_id = "+ userId +"\n" + + "\t\tINNER JOIN system_dept d1 ON d1.flag LIKE CONCAT( '%', d.id, '-' ) \n" + + "\t\tOR d1.flag LIKE CONCAT( '%-', d.id, '-%' ) \n" + + "\t\tOR d1.flag LIKE CONCAT( '-', d.id, '%' ) \n" + + "\tWHERE\n" + + "\t\tu.dept_id = d1.id \n" + + "\t\tAND u.STATUS = 0 \n" + + "\t) subordinate ON subordinate.id = t.user_id"); + } + query.orderByDesc(BpmOAReceiptDO::getCreateTime); + + return selectJoinPage(pageReqVO, BpmOAReceiptRespVO.class, query); + } + + ReceiptStatisticsVO selectStatistics(@Param("userId") Long userId, + @Param("relation") String relation); + + List selectReceiptStatisticsListByUserIds(@Param("userIds") List userIds, + @Param("createTime") LocalDateTime[] createTime); +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAReceiptService.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAReceiptService.java new file mode 100644 index 00000000..bd1bf894 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAReceiptService.java @@ -0,0 +1,80 @@ +package cn.iocoder.yudao.module.bpm.service.oa; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.bpm.api.oa.vo.receipt.BpmOAReceiptVO; +import cn.iocoder.yudao.module.bpm.api.oa.vo.receipt.ReceiptStatisticsDTO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.contract.BpmOAContractPageReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.receipt.BpmOAReceiptCreateReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.receipt.BpmOAReceiptPageReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.receipt.BpmOAReceiptRespVO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.receipt.ReceiptStatisticsVO; +import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAReceiptDO; + +import javax.validation.Valid; +import java.time.LocalDateTime; +import java.util.List; + +public interface BpmOAReceiptService { + + /** + * 创建回款申请 + * + * @param userId 用户编号 + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createReceipt(Long userId, @Valid BpmOAReceiptCreateReqVO createReqVO); + + /** + * 更新回款申请的状态 + * + * @param id 编号 + * @param result 结果 + */ + void updateReceiptResult(String processInstanceId, Long id, Integer result); + + /** + * 获得回款申请 + * + * @param id 编号 + * @return 退款申请 + */ + BpmOAReceiptDO getReceipt(Long id); + + /** + * 获得指定的回款申请 + * @param processInstanceId 流程实例编号 + * @return 退款申请 + */ + BpmOAReceiptDO getByProcessInstanceId(String processInstanceId); + + /** + * 获得回款申请分页列表 + * @param pageReqVO 分页信息 + * @return 分页列表 + */ + PageResult getReceiptPage(BpmOAReceiptPageReqVO pageReqVO); + + /** + * 获得回款统计信息 + * @param userId 用户编号 + * @param relation 查询类型 + * @return 回款统计信息 + */ + ReceiptStatisticsVO getStatistics(Long userId, String relation); + + /** + * 获得回款列表 + * @param respVO 参数信息 + * @return 回款信息列表 + */ + List getReceiptList(BpmOAReceiptVO respVO); + + /** + * 获得指定用户回款统计信息 + * @param userIds 用户编号 + * @param createTime 创建时间 + * @return 回款统计信息 + */ + List getReceiptStatisticsListByUserIds(List userIds, LocalDateTime[] createTime); +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAReceiptServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAReceiptServiceImpl.java new file mode 100644 index 00000000..15b08d18 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAReceiptServiceImpl.java @@ -0,0 +1,180 @@ +package cn.iocoder.yudao.module.bpm.service.oa; + +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.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.bpm.api.oa.vo.receipt.BpmOAReceiptVO; +import cn.iocoder.yudao.module.bpm.api.oa.vo.receipt.ReceiptStatisticsDTO; +import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi; +import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.receipt.BpmOAReceiptCreateReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.receipt.BpmOAReceiptPageReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.receipt.BpmOAReceiptRespVO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.receipt.ReceiptStatisticsVO; +import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAReceiptDO; +import cn.iocoder.yudao.module.bpm.dal.mysql.oa.BpmOAReceiptMapper; +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; +import cn.iocoder.yudao.module.bpm.service.task.BpmHistoryProcessInstanceService; +import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService; +import org.flowable.engine.runtime.ProcessInstance; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.time.LocalDateTime; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.OA_RECEIPT_NOT_EXISTS; + +/** + * OA 回款申请 Service 实现类 + * + * @author 符溶馨 + + */ +@Service +@Validated +public class BpmOAReceiptServiceImpl extends BpmOABaseService implements BpmOAReceiptService{ + + /** + * OA 退款对应的流程定义 KEY + */ + public static final String PROCESS_KEY = "oa_receipt_2"; + + @Resource + private BpmOAReceiptMapper receiptMapper; + + @Resource + private BpmProcessInstanceApi processInstanceApi; + + @Resource + private BpmHistoryProcessInstanceService historyProcessInstanceService; + + @Resource + private BpmProcessInstanceService bpmProcessInstanceService; + + @Override + public Long createReceipt(Long userId, BpmOAReceiptCreateReqVO createReqVO) { + + //插入OA 回款申请 + BpmOAReceiptDO receipt = BeanUtils.toBean(createReqVO, BpmOAReceiptDO.class) + .setUserId(userId) + .setResult(BpmProcessInstanceResultEnum.PROCESS.getResult()); + receiptMapper.insert(receipt) ; + + // 发起 BPM 流程 + Map processInstanceVariables = new HashMap<>(); + String processInstanceId = processInstanceApi.createProcessInstance(userId, + new BpmProcessInstanceCreateReqDTO().setProcessDefinitionKey(PROCESS_KEY) + .setVariables(processInstanceVariables).setBusinessKey(String.valueOf(receipt.getId()))).getCheckedData(); + + // 将工作流的编号,更新到 OA 回款申请单中 + receiptMapper.updateById(new BpmOAReceiptDO().setId(receipt.getId()).setProcessInstanceId(processInstanceId)); + + // 判断是否为重新发起的流程 + if (createReqVO.getProcessInstanceId() != null && createReqVO.getResult() == 3) { + + historyProcessInstanceService.createHistoryProcessInstance(processInstanceId, createReqVO.getProcessInstanceId()); + } + + List fileItems = createReqVO.getFileItems() ; + //这里的逻辑,如果fileItems不为空,且有数据,那么说明是上传了附件的,则需要更工作流文件表对应的实例Id + if (fileItems != null && !fileItems.isEmpty()) { + uploadBpmFileProcessInstanceId(processInstanceId,fileItems) ; + } + + return receipt.getId(); + } + + @Override + public void updateReceiptResult(String processInstanceId, Long id, Integer result) { + + BpmOAReceiptDO receiptDO = validateLeaveExists(id); + //审核通过 (最后节点) + if (BpmProcessInstanceResultEnum.APPROVE.getResult().equals(result)) { + + ProcessInstance instance = bpmProcessInstanceService.getProcessInstance(processInstanceId); + + if (instance.isEnded()) { + + } + } + + receiptMapper.updateById(new BpmOAReceiptDO().setId(id).setResult(result)); + } + + private BpmOAReceiptDO validateLeaveExists(Long id) { + BpmOAReceiptDO receiptDO = receiptMapper.selectById(id); + if (receiptDO == null) { + throw exception(OA_RECEIPT_NOT_EXISTS); + } + return receiptDO; + } + + @Override + public BpmOAReceiptDO getReceipt(Long id) { + + return receiptMapper.selectById(id); + } + + @Override + public BpmOAReceiptDO getByProcessInstanceId(String processInstanceId) { + + return receiptMapper.selectOne(BpmOAReceiptDO::getProcessInstanceId, processInstanceId); + } + + @Override + public PageResult getReceiptPage(BpmOAReceiptPageReqVO pageReqVO) { + + return receiptMapper.selectReceiptPage(pageReqVO, getLoginUserId()); + } + + @Override + public ReceiptStatisticsVO getStatistics(Long userId, String relation) { + ReceiptStatisticsVO respVO = receiptMapper.selectStatistics(userId, relation); + + // 设置数量、金额百分比 + respVO.setMoneyPercentage(calculatePercentageChange(respVO.getTodayAddMoney(), respVO.getYesterdayAddMoney())); + return respVO; + } + + @Override + public List getReceiptList(BpmOAReceiptVO respVO) { + + return receiptMapper.selectList(new LambdaQueryWrapperX() + .inIfPresent(BpmOAReceiptDO::getUserId, respVO.getUserId()) + .eq(BpmOAReceiptDO::getResult, BpmProcessInstanceResultEnum.APPROVE.getResult()) + .betweenIfPresent(BpmOAReceiptDO::getReturnTime, respVO.getStarTime(), respVO.getEndTime())); + } + + @Override + public List getReceiptStatisticsListByUserIds(List userIds, LocalDateTime[] createTime) { + + return receiptMapper.selectReceiptStatisticsListByUserIds(userIds, createTime); + } + + public static BigDecimal calculatePercentageChange(Object today, Object yesterday) { + + // 转换为 BigDecimal 进行高精度计算 + BigDecimal bigToday = new BigDecimal(today.toString()); + BigDecimal bigYesterday = new BigDecimal(yesterday.toString()); + + if (bigYesterday.compareTo(BigDecimal.ZERO) == 0) { + return BigDecimal.ZERO; + } + + // 计算百分比变化 + BigDecimal difference = bigToday.subtract(bigYesterday); // a - b + BigDecimal percentageChange = difference.divide(bigYesterday, 2, RoundingMode.HALF_UP); // (a - b) / b + + // 转为百分比并返回 + return percentageChange.multiply(new BigDecimal(100)); // (result) * 100 + } +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/listener/BpmOAReceiptResultListener.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/listener/BpmOAReceiptResultListener.java new file mode 100644 index 00000000..24b0e825 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/listener/BpmOAReceiptResultListener.java @@ -0,0 +1,32 @@ +package cn.iocoder.yudao.module.bpm.service.oa.listener; + +import cn.iocoder.yudao.module.bpm.framework.bpm.core.event.BpmProcessInstanceResultEvent; +import cn.iocoder.yudao.module.bpm.framework.bpm.core.event.BpmProcessInstanceResultEventListener; +import cn.iocoder.yudao.module.bpm.service.oa.BpmOAReceiptService; +import cn.iocoder.yudao.module.bpm.service.oa.BpmOAReceiptServiceImpl; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * OA 回款单的结果的监听器实现类 + * + * @author 符溶馨 + */ +@Component +public class BpmOAReceiptResultListener extends BpmProcessInstanceResultEventListener { + + @Resource + private BpmOAReceiptService receiptService; + + @Override + protected String getProcessDefinitionKey() { + + return BpmOAReceiptServiceImpl.PROCESS_KEY; + } + + @Override + protected void onEvent(BpmProcessInstanceResultEvent event) { + receiptService.updateReceiptResult(event.getId(), Long.parseLong(event.getBusinessKey()), event.getResult()); + } +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/mapper/oa/BpmOAReceiptMapper.xml b/yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/mapper/oa/BpmOAReceiptMapper.xml new file mode 100644 index 00000000..1922552f --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/mapper/oa/BpmOAReceiptMapper.xml @@ -0,0 +1,62 @@ + + + + + + + + +