diff --git a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/receipt/ReceiptSettlementDTO.java b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/receipt/ReceiptSettlementDTO.java index 0c8bcb8c..704b6ad1 100644 --- a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/receipt/ReceiptSettlementDTO.java +++ b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/receipt/ReceiptSettlementDTO.java @@ -12,4 +12,7 @@ public class ReceiptSettlementDTO { @Schema(description = "回款总金额") private BigDecimal money; + + @Schema(description = "渠道商回款总金额") + private BigDecimal channelAmount; } 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 647801bd..d9f90087 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 @@ -65,6 +65,7 @@ public interface ErrorCodeConstants { ErrorCode OA_PAYMENT_FILES_NOT_NULL = new ErrorCode(1_009_001_128, "后补发票不能为空!"); ErrorCode OA_EXPENSES_NOT_EXISTS = new ErrorCode(1_009_001_129, "开支日报申请不存在"); ErrorCode OA_LOAN_NOT_EXISTS = new ErrorCode(1_009_001_130, "借支申请不存在"); + ErrorCode OA_LOAN_NOT_CREATE = new ErrorCode(1_009_001_131, "厂区员工信息不存在"); // ========== 流程模型 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/financialpayment/vo/FinancialPaymentRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/financialpayment/vo/FinancialPaymentRespVO.java index b954a2af..17b24cbd 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/financialpayment/vo/FinancialPaymentRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/financialpayment/vo/FinancialPaymentRespVO.java @@ -62,4 +62,16 @@ public class FinancialPaymentRespVO { @Schema(description = "流程实例名称") private String processInstanceName; + + @Schema(description = "收款人名称") + private String recipientName; + + @Schema(description = "付款公司编号") + private Long companyId; + + @Schema(description = "付款公司工厂编号") + private Long companyFactoryId; + + @Schema(description = "付款公司名称") + private String companyName; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOAExpensesController.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOAExpensesController.java index 535015f8..75ad37e7 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOAExpensesController.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOAExpensesController.java @@ -74,4 +74,24 @@ public class BpmOAExpensesController { return success(expensesService.getExpensesTotal(pageReqVO)); } + + @GetMapping("/payment") + @Operation(summary = "提前付款") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + public CommonResult getPayment(Long id) { + + expensesService.getPayment(id); + return success(true); + } + + @GetMapping("/refused") + @Operation(summary = "拒绝付款") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @Parameter(name = "processInstanceId", description = "流程实例编号", required = true, example = "1024") + public CommonResult refused(@RequestParam("id") Long id, + @RequestParam("processInstanceId") String processInstanceId) { + + expensesService.refused(id, processInstanceId); + 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/BpmOALoanController.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOALoanController.java index ea81eb8a..3b8bbcbe 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOALoanController.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOALoanController.java @@ -2,9 +2,12 @@ package cn.iocoder.yudao.module.bpm.controller.admin.oa; import cn.hutool.core.collection.CollUtil; 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.loan.BpmOALoanCreateReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.loan.BpmOALoanPageReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.loan.BpmOALoanRespVO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.loan.BpmOAReturnVO; import cn.iocoder.yudao.module.bpm.dal.dataobject.financialpayment.FinancialPaymentDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOALoanDO; import cn.iocoder.yudao.module.bpm.service.financialpayment.FinancialPaymentService; @@ -143,30 +146,29 @@ public class BpmOALoanController { @GetMapping("/get-list") @Operation(summary = "获得指定用户的借支申请列表") - @Parameter(name = "id", description = "编号", required = true, example = "1024") - public CommonResult> getLoanList(@RequestParam("staffId") Long staffId) { + public CommonResult> getLoanList(BpmOALoanPageReqVO pageReqVO) { - List loanList = loanService.getListByStaffId(staffId); - List respVOS = BeanUtils.toBean(loanList, BpmOALoanRespVO.class); - if (CollUtil.isNotEmpty(respVOS)) { + PageResult loanList = loanService.getListByStaffId(pageReqVO); + PageResult respVOS = BeanUtils.toBean(loanList, BpmOALoanRespVO.class); + if (CollUtil.isNotEmpty(respVOS.getList())) { // 获取支付信息 - List processInstanceIds = convertList(loanList, BpmOALoanDO::getProcessInstanceId); + List processInstanceIds = convertList(loanList.getList(), BpmOALoanDO::getProcessInstanceId); Map financialPayments = convertMap(financialPaymentService.getFinancialPaymentList(processInstanceIds), FinancialPaymentDO::getProcessInstanceId); // 获取申请人信息 - Set userIds = convertSet(loanList, BpmOALoanDO::getUserId); + Set userIds = convertSet(loanList.getList(), BpmOALoanDO::getUserId); Map userMap = userApi.getUserMap(userIds); // 获取借支人信息 - Set loanUserIds = convertSet(loanList, BpmOALoanDO::getSfUserId); + Set loanUserIds = convertSet(loanList.getList(), BpmOALoanDO::getSfUserId); Map loanUserMap = convertMap(staffApi.getStaffList(loanUserIds).getCheckedData(), StaffDTO::getId); // 获取工厂信息 - Set deptIds = convertSet(loanList, BpmOALoanDO::getFactoryId); + Set deptIds = convertSet(loanList.getList(), BpmOALoanDO::getFactoryId); Map factoryMap = factoryInfoApi.getFactoryMap(deptIds); - respVOS.forEach(item -> { + respVOS.getList().forEach(item -> { // 设置申请人名称 item.setUserName(userMap.get(item.getUserId()).getNickname()); // 设置借支用户名称 @@ -180,4 +182,13 @@ public class BpmOALoanController { return success(respVOS); } + + @GetMapping("/get-return-list") + @Operation(summary = "获得指定用户的还款列表") + public CommonResult> getReturnList(BpmOALoanPageReqVO pageReqVO) { + + PageResult respVOS = loanService.getReturnList(pageReqVO); + + return success(respVOS); + } } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOAProcurePayController.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOAProcurePayController.java index 0facf882..2f9f5bfe 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOAProcurePayController.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOAProcurePayController.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.bpm.controller.admin.oa; +import cn.hutool.core.collection.CollUtil; 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; @@ -10,7 +11,8 @@ import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.procurepay.BpmOAProcur import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAProcureDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAProcurePayDO; import cn.iocoder.yudao.module.bpm.service.oa.BpmOAProcurePayService; -import cn.iocoder.yudao.module.bpm.service.oa.BpmOAProcureService; +import cn.iocoder.yudao.module.system.api.project.ProjectApi; +import cn.iocoder.yudao.module.system.api.project.dto.ProjectDTO; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; @@ -20,8 +22,12 @@ 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.Set; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; @Tag(name = "管理后台 - 采购支付") @RestController @@ -32,7 +38,7 @@ public class BpmOAProcurePayController { @Resource private BpmOAProcurePayService oAProcurePayService; @Resource - private BpmOAProcureService oaProcureService; + private ProjectApi projectApi; @PostMapping("/create") @Operation(summary = "创建采购支付") @@ -80,7 +86,18 @@ public class BpmOAProcurePayController { @Operation(summary = "获取可用采购单列表") public CommonResult> getAvailablePurchaseOrders(@RequestParam(name = "type", required = false) Integer type) { List list = oAProcurePayService.getAvailablePurchaseOrders(type); - return success(BeanUtils.toBean(list, BpmOAProcureRespVO.class)); + List respVOS = BeanUtils.toBean(list, BpmOAProcureRespVO.class); + if (CollUtil.isNotEmpty(respVOS)) { + // 获取项目编号列表 + Set projectNo = convertSet(respVOS, BpmOAProcureRespVO::getProjectNo); + List projectList = projectApi.getProjectList(projectNo).getCheckedData(); + Map projectMap = convertMap(projectList, ProjectDTO::getProjectNo); + + respVOS.forEach(respVO -> { + respVO.setProjectName(projectMap.get(respVO.getProjectNo()) != null ? projectMap.get(respVO.getProjectNo()).getName() : ""); + }); + } + return success(respVOS); } @GetMapping("/getByProcessInstanceId") diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/expenses/BpmOAExpensesCreateReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/expenses/BpmOAExpensesCreateReqVO.java index 751d7d2f..08fc0806 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/expenses/BpmOAExpensesCreateReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/expenses/BpmOAExpensesCreateReqVO.java @@ -27,7 +27,7 @@ public class BpmOAExpensesCreateReqVO { @Schema(description = "开支明细") private List expensesItem; - @Schema(description = "工厂类型 | 1公司 工厂") + @Schema(description = "工厂类型 |1工厂 2公司 ") private Integer factoryType; @Schema(description = "报销总金额", requiredMode = Schema.RequiredMode.REQUIRED) diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/expenses/BpmOAExpensesTotal.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/expenses/BpmOAExpensesTotal.java index a6615dbf..773f52b4 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/expenses/BpmOAExpensesTotal.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/expenses/BpmOAExpensesTotal.java @@ -14,4 +14,7 @@ public class BpmOAExpensesTotal { @Schema(description = "应付款金额") private BigDecimal payableAmount; + + @Schema(description = "剩余付款金额") + private BigDecimal remainingPayable; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/loan/BpmOALoanPageReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/loan/BpmOALoanPageReqVO.java new file mode 100644 index 00000000..11acd4f2 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/loan/BpmOALoanPageReqVO.java @@ -0,0 +1,25 @@ +package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.loan; + +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; +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 +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class BpmOALoanPageReqVO extends PageParam { + + @Schema(description = "员工ID") + private Long staffId; + + @Schema(description = "借支类型") + private Integer loanType; +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/loan/BpmOAReturnVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/loan/BpmOAReturnVO.java new file mode 100644 index 00000000..ed2e509b --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/loan/BpmOAReturnVO.java @@ -0,0 +1,32 @@ +package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.loan; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + +@Schema(description = "管理后台 - 借支申请还款 Response VO") +@Data +public class BpmOAReturnVO { + + @Schema(description = "员工ID") + private Long staffId; + + @Schema(description = "员工名称") + private String staffName; + + @Schema(description = "工厂ID") + private Long factoryId; + + @Schema(description = "工厂名称") + private String factoryName; + + @Schema(description = "还款月份") + private String month; + + @Schema(description = "还款金额") + private BigDecimal repaymentAmount; + + @Schema(description = "还款类型 | 1开支抵扣 2工资还款") + private Integer type; +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/financialpayment/FinancialPaymentDO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/financialpayment/FinancialPaymentDO.java index 12336b16..a477aba9 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/financialpayment/FinancialPaymentDO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/financialpayment/FinancialPaymentDO.java @@ -55,7 +55,7 @@ public class FinancialPaymentDO extends BaseDO { */ private String reason; /** - * 流程类型 1现金支出 2备用金 3采购付款 4报销 5付款申请 6薪资付款 7借支申请 8供应商采购付款 + * 流程类型 1现金支出 2备用金 3采购付款 4报销 5付款申请 6薪资付款 7借支申请 8供应商采购付款 9开支日报 */ private Integer type; /** @@ -83,6 +83,19 @@ public class FinancialPaymentDO extends BaseDO { * 流程结束时间 */ private LocalDateTime endTime; + /** + * 收款人名称 + */ + private String recipientName; + /** + * 付款公司编号 + */ + private Long companyId; + + /** + * 公司工厂编号 + */ + private Long companyFactoryId; /** * 名称 @@ -99,4 +112,9 @@ public class FinancialPaymentDO extends BaseDO { */ @TableField(exist = false) private String receiveUserNickName; + /** + * 付款公司名称 + */ + @TableField(exist = false) + private String companyName; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/BpmOAExpensesDO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/BpmOAExpensesDO.java index 81196b93..c5d8d143 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/BpmOAExpensesDO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/BpmOAExpensesDO.java @@ -7,6 +7,7 @@ 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 liquibase.pro.packaged.I; import lombok.*; import java.math.BigDecimal; @@ -54,6 +55,16 @@ public class BpmOAExpensesDO extends BaseDO { */ private BigDecimal totalMoney; + /** + * 支付金额 + */ + private BigDecimal amountPaid; + + /** + * 支付状态 | 0未支付 1已支付 2已抵扣 3未抵扣完 + */ + private Integer status; + /** * 申请结果 * 枚举 {@link BpmProcessInstanceResultEnum} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/BpmOALoanDO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/BpmOALoanDO.java index dd585491..3d879e6f 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/BpmOALoanDO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/BpmOALoanDO.java @@ -69,6 +69,11 @@ public class BpmOALoanDO extends BaseDO { */ private BigDecimal totalMoney; + /** + * 还款金额 + */ + private BigDecimal returnAmount; + /** * 借支原因 */ diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/oa/BpmOALoanMapper.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/oa/BpmOALoanMapper.java index 141caef2..798afdd8 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/oa/BpmOALoanMapper.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/oa/BpmOALoanMapper.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.module.bpm.api.oa.vo.loan.BpmOALoanSumDTO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.loan.BpmOALoanPageReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.loan.BpmOAReturnVO; import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOALoanDO; +import com.baomidou.mybatisplus.core.metadata.IPage; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; @@ -14,4 +18,7 @@ public interface BpmOALoanMapper extends BaseMapperX { List selectSumByStaffId(@Param("staffId") Collection staffId, @Param("month") String month); + + IPage selectReturnList(@Param("pageReqVO") BpmOALoanPageReqVO pageReqVO, + @Param("page") IPage page); } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskEntryLeaderScript.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskEntryLeaderScript.java index a236c88e..2cc987ca 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskEntryLeaderScript.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskEntryLeaderScript.java @@ -58,6 +58,12 @@ public class BpmTaskEntryLeaderScript implements BpmTaskAssignScript { //根据部门ID 获取部门信息 DeptRespDTO dept = deptApi.getDept(deptId).getCheckedData(); + // 获取4级部门信息 + if (dept.getLevel() > 4) { + String[] level = dept.getFlag().split("-"); + dept = deptApi.getDept(Long.valueOf(level[4])).getCheckedData(); + } + return dept != null && dept.getLeaderUserId() != null ? asSet(dept.getLeaderUserId()) : emptySet(); } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/financialpayment/FinancialPaymentService.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/financialpayment/FinancialPaymentService.java index b782b2e9..d0611ea3 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/financialpayment/FinancialPaymentService.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/financialpayment/FinancialPaymentService.java @@ -89,6 +89,13 @@ public interface FinancialPaymentService { */ List getFinancialPaymentList(List processInstanceIds); + /** + * 根据流程实例编号获取支付信息 + * @param processInstanceId 流程实例编号 + * @return 支付信息 + */ + FinancialPaymentDO getFinancialPaymentByProcessInstanceId(String processInstanceId); + /** * 获取支付信息 统计 * @param pageReqVO 查询条件 diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/financialpayment/FinancialPaymentServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/financialpayment/FinancialPaymentServiceImpl.java index a8dc10f7..86ae21b7 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/financialpayment/FinancialPaymentServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/financialpayment/FinancialPaymentServiceImpl.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.bpm.service.financialpayment; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.Constants; import cn.iocoder.yudao.framework.common.enums.SocialTypeEnum; @@ -24,6 +25,7 @@ import cn.iocoder.yudao.module.bpm.dal.mysql.oa.*; import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmProcessInstanceExtMapper; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum; +import cn.iocoder.yudao.module.bpm.service.oa.BpmOAExpensesService; import cn.iocoder.yudao.module.system.api.auth.AdminOauthUserOtherInfoApi; import cn.iocoder.yudao.module.system.api.auth.dto.AdminOauthUserOtherInfoApiDTO; import cn.iocoder.yudao.module.system.api.auth.vo.AdminOauthUserOtherInfoApiVO; @@ -89,6 +91,9 @@ public class FinancialPaymentServiceImpl implements FinancialPaymentService { @Resource private BpmOASalaryMapper salaryMapper; + @Resource + private BpmOAExpensesMapper expensesMapper; + @Override public Long createFinancialPayment(FinancialPaymentSaveVO vo) { FinancialPaymentItemSaveReqVO createReqVO = vo.getFinancialPaymentItemSaveReqVO(); @@ -139,6 +144,8 @@ public class FinancialPaymentServiceImpl implements FinancialPaymentService { case 8: supplierPurchasePaymentMapper.updateById(new BpmOASupplierPurchasePaymentDO().setId(financialPayment.getObjectId()).setResult(BpmProcessInstanceResultEnum.BACK.getResult())); break; + case 9: + expensesMapper.updateById(new BpmOAExpensesDO().setId(financialPayment.getObjectId()).setResult(BpmProcessInstanceResultEnum.BACK.getResult())); } BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO().setProcessInstanceId(financialPayment.getProcessInstanceId()) .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus()) @@ -147,19 +154,31 @@ public class FinancialPaymentServiceImpl implements FinancialPaymentService { } this.updateById(financialPayment); - // 判断是借支申请时 - if (financialPayment.getType() == 7 && financialPayment.getStatus() == 2) { + // 支付完成时 + if (financialPayment.getStatus() == 2) { - // 获取借支信息 - BpmOALoanDO loanDO = loanMapper.selectById(financialPayment.getObjectId()); + switch (financialPayment.getType()) { + case 7: // 借支申请时 + // 获取借支信息 + BpmOALoanDO loanDO = loanMapper.selectById(financialPayment.getObjectId()); - // 同步插入借支表中 - LoanDTO createDO = new LoanDTO() - .setUserId(loanDO.getSfUserId()) - .setDeptId(loanDO.getFactoryId()) - .setAmount(loanDO.getTotalMoney()) - .setReturnAmount(BigDecimal.ZERO); - loanApi.createLoan(createDO); + // 同步插入借支表中 + LoanDTO createDO = new LoanDTO() + .setUserId(loanDO.getSfUserId()) + .setDeptId(loanDO.getFactoryId()) + .setLoanType(loanDO.getLoanType()) + .setAmount(loanDO.getTotalMoney()) + .setReturnAmount(BigDecimal.ZERO); + loanApi.createLoan(createDO); + break; + case 9: // 开支日报时 + // 更新开支日报支付状态、支付金额 + expensesMapper.updateById(new BpmOAExpensesDO() + .setId(financialPayment.getObjectId()) + .setStatus(1) + .setAmountPaid(financialPayment.getActualPayment())); + + } } // -- 获取发起人的openId @@ -253,6 +272,15 @@ public class FinancialPaymentServiceImpl implements FinancialPaymentService { } + @Override + public FinancialPaymentDO getFinancialPaymentByProcessInstanceId(String processInstanceId) { + List financialPaymentDO = financialPaymentMapper.selectList(FinancialPaymentDO::getProcessInstanceId, processInstanceId); + if (CollUtil.isNotEmpty(financialPaymentDO)) { + return financialPaymentDO.get(0); + } + return null; + } + @Override public FinancialPaymentDO getPaymentTotal(FinancialPaymentPageReqVO pageReqVO) { pageReqVO.setReceiveUserId(getLoginUserId()); diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOACashServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOACashServiceImpl.java index 90c5faee..14b3f802 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOACashServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOACashServiceImpl.java @@ -229,6 +229,16 @@ public class BpmOACashServiceImpl extends BpmOABaseService implements BpmOACashS BpmProcessInstanceExtDO processInstance = bpmProcessInstanceService.getProcessInstanceDO(processInstanceId); CommonResult user = userApi.getUser(cash.getUserId()); + + // 从缓存中部门所属公司信息 + DeptRespDTO deptRespDTO = deptApi.getCompanyByDept(cashItemDOs.get(0).getDeptId()).getCheckedData(); + + // 获取收款人信息 + BankRespDTO bankRespDTO = new BankRespDTO(); + if (cash.getBankId() != null) { + bankRespDTO = bankApi.getBank(cash.getBankId()).getCheckedData(); + } + // -- 插入到财务支付表中 financialPaymentService.save(new FinancialPaymentDO() .setUserId(cash.getUserId()) @@ -242,6 +252,8 @@ public class BpmOACashServiceImpl extends BpmOABaseService implements BpmOACashS .setAmountPayable(isImprest == 1 ? amount.abs() : cash.getTotalMoney()) .setBeginTime(processInstance.getCreateTime()) .setEndTime(processInstance.getEndTime()) + .setRecipientName(bankRespDTO.getNickname()) + .setCompanyId(deptRespDTO != null ? deptRespDTO.getId() : null) ); } } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAExpensesService.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAExpensesService.java index 4c1fb0ca..5dd68001 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAExpensesService.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAExpensesService.java @@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAExpensesDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAExpensesItemDO; import javax.validation.Valid; +import java.math.BigDecimal; import java.util.List; public interface BpmOAExpensesService { @@ -70,4 +71,24 @@ public interface BpmOAExpensesService { * @return 统计信息 */ BpmOAExpensesTotal getExpensesTotal(BpmOAExpensesPageReqVO pageReqVO); + + /** + * 提前付款 | 手动插入至支付管理 + * @param id 生产开支id + */ + void getPayment(Long id); + + /** + * 更新生产开支 支付状态 + * @param status 支付状态 + * @param amountPaid 支付金额 + */ + void updateExpenses(Long id ,Integer status, BigDecimal amountPaid); + + /** + * 拒绝付款 + * @param id 生产开支id + * @param processInstanceId 流程实例编号 + */ + void refused(Long id, String processInstanceId); } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAExpensesServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAExpensesServiceImpl.java index ab9419f0..14b86f30 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAExpensesServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAExpensesServiceImpl.java @@ -1,40 +1,50 @@ package cn.iocoder.yudao.module.bpm.service.oa; +import cn.hutool.core.util.StrUtil; +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.framework.mybatis.core.util.MyBatisUtils; -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.expenses.*; import cn.iocoder.yudao.module.bpm.convert.oa.BpmOAExpensesConvert; +import cn.iocoder.yudao.module.bpm.dal.dataobject.financialpayment.FinancialPaymentDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAExpensesDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAExpensesItemDO; +import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO; import cn.iocoder.yudao.module.bpm.dal.mysql.oa.BpmOAExpensesItemMapper; import cn.iocoder.yudao.module.bpm.dal.mysql.oa.BpmOAExpensesMapper; 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.smartfactory.api.factoryInfo.FactoryInfoApi; import cn.iocoder.yudao.module.smartfactory.api.factoryInfo.dto.FactoryInfoDTO; +import cn.iocoder.yudao.module.smartfactory.api.staff.StaffApi; +import cn.iocoder.yudao.module.smartfactory.api.staff.dto.StaffDTO; 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.loan.LoanApi; +import cn.iocoder.yudao.module.system.api.loan.dto.LoanDTO; +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; +import org.flowable.engine.runtime.ProcessInstance; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; +import java.math.BigDecimal; import java.util.HashMap; import java.util.List; import java.util.Map; 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.convertMap; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.OA_EXPENSES_NOT_EXISTS; @@ -59,7 +69,7 @@ public class BpmOAExpensesServiceImpl extends BpmOABaseService implements BpmOAE private BpmOAExpensesItemMapper expensesItemMapper; @Resource - private BpmProcessInstanceApi processInstanceApi; + private BpmProcessInstanceService processInstanceService; @Resource private FactoryInfoApi factoryInfoApi; @@ -67,10 +77,22 @@ public class BpmOAExpensesServiceImpl extends BpmOABaseService implements BpmOAE @Resource private BankApi bankApi; + @Resource + private FinancialPaymentService financialPaymentService; + @Resource @Lazy // 解决循环依赖 private BpmHistoryProcessInstanceService historyProcessInstanceService; + @Resource + private AdminUserApi userApi; + + @Resource + private LoanApi loanApi; + + @Resource + private StaffApi staffApi; + @Override public Long createExpenses(Long userId, BpmOAExpensesCreateReqVO createReqVO) { @@ -90,9 +112,9 @@ public class BpmOAExpensesServiceImpl extends BpmOABaseService implements BpmOAE String type = bpmOAExpensesItemDOS.stream().map(item -> item.getType().toString()).collect(Collectors.joining(",")); processInstanceVariables.put("type", type); processInstanceVariables.put("factoryType", expenses.getFactoryType()); - String processInstanceId = processInstanceApi.createProcessInstance(userId, + String processInstanceId = processInstanceService.createProcessInstance(userId, new BpmProcessInstanceCreateReqDTO().setProcessDefinitionKey(PROCESS_KEY) - .setVariables(processInstanceVariables).setBusinessKey(String.valueOf(expenses.getId()))).getCheckedData(); + .setVariables(processInstanceVariables).setBusinessKey(String.valueOf(expenses.getId()))); // 将工作流的编号,更新到 OA 生产开支单中 expensesMapper.updateById(new BpmOAExpensesDO().setId(expenses.getId()).setProcessInstanceId(processInstanceId)); @@ -118,7 +140,48 @@ public class BpmOAExpensesServiceImpl extends BpmOABaseService implements BpmOAE // 获得现金支出业务数据 BpmOAExpensesDO expenses = validateLeaveExists(id); - expensesMapper.updateById(new BpmOAExpensesDO().setId(id).setResult(result)); + //审核通过 (最后节点) + if (BpmProcessInstanceResultEnum.APPROVE.getResult().equals(result)) { + + ProcessInstance instance = processInstanceService.getProcessInstance(processInstanceId); + if (instance.isEnded()) { + + // 获取申请人对应的厂区员工编号 + StaffDTO staffDTO = staffApi.getStaffByUserId(expenses.getUserId()).getCheckedData(); + if (staffDTO != null) { + + // 判断申请人是否存在 费用借支 + LoanDTO loanDTO = loanApi.getByUserId(staffDTO.getId(), 2).getCheckedData(); + if (loanDTO != null) { + + if (loanDTO.getRemainingAmount().compareTo(expenses.getTotalMoney()) >= 0) { + + // 设置开支日报支付状态为 已抵扣 + expenses.setStatus(2).setAmountPaid(expenses.getTotalMoney()); + + }else { + + // 设置开支日报支付状态为 未抵扣完毕 + expenses.setStatus(3).setAmountPaid(loanDTO.getRemainingAmount()); + } + + // 更新借支表中 归还金额 + loanApi.createLoan(new LoanDTO() + .setUserId(staffDTO.getId()) + .setLoanType(2) + .setAmount(BigDecimal.ZERO) + .setReturnAmount(expenses.getAmountPaid())); + } + } + } + } + + // 更新开支日报 审批结果、支付状态以及支付金额 + expensesMapper.updateById(new BpmOAExpensesDO() + .setId(id) + .setResult(result) + .setStatus(expenses.getStatus()) + .setAmountPaid(expenses.getAmountPaid())); } private BpmOAExpensesDO validateLeaveExists(Long id) { @@ -181,4 +244,70 @@ public class BpmOAExpensesServiceImpl extends BpmOABaseService implements BpmOAE public BpmOAExpensesTotal getExpensesTotal(BpmOAExpensesPageReqVO pageReqVO) { return expensesMapper.selectTotal(pageReqVO); } + + @Override + public void getPayment(Long id) { + + // 获取开支详情 + BpmOAExpensesDO expenses = this.getExpenses(id); + List expensesItems = this.getExpensesItem(id); + + // 校验是否已添加至支付管理 + if (financialPaymentService.getFinancialPaymentByProcessInstanceId(expenses.getProcessInstanceId()) == null) { + + String reason = expensesItems.stream().map(BpmOAExpensesItemDO::getDetail) + .filter(StrUtil::isNotEmpty) + .collect(Collectors.joining(",")); + + BpmProcessInstanceExtDO processInstance = processInstanceService.getProcessInstanceDO(expenses.getProcessInstanceId()); + // -- 插入到财务支付表中 + CommonResult user = userApi.getUser(expenses.getUserId()); + + // 获取收款人信息 + BankRespDTO bankRespDTO = bankApi.getBank(expenses.getBankId()).getCheckedData(); + + // 获取付款公司信息 + FactoryInfoDTO dto = new FactoryInfoDTO(); + if (expenses.getFactoryType() == 1) { + dto = factoryInfoApi.getFactoryInfo(expensesItems.get(0).getDeptId()).getCheckedData(); + } + + financialPaymentService.save(new FinancialPaymentDO() + .setUserId(expenses.getUserId()) + .setDeptId(user.getData() == null ? null : user.getData().getDeptId()) + .setProcessInstanceId(expenses.getProcessInstanceId()) + .setReason(reason) + .setObjectId(id) + .setType(9) + .setStatus(0) + .setAmountPayable(expenses.getTotalMoney()) + .setProcessInstanceName(processInstance.getName()) + .setBeginTime(processInstance.getCreateTime()) + .setEndTime(processInstance.getEndTime()) + .setRecipientName(bankRespDTO.getNickname()) + .setCompanyFactoryId(dto.getId()) + ); + } + } + + @Override + public void updateExpenses(Long id ,Integer status, BigDecimal amountPaid) { + + expensesMapper.updateById(new BpmOAExpensesDO() + .setId(id) + .setStatus(status) + .setAmountPaid(amountPaid)); + } + + @Override + public void refused(Long id, String processInstanceId) { + + // 设置状态为 驳回 + expensesMapper.updateById(new BpmOAExpensesDO() + .setId(id) + .setResult(BpmProcessInstanceResultEnum.BACK.getResult())); + + // 同步更新流程实例表 + processInstanceService.updateProcessInstanceResult(processInstanceId, BpmProcessInstanceResultEnum.BACK.getResult()); + } } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAImprestServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAImprestServiceImpl.java index 7a4e1af6..334a1980 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAImprestServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAImprestServiceImpl.java @@ -14,6 +14,10 @@ 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.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; @@ -40,7 +44,7 @@ import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.OA_IMPREST_NO public class BpmOAImprestServiceImpl extends BpmOABaseService implements BpmOAImprestService { /** - * OA 出差对应的流程定义 KEY + * OA 备用金对应的流程定义 KEY */ public static final String PROCESS_KEY = "oa_imprest"; @@ -49,14 +53,23 @@ public class BpmOAImprestServiceImpl extends BpmOABaseService implements BpmOAIm @Resource private BpmProcessInstanceApi processInstanceApi; + @Resource @Lazy // 解决循环依赖 private BpmProcessInstanceService bpmProcessInstanceService; + @Resource private FinancialPaymentService financialPaymentService; + @Resource private AdminUserApi userApi; + @Resource + private DeptApi deptApi; + + @Resource + private BankApi bankApi; + @Resource private BpmHistoryProcessInstanceService historyProcessInstanceService; @@ -95,7 +108,7 @@ public class BpmOAImprestServiceImpl extends BpmOABaseService implements BpmOAIm @Override public void updateImprestResult(String processInstanceId, Long id, Integer result) { - validateLeaveExists(id); + BpmOAImprestDO imprestDO = validateLeaveExists(id); imprestMapper.updateById(new BpmOAImprestDO().setId(id).setResult(result)); //审核通过 (最后节点) @@ -105,31 +118,44 @@ public class BpmOAImprestServiceImpl extends BpmOABaseService implements BpmOAIm if (instance.isEnded()) { //判断是否有采购报销 - BpmOAImprestDO cash = getImprest(id); BpmProcessInstanceExtDO processInstance = bpmProcessInstanceService.getProcessInstanceDO(processInstanceId); - CommonResult user = userApi.getUser(cash.getUserId()); + CommonResult user = userApi.getUser(imprestDO.getUserId()); + + // 从缓存中部门所属公司信息 + DeptRespDTO deptRespDTO = deptApi.getDept(imprestDO.getCompanyId()).getCheckedData(); + + // 获取收款人信息 + BankRespDTO bankRespDTO = new BankRespDTO(); + if (imprestDO.getBankId() != null) { + bankRespDTO = bankApi.getBank(imprestDO.getBankId()).getCheckedData(); + } + // -- 插入到财务支付表中 financialPaymentService.save(new FinancialPaymentDO() - .setUserId(cash.getUserId()) + .setUserId(imprestDO.getUserId()) .setDeptId(user.getData() == null ? null : user.getData().getDeptId()) - .setProcessInstanceId(cash.getProcessInstanceId()) - .setReason(cash.getReason()) + .setProcessInstanceId(imprestDO.getProcessInstanceId()) + .setReason(imprestDO.getReason()) .setObjectId(id) .setType(2) .setStatus(0) - .setAmountPayable(cash.getAmount()) + .setAmountPayable(imprestDO.getAmount()) .setProcessInstanceName(processInstance.getName()) .setBeginTime(processInstance.getCreateTime()) .setEndTime(processInstance.getEndTime()) + .setRecipientName(bankRespDTO.getNickname()) + .setCompanyId(deptRespDTO != null ? deptRespDTO.getId() : null) ); } } } - private void validateLeaveExists(Long id) { - if (imprestMapper.selectById(id) == null) { + private BpmOAImprestDO validateLeaveExists(Long id) { + BpmOAImprestDO imprestDO = imprestMapper.selectById(id); + if (imprestDO == null) { throw exception(OA_IMPREST_NOT_EXISTS); } + return imprestDO; } @Override diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOALoanService.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOALoanService.java index 7ff8959b..0d2e5951 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOALoanService.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOALoanService.java @@ -1,7 +1,10 @@ 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.loan.BpmOALoanSumDTO; import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.loan.BpmOALoanCreateReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.loan.BpmOALoanPageReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.loan.BpmOAReturnVO; import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOALoanDO; import javax.validation.Valid; @@ -50,11 +53,11 @@ public interface BpmOALoanService { BpmOALoanDO getByProcessInstanceId(String processInstanceId); /** - * 获得指定用户的借支列表 - * @param staffId 员工编号 + * 获得指定用户的借支分页列表 + * @param pageReqVO 分页参数 * @return 借支列表 */ - List getListByStaffId(Long staffId); + PageResult getListByStaffId(BpmOALoanPageReqVO pageReqVO); /** * 获取员工当月需抵扣的借支金额 @@ -62,4 +65,11 @@ public interface BpmOALoanService { * @return 借支金额统计 */ List getListByStaffId(Collection staffId, String month); + + /** + * 获取员工还款分页列表 + * @param pageReqVO 分页信息 + * @return 还款分页列表 + */ + PageResult getReturnList(BpmOALoanPageReqVO pageReqVO); } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOALoanServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOALoanServiceImpl.java index fa0d9213..ad4f4b5e 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOALoanServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOALoanServiceImpl.java @@ -2,12 +2,16 @@ package cn.iocoder.yudao.module.bpm.service.oa; 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.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils; import cn.iocoder.yudao.module.bpm.api.oa.vo.loan.BpmOALoanSumDTO; import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.loan.BpmOALoanCreateReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.loan.BpmOALoanPageReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.loan.BpmOAReturnVO; import cn.iocoder.yudao.module.bpm.dal.dataobject.financialpayment.FinancialPaymentDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOALoanDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO; @@ -16,8 +20,13 @@ 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.smartfactory.api.staff.StaffApi; +import cn.iocoder.yudao.module.smartfactory.api.staff.dto.StaffDTO; +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.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; +import com.baomidou.mybatisplus.core.metadata.IPage; import org.flowable.engine.runtime.ProcessInstance; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -30,6 +39,7 @@ import java.util.List; import java.util.Map; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.OA_LOAN_NOT_CREATE; import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.OA_LOAN_NOT_EXISTS; /** @@ -61,10 +71,26 @@ public class BpmOALoanServiceImpl extends BpmOABaseService implements BpmOALoanS @Resource private FinancialPaymentService financialPaymentService; + @Resource + private StaffApi staffApi; + + @Resource + private BankApi bankApi; + @Override @Transactional(rollbackFor = Exception.class) public Long createLoan(Long userId, BpmOALoanCreateReqVO vo) { + + // 提交是费用借支时 + if (vo.getLoanType() == 2) { + + // 校验创建 + StaffDTO staffDTO = validateCreate(userId, vo); + vo.setSfUserId(staffDTO.getId()); + vo.setFactoryId(staffDTO.getFactoryId()); + } + //插入OA 借支申请 BpmOALoanDO loan = BeanUtils.toBean(vo, BpmOALoanDO.class) .setUserId(userId) @@ -92,9 +118,19 @@ public class BpmOALoanServiceImpl extends BpmOABaseService implements BpmOALoanS return loan.getId(); } + private StaffDTO validateCreate(Long userId, BpmOALoanCreateReqVO vo) { + + StaffDTO staffDTO = staffApi.getStaffByUserId(userId).getCheckedData(); + if (staffDTO == null) { + throw exception(OA_LOAN_NOT_CREATE); + } + + return staffDTO; + } + @Override public void updateLoanResult(String processInstanceId, Long id, Integer result) { - BpmOALoanDO loanDO = validateLeaveExists(id); + BpmOALoanDO loanDO = validateLoanExists(id); loanMapper.updateById(new BpmOALoanDO().setId(id).setResult(result)); //审核通过 (最后节点) @@ -106,6 +142,10 @@ public class BpmOALoanServiceImpl extends BpmOABaseService implements BpmOALoanS BpmProcessInstanceExtDO processInstance = processInstanceService.getProcessInstanceDO(processInstanceId); // -- 插入到财务支付表中 CommonResult user = userApi.getUser(loanDO.getUserId()); + + // 获取收款人信息 + BankRespDTO bankRespDTO = bankApi.getBank(loanDO.getBankId()).getCheckedData(); + financialPaymentService.save(new FinancialPaymentDO() .setUserId(loanDO.getUserId()) .setDeptId(user.getData() == null ? null : user.getData().getDeptId()) @@ -118,12 +158,13 @@ public class BpmOALoanServiceImpl extends BpmOABaseService implements BpmOALoanS .setProcessInstanceName(processInstance.getName()) .setBeginTime(processInstance.getCreateTime()) .setEndTime(processInstance.getEndTime()) + .setRecipientName(bankRespDTO.getNickname()) ); } } } - private BpmOALoanDO validateLeaveExists(Long id) { + private BpmOALoanDO validateLoanExists(Long id) { BpmOALoanDO loanDO = loanMapper.selectById(id); if (loanDO == null) { throw exception(OA_LOAN_NOT_EXISTS); @@ -148,9 +189,10 @@ public class BpmOALoanServiceImpl extends BpmOABaseService implements BpmOALoanS } @Override - public List getListByStaffId(Long staffId) { - return loanMapper.selectList(new LambdaQueryWrapperX() - .eq(BpmOALoanDO::getSfUserId, staffId) + public PageResult getListByStaffId(BpmOALoanPageReqVO pageReqVO) { + return loanMapper.selectPage(pageReqVO, new LambdaQueryWrapperX() + .eq(BpmOALoanDO::getSfUserId, pageReqVO.getStaffId()) + .eq(BpmOALoanDO::getLoanType, pageReqVO.getLoanType()) .eq(BpmOALoanDO::getResult, BpmProcessInstanceResultEnum.APPROVE.getResult())); } @@ -158,4 +200,10 @@ public class BpmOALoanServiceImpl extends BpmOABaseService implements BpmOALoanS public List getListByStaffId(Collection staffId, String month) { return loanMapper.selectSumByStaffId(staffId, month); } + + @Override + public PageResult getReturnList(BpmOALoanPageReqVO pageReqVO) { + IPage page = loanMapper.selectReturnList(pageReqVO, MyBatisUtils.buildPage(pageReqVO)); + return new PageResult<>(page.getRecords(), page.getTotal()); + } } 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 ab6229a0..2c325b6e 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 @@ -125,6 +125,16 @@ public class BpmOAPaymentServiceImpl extends BpmOABaseService implements BpmOAPa BpmProcessInstanceExtDO processInstance = processInstanceService.getProcessInstanceDO(processInstanceId); // -- 插入到财务支付表中 CommonResult user = userApi.getUser(paymentDO.getUserId()); + + // 从缓存中部门所属公司信息 + DeptRespDTO deptRespDTO = deptApi.getDept(paymentDO.getPaymentCompany()).getCheckedData(); + + // 获取收款人信息 + BankRespDTO bankRespDTO = new BankRespDTO(); + if (paymentDO.getBankId() != null) { + bankRespDTO = bankApi.getBank(paymentDO.getBankId()).getCheckedData(); + } + financialPaymentService.save(new FinancialPaymentDO() .setUserId(paymentDO.getUserId()) .setDeptId(user.getData() == null ? null : user.getData().getDeptId()) @@ -137,6 +147,8 @@ public class BpmOAPaymentServiceImpl extends BpmOABaseService implements BpmOAPa .setProcessInstanceName(processInstance.getName()) .setBeginTime(processInstance.getCreateTime()) .setEndTime(processInstance.getEndTime()) + .setRecipientName(bankRespDTO.getNickname()) + .setCompanyId(deptRespDTO != null ? deptRespDTO.getId() : null) ); } } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAReimbursementServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAReimbursementServiceImpl.java index 0679d9bd..79ddedef 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAReimbursementServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAReimbursementServiceImpl.java @@ -25,6 +25,7 @@ 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.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.user.AdminUserApi; @@ -181,12 +182,6 @@ public class BpmOAReimbursementServiceImpl extends BpmOABaseService implements B //判断是否有采购报销 List procureIds = new ArrayList<>(); -// List reimbursements = bpmOAReimbursementDO.getReimbursements(); -// -// //直接从数据库取出来的List 实际上是List类型 所以不能直接遍历 -// //将list再次转为json串,然后由json串再转为list -// String json = JsonUtils.toJsonString(reimbursements); -// reimbursements = JsonUtils.parseArray(json, Reimbursement.class); for (BpmOAReimbursementItemDO reimbursement : reimbursements) { //报销类别为 采购费时 if ("4".equals(reimbursement.getType())) { @@ -238,6 +233,10 @@ public class BpmOAReimbursementServiceImpl extends BpmOABaseService implements B BpmProcessInstanceExtDO processInstance = bpmProcessInstanceService.getProcessInstanceDO(processInstanceId); // -- 插入到财务支付表中 CommonResult user = userApi.getUser(bpmOAReimbursementDO.getUserId()); + + // 从缓存中部门所属公司信息 + DeptRespDTO deptRespDTO = deptApi.getCompanyByDept(reimbursements.get(0).getDeptId()).getCheckedData(); + financialPaymentService.save(new FinancialPaymentDO() .setUserId(bpmOAReimbursementDO.getUserId()) .setDeptId(user.getData() == null ? null : user.getData().getDeptId()) @@ -250,6 +249,8 @@ public class BpmOAReimbursementServiceImpl extends BpmOABaseService implements B .setProcessInstanceName(processInstance.getName()) .setBeginTime(processInstance.getCreateTime()) .setEndTime(processInstance.getEndTime()) + .setRecipientName(bpmOAReimbursementDO.getNickname()) + .setCompanyId(deptRespDTO != null ? deptRespDTO.getId() : null) ); } } 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 a064f7aa..dc01c89c 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 @@ -13,6 +13,7 @@ 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.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.user.AdminUserApi; @@ -110,6 +111,10 @@ public class BpmOASalaryServiceImpl extends BpmOABaseService implements BpmOASal BpmProcessInstanceExtDO processInstance = processInstanceService.getProcessInstanceDO(processInstanceId); // -- 插入到财务支付表中 CommonResult user = userApi.getUser(salaryDO.getUserId()); + + // 从缓存中部门所属公司信息 + DeptRespDTO deptRespDTO = deptApi.getDept(salaryDO.getCompanyDeptId()).getCheckedData(); + financialPaymentService.save(new FinancialPaymentDO() .setUserId(salaryDO.getUserId()) .setDeptId(user.getData() == null ? null : user.getData().getDeptId()) @@ -122,6 +127,7 @@ public class BpmOASalaryServiceImpl extends BpmOABaseService implements BpmOASal .setProcessInstanceName(processInstance.getName()) .setBeginTime(processInstance.getCreateTime()) .setEndTime(processInstance.getEndTime()) + .setCompanyId(deptRespDTO != null && deptRespDTO.getFactoryId() == null ? deptRespDTO.getId() : null) ); } } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java index 6b5530f9..d2beb128 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java @@ -146,6 +146,14 @@ public interface BpmProcessInstanceService { */ void updateProcessInstanceExtReject(String id, String reason); + /** + * 更新 ProcessInstance 拓展记录结果 + * + * @param id 流程编号 + * @param result 结果 + */ + void updateProcessInstanceResult(String id, Integer result); + /** * /** * 流程实例数量统计查询 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 c64e7a1b..6208054c 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.map.MapUtil; 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.common.util.object.BeanUtils; 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.data.redis.core.StringRedisTemplate; 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; @Resource @Lazy // 解决循环依赖 private StringRedisTemplate stringRedisTemplate; @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()); // 发起流程 if (MapUtil.isEmpty(createReqVO.getVariables())){ createReqVO.setVariables(new HashMap<>()); } 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()); // 发起流程 if (MapUtil.isEmpty(createReqDTO.getVariables())){ createReqDTO.setVariables(new HashMap<>()); } 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; DeptRespDTO companyDept = null; if (startUser != null) { dept = deptApi.getDept(startUser.getDeptId()).getCheckedData(); companyDept = deptApi.getUserCompanyDept(startUser.getId()).getCheckedData(); } // 拼接结果 return BpmProcessInstanceConvert.INSTANCE.convert2(processInstance, processInstanceExt, processDefinition, processDefinitionExt, bpmnXml, startUser, dept, companyDept); } @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); // 删除 流程审批部门缓存 updateAssigneeDeptRedis(event.getProcessInstanceId()); // 发送流程实例的状态事件 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); // 删除 流程审批部门缓存 updateAssigneeDeptRedis(instance.getProcessInstanceId()); 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); // 删除 流程审批部门缓存 updateAssigneeDeptRedis(id); // 发送流程被不通过的消息 messageService.sendMessageWhenProcessInstanceReject(BpmProcessInstanceConvert.INSTANCE.convert2RejectReq(processInstance, reason)); // 发送流程实例的状态事件 processInstanceResultEventPublisher.sendProcessInstanceResultEvent( BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult())); } /** * 删除 流程审批部门缓存 * @param processInstanceId 流程实例id */ public void updateAssigneeDeptRedis(String processInstanceId) { stringRedisTemplate.delete("assignee_dept_" + processInstanceId); } 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()); // 设置流程审批部门缓存 stringRedisTemplate.opsForValue().set("assignee_dept_" + instance.getId(), startUser.getDeptId().toString()); // 在事务提交时,批量执行操作,所以直接查询会无法查询到 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); } @Override public List getProcessInstancesGroupByModelName(BpmProcessInstanceStatisticsReqVO pageReqVO) { pageReqVO = getUserids(pageReqVO); return processInstanceExtMapper.getProcessInstancesGroupByModelName(pageReqVO); } @Override public List getProcessInstancesGroupByResultStatus(BpmProcessInstanceStatisticsReqVO pageReqVO) { pageReqVO = getUserids(pageReqVO); return processInstanceExtMapper.getProcessInstancesGroupByResultStatus(pageReqVO); } @Override 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); // 设置发起人信息 printData.setStartUser(BeanUtils.toBean(bpmProcessInstance.getStartUser(), BpmOAPrintDataRespVO.User.class)); 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 +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.map.MapUtil; 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.common.util.object.BeanUtils; 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 com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; 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.data.redis.core.StringRedisTemplate; 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; @Resource @Lazy // 解决循环依赖 private StringRedisTemplate stringRedisTemplate; @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()); // 发起流程 if (MapUtil.isEmpty(createReqVO.getVariables())){ createReqVO.setVariables(new HashMap<>()); } 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()); // 发起流程 if (MapUtil.isEmpty(createReqDTO.getVariables())){ createReqDTO.setVariables(new HashMap<>()); } 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; DeptRespDTO companyDept = null; if (startUser != null) { dept = deptApi.getDept(startUser.getDeptId()).getCheckedData(); companyDept = deptApi.getUserCompanyDept(startUser.getId()).getCheckedData(); } // 拼接结果 return BpmProcessInstanceConvert.INSTANCE.convert2(processInstance, processInstanceExt, processDefinition, processDefinitionExt, bpmnXml, startUser, dept, companyDept); } @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); // 删除 流程审批部门缓存 updateAssigneeDeptRedis(event.getProcessInstanceId()); // 发送流程实例的状态事件 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); // 删除 流程审批部门缓存 updateAssigneeDeptRedis(instance.getProcessInstanceId()); 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); // 删除 流程审批部门缓存 updateAssigneeDeptRedis(id); // 发送流程被不通过的消息 messageService.sendMessageWhenProcessInstanceReject(BpmProcessInstanceConvert.INSTANCE.convert2RejectReq(processInstance, reason)); // 发送流程实例的状态事件 processInstanceResultEventPublisher.sendProcessInstanceResultEvent( BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult())); } @Override public void updateProcessInstanceResult(String id, Integer result) { processInstanceExtMapper.update(null, new LambdaUpdateWrapper() .set(BpmProcessInstanceExtDO::getResult, result) .eq(BpmProcessInstanceExtDO::getProcessInstanceId, id)); } /** * 删除 流程审批部门缓存 * @param processInstanceId 流程实例id */ public void updateAssigneeDeptRedis(String processInstanceId) { stringRedisTemplate.delete("assignee_dept_" + processInstanceId); } 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()); // 设置流程审批部门缓存 stringRedisTemplate.opsForValue().set("assignee_dept_" + instance.getId(), startUser.getDeptId().toString()); // 在事务提交时,批量执行操作,所以直接查询会无法查询到 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); } @Override public List getProcessInstancesGroupByModelName(BpmProcessInstanceStatisticsReqVO pageReqVO) { pageReqVO = getUserids(pageReqVO); return processInstanceExtMapper.getProcessInstancesGroupByModelName(pageReqVO); } @Override public List getProcessInstancesGroupByResultStatus(BpmProcessInstanceStatisticsReqVO pageReqVO) { pageReqVO = getUserids(pageReqVO); return processInstanceExtMapper.getProcessInstancesGroupByResultStatus(pageReqVO); } @Override 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); // 设置发起人信息 printData.setStartUser(BeanUtils.toBean(bpmProcessInstance.getStartUser(), BpmOAPrintDataRespVO.User.class)); 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/resources/mapper/financialpayment/FinancialPaymentMapper.xml b/yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/mapper/financialpayment/FinancialPaymentMapper.xml index 811c918d..d4ce10fe 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/mapper/financialpayment/FinancialPaymentMapper.xml +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/mapper/financialpayment/FinancialPaymentMapper.xml @@ -15,11 +15,14 @@ a.*, b.nickname as nickname, c.name as deptName, - d.nickname as receiveUserNickName + d.nickname as receiveUserNickName, + case when ISNULL(a.company_id) THEN sf.short_name ELSE company.short_name END as companyName from bpm_financial_payment as a left join system_users as b on a.user_id = b.id left join system_dept as c on b.dept_id = c.id left join system_users as d on a.receive_user_id = d.id + left join system_dept as company on company.id = a.company_id + left join sf_factory_info as sf on sf.id = a.company_factory_id a.deleted = 0 diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/mapper/oa/BpmOAExpensesMapper.xml b/yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/mapper/oa/BpmOAExpensesMapper.xml index 8f7c07a4..77a1a869 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/mapper/oa/BpmOAExpensesMapper.xml +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/mapper/oa/BpmOAExpensesMapper.xml @@ -26,7 +26,8 @@ ub.bank_name AS bankName, b.total_money AS totalMoney, b.process_instance_id AS processInstanceId, - c.end_time AS endTime + c.end_time AS endTime, + b.status AS status FROM bpm_oa_expenses b JOIN bpm_oa_expenses_item a ON a.expenses_id = b.id JOIN bpm_process_instance_ext c ON c.process_instance_id = b.process_instance_id @@ -62,8 +63,9 @@ + + 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 index 165083ea..01a0705e 100644 --- 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 @@ -62,21 +62,24 @@ diff --git a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/hrm/api/crmcontract/dto/CrmContractProductSettlementDTO.java b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/hrm/api/crmcontract/dto/CrmContractProductSettlementDTO.java index db2633e5..9c89fc0b 100644 --- a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/hrm/api/crmcontract/dto/CrmContractProductSettlementDTO.java +++ b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/hrm/api/crmcontract/dto/CrmContractProductSettlementDTO.java @@ -22,6 +22,9 @@ public class CrmContractProductSettlementDTO { @Schema(description = "数量") private Integer nums; + @Schema(description = "渠道商转介数量") + private Integer channelNums; + @Schema(description = "折扣") private BigDecimal discount; diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmbusiness/vo/CrmBusinessRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmbusiness/vo/CrmBusinessRespVO.java index fc39bba4..28b877fa 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmbusiness/vo/CrmBusinessRespVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmbusiness/vo/CrmBusinessRespVO.java @@ -76,4 +76,15 @@ public class CrmBusinessRespVO { @Schema(description = "负责人") private String ownUserName; + @Schema(description = "是否渠道商转介 | 0否 1是") + private Integer isChannel; + + @Schema(description = "渠道商名称") + private String channelName; + + @Schema(description = "渠道商联系方式") + private String channelPhone; + + @Schema(description = "渠道商银行卡号") + private String channelBankNo; } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmbusiness/vo/CrmBusinessSaveReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmbusiness/vo/CrmBusinessSaveReqVO.java index d907dab6..97e5b9a4 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmbusiness/vo/CrmBusinessSaveReqVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmbusiness/vo/CrmBusinessSaveReqVO.java @@ -54,8 +54,19 @@ public class CrmBusinessSaveReqVO { @Schema(description = "负责人ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "24317") private Long ownerUserId; - @Schema(description = "商机产品关联列表") private List businessProducts; + @Schema(description = "是否渠道商转介 | 0否 1是") + private Integer isChannel; + + @Schema(description = "渠道商名称") + private String channelName; + + @Schema(description = "渠道商联系方式") + private String channelPhone; + + @Schema(description = "渠道商银行卡号") + private String channelBankNo; + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/salesperformancesettlement/vo/SalesPerformanceSettlementRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/salesperformancesettlement/vo/SalesPerformanceSettlementRespVO.java index 2b074917..9e94c15c 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/salesperformancesettlement/vo/SalesPerformanceSettlementRespVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/salesperformancesettlement/vo/SalesPerformanceSettlementRespVO.java @@ -41,9 +41,15 @@ public class SalesPerformanceSettlementRespVO { @Schema(description = "实际回款额") private BigDecimal actualPayment; + @Schema(description = "渠道回款额") + private BigDecimal channelPayment; + @Schema(description = "实际销售额") private Integer actualSale; + @Schema(description = "渠道销售额") + private Integer channelSale; + @Schema(description = "回款目标") private BigDecimal paymentTarget; diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/salesperformancesettlement/vo/SalesPerformanceSettlementSaveReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/salesperformancesettlement/vo/SalesPerformanceSettlementSaveReqVO.java index acd85d1a..1853bd87 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/salesperformancesettlement/vo/SalesPerformanceSettlementSaveReqVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/salesperformancesettlement/vo/SalesPerformanceSettlementSaveReqVO.java @@ -32,9 +32,15 @@ public class SalesPerformanceSettlementSaveReqVO { @Schema(description = "实际回款额") private BigDecimal actualPayment; + @Schema(description = "渠道回款额") + private BigDecimal channelPayment; + @Schema(description = "实际销售额") private Integer actualSale; + @Schema(description = "渠道销售额") + private Integer channelSale; + @Schema(description = "评分") private BigDecimal score; diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/crmbusiness/CrmBusinessDO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/crmbusiness/CrmBusinessDO.java index c731e46c..e0c17e0c 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/crmbusiness/CrmBusinessDO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/crmbusiness/CrmBusinessDO.java @@ -77,6 +77,20 @@ public class CrmBusinessDO extends BaseDO { * 负责人ID */ private Long ownerUserId; - - + /** + * 是否渠道商转介 | 0否 1是 + */ + private Integer isChannel; + /** + * 渠道商名称 + */ + private String channelName; + /** + * 渠道商电话 + */ + private String channelPhone; + /** + * 渠道商银行账号 + */ + private String channelBankNo; } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/salesperformancesettlement/SalesPerformanceSettlementDO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/salesperformancesettlement/SalesPerformanceSettlementDO.java index 0283b5e2..424f1604 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/salesperformancesettlement/SalesPerformanceSettlementDO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/salesperformancesettlement/SalesPerformanceSettlementDO.java @@ -51,10 +51,18 @@ public class SalesPerformanceSettlementDO extends BaseDO { * 实际回款额 */ private BigDecimal actualPayment; + /** + * 渠道商回款额 + */ + private BigDecimal channelPayment; /** * 实际销售额 */ private Integer actualSale; + /** + * 渠道商销售额 + */ + private Integer channelSale; /** * 评分 */ diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/salesperformancesettlement/SalesPerformanceSettlementServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/salesperformancesettlement/SalesPerformanceSettlementServiceImpl.java index 1af07d2a..97446a58 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/salesperformancesettlement/SalesPerformanceSettlementServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/salesperformancesettlement/SalesPerformanceSettlementServiceImpl.java @@ -55,6 +55,7 @@ import java.util.function.Function; 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.convertMap; import static cn.iocoder.yudao.module.hrm.enums.ErrorCodeConstants.NOT_EDITABLE_UNTIL_SALES_TARGET_HAS_BEEN_APPLIED; /** @@ -219,6 +220,10 @@ public class SalesPerformanceSettlementServiceImpl extends ServiceImpl productMap = contractProductSettlementDTOList.stream().collect(Collectors.groupingBy(CrmContractProductSettlementDTO::getUserId, Collectors.summingInt(CrmContractProductSettlementDTO::getNums))); + //根据用户id分组 并且合并渠道商转介数量 + Map channelMap = contractProductSettlementDTOList.stream().collect(Collectors.groupingBy(CrmContractProductSettlementDTO::getUserId, + Collectors.summingInt(CrmContractProductSettlementDTO::getChannelNums))); + // -- 回款申请 / - 回了多少就是多少咯 - 这个没啥业务判断当前月回了多少款即可 LocalDateTime beginTime = LocalDateTimeUtils.beginOfMonth(now); LocalDateTime endTime = LocalDateTimeUtils.endOfMonth(now); @@ -227,8 +232,8 @@ public class SalesPerformanceSettlementServiceImpl extends ServiceImpl receiptSettlementList = receiptApi.getReceiptSettlement(receiptSettlementVO).getCheckedData(); receiptSettlementList = CollUtil.isEmpty(receiptSettlementList) ? Collections.emptyList() : receiptSettlementList; - Map receiptSettlementMap = receiptSettlementList.stream() - .collect(Collectors.toMap(ReceiptSettlementDTO::getUserId, ReceiptSettlementDTO::getMoney)); + Map receiptSettlementMap = convertMap(receiptSettlementList, ReceiptSettlementDTO::getUserId); + List salesPerformanceSettlementDOS = salesPerformanceSettlementMapper.selectList(new LambdaQueryWrapperX() .eq(SalesPerformanceSettlementDO::getYear, year) .eq(SalesPerformanceSettlementDO::getMonth, month)); @@ -244,6 +249,7 @@ public class SalesPerformanceSettlementServiceImpl extends ServiceImpl> getDeptListByType(@RequestParam("type") String type); + + @GetMapping("/getCompanyByDept") + @Operation(summary = "获取指定类型的部门列表") + @Parameter(name = "deptId", description = "部门编号", required = true) + CommonResult getCompanyByDept(@RequestParam("deptId") Long deptId); } diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/loan/LoanApi.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/loan/LoanApi.java index 58070d30..ad2ccfcf 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/loan/LoanApi.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/loan/LoanApi.java @@ -12,6 +12,9 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; +import java.util.Collection; +import java.util.List; + @FeignClient(name = ApiConstants.NAME) // TODO 芋艿:fallbackFactory = @Tag(name = "RPC 服务 - 假期") public interface LoanApi { @@ -25,5 +28,24 @@ public interface LoanApi { @GetMapping(PREFIX + "/getByUserId") @Operation(summary = "获取借支记录") @Parameter(name = "userId", description = "用户编号", required = true) - CommonResult getByUserId(@RequestParam("userId") Long userId); + @Parameter(name = "loanType", description = "借支类型", required = true) + CommonResult getByUserId(@RequestParam("userId") Long userId, + @RequestParam("loanType") Integer loanType); + + @GetMapping(PREFIX + "/getListByUserId") + @Operation(summary = "获取借支记录") + @Parameter(name = "userIds", description = "用户编号", required = true) + @Parameter(name = "loanType", description = "借支类型", required = true) + CommonResult> getListByUserId(@RequestParam("userIds") Collection userId, + @RequestParam("loanType") Integer loanType); + + + @GetMapping(PREFIX + "/getListByMonth") + @Operation(summary = "获取员工截止当前月份的工资借支余额") + @Parameter(name = "userIds", description = "用户编号", required = true) + @Parameter(name = "month", description = "月份", required = true) + CommonResult> getListByMonth(@RequestParam("userIds") Collection userId, + @RequestParam("month") String month); + + } diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/loan/dto/LoanDTO.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/loan/dto/LoanDTO.java index 04919f3d..348c0510 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/loan/dto/LoanDTO.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/loan/dto/LoanDTO.java @@ -25,6 +25,9 @@ public class LoanDTO { @Schema(description = "借支用户部门名称") private String deptName; + @Schema(description = "借支类型 | 1工资 2费用") + private Integer loanType; + @Schema(description = "借支总额") private BigDecimal amount; diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/project/ProjectApi.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/project/ProjectApi.java index 99555a67..e372b114 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/project/ProjectApi.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/project/ProjectApi.java @@ -12,6 +12,9 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; +import java.util.Collection; +import java.util.List; + @FeignClient(name = ApiConstants.NAME) // TODO 芋艿:fallbackFactory = @Tag(name = "RPC 服务 - 项目") public interface ProjectApi { @@ -26,4 +29,8 @@ public interface ProjectApi { @Operation(summary = "获得项目") @Parameter(name = "projectNo", description = "项目编号", required = true) CommonResult getProject(@RequestParam("projectNo") String projectNo); + + @PostMapping(PREFIX + "/get") + @Operation(summary = "获得项目") + CommonResult> getProjectList(@RequestBody Collection projectNos); } diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java index 53fb73db..08c74c58 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java @@ -282,6 +282,7 @@ public interface ErrorCodeConstants { ErrorCode RENTAL_REFUND_AMOUNT_EXCESS = new ErrorCode(1_013_001_007, "退款金额不能大于收款金额!"); ErrorCode RENTAL_ITEMS_NOT_REFUND = new ErrorCode(1_013_001_008, "物品还未全部退还,不能全额退款!"); ErrorCode RENTAL_ORDER_CUSTOMER_EXISTS = new ErrorCode(1_013_001_009, "该客户已存在租赁订单!"); + ErrorCode RENTAL_SALE_RECORD_NOT_EXISTS = new ErrorCode(1_013_001_010, "租赁转销售记录不存在!"); // ========== 项目管理相关 1-014-001-001 ========== ErrorCode PROJECT_NOT_EXISTS = new ErrorCode(1_014_001_001, "项目不存在!"); 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 adecb122..2b2e6517 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 @@ -159,4 +159,11 @@ public class DeptApiImpl implements DeptApi { List deptList = deptService.getDeptListByType(type); return success(BeanUtils.toBean(deptList, DeptRespDTO.class)); } + + @Override + @DataPermission(enable = false) + public CommonResult getCompanyByDept(Long deptId) { + DeptDO dept = deptService.getCompanyByDept(deptId); + return success(BeanUtils.toBean(dept, DeptRespDTO.class)); + } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/loan/LoanApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/loan/LoanApiImpl.java index 0c9c73c2..c274256d 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/loan/LoanApiImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/loan/LoanApiImpl.java @@ -11,6 +11,9 @@ import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; +import java.util.Collection; +import java.util.List; + import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @RestController // 提供 RESTful API 接口,给 Feign 调用 @@ -28,8 +31,20 @@ public class LoanApiImpl implements LoanApi { } @Override - public CommonResult getByUserId(Long userId) { - LoanDO loanDO = loanService.getByUserId(userId); + public CommonResult getByUserId(Long userId, Integer loanType) { + LoanDO loanDO = loanService.getByUserId(userId, loanType); return success(BeanUtils.toBean(loanDO, LoanDTO.class)); } + + @Override + public CommonResult> getListByUserId(Collection userId, Integer loanType) { + List loanDOList = loanService.getListByUserId(userId, loanType); + return success(BeanUtils.toBean(loanDOList, LoanDTO.class)); + } + + @Override + public CommonResult> getListByMonth(Collection userId, String month) { + List loanDOList = loanService.getListByMonth(userId, month); + return success(BeanUtils.toBean(loanDOList, LoanDTO.class)); + } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/project/ProjectApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/project/ProjectApiImpl.java index a2da17ca..08f763ec 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/project/ProjectApiImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/project/ProjectApiImpl.java @@ -11,6 +11,9 @@ import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; +import java.util.Collection; +import java.util.List; + import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @RestController // 提供 RESTful API 接口,给 Feign 调用 @@ -30,4 +33,10 @@ public class ProjectApiImpl implements ProjectApi { ProjectDO projectDO = projectService.getProject(projectNo); return success(BeanUtils.toBean(projectDO, ProjectDTO.class)); } + + @Override + public CommonResult> getProjectList(Collection projectNos) { + List projectDOList = projectService.getProjectList(projectNos); + return success(BeanUtils.toBean(projectDOList, ProjectDTO.class)); + } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/customersettlement/CustomerSettlementController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/customersettlement/CustomerSettlementController.java index 5165d76d..c3225dca 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/customersettlement/CustomerSettlementController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/customersettlement/CustomerSettlementController.java @@ -71,10 +71,11 @@ public class CustomerSettlementController { } @PutMapping("/update-confirm") - @Operation(summary = "确认结算信息") + @Operation(summary = "修改结算状态") @PreAuthorize("@ss.hasPermission('system:customer-settlement:update')") - public CommonResult updateConfirm(@RequestParam("id") Long id) { - customerSettlementService.updateConfirm(id); + public CommonResult updateConfirm(@RequestParam("id") Long id, + @RequestParam("status") Integer status) { + customerSettlementService.updateConfirm(id, status); return success(true); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/customersettlement/vo/CustomerSettlementRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/customersettlement/vo/CustomerSettlementRespVO.java index df944b3c..494b30b0 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/customersettlement/vo/CustomerSettlementRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/customersettlement/vo/CustomerSettlementRespVO.java @@ -35,11 +35,14 @@ public class CustomerSettlementRespVO { @Schema(description = "收款明细") private List paymentItem; - @Schema(description = "其他扣款明细") - private List otherDeductions; + @Schema(description = "备注") + private String notes; + + @Schema(description = "结算状态 | 1已复核 2已确认") + private Integer status; @Schema(description = "附件") - private List url; + private List fileItems; @Schema(description = "创建人") private String creator; @@ -51,7 +54,4 @@ public class CustomerSettlementRespVO { @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) @ExcelProperty("创建时间") private LocalDateTime createTime; - - @Schema(description = "是否确认") - private Integer isConfirm; } \ 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/customersettlement/vo/CustomerSettlementSaveReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/customersettlement/vo/CustomerSettlementSaveReqVO.java index f4243f41..776701ac 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/customersettlement/vo/CustomerSettlementSaveReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/customersettlement/vo/CustomerSettlementSaveReqVO.java @@ -29,10 +29,13 @@ public class CustomerSettlementSaveReqVO { @Schema(description = "收款明细") private List paymentItem; - @Schema(description = "其他扣款明细") - private List otherDeductions; + @Schema(description = "备注") + private String notes; + + @Schema(description = "结算状态 | 1已复核 2已确认") + private Integer status; @Schema(description = "上传附件", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "https://www.iocoder.cn") - private List url; + private List fileItems; } \ 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/customersettlement/vo/OtherDeductionsVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/customersettlement/vo/OtherDeductionsVO.java index 0302e511..6aa23c56 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/customersettlement/vo/OtherDeductionsVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/customersettlement/vo/OtherDeductionsVO.java @@ -3,11 +3,15 @@ package cn.iocoder.yudao.module.system.controller.admin.customersettlement.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import java.math.BigDecimal; + @Schema(description = "管理后台 - 其他扣款明细 Response VO") @Data public class OtherDeductionsVO { + @Schema(description = "扣款项") private String key; - private String value; + @Schema(description = "扣款金额") + private BigDecimal value; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/customersettlement/vo/SettlementItemVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/customersettlement/vo/SettlementItemVO.java index a2ac863a..3bd61763 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/customersettlement/vo/SettlementItemVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/customersettlement/vo/SettlementItemVO.java @@ -5,6 +5,7 @@ import lombok.Data; import javax.validation.constraints.NotNull; import java.math.BigDecimal; +import java.util.List; @Schema(description = "管理后台 - 结算明细新增/修改 Request VO") @Data @@ -23,8 +24,8 @@ public class SettlementItemVO { @Schema(description = "应结算金额") private BigDecimal shouldSettlementAmount; - @Schema(description = "扣款金额") - private BigDecimal deductionAmount; + @Schema(description = "扣款明细") + private List deductionItems; @Schema(description = "结算金额") private BigDecimal settlementAmount; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/loan/LoanController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/loan/LoanController.java index ad86ff6a..2e608ec5 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/loan/LoanController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/loan/LoanController.java @@ -60,7 +60,7 @@ public class LoanController { @Parameter(name = "staffId", description = "员工编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('system:loan:query')") public CommonResult getByStaffId(@RequestParam("id") Long id) { - LoanDO loan = loanService.getByUserId(id); + LoanDO loan = loanService.getByUserId(id, 1); return success(BeanUtils.toBean(loan, LoanRespVO.class)); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/loan/vo/LoanRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/loan/vo/LoanRespVO.java index bade4655..c8f22461 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/loan/vo/LoanRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/loan/vo/LoanRespVO.java @@ -19,6 +19,9 @@ public class LoanRespVO { @Schema(description = "借支用户编号") private Long userId; + @Schema(description = "借支员工编号") + private Long staffId; + @Schema(description = "借支用户姓名") private String userName; @@ -28,6 +31,9 @@ public class LoanRespVO { @Schema(description = "借支用户部门名称") private String deptName; + @Schema(description = "借支类型 | 1工资 2费用") + private Integer loanType; + @Schema(description = "借支总额") private BigDecimal amount; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/loan/vo/LoanSaveReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/loan/vo/LoanSaveReqVO.java index 2da6f917..9e75e44e 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/loan/vo/LoanSaveReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/loan/vo/LoanSaveReqVO.java @@ -18,9 +18,12 @@ public class LoanSaveReqVO { private Long userId; @Schema(description = "借支用户部门编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "128") - @NotNull(message = "借支用户部门编号不能为空") private Long deptId; + @Schema(description = "借支类型 | 1工资 2费用") + @NotNull(message = "借支类型不能为空") + private Integer loanType; + @Schema(description = "借支总额") private BigDecimal amount; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/rental/RentalCustomerController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/rental/RentalCustomerController.java index f0e48d98..5d782f68 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/rental/RentalCustomerController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/rental/RentalCustomerController.java @@ -1,11 +1,11 @@ package cn.iocoder.yudao.module.system.controller.admin.rental; +import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; -import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; -import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; +import cn.iocoder.yudao.module.smartfactory.api.factoryInfo.FactoryInfoApi; +import cn.iocoder.yudao.module.smartfactory.api.factoryInfo.dto.FactoryInfoDTO; import cn.iocoder.yudao.module.system.controller.admin.rental.vo.customer.RentalCustomerPageReqVO; import cn.iocoder.yudao.module.system.controller.admin.rental.vo.customer.RentalCustomerRespVO; import cn.iocoder.yudao.module.system.controller.admin.rental.vo.customer.RentalCustomerSaveReqVO; @@ -20,13 +20,14 @@ import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; -import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; -import java.io.IOException; 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.operatelog.core.enums.OperateTypeEnum.EXPORT; @Tag(name = "管理后台 - 租赁客户") @@ -38,6 +39,9 @@ public class RentalCustomerController { @Resource private RentalCustomerService rentalCustomerService; + @Resource + private FactoryInfoApi factoryInfoApi; + @PostMapping("/create") @Operation(summary = "创建租赁客户") @PreAuthorize("@ss.hasPermission('system:rental-customer:create')") @@ -87,11 +91,47 @@ public class RentalCustomerController { return success(BeanUtils.toBean(rentalCustomer, RentalCustomerRespVO.class)); } + @GetMapping("/get-list-by-factory") + @Operation(summary = "获得对应工厂的客户列表") + @Parameter(name = "userId", description = "用户id", required = true) + @PreAuthorize("@ss.hasPermission('system:rental-customer:query')") + public CommonResult> getListByFactory(@RequestParam("userId") Long userId) { + List rentalCustomer = rentalCustomerService.getListByFactory(userId); + return success(BeanUtils.toBean(rentalCustomer, RentalCustomerRespVO.class)); + } + @GetMapping("/page") @Operation(summary = "获得租赁客户分页") @PreAuthorize("@ss.hasPermission('system:rental-customer:query')") public CommonResult> getRentalCustomerPage(@Valid RentalCustomerPageReqVO pageReqVO) { PageResult pageResult = rentalCustomerService.getRentalCustomerPage(pageReqVO); - return success(BeanUtils.toBean(pageResult, RentalCustomerRespVO.class)); + PageResult respVO = BeanUtils.toBean(pageResult, RentalCustomerRespVO.class); + if (CollUtil.isNotEmpty(respVO.getList())) { + // 获取工厂编号 + Set factoryIds = pageResult.getList().stream() + .map(RentalCustomerDO::getFactoryIds) + .filter(Objects::nonNull) + .flatMap(Set::stream) + .collect(Collectors.toSet()); + // 获取工厂信息 + List factoryInfoDTOS = factoryInfoApi.getFactoryInfoList(factoryIds).getCheckedData(); + // 映射工厂名称 + Map factoryMap = factoryInfoDTOS.stream() + .collect(Collectors.toMap(FactoryInfoDTO::getId, FactoryInfoDTO::getShortName)); + + respVO.getList().forEach(item -> { + // 设置工厂名称 + Set itemFactoryIds = item.getFactoryIds(); + if (itemFactoryIds != null) { + List factoryNames = itemFactoryIds.stream() + .map(factoryMap::get) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + item.setFactoryNames(factoryNames); + } + }); + } + + return success(respVO); } } \ 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/rental/RentalOrderController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/rental/RentalOrderController.java index a5b1c856..9cd6c517 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/rental/RentalOrderController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/rental/RentalOrderController.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.system.controller.admin.rental; +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; @@ -31,6 +32,8 @@ import java.util.Objects; 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.security.core.util.SecurityFrameworkUtils.getLoginUserId; @Tag(name = "管理后台 - 租赁订单") @@ -101,10 +104,33 @@ public class RentalOrderController { return success(respVO); } + @GetMapping("/getByOrderNo") + @Operation(summary = "获得租赁订单") + @Parameter(name = "orderNo", description = "订单编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('system:rental-order:query')") + public CommonResult getRentalOrder(@RequestParam("orderNo") String orderNo) { + RentalOrderDO rentalOrder = rentalOrderService.getRentalOrder(orderNo); + RentalOrderRespVO respVO = BeanUtils.toBean(rentalOrder, RentalOrderRespVO.class); + + // 获取已收金额 + RentalDepositAmountReqVO amountReqVO = rentalDepositRecordService.getRentalDepositRecordAmount(rentalOrder.getOrderNo(), false); + // 设置剩余金额 = 已收金额 - 已退金额 + respVO.setRemainingDeposit(amountReqVO.getReceivedAmount().subtract(amountReqVO.getRefundAmount())); + + return success(respVO); + } + @GetMapping("/page") @Operation(summary = "获得租赁订单分页") @PreAuthorize("@ss.hasPermission('system:rental-order:query')") public CommonResult> getRentalOrderPage(@Valid RentalOrderPageReqVO pageReqVO) { + + // 获取当前登陆用户的 所属工厂的客户信息 + List rentalCustomerDOList = rentalCustomerService.getListByFactory(getLoginUserId()); + if (CollUtil.isNotEmpty(rentalCustomerDOList)) { + pageReqVO.setCustomerIds(convertList(rentalCustomerDOList, RentalCustomerDO::getId)); + } + PageResult pageResult = rentalOrderService.getRentalOrderPage(pageReqVO); // 获取等待退款的订单号 List orderNos = pageResult.getList().stream() @@ -118,7 +144,6 @@ public class RentalOrderController { // 设置对应的订单号中的 申请退款和扣款金额 pageResult.getList().forEach(item -> { - // 设置剩余押金 item.setRemainingDeposit(item.getReceivedAmount().subtract(item.getRefundAmount().add(item.getChargebacksAmount()))); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/rental/RentalSaleRecordController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/rental/RentalSaleRecordController.java new file mode 100644 index 00000000..89d5a753 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/rental/RentalSaleRecordController.java @@ -0,0 +1,96 @@ +package cn.iocoder.yudao.module.system.controller.admin.rental; + +import cn.hutool.core.collection.CollUtil; +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.system.controller.admin.rental.vo.rentalsalerecord.RentalSaleRecordPageReqVO; +import cn.iocoder.yudao.module.system.controller.admin.rental.vo.rentalsalerecord.RentalSaleRecordRespVO; +import cn.iocoder.yudao.module.system.controller.admin.rental.vo.rentalsalerecord.RentalSaleRecordSaveReqVO; +import cn.iocoder.yudao.module.system.controller.admin.rental.vo.rentalsalerecord.RentalSaleStatusReqVO; +import cn.iocoder.yudao.module.system.dal.dataobject.rental.RentalSaleRecordDO; +import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; +import cn.iocoder.yudao.module.system.service.rental.RentalSaleRecordService; +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; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; + +import java.util.List; +import java.util.Map; + +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.security.core.util.SecurityFrameworkUtils.getLoginUserId; + + +@Tag(name = "管理后台 - 租赁转销售记录") +@RestController +@RequestMapping("/system/rental-sale-record") +@Validated +public class RentalSaleRecordController { + + @Resource + private RentalSaleRecordService rentalSaleRecordService; + + @Resource + private AdminUserService userService; + + @PostMapping("/create") + @Operation(summary = "创建租赁转销售记录") + public CommonResult createRentalSaleRecord(@Valid @RequestBody RentalSaleRecordSaveReqVO createReqVO) { + return success(rentalSaleRecordService.createRentalSaleRecord(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新租赁转销售状态") + @PreAuthorize("@ss.hasPermission('system:rental-sale-record:update')") + public CommonResult updateRentalSaleRecord(@Valid @RequestBody RentalSaleStatusReqVO updateReqVO) { + if (updateReqVO.getStatus() == 1) { + updateReqVO.setReturnUserId(getLoginUserId()); + } + rentalSaleRecordService.updateRentalSaleRecord(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除租赁转销售记录") + @Parameter(name = "id", description = "编号", required = true) + public CommonResult deleteRentalSaleRecord(@RequestParam("id") Long id) { + rentalSaleRecordService.deleteRentalSaleRecord(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得租赁转销售记录") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + public CommonResult getRentalSaleRecord(@RequestParam("id") Long id) { + RentalSaleRecordDO rentalSaleRecord = rentalSaleRecordService.getRentalSaleRecord(id); + return success(BeanUtils.toBean(rentalSaleRecord, RentalSaleRecordRespVO.class)); + } + + @GetMapping("/page") + @Operation(summary = "获得租赁转销售记录分页") + public CommonResult> getRentalSaleRecordPage(@Valid RentalSaleRecordPageReqVO pageReqVO) { + PageResult pageResult = rentalSaleRecordService.getRentalSaleRecordPage(pageReqVO); + PageResult respVO = BeanUtils.toBean(pageResult, RentalSaleRecordRespVO.class); + if (CollUtil.isNotEmpty(respVO.getList())) { + // 获取退还经办人信息 + List userIds = convertList(respVO.getList(), RentalSaleRecordRespVO::getReturnUserId); + Map userMap = userService.getUserMap(userIds); + + respVO.getList().forEach(item -> { + // 设置退还经办人名称 + item.setReturnUserName(userMap.containsKey(item.getReturnUserId()) ? userMap.get(item.getReturnUserId()).getNickname() : ""); + }); + + } + return success(respVO); + } +} \ 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/rental/vo/customer/RentalCustomerPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/rental/vo/customer/RentalCustomerPageReqVO.java index 3ec41554..9aff690a 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/rental/vo/customer/RentalCustomerPageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/rental/vo/customer/RentalCustomerPageReqVO.java @@ -33,6 +33,9 @@ public class RentalCustomerPageReqVO extends PageParam { @Schema(description = "剩余押金金额") private BigDecimal amount; + @Schema(description = "工厂id") + private Long factoryId; + @Schema(description = "创建时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/rental/vo/customer/RentalCustomerRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/rental/vo/customer/RentalCustomerRespVO.java index 903b2d89..c0bf709e 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/rental/vo/customer/RentalCustomerRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/rental/vo/customer/RentalCustomerRespVO.java @@ -5,6 +5,8 @@ import lombok.Data; import java.math.BigDecimal; import java.time.LocalDateTime; +import java.util.List; +import java.util.Set; @Schema(description = "管理后台 - 租赁客户 Response VO") @Data @@ -13,6 +15,12 @@ public class RentalCustomerRespVO { @Schema(description = "租赁客户表单主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") private Long id; + @Schema(description = "所属工厂id集合") + private Set factoryIds; + + @Schema(description = "工厂名称") + private List factoryNames; + @Schema(description = "客户名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六") private String name; @@ -31,6 +39,9 @@ public class RentalCustomerRespVO { @Schema(description = "状态 | 0开启 1关闭") private Integer status; + @Schema(description = "周转天数") + private Integer turnoverDays; + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) private LocalDateTime createTime; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/rental/vo/customer/RentalCustomerSaveReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/rental/vo/customer/RentalCustomerSaveReqVO.java index a419c939..42476418 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/rental/vo/customer/RentalCustomerSaveReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/rental/vo/customer/RentalCustomerSaveReqVO.java @@ -4,7 +4,9 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; import java.math.BigDecimal; +import java.util.Set; @Schema(description = "管理后台 - 租赁客户新增/修改 Request VO") @Data @@ -13,6 +15,9 @@ public class RentalCustomerSaveReqVO { @Schema(description = "租赁客户表单主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") private Long id; + @Schema(description = "所属工厂id集合") + private Set factoryIds; + @Schema(description = "客户名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六") private String name; @@ -30,6 +35,10 @@ public class RentalCustomerSaveReqVO { @Schema(description = "剩余押金金额") private BigDecimal amount; + @Schema(description = "周转天数") + @NotNull(message = "周转天数不能为空") + private Integer turnoverDays; + @Schema(description = "状态 | 0开启 1关闭") private Integer status; } \ 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/rental/vo/order/RentalOrderPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/rental/vo/order/RentalOrderPageReqVO.java index d1880eaf..d3b96f14 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/rental/vo/order/RentalOrderPageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/rental/vo/order/RentalOrderPageReqVO.java @@ -8,6 +8,7 @@ import lombok.ToString; import org.springframework.format.annotation.DateTimeFormat; import java.time.LocalDateTime; +import java.util.List; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; @@ -26,6 +27,9 @@ public class RentalOrderPageReqVO extends PageParam { @Schema(description = "客户编号") private Long customerId; + @Schema(description = "客户编号") + private List customerIds; + @Schema(description = "押金金额") private Integer depositAmount; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/rental/vo/rentaldepositrecord/RentalDepositRecordSaveReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/rental/vo/rentaldepositrecord/RentalDepositRecordSaveReqVO.java index 9fe4495b..f1d405df 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/rental/vo/rentaldepositrecord/RentalDepositRecordSaveReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/rental/vo/rentaldepositrecord/RentalDepositRecordSaveReqVO.java @@ -33,7 +33,7 @@ public class RentalDepositRecordSaveReqVO { private String bankNo; @Schema(description = "客户银行卡号", requiredMode = Schema.RequiredMode.REQUIRED) - @NotEmpty(message = "客户银行卡号不能为空") + @NotNull(message = "客户银行卡号不能为空") private String customerBankNo; @Schema(description = "收款/退款金额", requiredMode = Schema.RequiredMode.REQUIRED) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/rental/vo/rentalsalerecord/RentalSaleRecordPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/rental/vo/rentalsalerecord/RentalSaleRecordPageReqVO.java new file mode 100644 index 00000000..bf0cad2d --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/rental/vo/rentalsalerecord/RentalSaleRecordPageReqVO.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.system.controller.admin.rental.vo.rentalsalerecord; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +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.time.LocalDate; +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - 租赁转销售记录分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class RentalSaleRecordPageReqVO extends PageParam { + + @Schema(description = "订单编号", example = "1024") + private String orderNo; + + @Schema(description = "转销售记录日期") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDate[] saleDate; + + @Schema(description = "状态 | 0销售 1退还", example = "0") + private Integer status; + + @Schema(description = "退还经办人用户编号", example = "146") + private Long returnUserId; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} \ 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/rental/vo/rentalsalerecord/RentalSaleRecordRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/rental/vo/rentalsalerecord/RentalSaleRecordRespVO.java new file mode 100644 index 00000000..b4ba80ec --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/rental/vo/rentalsalerecord/RentalSaleRecordRespVO.java @@ -0,0 +1,44 @@ +package cn.iocoder.yudao.module.system.controller.admin.rental.vo.rentalsalerecord; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 租赁转销售记录 Response VO") +@Data +public class RentalSaleRecordRespVO { + + @Schema(description = "订单租赁物品记录表单主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Long id; + + @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Long customerId; + + @Schema(description = "订单编号", requiredMode = Schema.RequiredMode.REQUIRED) + private String orderNo; + + @Schema(description = "入账记录表主键编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Long depositId; + + @Schema(description = "金额", requiredMode = Schema.RequiredMode.REQUIRED) + private BigDecimal amount; + + @Schema(description = "转销售记录日期", requiredMode = Schema.RequiredMode.REQUIRED) + private LocalDate saleDate; + + @Schema(description = "状态 | 0销售 1退还", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") + private Integer status; + + @Schema(description = "退还经办人用户编号", example = "146") + private Long returnUserId; + + @Schema(description = "退还经办人用户名称", example = "146") + private String returnUserName; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + private LocalDateTime createTime; + +} \ 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/rental/vo/rentalsalerecord/RentalSaleRecordSaveReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/rental/vo/rentalsalerecord/RentalSaleRecordSaveReqVO.java new file mode 100644 index 00000000..3eea3810 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/rental/vo/rentalsalerecord/RentalSaleRecordSaveReqVO.java @@ -0,0 +1,45 @@ +package cn.iocoder.yudao.module.system.controller.admin.rental.vo.rentalsalerecord; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.math.BigDecimal; +import java.time.LocalDate; + +@Schema(description = "管理后台 - 租赁转销售记录新增/修改 Request VO") +@Data +public class RentalSaleRecordSaveReqVO { + + @Schema(description = "订单租赁物品记录表单主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Long id; + + @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "客户编号不能为空") + private Long customerId; + + @Schema(description = "订单编号", requiredMode = Schema.RequiredMode.REQUIRED) + @NotEmpty(message = "订单编号不能为空") + private String orderNo; + + @Schema(description = "入账记录表主键编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "入账记录表主键编号不能为空") + private Long depositId; + + @Schema(description = "金额", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "金额不能为空") + private BigDecimal amount; + + @Schema(description = "转销售记录日期", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "转销售记录日期不能为空") + private LocalDate saleDate; + + @Schema(description = "状态 | 0销售 1退还", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") + @NotNull(message = "状态 | 0销售 1退还不能为空") + private Integer status; + + @Schema(description = "退还经办人用户编号", example = "146") + private Long returnUserId; + +} \ 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/rental/vo/rentalsalerecord/RentalSaleStatusReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/rental/vo/rentalsalerecord/RentalSaleStatusReqVO.java new file mode 100644 index 00000000..9f8399e2 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/rental/vo/rentalsalerecord/RentalSaleStatusReqVO.java @@ -0,0 +1,32 @@ +package cn.iocoder.yudao.module.system.controller.admin.rental.vo.rentalsalerecord; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; +import java.math.BigDecimal; + +@Schema(description = "管理后台 - 租金转销售状态 Request VO") +@Data +public class RentalSaleStatusReqVO { + + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + @NotNull(message = "编号不能为空") + private Long id; + + @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Long customerId; + + @Schema(description = "入账编号") + private Long depositId; + + @Schema(description = "金额") + private BigDecimal amount; + + @Schema(description = "状态 | 0销售 1退还", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") + @NotNull(message = "状态不能为空") + private Integer status; + + @Schema(description = "退还经办人用户编号", example = "146") + private Long returnUserId; +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/customersettlement/CustomerSettlementDO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/customersettlement/CustomerSettlementDO.java index a1c7055f..0eb8d2a6 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/customersettlement/CustomerSettlementDO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/customersettlement/CustomerSettlementDO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.system.dal.dataobject.customersettlement; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.module.system.controller.admin.customersettlement.vo.OtherDeductionsVO; import cn.iocoder.yudao.module.system.controller.admin.customersettlement.vo.PaymentItem; import cn.iocoder.yudao.module.system.controller.admin.worklog.vo.upload.UploadUserFile; import com.baomidou.mybatisplus.annotation.KeySequence; @@ -50,19 +49,18 @@ public class CustomerSettlementDO extends BaseDO { private List paymentItem; /** - * 其他扣款明细 + * 备注 */ - @TableField(typeHandler = JacksonTypeHandler.class) - private List otherDeductions; + private String notes; + + /** + * 结算状态 | 1已复核 2已确认 + */ + private Integer status; /** * 上传附件 */ @TableField(typeHandler = JacksonTypeHandler.class) - private List url; - - /** - * 是否确认 | 0否 1是 - */ - private Integer isConfirm; + private List fileItems; } \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/customersettlement/SettlementItemDO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/customersettlement/SettlementItemDO.java index 6e3d4ddd..8b0b9409 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/customersettlement/SettlementItemDO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/customersettlement/SettlementItemDO.java @@ -1,11 +1,15 @@ package cn.iocoder.yudao.module.system.dal.dataobject.customersettlement; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.module.system.controller.admin.customersettlement.vo.OtherDeductionsVO; +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.util.List; /** * 结算明细信息 DO @@ -48,9 +52,10 @@ public class SettlementItemDO extends BaseDO { private BigDecimal shouldSettlementAmount; /** - * 扣款金额 + * 扣款明细 */ - private BigDecimal deductionAmount; + @TableField(typeHandler = JacksonTypeHandler.class) + private List deductionItems; /** * 结算金额 diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/loan/LoanDO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/loan/LoanDO.java index e8c6e6c6..e5786adc 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/loan/LoanDO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/loan/LoanDO.java @@ -36,6 +36,10 @@ public class LoanDO extends BaseDO { * 借支用户部门编号 */ private Long deptId; + /** + * 借支类型 | 1工资 2费用 + */ + private Integer loanType; /** * 借支总额 */ diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/rental/RentalCustomerDO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/rental/RentalCustomerDO.java index 33e5e265..70e8728c 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/rental/RentalCustomerDO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/rental/RentalCustomerDO.java @@ -1,18 +1,21 @@ package cn.iocoder.yudao.module.system.dal.dataobject.rental; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.framework.mybatis.core.type.JsonLongSetTypeHandler; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.*; import java.math.BigDecimal; +import java.util.Set; /** * 租赁客户 DO * * @author 符溶馨 */ -@TableName("system_rental_customer") +@TableName(value = "system_rental_customer", autoResultMap = true) @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) @@ -26,6 +29,11 @@ public class RentalCustomerDO extends BaseDO { */ @TableId private Long id; + /** + * 所属工厂集合 + */ + @TableField(typeHandler = JsonLongSetTypeHandler.class) + private Set factoryIds; /** * 客户名称 */ @@ -47,6 +55,11 @@ public class RentalCustomerDO extends BaseDO { */ private BigDecimal amount; + /** + * 周转天数 + */ + private Integer turnoverDays; + /** * 状态 0开启 1关闭 */ diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/rental/RentalDepositRecordDO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/rental/RentalDepositRecordDO.java index 3744c117..e0262e78 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/rental/RentalDepositRecordDO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/rental/RentalDepositRecordDO.java @@ -62,7 +62,7 @@ public class RentalDepositRecordDO extends BaseDO { */ private LocalDate paymentDate; /** - * 类型 | 1收款 2退款 + * 类型 | 1收款 2退款 3转销售 */ private Integer type; /** diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/rental/RentalSaleRecordDO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/rental/RentalSaleRecordDO.java new file mode 100644 index 00000000..db2ddbc2 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/rental/RentalSaleRecordDO.java @@ -0,0 +1,61 @@ +package cn.iocoder.yudao.module.system.dal.dataobject.rental; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +import java.math.BigDecimal; +import java.time.LocalDate; + +/** + * 租赁转销售记录 DO + * + * @author 符溶馨 + */ +@TableName("system_rental_sale_record") +@KeySequence("system_rental_sale_record_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class RentalSaleRecordDO extends BaseDO { + + /** + * 订单租赁物品记录表单主键 + */ + @TableId + private Long id; + /** + * 客户编号 + */ + private Long customerId; + /** + * 订单编号 + */ + private String orderNo; + /** + * 入账记录表主键编号 + */ + private Long depositId; + /** + * 金额 + */ + private BigDecimal amount; + /** + * 转销售记录日期 + */ + private LocalDate saleDate; + /** + * 状态 | 0销售 1退还 + */ + private Integer status; + /** + * 退还经办人用户编号 + */ + private Long returnUserId; + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dept/DeptMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dept/DeptMapper.java index 595ed075..33d8352b 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dept/DeptMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dept/DeptMapper.java @@ -63,5 +63,5 @@ public interface DeptMapper extends BaseMapperX { } List selectCompany(@Param("flag") String flag, - @Param("type") String type); + @Param("type") List type); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/loan/LoanMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/loan/LoanMapper.java index b7c189ad..bada070d 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/loan/LoanMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/loan/LoanMapper.java @@ -6,6 +6,10 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.system.controller.admin.loan.vo.LoanPageReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.loan.LoanDO; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.Collection; +import java.util.List; /** * 借支管理 Mapper @@ -20,7 +24,8 @@ public interface LoanMapper extends BaseMapperX { .eqIfPresent(LoanDO::getUserId, reqVO.getUserId()) .eqIfPresent(LoanDO::getDeptId, reqVO.getDeptId()) .betweenIfPresent(LoanDO::getCreateTime, reqVO.getCreateTime()) - .orderByDesc(LoanDO::getId)); + .orderByDesc(LoanDO::getUserId)); } + List selectListByMonth(@Param("userId") Collection userId, @Param("month") String month); } \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/rental/RentalCustomerMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/rental/RentalCustomerMapper.java index 1b3b82c8..da9e6701 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/rental/RentalCustomerMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/rental/RentalCustomerMapper.java @@ -6,6 +6,10 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.system.controller.admin.rental.vo.customer.RentalCustomerPageReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.rental.RentalCustomerDO; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Objects; /** * 租赁客户 Mapper @@ -23,7 +27,9 @@ public interface RentalCustomerMapper extends BaseMapperX { .eqIfPresent(RentalCustomerDO::getBankNo, reqVO.getBankNo()) .eqIfPresent(RentalCustomerDO::getAmount, reqVO.getAmount()) .betweenIfPresent(RentalCustomerDO::getCreateTime, reqVO.getCreateTime()) + .apply(Objects.nonNull(reqVO.getFactoryId()), "JSON_CONTAINS(factory_ids, '{0}', '$')", reqVO.getFactoryId()) .orderByDesc(RentalCustomerDO::getId)); } + List selectListByFactory(@Param("userId") Long userId); } \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/rental/RentalDepositRecordMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/rental/RentalDepositRecordMapper.java index 5b0e7bea..3616b668 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/rental/RentalDepositRecordMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/rental/RentalDepositRecordMapper.java @@ -9,8 +9,6 @@ import cn.iocoder.yudao.module.system.dal.dataobject.rental.RentalDepositRecordD import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; -import java.math.BigDecimal; - /** * 租赁订单押金记录 Mapper * diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/rental/RentalOrderMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/rental/RentalOrderMapper.java index d62779a9..36c62425 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/rental/RentalOrderMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/rental/RentalOrderMapper.java @@ -39,6 +39,7 @@ public interface RentalOrderMapper extends BaseMapperX { .eqIfPresent(RentalOrderDO::getStatus, reqVO.getStatus()) .likeIfPresent(RentalOrderDO::getRecipient, reqVO.getRecipient()) .betweenIfPresent(RentalOrderDO::getCreateTime, reqVO.getCreateTime()) + .inIfPresent(RentalOrderDO::getCustomerId, reqVO.getCustomerIds()) .groupBy(RentalOrderDO::getOrderNo) .orderByDesc(RentalOrderDO::getCreateTime); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/rental/RentalSaleRecordMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/rental/RentalSaleRecordMapper.java new file mode 100644 index 00000000..1bbbf1f8 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/rental/RentalSaleRecordMapper.java @@ -0,0 +1,32 @@ +package cn.iocoder.yudao.module.system.dal.mysql.rental; + +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.system.controller.admin.rental.vo.rentalsalerecord.RentalSaleRecordPageReqVO; +import cn.iocoder.yudao.module.system.controller.admin.rental.vo.rentalsalerecord.RentalSaleRecordRespVO; +import cn.iocoder.yudao.module.system.dal.dataobject.rental.RentalSaleRecordDO; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * 租赁转销售记录 Mapper + * + * @author 符溶馨 + */ +@Mapper +public interface RentalSaleRecordMapper extends BaseMapperX { + + default PageResult selectPage(RentalSaleRecordPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(RentalSaleRecordDO::getOrderNo, reqVO.getOrderNo()) + .betweenIfPresent(RentalSaleRecordDO::getSaleDate, reqVO.getSaleDate()) + .eqIfPresent(RentalSaleRecordDO::getStatus, reqVO.getStatus()) + .eqIfPresent(RentalSaleRecordDO::getReturnUserId, reqVO.getReturnUserId()) + .betweenIfPresent(RentalSaleRecordDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(RentalSaleRecordDO::getId)); + } + + List selectSaleDepositRecordList(); +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/redis/RedisKeyConstants.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/redis/RedisKeyConstants.java index 5db4eae5..044a55d1 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/redis/RedisKeyConstants.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/redis/RedisKeyConstants.java @@ -113,4 +113,11 @@ public interface RedisKeyConstants { * VALUE 数据格式:String 剩余金额 */ String RENTAL_ORDER_AMOUNT = "rental_order_amount"; + + /** + * 所有公司类型部门的缓存 + * KEY 格式:company_dept + * VALUE 数据格式:String 剩余金额 + */ + String COMPANY_DEPT = "COMPANY_DEPT"; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/job/rental/RentalSaleJob.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/job/rental/RentalSaleJob.java new file mode 100644 index 00000000..777aff44 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/job/rental/RentalSaleJob.java @@ -0,0 +1,83 @@ +package cn.iocoder.yudao.module.system.job.rental; + +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.framework.tenant.core.job.TenantJob; +import cn.iocoder.yudao.module.system.controller.admin.rental.vo.rentalsalerecord.RentalSaleRecordRespVO; +import cn.iocoder.yudao.module.system.controller.admin.rental.vo.rentalsalerecord.RentalSaleRecordSaveReqVO; +import cn.iocoder.yudao.module.system.dal.dataobject.rental.RentalCustomerDO; +import cn.iocoder.yudao.module.system.dal.dataobject.rental.RentalDepositRecordDO; +import cn.iocoder.yudao.module.system.dal.mysql.rental.RentalCustomerMapper; +import cn.iocoder.yudao.module.system.service.rental.RentalDepositRecordService; +import cn.iocoder.yudao.module.system.service.rental.RentalSaleRecordService; +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.core.handler.annotation.XxlJob; +import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Component +@Slf4j +@EnableScheduling +public class RentalSaleJob { + + @Resource + private RentalSaleRecordService saleRecordService; + + @Resource + private RentalCustomerMapper customerMapper; + + @Resource + private RentalDepositRecordService depositRecordService; + + @XxlJob("rentalSaleJob") + @TenantJob // --- ⚠️ 这个注解 会将租户列表拉出来 完了后逐个租户执行 定时任务需要注意 + public ReturnT execute() { + + // 获取 当前日期已到达周转日期的收款记录 + List saleRecordList = saleRecordService.getSaleDepositRecordList(); + + List saleRecordSaveReqVOList = BeanUtils.toBean(saleRecordList, RentalSaleRecordSaveReqVO.class); + + // 插入销售数据 + saleRecordService.createBatch(saleRecordSaveReqVOList); + + // 映射出一个map key为客户编号 value为 saleRecordSaveReqVOList该客户金额的和 + Map customerAmountMap = saleRecordSaveReqVOList.stream() + .collect(Collectors.groupingBy( + RentalSaleRecordSaveReqVO::getCustomerId, + Collectors.reducing(BigDecimal.ZERO, RentalSaleRecordSaveReqVO::getAmount, BigDecimal::add) + )); + + // 获取所有客户信息 + List RentalCustomerDO = customerMapper.selectList(); + + // 更新客户押金金额 + RentalCustomerDO = RentalCustomerDO.stream() + .peek(customer -> { + BigDecimal originalAmount = customer.getAmount(); + BigDecimal deductionAmount = customerAmountMap.getOrDefault(customer.getId(), BigDecimal.ZERO); + customer.setAmount(originalAmount.subtract(deductionAmount)); + }) + .collect(Collectors.toList()); + + // 同步更新 客户押金金额 + customerMapper.updateBatch(RentalCustomerDO); + + List updateList = saleRecordList.stream() + .map(saleRecord -> new RentalDepositRecordDO() + .setId(saleRecord.getDepositId()) + .setType(3)) + .collect(Collectors.toList()); + // 同步更新 租金记录表 + depositRecordService.updateRentalDepositRecordType(updateList); + + // 返回执行成功 + return ReturnT.SUCCESS; + } +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/customersettlement/CustomerSettlementService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/customersettlement/CustomerSettlementService.java index 3cf3f2ba..ffa7f6a9 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/customersettlement/CustomerSettlementService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/customersettlement/CustomerSettlementService.java @@ -65,7 +65,9 @@ public interface CustomerSettlementService { /** * 更新结算信息确认状态 - * @param id 编号 + * + * @param id 编号 + * @param status */ - void updateConfirm(Long id); + void updateConfirm(Long id, Integer status); } \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/customersettlement/CustomerSettlementServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/customersettlement/CustomerSettlementServiceImpl.java index 57a933c5..abbebddb 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/customersettlement/CustomerSettlementServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/customersettlement/CustomerSettlementServiceImpl.java @@ -63,7 +63,7 @@ public class CustomerSettlementServiceImpl implements CustomerSettlementService settlementItemMapper.insertBatch(itemDO); } - if (CollUtil.isNotEmpty(customerSettlement.getUrl())) { + if (CollUtil.isNotEmpty(customerSettlement.getFileItems())) { // 更新交易凭证附件 业务编号 UpdateBusinessFile(customerSettlement); } @@ -74,7 +74,7 @@ public class CustomerSettlementServiceImpl implements CustomerSettlementService private void UpdateBusinessFile(CustomerSettlementDO updateReqVO) { - List urls = updateReqVO.getUrl().stream().map(UploadUserFile::getUrl).collect(Collectors.toList()); + List urls = updateReqVO.getFileItems().stream().map(UploadUserFile::getUrl).collect(Collectors.toList()); fileApi.updateBusinessFile(urls, updateReqVO.getId().toString()); } @@ -153,13 +153,13 @@ public class CustomerSettlementServiceImpl implements CustomerSettlementService } @Override - public void updateConfirm(Long id) { + public void updateConfirm(Long id, Integer status) { // 校验存在 validateCustomerSettlementExists(id); // 更新 customerSettlementMapper.updateById(new CustomerSettlementDO() .setId(id) - .setIsConfirm(1)); + .setStatus(status)); } } \ No newline at end of file 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 8bde5a0f..406bf3c2 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 @@ -187,7 +187,6 @@ public interface DeptService { /** * 获取指定类型的部门列表 - * * @param type 部门类型 * @return 部门列表 */ @@ -195,11 +194,17 @@ public interface DeptService { /** * 获取工厂部门 - * * @return 部门列表 */ List getFactoryDept(); + /** + * 获取部门所属公司信息 + * @param deptId 部门编号 + * @return 公司信息 + */ + DeptDO getCompanyByDept(Long deptId); + /** * 获取当前登录用户负责的工厂部门 * 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 f2e9aa15..edf37cd4 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 @@ -373,7 +373,7 @@ public class DeptServiceImpl implements DeptService { } // 根据所在部门信息获取 所在公司信息 - List companyDeptList = deptMapper.selectCompany(deptDo.getFlag(), DeptTypeEnum.COMPANY.getValue()); + List companyDeptList = deptMapper.selectCompany(deptDo.getFlag(), Arrays.asList(DeptTypeEnum.HEAD_COMPANY.getValue(), DeptTypeEnum.COMPANY.getValue())); if (CollectionUtil.isEmpty(companyDeptList)) { return new DeptDO(); @@ -404,6 +404,23 @@ public class DeptServiceImpl implements DeptService { .isNotNull(DeptDO::getFactoryId)); } + @Override + @DataPermission(enable = false) + @Cacheable(cacheNames = RedisKeyConstants.COMPANY_DEPT, key = "#deptId") + public DeptDO getCompanyByDept(Long deptId) { + DeptDO deptDO = deptMapper.selectById(deptId); + if (deptDO.getType().equals(DeptTypeEnum.COMPANY.getValue())) { + return deptDO; + } + + // 从缓存中获取所有非虚机构的公司信息 + List companyDOs = this.getCompanyDept(2); + return companyDOs.stream() + .filter(company -> deptDO.getFlag().contains(company.getFlag())) + .findFirst() + .orElse(null); + } + @Override public List getFactoryDeptByLeaderId(Long id) { return deptMapper.selectList(new LambdaQueryWrapperX() diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/loan/LoanService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/loan/LoanService.java index fa6e54db..c1c85cdf 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/loan/LoanService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/loan/LoanService.java @@ -6,6 +6,8 @@ import cn.iocoder.yudao.module.system.controller.admin.loan.vo.LoanSaveReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.loan.LoanDO; import javax.validation.Valid; +import java.util.Collection; +import java.util.List; /** * 借支管理 Service 接口 @@ -41,7 +43,24 @@ public interface LoanService { /** * 根据用户编号获取借支管理 * @param userId 用户编号 + * @param loanType 借支类型 * @return 借支记录 */ - LoanDO getByUserId(Long userId); + LoanDO getByUserId(Long userId, Integer loanType); + + /** + * 根据用户编号集合获取借支管理 + * @param userIds 用户编号集合 + * @param loanType 借支类型 + * @return 借支记录 + */ + List getListByUserId(Collection userIds, Integer loanType); + + /** + * 获取员工截止当前月份的工资借支余额 + * @param userId 用户编号集合 + * @param month 月份 + * @return 借支记录 + */ + List getListByMonth(Collection userId, String month); } \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/loan/LoanServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/loan/LoanServiceImpl.java index c3af0f0c..653ab663 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/loan/LoanServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/loan/LoanServiceImpl.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.system.service.loan; 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.loan.vo.LoanPageReqVO; import cn.iocoder.yudao.module.system.controller.admin.loan.vo.LoanSaveReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.loan.LoanDO; @@ -10,6 +11,8 @@ import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; +import java.util.Collection; +import java.util.List; /** * 借支管理 Service 实现类 @@ -27,7 +30,9 @@ public class LoanServiceImpl implements LoanService { public void createLoan(LoanSaveReqVO createReqVO) { // 判断该借支用户 是否已存在借支记录 - LoanDO loanDO = loanMapper.selectOne(LoanDO::getUserId, createReqVO.getUserId()); + LoanDO loanDO = loanMapper.selectOne(new LambdaQueryWrapperX() + .eq(LoanDO::getUserId, createReqVO.getUserId()) + .eq(LoanDO::getLoanType, createReqVO.getLoanType())); if (loanDO != null) { // 借支用户已存在借支记录,则更新该借支用户记录 LoanDO updateDO = new LoanDO() @@ -38,8 +43,6 @@ public class LoanServiceImpl implements LoanService { loanMapper.updateById(updateDO); }else { // 借支用户不存在借支记录,则插入一条新记录 - - // 插入 LoanDO createDO = BeanUtils.toBean(createReqVO, LoanDO.class); loanMapper.insert(createDO); } @@ -56,7 +59,22 @@ public class LoanServiceImpl implements LoanService { } @Override - public LoanDO getByUserId(Long userId) { - return loanMapper.selectOne(LoanDO::getUserId, userId); + public LoanDO getByUserId(Long userId, Integer loanType) { + return loanMapper.selectOne(new LambdaQueryWrapperX() + .eq(LoanDO::getUserId, userId) + .eq(LoanDO::getLoanType, loanType)); + } + + @Override + public List getListByUserId(Collection userIds, Integer loanType) { + return loanMapper.selectList(new LambdaQueryWrapperX() + .in(LoanDO::getUserId, userIds) + .eq(LoanDO::getLoanType, loanType)); + } + + @Override + public List getListByMonth(Collection userId, String month) { + + return loanMapper.selectListByMonth(userId, month); } } \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/project/ProjectService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/project/ProjectService.java index 54562973..07d4b2b8 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/project/ProjectService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/project/ProjectService.java @@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.system.controller.admin.project.vo.ProjectSaveReq import cn.iocoder.yudao.module.system.dal.dataobject.project.ProjectDO; import javax.validation.Valid; +import java.util.Collection; import java.util.List; /** @@ -67,4 +68,11 @@ public interface ProjectService { * @return 项目列表 */ List getMyProject(Long userId); + + /** + * 获得项目列表 + * @param projectNos 项目编号集合 + * @return 项目信息列表 + */ + List getProjectList(Collection projectNos); } \ No newline at end of file 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 f2b9fbc0..82fdba67 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 @@ -12,6 +12,7 @@ import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; +import java.util.Collection; import java.util.List; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; @@ -86,4 +87,10 @@ public class ProjectServiceImpl implements ProjectService { .eq(ProjectDO::getStatus, 1)); } + @Override + public List getProjectList(Collection projectNos) { + + return projectMapper.selectList(ProjectDO::getProjectNo, projectNos); + } + } \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/rental/RentalCustomerService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/rental/RentalCustomerService.java index c49cb2b5..c50e3b9f 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/rental/RentalCustomerService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/rental/RentalCustomerService.java @@ -2,12 +2,12 @@ package cn.iocoder.yudao.module.system.service.rental; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.system.controller.admin.rental.vo.customer.RentalCustomerPageReqVO; -import cn.iocoder.yudao.module.system.controller.admin.rental.vo.customer.RentalCustomerRespVO; import cn.iocoder.yudao.module.system.controller.admin.rental.vo.customer.RentalCustomerSaveReqVO; import cn.iocoder.yudao.module.system.controller.admin.rental.vo.customer.RentalCustomerStatusReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.rental.RentalCustomerDO; import javax.validation.Valid; +import java.math.BigDecimal; import java.util.List; /** @@ -38,6 +38,14 @@ public interface RentalCustomerService { */ void updateRentalCustomerStatus(RentalCustomerStatusReqVO updateReqVO); + /** + * 更新客户剩余押金金额 + * + * @param id 编号 + * @param amount 金额 + */ + void updateRentalCustomerAmount(Long id, BigDecimal amount); + /** * 删除租赁客户 * @@ -66,4 +74,11 @@ public interface RentalCustomerService { * @return 租赁客户列表 */ List getRentalCustomerList(); + + /** + * 得对应工厂的客户列表 + * @param userId 当前登陆用户编号 + * @return 客户列表 + */ + List getListByFactory(Long userId); } \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/rental/RentalCustomerServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/rental/RentalCustomerServiceImpl.java index 071a1b2c..b3018d91 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/rental/RentalCustomerServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/rental/RentalCustomerServiceImpl.java @@ -4,7 +4,6 @@ import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.system.controller.admin.rental.vo.customer.RentalCustomerPageReqVO; -import cn.iocoder.yudao.module.system.controller.admin.rental.vo.customer.RentalCustomerRespVO; import cn.iocoder.yudao.module.system.controller.admin.rental.vo.customer.RentalCustomerSaveReqVO; import cn.iocoder.yudao.module.system.controller.admin.rental.vo.customer.RentalCustomerStatusReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.rental.RentalCustomerDO; @@ -13,7 +12,7 @@ import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; - +import java.math.BigDecimal; import java.util.List; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; @@ -59,6 +58,14 @@ public class RentalCustomerServiceImpl implements RentalCustomerService { rentalCustomerMapper.updateById(updateObj); } + @Override + public void updateRentalCustomerAmount(Long id, BigDecimal amount) { + // 校验存在 + validateRentalCustomerExists(id); + // 更新 + rentalCustomerMapper.updateById(new RentalCustomerDO().setId(id).setAmount(amount)); + } + @Override public void deleteRentalCustomer(Long id) { // 校验存在 @@ -88,4 +95,9 @@ public class RentalCustomerServiceImpl implements RentalCustomerService { return rentalCustomerMapper.selectList(RentalCustomerDO::getStatus, CommonStatusEnum.ENABLE.getStatus()); } + @Override + public List getListByFactory(Long userId) { + return rentalCustomerMapper.selectListByFactory(userId); + } + } \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/rental/RentalDepositRecordService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/rental/RentalDepositRecordService.java index cb8a66ec..365c0a99 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/rental/RentalDepositRecordService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/rental/RentalDepositRecordService.java @@ -7,7 +7,6 @@ import cn.iocoder.yudao.module.system.controller.admin.rental.vo.rentaldepositre import cn.iocoder.yudao.module.system.dal.dataobject.rental.RentalDepositRecordDO; import javax.validation.Valid; -import java.math.BigDecimal; import java.util.List; /** @@ -39,6 +38,13 @@ public interface RentalDepositRecordService { */ void updateRentalDepositRecord(@Valid RentalDepositRecordSaveReqVO updateReqVO); + /** + * 更新租赁订单押金记录类型 + * + * @param updateReqVO 修改信息 +| */ + void updateRentalDepositRecordType(List updateReqVO); + /** * 获得租赁订单押金记录 * diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/rental/RentalDepositRecordServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/rental/RentalDepositRecordServiceImpl.java index 538f158b..c94c7b2e 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/rental/RentalDepositRecordServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/rental/RentalDepositRecordServiceImpl.java @@ -5,7 +5,6 @@ import cn.iocoder.yudao.framework.common.pojo.UploadUserFile; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.bpm.api.oa.BpmOARefundApi; import cn.iocoder.yudao.module.infra.api.file.FileApi; -import cn.iocoder.yudao.module.system.controller.admin.rental.vo.customer.RentalCustomerSaveReqVO; import cn.iocoder.yudao.module.system.controller.admin.rental.vo.itemsrecord.RentalItemsCountReqVO; import cn.iocoder.yudao.module.system.controller.admin.rental.vo.rentaldepositrecord.RentalDepositAmountReqVO; import cn.iocoder.yudao.module.system.controller.admin.rental.vo.rentaldepositrecord.RentalDepositRecordPageReqVO; @@ -119,9 +118,7 @@ public class RentalDepositRecordServiceImpl implements RentalDepositRecordServic Long customerId = rentalOrderService.getCustomerIdByOrderNo(createReqVO.getOrderNo()); if (customerId != null) { // 同步更新客户剩余押金 金额 - customerService.updateRentalCustomer(new RentalCustomerSaveReqVO() - .setId(customerId) - .setAmount(customerDepositAmount)); + customerService.updateRentalCustomerAmount(customerId, customerDepositAmount); } // 返回 @@ -155,6 +152,13 @@ public class RentalDepositRecordServiceImpl implements RentalDepositRecordServic rentalDepositRecordMapper.updateById(updateObj); } + @Override + public void updateRentalDepositRecordType(List updateReqVO) { + + // 更新 + rentalDepositRecordMapper.updateBatch(updateReqVO); + } + private void validateRentalDepositRecordExists(Long id) { if (rentalDepositRecordMapper.selectById(id) == null) { throw exception(RENTAL_DEPOSIT_RECORD_NOT_EXISTS); @@ -175,5 +179,4 @@ public class RentalDepositRecordServiceImpl implements RentalDepositRecordServic public RentalDepositAmountReqVO getRentalDepositRecordAmount(String orderNo, Boolean isUpdate) { return rentalDepositRecordMapper.selectAmount(orderNo, isUpdate); } - } \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/rental/RentalSaleRecordService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/rental/RentalSaleRecordService.java new file mode 100644 index 00000000..ec49e288 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/rental/RentalSaleRecordService.java @@ -0,0 +1,70 @@ +package cn.iocoder.yudao.module.system.service.rental; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.system.controller.admin.rental.vo.rentalsalerecord.RentalSaleRecordPageReqVO; +import cn.iocoder.yudao.module.system.controller.admin.rental.vo.rentalsalerecord.RentalSaleRecordRespVO; +import cn.iocoder.yudao.module.system.controller.admin.rental.vo.rentalsalerecord.RentalSaleRecordSaveReqVO; +import cn.iocoder.yudao.module.system.controller.admin.rental.vo.rentalsalerecord.RentalSaleStatusReqVO; +import cn.iocoder.yudao.module.system.dal.dataobject.rental.RentalSaleRecordDO; + +import javax.validation.Valid; +import java.util.List; + +/** + * 租赁转销售记录 Service 接口 + * + * @author 符溶馨 + */ +public interface RentalSaleRecordService { + + /** + * 创建租赁转销售记录 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createRentalSaleRecord(@Valid RentalSaleRecordSaveReqVO createReqVO); + + /** + * 创建租赁转销售记录 + * + * @param createReqVO 创建信息 + */ + void createBatch(@Valid List createReqVO); + + /** + * 更新租赁转销售记录 + * + * @param updateReqVO 更新信息 + */ + void updateRentalSaleRecord(@Valid RentalSaleStatusReqVO updateReqVO); + + /** + * 删除租赁转销售记录 + * + * @param id 编号 + */ + void deleteRentalSaleRecord(Long id); + + /** + * 获得租赁转销售记录 + * + * @param id 编号 + * @return 租赁转销售记录 + */ + RentalSaleRecordDO getRentalSaleRecord(Long id); + + /** + * 获得租赁转销售记录分页 + * + * @param pageReqVO 分页查询 + * @return 租赁转销售记录分页 + */ + PageResult getRentalSaleRecordPage(RentalSaleRecordPageReqVO pageReqVO); + + /** + * 获取所有到达周转期的租赁订单押金记录 + * @return 订单押金记录 + */ + List getSaleDepositRecordList(); +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/rental/RentalSaleRecordServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/rental/RentalSaleRecordServiceImpl.java new file mode 100644 index 00000000..cc165c55 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/rental/RentalSaleRecordServiceImpl.java @@ -0,0 +1,111 @@ +package cn.iocoder.yudao.module.system.service.rental; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.system.controller.admin.rental.vo.rentalsalerecord.RentalSaleRecordPageReqVO; +import cn.iocoder.yudao.module.system.controller.admin.rental.vo.rentalsalerecord.RentalSaleRecordRespVO; +import cn.iocoder.yudao.module.system.controller.admin.rental.vo.rentalsalerecord.RentalSaleRecordSaveReqVO; +import cn.iocoder.yudao.module.system.controller.admin.rental.vo.rentalsalerecord.RentalSaleStatusReqVO; +import cn.iocoder.yudao.module.system.dal.dataobject.rental.RentalCustomerDO; +import cn.iocoder.yudao.module.system.dal.dataobject.rental.RentalDepositRecordDO; +import cn.iocoder.yudao.module.system.dal.dataobject.rental.RentalSaleRecordDO; +import cn.iocoder.yudao.module.system.dal.mysql.rental.RentalCustomerMapper; +import cn.iocoder.yudao.module.system.dal.mysql.rental.RentalSaleRecordMapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.util.Collections; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.RENTAL_SALE_RECORD_NOT_EXISTS; + +/** + * 租赁转销售记录 Service 实现类 + * + * @author 符溶馨 + */ +@Service +@Validated +public class RentalSaleRecordServiceImpl implements RentalSaleRecordService { + + @Resource + private RentalSaleRecordMapper rentalSaleRecordMapper; + + @Resource + private RentalCustomerMapper customerMapper; + + @Resource + private RentalDepositRecordService depositRecordService; + + @Override + public Long createRentalSaleRecord(RentalSaleRecordSaveReqVO createReqVO) { + // 插入 + RentalSaleRecordDO rentalSaleRecord = BeanUtils.toBean(createReqVO, RentalSaleRecordDO.class); + rentalSaleRecordMapper.insert(rentalSaleRecord); + // 返回 + return rentalSaleRecord.getId(); + } + + @Override + public void createBatch(List createReqVO) { + + // 批量插入 + List rentalSaleDO = BeanUtils.toBean(createReqVO, RentalSaleRecordDO.class); + rentalSaleRecordMapper.insertBatch(rentalSaleDO); + } + + @Override + public void updateRentalSaleRecord(RentalSaleStatusReqVO updateReqVO) { + // 校验存在 + validateRentalSaleRecordExists(updateReqVO.getId()); + // 更新 + RentalSaleRecordDO updateObj = BeanUtils.toBean(updateReqVO, RentalSaleRecordDO.class); + rentalSaleRecordMapper.updateById(updateObj); + + if (updateReqVO.getStatus() == 1) { + + // 同步更新客户押金 + customerMapper.update(null, new LambdaUpdateWrapper() + .setSql("amount = amount + " + updateReqVO.getAmount()) + .eq(RentalCustomerDO::getId, updateReqVO.getCustomerId())); + + // 同步更新入账类型 + RentalDepositRecordDO depositRecordDO = new RentalDepositRecordDO() + .setId(updateReqVO.getDepositId()) + .setType(1); + depositRecordService.updateRentalDepositRecordType(Collections.singletonList(depositRecordDO)); + } + } + + @Override + public void deleteRentalSaleRecord(Long id) { + // 校验存在 + validateRentalSaleRecordExists(id); + // 删除 + rentalSaleRecordMapper.deleteById(id); + } + + private void validateRentalSaleRecordExists(Long id) { + if (rentalSaleRecordMapper.selectById(id) == null) { + throw exception(RENTAL_SALE_RECORD_NOT_EXISTS); + } + } + + @Override + public RentalSaleRecordDO getRentalSaleRecord(Long id) { + return rentalSaleRecordMapper.selectById(id); + } + + @Override + public PageResult getRentalSaleRecordPage(RentalSaleRecordPageReqVO pageReqVO) { + return rentalSaleRecordMapper.selectPage(pageReqVO); + } + + @Override + public List getSaleDepositRecordList() { + return rentalSaleRecordMapper.selectSaleDepositRecordList(); + } +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/resources/application-local.yaml b/yudao-module-system/yudao-module-system-biz/src/main/resources/application-local.yaml index 8e5c46f4..c1f3775c 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/resources/application-local.yaml +++ b/yudao-module-system/yudao-module-system-biz/src/main/resources/application-local.yaml @@ -80,9 +80,16 @@ spring: xxl: job: - enabled: false # 是否开启调度中心,默认为 true 开启 + enabled: true # 是否开启调度中心,默认为 true 开启 admin: addresses: http://127.0.0.1:9090/xxl-job-admin # 调度中心部署跟地址 + executor: + appname: ${spring.application.name} # 执行器 AppName + ip: # 执行器IP [选填]:默认为空表示自动获取IP,多网卡时可手动设置指定IP,该IP不会绑定Host仅作为通讯实用;地址信息用于 "执行器注册" 和 "调度中心请求并触发任务"; + port: 6666 # ### 执行器端口号 [选填]:小于等于0则自动获取;默认端口为9999,单机部署多个执行器时,注意要配置不同执行器端口; + logpath: ${user.home}/logs/xxl-job/${spring.application.name} # 执行器运行日志文件存储磁盘路径 # 执行器运行日志文件存储磁盘路径 [选填] :需要对该路径拥有读写权限;为空则使用默认路径; + #accessToken: default_token + logretentiondays: 30 # 执行器日志文件保存天数 [选填] : 过期日志自动清理, 限制值大于等于3时生效; 否则, 如-1, 关闭自动清理功能; --- #################### 服务保障相关配置 #################### diff --git a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/dept/DeptMapper.xml b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/dept/DeptMapper.xml index 4ed0e5c3..b58a08e6 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/dept/DeptMapper.xml +++ b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/dept/DeptMapper.xml @@ -16,7 +16,10 @@ system_dept WHERE #{flag} LIKE CONCAT('%', flag, '%') - AND type = #{type} + AND type IN + + #{item} + AND deleted = 0 \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/loan/LoanMapper.xml b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/loan/LoanMapper.xml new file mode 100644 index 00000000..5fe07691 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/loan/LoanMapper.xml @@ -0,0 +1,33 @@ + + + + + + + + diff --git a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/rental/RentalCustomerMapper.xml b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/rental/RentalCustomerMapper.xml new file mode 100644 index 00000000..6ea66f0f --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/rental/RentalCustomerMapper.xml @@ -0,0 +1,34 @@ + + + + + + + + + diff --git a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/rental/RentalDepositRecordMapper.xml b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/rental/RentalDepositRecordMapper.xml index 7d657777..70a3a0c5 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/rental/RentalDepositRecordMapper.xml +++ b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/rental/RentalDepositRecordMapper.xml @@ -11,7 +11,7 @@ + diff --git a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/rental/RentalSaleRecordMapper.xml b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/rental/RentalSaleRecordMapper.xml new file mode 100644 index 00000000..0a8b7425 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/rental/RentalSaleRecordMapper.xml @@ -0,0 +1,29 @@ + + + + + + + + + diff --git a/zn-module-smartfactory/zn-module-smartfactory-api/src/main/java/cn/iocoder/yudao/module/smartfactory/api/staff/StaffApi.java b/zn-module-smartfactory/zn-module-smartfactory-api/src/main/java/cn/iocoder/yudao/module/smartfactory/api/staff/StaffApi.java index b42a669b..99a6895a 100644 --- a/zn-module-smartfactory/zn-module-smartfactory-api/src/main/java/cn/iocoder/yudao/module/smartfactory/api/staff/StaffApi.java +++ b/zn-module-smartfactory/zn-module-smartfactory-api/src/main/java/cn/iocoder/yudao/module/smartfactory/api/staff/StaffApi.java @@ -28,4 +28,9 @@ public interface StaffApi { @Operation(summary = "获得员工信息") @Parameter(name = "staffIds", description = "员工编号数组", required = true, example = "1,2,3") CommonResult> getStaffList(@RequestParam("staffIds") Collection staffId); + + @GetMapping(PREFIX + "/getByUserId") + @Operation(summary = "根据系统用户编号获得员工信息") + @Parameter(name = "userId", description = "系统用户编号", required = true, example = "1") + CommonResult getStaffByUserId(@RequestParam("userId") Long userId); } diff --git a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/api/staff/StaffApiImpl.java b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/api/staff/StaffApiImpl.java index 988058c0..f863ff4f 100644 --- a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/api/staff/StaffApiImpl.java +++ b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/api/staff/StaffApiImpl.java @@ -8,7 +8,6 @@ import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; - import java.util.Collection; import java.util.List; @@ -30,4 +29,9 @@ public class StaffApiImpl implements StaffApi { public CommonResult> getStaffList(Collection staffId) { return success(BeanUtils.toBean(staffService.getList(staffId), StaffDTO.class)); } + + @Override + public CommonResult getStaffByUserId(Long userId) { + return success(BeanUtils.toBean(staffService.getStaffByUserId(userId), StaffDTO.class)); + } } diff --git a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/controller/admin/attendance/StaffAttendanceRecordController.java b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/controller/admin/attendance/StaffAttendanceRecordController.java index ae725323..18c80bc7 100644 --- a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/controller/admin/attendance/StaffAttendanceRecordController.java +++ b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/controller/admin/attendance/StaffAttendanceRecordController.java @@ -128,6 +128,18 @@ public class StaffAttendanceRecordController { return success(staffAttendanceRecordService.getType(factoryId, month)); } + @GetMapping("/isReview") + @Operation(summary = "获得厂区员工考勤记录审核状态") + @Parameter(name = "factoryId", description = "工厂编号", required = true, example = "1024") + @Parameter(name = "month", description = "考勤月份", required = true, example = "2025-11") + @PreAuthorize("@ss.hasPermission('smartfactory:staff-attendance-record:query')") + public CommonResult getIsReview(@RequestParam("factoryId") Long factoryId, + @RequestParam("month") String month) { + + // 获取考勤审核状态 + return success(staffAttendanceRecordService.getIsReview(factoryId, month)); + } + @GetMapping("/list") @Operation(summary = "获得厂区员工考勤记录列表") @PreAuthorize("@ss.hasPermission('smartfactory:staff-attendance-record:query')") @@ -137,8 +149,37 @@ public class StaffAttendanceRecordController { // 查询该厂区员工在 其他厂区得考勤记录 List otherRecordDOS = staffAttendanceRecordService.getOtherRecord(reqVO); + // 获取工厂员工列表 + List staffDOS = staffService.getListByFactory(reqVO.getFactoryId(), true); + Map staffMap = convertMap(staffDOS, StaffDO::getId); + if (CollUtil.isNotEmpty(recordDOS)) { - return success(convertRecord(reqVO, recordDOS, otherRecordDOS)); + List recordRespVO = convertRecord(reqVO, recordDOS, otherRecordDOS); + + // 筛选掉已经存在的员工 + List staffIds = staffDOS.stream() + .map(StaffDO::getId) + .filter(id -> !convertList(recordDOS, StaffAttendanceRecordDO::getStaffId).contains(id)) + .collect(Collectors.toList()); + + // 获取其他员工的考勤记录, 打卡状态设置为null + List otherRecords = recordRespVO.get(0).getRecords().stream() + .map(record -> BeanUtils.toBean(record, AttendanceRecordVO.class) + .setStatus(null)) + .collect(Collectors.toList()); + List otherRespVO = staffIds.stream() + .map(id -> new StaffAttendanceRecordRespVO() + .setStaffId(id) + .setFactoryId(reqVO.getFactoryId()) + .setMonth(reqVO.getMonth()) + .setType(reqVO.getType()) + .setStaffName(staffMap.get(id).getNickName()) + .setWorkTypeId(staffMap.get(id).getWorkTypeId()) + .setRecords(otherRecords)) + .collect(Collectors.toList()); + + recordRespVO.addAll(otherRespVO); + return success(recordRespVO); }else { // 判断是否 新增考勤情况 if (reqVO.getFactoryId() != null && reqVO.getMonth() != null && reqVO.getType() != null) { @@ -156,8 +197,6 @@ public class StaffAttendanceRecordController { .setWorkTypeId(staffDO.getWorkTypeId()); return success(Collections.singletonList(respVO)); }else { - // 获取工厂员工列表 - List staffDOS = staffService.getListByFactory(reqVO.getFactoryId(), true); List respVO = staffDOS.stream() .map(staffDO -> new StaffAttendanceRecordRespVO() .setStaffId(staffDO.getId()) @@ -310,4 +349,16 @@ public class StaffAttendanceRecordController { ExcelUtils.write(response, "厂区员工考勤记录.xls", "数据", StaffAttendanceRecordRespVO.class, convertRecord(reqVO, recordDOS, null)); } + + @PutMapping("/review") + @Operation(summary = "考勤记录审核") + @Parameter(name = "factoryId", description = "工厂编号", required = true, example = "1024") + @Parameter(name = "month", description = "考勤月份", required = true, example = "2025-11") + @PreAuthorize("@ss.hasPermission('smartfactory:staff-attendance-record:review')") + public CommonResult reviewAttendanceRecord(@RequestParam("factoryId") Long factoryId, + @RequestParam("month") String month) { + + staffAttendanceRecordService.updateReview(factoryId, month); + return success(true); + } } \ No newline at end of file diff --git a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/controller/admin/attendance/vo/StaffAttendanceRecordRespVO.java b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/controller/admin/attendance/vo/StaffAttendanceRecordRespVO.java index d74bddb1..ae159d78 100644 --- a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/controller/admin/attendance/vo/StaffAttendanceRecordRespVO.java +++ b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/controller/admin/attendance/vo/StaffAttendanceRecordRespVO.java @@ -38,6 +38,9 @@ public class StaffAttendanceRecordRespVO { @Schema(description = "其他打卡记录") private List childRecords; + @Schema(description = "是否已审核") + private Integer isReview; + public StaffAttendanceRecordRespVO(Long staffId, Long factoryId, Integer type, String month) { this.staffId = staffId; this.factoryId = factoryId; diff --git a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/controller/admin/industrialinjury/IndustrialInjuryController.java b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/controller/admin/industrialinjury/IndustrialInjuryController.java index 36b48d7c..49823b44 100644 --- a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/controller/admin/industrialinjury/IndustrialInjuryController.java +++ b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/controller/admin/industrialinjury/IndustrialInjuryController.java @@ -96,6 +96,8 @@ public class IndustrialInjuryController { result.getList().forEach(vo -> { vo.setStaffName(userMap.get(vo.getStaffId()) != null ? userMap.get(vo.getStaffId()).getNickName() : null); vo.setFactoryName(factoryMap.get(vo.getFactoryId()) != null ? factoryMap.get(vo.getFactoryId()).getName() : null); + // 设置理赔总金额 + vo.setClaimTotalAmount(vo.getClaimAmount().add(vo.getAgreementClaimAmount())); }); } diff --git a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/controller/admin/industrialinjury/vo/AdvancePaymentItem.java b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/controller/admin/industrialinjury/vo/AdvancePaymentItem.java index a2416ee5..8dcafd58 100644 --- a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/controller/admin/industrialinjury/vo/AdvancePaymentItem.java +++ b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/controller/admin/industrialinjury/vo/AdvancePaymentItem.java @@ -12,10 +12,16 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ @Data public class AdvancePaymentItem { + @Schema(description = "垫资方 | 1公司 2工厂") + private Integer payer; + @Schema(description = "金额") private BigDecimal amount; @Schema(description = "时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private String time; + + @Schema(description = "备注") + private String notes; } diff --git a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/controller/admin/industrialinjury/vo/ClaimAmountItem.java b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/controller/admin/industrialinjury/vo/ClaimAmountItem.java index a30fe7ba..2f9f9ab3 100644 --- a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/controller/admin/industrialinjury/vo/ClaimAmountItem.java +++ b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/controller/admin/industrialinjury/vo/ClaimAmountItem.java @@ -12,8 +12,8 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ @Data public class ClaimAmountItem { - @Schema(description = "理赔方") - private String payee; + @Schema(description = "理赔类型") + private Integer payee; @Schema(description = "金额") private BigDecimal amount; @@ -21,4 +21,7 @@ public class ClaimAmountItem { @Schema(description = "理赔时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private String time; + + @Schema(description = "备注") + private String notes; } diff --git a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/controller/admin/industrialinjury/vo/IndustrialInjuryRespVO.java b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/controller/admin/industrialinjury/vo/IndustrialInjuryRespVO.java index e330ec97..7d86a639 100644 --- a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/controller/admin/industrialinjury/vo/IndustrialInjuryRespVO.java +++ b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/controller/admin/industrialinjury/vo/IndustrialInjuryRespVO.java @@ -48,10 +48,6 @@ public class IndustrialInjuryRespVO { @Schema(description = "医药垫资明细") private List advancePaymentItems; - @Schema(description = "垫资方 | 1公司 2工厂") - @ExcelProperty("垫资方 | 1公司 2工厂") - private Integer payer; - @Schema(description = "理赔金额") @ExcelProperty("理赔金额") private BigDecimal claimAmount; @@ -59,10 +55,33 @@ public class IndustrialInjuryRespVO { @Schema(description = "理赔明细") private List claimAmountItems; - @Schema(description = "状态 | 1处理中 2已完成", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - @ExcelProperty("状态 | 1处理中 2已完成") + @Schema(description = "协议理赔金额") + private BigDecimal agreementClaimAmount; + + @Schema(description = "协议理赔明细") + private List agreementClaimItems; + + @Schema(description = "理赔总金额") + private BigDecimal claimTotalAmount; + + @Schema(description = "备注") + private String notes; + + @Schema(description = "状态 | 1处理中 2已完成") private Integer status; + @Schema(description = "是否上传发票 |0否 1是") + private Integer isUploadInvoice; + + @Schema(description = "是否保险理赔|0否 1是") + private Integer isInsuranceClaims; + + @Schema(description = "是否协议理赔|0否 1是") + private Integer isAgreementClaims; + + @Schema(description = "发票文件信息") + private List invoiceFileItems; + @Schema(description = "附件信息") @ExcelProperty("附件信息") private List fileItems; @@ -70,5 +89,4 @@ public class IndustrialInjuryRespVO { @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) @ExcelProperty("创建时间") private LocalDateTime createTime; - } \ No newline at end of file diff --git a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/controller/admin/industrialinjury/vo/IndustrialInjurySaveReqVO.java b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/controller/admin/industrialinjury/vo/IndustrialInjurySaveReqVO.java index 9522f7b6..c1cb0bb8 100644 --- a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/controller/admin/industrialinjury/vo/IndustrialInjurySaveReqVO.java +++ b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/controller/admin/industrialinjury/vo/IndustrialInjurySaveReqVO.java @@ -34,18 +34,36 @@ public class IndustrialInjurySaveReqVO { @Schema(description = "医药垫资明细") private List advancePaymentItems; - @Schema(description = "垫资方 | 1公司 2工厂") - private Integer payer; - @Schema(description = "理赔金额") private BigDecimal claimAmount; @Schema(description = "理赔明细") private List claimAmountItems; + @Schema(description = "协议理赔金额") + private BigDecimal agreementClaimAmount; + + @Schema(description = "协议理赔明细") + private List agreementClaimItems; + + @Schema(description = "备注") + private String notes; + @Schema(description = "状态 | 1处理中 2已完成") private Integer status; + @Schema(description = "是否上传发票 |0否 1是") + private Integer isUploadInvoice; + + @Schema(description = "是否保险理赔|0否 1是") + private Integer isInsuranceClaims; + + @Schema(description = "是否协议理赔|0否 1是") + private Integer isAgreementClaims; + + @Schema(description = "发票文件信息") + private List invoiceFileItems; + @Schema(description = "附件信息") private List fileItems; diff --git a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/controller/admin/staffsalary/StaffSalaryController.java b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/controller/admin/staffsalary/StaffSalaryController.java index 5f524825..05344bd3 100644 --- a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/controller/admin/staffsalary/StaffSalaryController.java +++ b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/controller/admin/staffsalary/StaffSalaryController.java @@ -9,11 +9,7 @@ import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; import cn.iocoder.yudao.module.smartfactory.controller.admin.staffsalary.vo.StaffSalaryPageReqVO; import cn.iocoder.yudao.module.smartfactory.controller.admin.staffsalary.vo.StaffSalaryRespVO; import cn.iocoder.yudao.module.smartfactory.controller.admin.staffsalary.vo.StaffSalarySaveReqVO; -import cn.iocoder.yudao.module.smartfactory.dal.dataobject.factoryinfo.FactoryInfoDO; -import cn.iocoder.yudao.module.smartfactory.dal.dataobject.staff.StaffDO; import cn.iocoder.yudao.module.smartfactory.dal.dataobject.staffsalary.StaffSalaryDO; -import cn.iocoder.yudao.module.smartfactory.service.factoryinfo.FactoryInfoService; -import cn.iocoder.yudao.module.smartfactory.service.staff.StaffService; import cn.iocoder.yudao.module.smartfactory.service.staffsalary.StaffSalaryService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -26,7 +22,6 @@ import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; import java.io.IOException; -import java.math.BigDecimal; import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @@ -41,12 +36,6 @@ public class StaffSalaryController { @Resource private StaffSalaryService staffSalaryService; - @Resource - private StaffService staffService; - - @Resource - private FactoryInfoService factoryInfoService; - @PostMapping("/create") @Operation(summary = "创建员工工资") @PreAuthorize("@ss.hasPermission('smartfactory:staff-salary:create')") @@ -89,29 +78,6 @@ public class StaffSalaryController { return success(BeanUtils.toBean(staffSalary, StaffSalaryRespVO.class)); } - @GetMapping("/get-list") - @Operation(summary = "获得指定员工工资列表") - @Parameter(name = "staffId", description = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('smartfactory:staff-salary:query')") - public CommonResult> getListByStaffId(@RequestParam("staffId") Long staffId) { - List staffSalary = staffSalaryService.getListByStaffId(staffId); - List respVOS = BeanUtils.toBean(staffSalary, StaffSalaryRespVO.class); - - // 获取员工信息 - StaffDO staffDO = staffService.getStaff(staffId); - // 获取工厂信息 - FactoryInfoDO factoryInfoDO = factoryInfoService.getFactoryInfo(staffDO.getFactoryId()); - - // 移除归还金额为0的记录 - respVOS.removeIf(vo -> vo.getRealAmount().compareTo(BigDecimal.ZERO) == 0); - respVOS.forEach(vo -> { - vo.setStaffName(staffDO.getNickName()); - vo.setFactoryName(factoryInfoDO.getName()); - }); - - return success(respVOS); - } - @GetMapping("/page") @Operation(summary = "获得厂区员工工资分页") @PreAuthorize("@ss.hasPermission('smartfactory:staff-salary:query')") diff --git a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/dal/dataobject/attendance/SfAttendanceReviewDO.java b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/dal/dataobject/attendance/SfAttendanceReviewDO.java new file mode 100644 index 00000000..7f39e395 --- /dev/null +++ b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/dal/dataobject/attendance/SfAttendanceReviewDO.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.module.smartfactory.dal.dataobject.attendance; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +/** + * 厂区员工考勤审核表 DO + * + * @author 符溶馨 + */ +@TableName("sf_attendance_review") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SfAttendanceReviewDO extends BaseDO { + + /** + * 主键id + */ + @TableId + private Long id; + /** + * 工厂id + */ + private Long factoryId; + /** + * 考勤月份 + */ + private String month; + /** + * 审核状态 | 0未审核 1已审核 + */ + private Integer status; +} diff --git a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/dal/dataobject/industrialinjury/IndustrialInjuryDO.java b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/dal/dataobject/industrialinjury/IndustrialInjuryDO.java index 625b08a8..1639da69 100644 --- a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/dal/dataobject/industrialinjury/IndustrialInjuryDO.java +++ b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/dal/dataobject/industrialinjury/IndustrialInjuryDO.java @@ -60,10 +60,6 @@ public class IndustrialInjuryDO extends BaseDO { */ @TableField(typeHandler = JacksonTypeHandler.class) private List advancePaymentItems; - /** - * 垫资方 | 1公司 2工厂 - */ - private Integer payer; /** * 理赔金额 */ @@ -73,10 +69,40 @@ public class IndustrialInjuryDO extends BaseDO { */ @TableField(typeHandler = JacksonTypeHandler.class) private List claimAmountItems; + /** + * 协议理赔金额 + */ + private BigDecimal agreementClaimAmount; + /** + * 协议理赔明细 + */ + @TableField(typeHandler = JacksonTypeHandler.class) + private List agreementClaimItems; /** * 状态 | 1处理中 2已完成 */ private Integer status; + /** + * 是否上传发票 | 0否 1是 + */ + private Integer isUploadInvoice; + /** + * 是否保险理赔 | 0否 1是 + */ + private Integer isInsuranceClaims; + /** + * 是否协议理赔 | 0否 1是 + */ + private Integer isAgreementClaims; + /** + * 备注 + */ + private String notes; + /** + * 发票附件信息 + */ + @TableField(typeHandler = JacksonTypeHandler.class) + private List invoiceFileItems; /** * 附件信息 */ diff --git a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/dal/mysql/attendance/SfAttendanceReviewMapper.java b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/dal/mysql/attendance/SfAttendanceReviewMapper.java new file mode 100644 index 00000000..7ea05e92 --- /dev/null +++ b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/dal/mysql/attendance/SfAttendanceReviewMapper.java @@ -0,0 +1,14 @@ +package cn.iocoder.yudao.module.smartfactory.dal.mysql.attendance; + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.smartfactory.dal.dataobject.attendance.SfAttendanceReviewDO; +import org.apache.ibatis.annotations.Mapper; + +/** + * 厂区员工考勤审核 Mapper + * + * @author 符溶馨 + */ +@Mapper +public interface SfAttendanceReviewMapper extends BaseMapperX { +} diff --git a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/dal/mysql/industrialinjury/IndustrialInjuryMapper.java b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/dal/mysql/industrialinjury/IndustrialInjuryMapper.java index 34e7dc66..4ef4dd5c 100644 --- a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/dal/mysql/industrialinjury/IndustrialInjuryMapper.java +++ b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/dal/mysql/industrialinjury/IndustrialInjuryMapper.java @@ -20,7 +20,6 @@ public interface IndustrialInjuryMapper extends BaseMapperX .eqIfPresent(IndustrialInjuryDO::getStaffId, reqVO.getStaffId()) .eqIfPresent(IndustrialInjuryDO::getFactoryId, reqVO.getFactoryId()) .betweenIfPresent(IndustrialInjuryDO::getHappenTime, reqVO.getHappenTime()) - .eqIfPresent(IndustrialInjuryDO::getPayer, reqVO.getPayer()) .eqIfPresent(IndustrialInjuryDO::getStatus, reqVO.getStatus()) .orderByDesc(IndustrialInjuryDO::getId)); } diff --git a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/dal/mysql/staff/StaffMapper.java b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/dal/mysql/staff/StaffMapper.java index 9c80bbce..2457757c 100644 --- a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/dal/mysql/staff/StaffMapper.java +++ b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/dal/mysql/staff/StaffMapper.java @@ -78,4 +78,6 @@ public interface StaffMapper extends BaseMapperX { return selectJoinPage(pageReqVO, StaffSalaryRespVO.class, query); } + + StaffDO selectStaffByUserId(@Param("userId") Long userId); } diff --git a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/service/attendance/StaffAttendanceRecordService.java b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/service/attendance/StaffAttendanceRecordService.java index 4eba902d..b9dfb6d1 100644 --- a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/service/attendance/StaffAttendanceRecordService.java +++ b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/service/attendance/StaffAttendanceRecordService.java @@ -73,4 +73,19 @@ public interface StaffAttendanceRecordService { * @return 勤记录列表 */ List getRecordListGroupByStaffId(String month); + + /** + * 考勤记录审核 + * @param factoryId 工厂编号 + * @param month 考勤月份 + */ + void updateReview(Long factoryId, String month); + + /** + * 获取考勤记录是否已审核 + * @param factoryId 工厂编号 + * @param month 考勤月份 + * @return 是否已审核 + */ + Integer getIsReview(Long factoryId, String month); } \ No newline at end of file diff --git a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/service/attendance/StaffAttendanceRecordServiceImpl.java b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/service/attendance/StaffAttendanceRecordServiceImpl.java index 5ef9fb85..f83debdf 100644 --- a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/service/attendance/StaffAttendanceRecordServiceImpl.java +++ b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/service/attendance/StaffAttendanceRecordServiceImpl.java @@ -5,8 +5,14 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.smartfactory.controller.admin.attendance.vo.StaffAttendanceRecordReqVO; import cn.iocoder.yudao.module.smartfactory.controller.admin.attendance.vo.StaffAttendanceRecordSaveReqVO; +import cn.iocoder.yudao.module.smartfactory.dal.dataobject.attendance.SfAttendanceReviewDO; import cn.iocoder.yudao.module.smartfactory.dal.dataobject.attendance.StaffAttendanceRecordDO; +import cn.iocoder.yudao.module.smartfactory.dal.mysql.attendance.SfAttendanceReviewMapper; import cn.iocoder.yudao.module.smartfactory.dal.mysql.attendance.StaffAttendanceRecordMapper; +import cn.iocoder.yudao.module.smartfactory.service.staffsalary.StaffSalaryService; +import cn.iocoder.yudao.module.smartfactory.framework.job.staffSalary.StaffSalaryJob; +import cn.iocoder.yudao.module.smartfactory.service.staffsalary.StaffSalaryService; +import org.springframework.data.redis.connection.stream.ObjectRecord; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -32,6 +38,12 @@ public class StaffAttendanceRecordServiceImpl implements StaffAttendanceRecordSe @Resource private StaffAttendanceRecordMapper staffAttendanceRecordMapper; + @Resource + private StaffSalaryService staffSalaryService; + + @Resource + private SfAttendanceReviewMapper attendanceReviewMapper; + @Override public void createStaffAttendanceRecord(List createReqVO) { @@ -164,4 +176,27 @@ public class StaffAttendanceRecordServiceImpl implements StaffAttendanceRecordSe .eq(StaffAttendanceRecordDO::getStatus, 1) .eq(StaffAttendanceRecordDO::getMonth, month)); } + + @Override + public void updateReview(Long factoryId, String month) { + + attendanceReviewMapper.insert(new SfAttendanceReviewDO() + .setFactoryId(factoryId) + .setMonth(month) + .setStatus(1)); + + List createDo = staffAttendanceRecordMapper.selectList(new LambdaQueryWrapperX() + .eq(StaffAttendanceRecordDO::getFactoryId, factoryId) + .eq(StaffAttendanceRecordDO::getMonth, month)); + // 审核考勤记录后, 自动计算员工薪资 + staffSalaryService.calculateSalary(createDo); + } + + @Override + public Integer getIsReview(Long factoryId, String month) { + SfAttendanceReviewDO attendanceReviewDO = attendanceReviewMapper.selectOne(new LambdaQueryWrapperX() + .eq(SfAttendanceReviewDO::getFactoryId, factoryId) + .eq(SfAttendanceReviewDO::getMonth, month)); + return attendanceReviewDO != null ? attendanceReviewDO.getStatus() : 0; + } } \ No newline at end of file diff --git a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/service/staff/StaffService.java b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/service/staff/StaffService.java index ea62825c..2f994148 100644 --- a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/service/staff/StaffService.java +++ b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/service/staff/StaffService.java @@ -67,14 +67,12 @@ public interface StaffService { /** * 获取人员数量 - * * @return */ Integer getCount(); /** * 查询工厂员工信息 - * * @param factoryId 工厂编号 * @return */ @@ -82,8 +80,7 @@ public interface StaffService { /** * 导入员工 - * - * @param list 导入数据集合 + * @param list 导入数据集合 * @param updateSupport 是否可更新 * @return 导入结果 */ @@ -93,7 +90,7 @@ public interface StaffService { * 获取指定厂区得员工列表 * * @param factoryId 工厂编号 - * @param isIn 是否获取该厂区员工 + * @param isIn 是否获取该厂区员工 * @return 员工列表 */ List getListByFactory(Long factoryId, Boolean isIn); @@ -108,7 +105,6 @@ public interface StaffService { /** * 获取员工信息列表 - * * @param staffIds 员工编号集合 * @return 员工信息列表 */ @@ -125,8 +121,15 @@ public interface StaffService { /** * - * @param userId + * * @return */ Long getTheFactoryOfTheCurrentlyLoggedInUser(); + + /** + * 根据系统用户编号获取员工信息 + * @param userId 系统用户编号 + * @return 员工信息 + */ + StaffDO getStaffByUserId(Long userId); } diff --git a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/service/staff/StaffServiceImpl.java b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/service/staff/StaffServiceImpl.java index 3c67a442..660f4091 100644 --- a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/service/staff/StaffServiceImpl.java +++ b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/service/staff/StaffServiceImpl.java @@ -58,6 +58,10 @@ public class StaffServiceImpl implements StaffService { @Override public Long createStaff(StaffSaveReqVO createReqVO) { + + // 身份证号是否已经存在 + validateUserForCreate(null, null, null, createReqVO.getIdCard()); + // 插入 StaffDO staff = BeanUtils.toBean(createReqVO, StaffDO.class); staffMapper.insert(staff); @@ -70,6 +74,10 @@ public class StaffServiceImpl implements StaffService { if (staffMapper.selectById(updateReqVO.getId()) == null) { throw exception(STAFF_NOT_EXISTS); } + + // 身份证号是否已经存在 + validateUserForCreate(null, null, null, updateReqVO.getIdCard()); + // 更新 StaffDO updateObj = BeanUtils.toBean(updateReqVO, StaffDO.class); staffMapper.updateById(updateObj); @@ -274,4 +282,10 @@ public class StaffServiceImpl implements StaffService { } return dto.getFactoryId(); } + + @Override + public StaffDO getStaffByUserId(Long userId) { + + return staffMapper.selectStaffByUserId(userId); + } } diff --git a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/service/staffsalary/StaffSalaryService.java b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/service/staffsalary/StaffSalaryService.java index fa0666d2..5f1e1d7f 100644 --- a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/service/staffsalary/StaffSalaryService.java +++ b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/service/staffsalary/StaffSalaryService.java @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.smartfactory.controller.admin.staffsalary.vo.StaffSalaryPageReqVO; import cn.iocoder.yudao.module.smartfactory.controller.admin.staffsalary.vo.StaffSalaryRespVO; import cn.iocoder.yudao.module.smartfactory.controller.admin.staffsalary.vo.StaffSalarySaveReqVO; +import cn.iocoder.yudao.module.smartfactory.dal.dataobject.attendance.StaffAttendanceRecordDO; import cn.iocoder.yudao.module.smartfactory.dal.dataobject.staffsalary.StaffSalaryDO; import javax.validation.Valid; @@ -60,9 +61,8 @@ public interface StaffSalaryService { void updateStatus(StaffSalarySaveReqVO updateReqVO); /** - * 获取指定员工工资列表 - * @param staffId 员工id - * @return 工资列表 + * 工资计算 + * @param vo 考勤信息 */ - List getListByStaffId(Long staffId); + void calculateSalary(List vo); } \ No newline at end of file diff --git a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/service/staffsalary/StaffSalaryServiceImpl.java b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/service/staffsalary/StaffSalaryServiceImpl.java index f2704092..87733da5 100644 --- a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/service/staffsalary/StaffSalaryServiceImpl.java +++ b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/java/cn/iocoder/yudao/module/smartfactory/service/staffsalary/StaffSalaryServiceImpl.java @@ -1,25 +1,40 @@ package cn.iocoder.yudao.module.smartfactory.service.staffsalary; +import cn.hutool.core.collection.CollUtil; 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.bpm.api.oa.BpmOALoanApi; +import cn.iocoder.yudao.module.bpm.api.oa.vo.loan.BpmOALoanSumDTO; import cn.iocoder.yudao.module.smartfactory.controller.admin.staffsalary.vo.StaffSalaryPageReqVO; import cn.iocoder.yudao.module.smartfactory.controller.admin.staffsalary.vo.StaffSalaryRespVO; import cn.iocoder.yudao.module.smartfactory.controller.admin.staffsalary.vo.StaffSalarySaveReqVO; +import cn.iocoder.yudao.module.smartfactory.dal.dataobject.attendance.StaffAttendanceRecordDO; +import cn.iocoder.yudao.module.smartfactory.dal.dataobject.staff.StaffDO; import cn.iocoder.yudao.module.smartfactory.dal.dataobject.staffsalary.StaffSalaryDO; import cn.iocoder.yudao.module.smartfactory.dal.mysql.staff.StaffMapper; import cn.iocoder.yudao.module.smartfactory.dal.mysql.staffsalary.StaffSalaryMapper; +import cn.iocoder.yudao.module.smartfactory.service.staff.StaffService; import cn.iocoder.yudao.module.system.api.loan.LoanApi; import cn.iocoder.yudao.module.system.api.loan.dto.LoanDTO; 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.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; +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.convertMap; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.module.smartfactory.enums.ErrorCodeConstants.STAFF_SALARY_EXISTS; import static cn.iocoder.yudao.module.smartfactory.enums.ErrorCodeConstants.STAFF_SALARY_NOT_EXISTS; @@ -41,6 +56,12 @@ public class StaffSalaryServiceImpl implements StaffSalaryService { @Resource private LoanApi loanApi; + @Resource + private BpmOALoanApi bpmOALoanApi; + + @Resource + private StaffService staffService; + @Override public Long createStaffSalary(StaffSalarySaveReqVO createReqVO) { @@ -120,10 +141,99 @@ public class StaffSalaryServiceImpl implements StaffSalaryService { } @Override - public List getListByStaffId(Long staffId) { + public void calculateSalary(List vo) { - return staffSalaryMapper.selectList(new LambdaQueryWrapperX() - .eq(StaffSalaryDO::getStaffId, staffId) - .eq(StaffSalaryDO::getStatus, 1)); + // 获取厂区考勤类型 + Integer type = vo.get(0).getType(); + // 获取厂区考勤月份 + String month = vo.get(0).getMonth(); + + // 获取当前考勤月份得第一天 + LocalDate firstDayOfMonth = LocalDate.parse(month + "-01", DateTimeFormatter.ISO_LOCAL_DATE); + + LocalDate[] date = new LocalDate[2]; + if (type == 1) { + + date = new LocalDate[]{ + firstDayOfMonth.minusMonths(1).withDayOfMonth(26), + firstDayOfMonth.withDayOfMonth(25) + }; + }else if (type == 2) { + + date = new LocalDate[]{ + firstDayOfMonth, + firstDayOfMonth.withDayOfMonth(firstDayOfMonth.lengthOfMonth()) + }; + } + + Map> recordMap = vo.stream() + .collect(Collectors.groupingBy(StaffAttendanceRecordDO::getStaffId)); + + // 获取厂区得员工信息 + List staffDOS = staffService.getList(convertSet(vo, StaffAttendanceRecordDO::getStaffId)); + Map staffMap = convertMap(staffDOS, StaffDO::getId); + + // 获取员工借支记录 + List loanDOS = bpmOALoanApi.getListByStaffId(recordMap.keySet(), month).getCheckedData(); + Map loanMap = loanDOS.stream() + .collect(Collectors.toMap( + BpmOALoanSumDTO::getSfUserId, + BpmOALoanSumDTO::getTotalAmount, + BigDecimal::add + )); + + // 获取员工剩余的 工资借支金额 + List sysLoanDOS = loanApi.getListByMonth(recordMap.keySet(), month).getCheckedData(); + Map sysLoanMap = new HashMap<>(); + if (CollUtil.isNotEmpty(sysLoanDOS)) { + sysLoanMap = sysLoanDOS.stream() + .collect(Collectors.toMap(LoanDTO::getUserId, LoanDTO::getRemainingAmount)); + } + + List salaryDOS = new ArrayList<>(); + for (Map.Entry> entry : recordMap.entrySet()) { + Long staffId = entry.getKey(); + // 获取该员工的上班考勤记录 + List items = entry.getValue().stream() + .filter(item -> item.getStatus() == 1) + .collect(Collectors.toList()); + + // 创建薪资DO + StaffSalaryDO salaryDO = new StaffSalaryDO() + .setStaffId(staffId) + .setMonth(month) + .setAttendanceDays(items.size()) + .setFactoryId(entry.getValue().get(0).getFactoryId()) + .setReturnAmount(loanMap.getOrDefault(staffId, BigDecimal.ZERO) + .add(sysLoanMap.getOrDefault(staffId, BigDecimal.ZERO))); + + // 计算当月的工作天数 + long days = ChronoUnit.DAYS.between(date[0], date[1]); + int workDays = (int) days + 1; + + // 计算应发工资 + if (staffMap.get(staffId).getSalary() != null) { // 没有录入基本薪资时,不做计算 + + if (salaryDO.getAttendanceDays() == workDays) { + // 设置应发工资 + salaryDO.setPayableAmount(staffMap.get(staffId).getSalary()); + // 设置实发工资 + salaryDO.setRealAmount(staffMap.get(staffId).getSalary()); + } else { + BigDecimal payableAmount = staffMap.get(staffId).getSalary().divide(BigDecimal.valueOf(workDays), RoundingMode.HALF_UP) + .multiply(BigDecimal.valueOf(salaryDO.getAttendanceDays())); + // 设置应发工资 + salaryDO.setPayableAmount(payableAmount); + // 设置实发工资 + salaryDO.setRealAmount(payableAmount); + } + } + + // 插入集合 + salaryDOS.add(salaryDO); + } + + // 插入工资记录 + staffSalaryMapper.insertBatch(salaryDOS); } } \ No newline at end of file diff --git a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/resources/mapper/staff/StaffMapper.xml b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/resources/mapper/staff/StaffMapper.xml index c3bc4930..dc2916ca 100644 --- a/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/resources/mapper/staff/StaffMapper.xml +++ b/zn-module-smartfactory/zn-module-smartfactory-biz/src/main/resources/mapper/staff/StaffMapper.xml @@ -51,4 +51,21 @@ + +