From b1e7f9a9f676911105a52c7c5cf5ff62c57b68b9 Mon Sep 17 00:00:00 2001 From: furongxin <419481438@qq.com> Date: Sun, 8 Dec 2024 13:36:06 +0800 Subject: [PATCH] =?UTF-8?q?feat(bpm):=20=E6=96=B0=E5=A2=9E=E5=90=88?= =?UTF-8?q?=E5=90=8C=E5=AE=A1=E6=89=B9=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加合同审批相关的 API 接口和实现类 - 创建合同审批的请求和响应对象 - 实现合同审批的创建、查询等功能 - 添加合同统计相关接口和实现 - 优化合同审批页面列表展示 --- yudao-module-bpm/yudao-module-bpm-api/pom.xml | 4 + .../module/bpm/api/oa/BpmOAContractApi.java | 43 +++ .../module/bpm/api/oa/BpmOAEntryApi.java | 2 +- .../module/bpm/api/oa/BpmOAInvoiceApi.java | 21 ++ .../module/bpm/api/oa/BpmOALeaveApi.java | 2 +- .../module/bpm/api/oa/BpmOARefundApi.java | 2 +- .../api/oa/vo/contract/BpmOAContractDTO.java | 97 +++++ .../api/oa/vo/contract/BpmOAContractVO.java | 30 ++ .../oa/vo/contract/ContractStatisticsDTO.java | 38 ++ .../api/oa/vo/{ => entry}/BpmOAEntryDTO.java | 2 +- .../vo/{ => evection}/BpmOAEvectionDTO.java | 2 +- .../api/oa/vo/invoice/BpmOAInvoiceDTO.java | 88 +++++ .../oa/vo/{ => leave}/BpmOALeaveRpcVO.java | 2 +- .../oa/vo/{ => refund}/BpmOARefundDTO.java | 2 +- .../module/bpm/enums/ErrorCodeConstants.java | 2 +- yudao-module-bpm/yudao-module-bpm-biz/pom.xml | 16 + .../bpm/api/oa/BpmOAContractApiImpl.java | 55 +++ .../module/bpm/api/oa/BpmOAEntryApiImpl.java | 2 +- .../bpm/api/oa/BpmOAInvoiceApiImpl.java | 32 ++ .../module/bpm/api/oa/BpmOALeaveApiImpl.java | 2 +- .../module/bpm/api/oa/BpmOARefundApiImpl.java | 2 +- .../admin/oa/BpmOAContractController.java | 90 ++++- .../admin/oa/BpmOAInvoiceController.java | 9 + .../vo/contract/BpmOAContractCreateReqVO.java | 169 +++------ .../vo/contract/BpmOAContractPageReqVO.java | 43 +++ .../oa/vo/contract/BpmOAContractRespVO.java | 81 +++- .../vo/contract/ContractStatisticsRespVO.java | 38 ++ .../oa/vo/contract/CrmContractProductVO.java | 38 ++ .../vo/invoice/BpmOAInvoiceCreateReqVO.java | 46 ++- .../oa/vo/invoice/BpmOAInvoicePageReqVO.java | 31 ++ .../oa/vo/invoice/BpmOAInvoiceRespVO.java | 46 ++- .../admin/task/BpmTaskController.java | 54 ++- .../task/vo/task/BpmCrmTaskPageReqVO.java | 20 + .../dal/dataobject/oa/BpmOAContractDO.java | 85 ++++- .../bpm/dal/dataobject/oa/BpmOAInvoiceDO.java | 58 ++- .../bpm/dal/mysql/oa/BpmOAContractMapper.java | 56 +++ .../bpm/dal/mysql/oa/BpmOAInvoiceMapper.java | 52 +++ .../bpm/dal/mysql/oa/BpmOALeaveMapper.java | 2 +- .../bpm/dal/mysql/task/BpmTaskExtMapper.java | 14 + .../rpc/config/RpcConfiguration.java | 8 +- .../bpm/service/oa/BpmOAContractService.java | 68 +++- .../service/oa/BpmOAContractServiceImpl.java | 351 ++++++++++++++++-- .../bpm/service/oa/BpmOAInvoiceService.java | 18 + .../service/oa/BpmOAInvoiceServiceImpl.java | 97 ++++- .../bpm/service/oa/BpmOALeaveService.java | 2 +- .../bpm/service/oa/BpmOALeaveServiceImpl.java | 2 +- .../listener/BpmOAContractResultListener.java | 2 +- .../bpm/service/task/BpmTaskService.java | 8 + .../bpm/service/task/BpmTaskServiceImpl.java | 6 + .../mapper/oa/BpmOAContractMapper.xml | 65 ++++ .../resources/mapper/oa/BpmOALeaveMapper.xml | 2 +- .../hrm/api/crmbusiness/BusinessApi.java | 23 ++ .../api/crmbusiness/dto/CrmBusinessDTO.java | 62 ++++ .../hrm/api/crmcontract/ContractApi.java | 31 ++ .../dto/CrmContractProductDTO.java | 38 ++ .../hrm/api/crmcustomer/CrmCustomerApi.java | 21 ++ .../api/crmcustomer/dto/CrmCustomerDTO.java | 113 ++++++ .../yudao-module-crm-biz/.flattened-pom.xml | 6 + yudao-module-crm/yudao-module-crm-biz/pom.xml | 6 + .../crm/api/crmbusiness/BusinessApiImpl.java | 31 ++ .../crm/api/crmcontract/ContractApiImpl.java | 40 ++ .../api/crmcustomer/CrmCustomerApiImpl.java | 31 ++ .../CrmAchievementController.java | 6 +- .../admin/crmanalysis/CustomerController.java | 4 - .../crmclues/vo/CrmCluesStatisticsRespVO.java | 18 + .../vo/CustomerStatisticRespVO.java | 18 + .../crmrecord/vo/RecordStatisticsRespVO.java | 24 ++ .../crmachievement/CrmAchievementMapper.java | 22 ++ .../dal/mysql/crmclues/CrmCluesMapper.java | 5 + .../mysql/crmcontract/CrmContractMapper.java | 7 - .../mysql/crmcustomer/CrmCustomerMapper.java | 5 +- .../dal/mysql/crmrecord/CrmRecordMapper.java | 4 + .../rpc/config/RpcConfiguration.java | 4 +- .../crmachievement/CrmAchievementService.java | 4 +- .../CrmAchievementServiceImpl.java | 271 ++++++++------ .../crmanalysis/AchievementServiceImpl.java | 111 +++--- .../service/crmanalysis/CustomerService.java | 12 +- .../crmanalysis/CustomerServiceImpl.java | 128 ++++--- .../crm/service/crmclues/CrmCluesService.java | 8 +- .../service/crmclues/CrmCluesServiceImpl.java | 6 + .../crmcontract/CrmContractService.java | 13 +- .../crmcontract/CrmContractServiceImpl.java | 6 + .../crmcustomer/CrmCustomerService.java | 7 + .../crmcustomer/CrmCustomerServiceImpl.java | 29 +- .../CrmCustomerContactsService.java | 6 +- .../CrmCustomerContactsServiceImpl.java | 1 - .../service/crmindex/CrmIndexServiceImpl.java | 128 ++++--- .../crminvoice/CrmInvoiceServiceImpl.java | 22 +- .../service/crmrecord/CrmRecordService.java | 10 + .../crmrecord/CrmRecordServiceImpl.java | 7 + .../mapper/crmclues/CrmCluesMapper.xml | 24 ++ .../mapper/crmcontract/CrmContractMapper.xml | 21 ++ .../mapper/crmcustomer/CrmCustomerMapper.xml | 24 ++ .../mapper/crmrecord/CrmRecordMapper.xml | 37 ++ .../api/storeproduct/StoreProductApi.java | 13 +- .../StoreProductAttrValueApi.java | 8 +- .../api/storeproduct/StoreProductApiImpl.java | 11 +- .../StoreProductAttrValueApiImpl.java | 20 +- .../StoreProductAttrValueMapper.java | 2 +- .../storeproduct/StoreProductService.java | 8 + .../storeproduct/StoreProductServiceImpl.java | 5 + .../StoreProductAttrValueService.java | 8 + .../StoreProductAttrValueServiceImpl.java | 5 + .../src/main/resources/application-local.yaml | 6 +- .../yudao/module/system/api/dept/DeptApi.java | 5 + .../module/system/api/user/AdminUserApi.java | 11 + .../api/user/dto/AdminUserPageApiDTO.java | 7 +- .../module/system/api/dept/DeptApiImpl.java | 8 + .../system/api/user/AdminUserApiImpl.java | 11 + .../controller/admin/dept/DeptController.java | 27 ++ .../admin/rental/RentalOrderController.java | 2 +- .../controller/admin/user/UserController.java | 7 +- .../dal/mysql/user/AdminUserMapper.java | 5 + .../system/job/fieldwork/FieldworkJob.java | 2 +- .../system/service/dept/DeptService.java | 7 + .../system/service/dept/DeptServiceImpl.java | 8 + .../system/service/user/AdminUserService.java | 8 + .../service/user/AdminUserServiceImpl.java | 13 + .../resources/mapper/user/AdminUserMapper.xml | 26 ++ 119 files changed, 3072 insertions(+), 562 deletions(-) create mode 100644 yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOAContractApi.java create mode 100644 yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOAInvoiceApi.java create mode 100644 yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/contract/BpmOAContractDTO.java create mode 100644 yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/contract/BpmOAContractVO.java create mode 100644 yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/contract/ContractStatisticsDTO.java rename yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/{ => entry}/BpmOAEntryDTO.java (97%) rename yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/{ => evection}/BpmOAEvectionDTO.java (97%) create mode 100644 yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/invoice/BpmOAInvoiceDTO.java rename yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/{ => leave}/BpmOALeaveRpcVO.java (96%) rename yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/{ => refund}/BpmOARefundDTO.java (96%) create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOAContractApiImpl.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOAInvoiceApiImpl.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/contract/BpmOAContractPageReqVO.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/contract/ContractStatisticsRespVO.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/contract/CrmContractProductVO.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/invoice/BpmOAInvoicePageReqVO.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmCrmTaskPageReqVO.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/mapper/oa/BpmOAContractMapper.xml create mode 100644 yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/hrm/api/crmbusiness/BusinessApi.java create mode 100644 yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/hrm/api/crmbusiness/dto/CrmBusinessDTO.java create mode 100644 yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/hrm/api/crmcontract/ContractApi.java create mode 100644 yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/hrm/api/crmcontract/dto/CrmContractProductDTO.java create mode 100644 yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/hrm/api/crmcustomer/CrmCustomerApi.java create mode 100644 yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/hrm/api/crmcustomer/dto/CrmCustomerDTO.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/api/crmbusiness/BusinessApiImpl.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/api/crmcontract/ContractApiImpl.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/api/crmcustomer/CrmCustomerApiImpl.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmclues/vo/CrmCluesStatisticsRespVO.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmcustomer/vo/CustomerStatisticRespVO.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmrecord/vo/RecordStatisticsRespVO.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/crmrecord/CrmRecordMapper.xml diff --git a/yudao-module-bpm/yudao-module-bpm-api/pom.xml b/yudao-module-bpm/yudao-module-bpm-api/pom.xml index 470b4b53..06e83885 100644 --- a/yudao-module-bpm/yudao-module-bpm-api/pom.xml +++ b/yudao-module-bpm/yudao-module-bpm-api/pom.xml @@ -42,6 +42,10 @@ spring-cloud-starter-openfeign true + + cn.iocoder.cloud + yudao-spring-boot-starter-protection + diff --git a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOAContractApi.java b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOAContractApi.java new file mode 100644 index 00000000..9fce8b07 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOAContractApi.java @@ -0,0 +1,43 @@ +package cn.iocoder.yudao.module.bpm.api.oa; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.idempotent.core.annotation.Idempotent; +import cn.iocoder.yudao.module.bpm.api.oa.vo.contract.BpmOAContractDTO; +import cn.iocoder.yudao.module.bpm.api.oa.vo.contract.BpmOAContractVO; +import cn.iocoder.yudao.module.bpm.api.oa.vo.contract.ContractStatisticsDTO; +import cn.iocoder.yudao.module.bpm.enums.ApiConstants; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; + +import java.time.LocalDateTime; +import java.util.List; + +@FeignClient(name = ApiConstants.NAME) // TODO 芋艿:fallbackFactory = +@Tag(name = "RPC 服务 - 流程实例") +public interface BpmOAContractApi { + + String PREFIX = ApiConstants.PREFIX + "/oa/contract"; + + @PostMapping(PREFIX + "/create") + @Operation(summary = "创建合同审批流程") + @Idempotent(timeout = 10) + CommonResult create(@RequestBody BpmOAContractDTO createReqVO); + + @GetMapping(PREFIX + "/get-contract-count") + @Operation(summary = "获得当日合同统计 | 新增数量、新增金额") + CommonResult getContractCount(@RequestParam("relation") String relation); + + @GetMapping(PREFIX + "/get-contract-statistics") + @Operation(summary = "获得指定用户的合同统计信息") + CommonResult> getContractStatistics(@RequestParam("userId") List userIds, + @RequestParam(name = "createTime", required = false) LocalDateTime[] createTime); + + @PostMapping(PREFIX + "/getList") + @Operation(summary = "获得合同列表") + CommonResult> getContractList(@RequestBody BpmOAContractVO respVO); +} diff --git a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOAEntryApi.java b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOAEntryApi.java index ce496609..8cfdcf77 100644 --- a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOAEntryApi.java +++ b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOAEntryApi.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.bpm.api.oa; import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.module.bpm.api.oa.vo.BpmOAEntryDTO; +import cn.iocoder.yudao.module.bpm.api.oa.vo.entry.BpmOAEntryDTO; import cn.iocoder.yudao.module.bpm.enums.ApiConstants; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; diff --git a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOAInvoiceApi.java b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOAInvoiceApi.java new file mode 100644 index 00000000..34d92a00 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOAInvoiceApi.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.bpm.api.oa; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.module.bpm.api.oa.vo.invoice.BpmOAInvoiceDTO; +import cn.iocoder.yudao.module.bpm.enums.ApiConstants; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +@FeignClient(name = ApiConstants.NAME) // TODO 芋艿:fallbackFactory = +@Tag(name = "RPC 服务 - 流程实例") +public interface BpmOAInvoiceApi { + + String PREFIX = ApiConstants.PREFIX + "/oa/invoice"; + + @PostMapping(PREFIX + "/create") + @Operation(summary = "创建开票申请流程") + CommonResult create(@RequestBody BpmOAInvoiceDTO createReqVO); +} diff --git a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOALeaveApi.java b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOALeaveApi.java index 7a679ae1..d7e167de 100644 --- a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOALeaveApi.java +++ b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOALeaveApi.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.bpm.api.oa; import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.module.bpm.api.oa.vo.BpmOALeaveRpcVO; +import cn.iocoder.yudao.module.bpm.api.oa.vo.leave.BpmOALeaveRpcVO; import cn.iocoder.yudao.module.bpm.enums.ApiConstants; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; diff --git a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOARefundApi.java b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOARefundApi.java index a4246e9f..bccad797 100644 --- a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOARefundApi.java +++ b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOARefundApi.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.bpm.api.oa; import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.module.bpm.api.oa.vo.BpmOARefundDTO; +import cn.iocoder.yudao.module.bpm.api.oa.vo.refund.BpmOARefundDTO; import cn.iocoder.yudao.module.bpm.enums.ApiConstants; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; diff --git a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/contract/BpmOAContractDTO.java b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/contract/BpmOAContractDTO.java new file mode 100644 index 00000000..02cf1d8c --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/contract/BpmOAContractDTO.java @@ -0,0 +1,97 @@ +package cn.iocoder.yudao.module.bpm.api.oa.vo.contract; + +import cn.iocoder.yudao.framework.common.pojo.UploadUserFile; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import javax.validation.constraints.NotNull; +import java.math.BigDecimal; +import java.time.LocalDate; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY; + +/** + * 合同审批 创建 Request VO + * + * @author 符溶馨 + */ +@Schema(description = "管理后台 - 合同审批创建 Request VO") +@Data +public class BpmOAContractDTO { + + @Schema(description = "合同类型 | 字典值 bpm_oa_contract_type", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "合同类型不能为空") + private Integer contractType; + + @Schema(description = "合同名称", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "合同名称不能为空") + private String contractName; + + @Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "合同编号不能为空") + private String contractNo; + + @Schema(description = "签约日期", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "签约日期不能为空") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY) + private LocalDate signingDate; + + @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private Long customerId; + + @Schema(description = "客户名称", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private String customerName; + + @Schema(description = "客户签约人(联系人ID)", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private Long contactsId; + + @Schema(description = "客户签约人(联系人)名称", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private String contactsName; + + @Schema(description = "签约公司编号", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "签约公司不能为空") + private Long companyId; + + @Schema(description = "签约人编号", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private Long signatoryId; + + @Schema(description = "合同金额", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private BigDecimal contractMoney; + + @Schema(description = "已收/已付金额", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private BigDecimal returnMoney; + + @Schema(description = "已开票金额", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private BigDecimal invoiceMoney; + + @Schema(description = "产品总金额", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private BigDecimal totalPrice; + + @Schema(description = "整单优惠金额", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private BigDecimal discountRate; + + @Schema(description = "商机ID", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private Long businessId; + + @Schema(description = "合同开始时间", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY) + private LocalDate startDate; + + @Schema(description = "合同结束时间", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY) + private LocalDate endDate; + + @Schema(description = "合同状态 | 1已签约 2过期", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private Integer status; + + @Schema(description = "流程实例编号") + private String processInstanceId; + + @Schema(description = "状态-参见 bpm_process_instance_result 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Integer result; + + @Schema(description = "上传文件", requiredMode = Schema.RequiredMode.REQUIRED) + private List fileItems; +} diff --git a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/contract/BpmOAContractVO.java b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/contract/BpmOAContractVO.java new file mode 100644 index 00000000..642d672f --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/contract/BpmOAContractVO.java @@ -0,0 +1,30 @@ +package cn.iocoder.yudao.module.bpm.api.oa.vo.contract; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.Date; +import java.util.List; + +@Schema(description = "BpmOA合同审批流程的VO对象") +@Data +public class BpmOAContractVO { + + /** + * 合同类型 + * 1 销售合同 + */ + public static final Integer SALE_CONTRACT = 1; + + @Schema(description = "用户编号") + private List userId; + + @Schema(description = "合同类型") + private Integer contractType; + + @Schema(description = "开始时间") + private Date starTime; + + @Schema(description = "结束时间") + private Date endTime; +} diff --git a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/contract/ContractStatisticsDTO.java b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/contract/ContractStatisticsDTO.java new file mode 100644 index 00000000..fd3097bd --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/contract/ContractStatisticsDTO.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.bpm.api.oa.vo.contract; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + +@Schema(description = "管理后台 - 合同审批 请求Request VO") +@Data +public class ContractStatisticsDTO { + + @Schema(description = "用户编号") + private Long userId; + + @Schema(description = "今日新增合同数") + private Integer todayAdditions; + + @Schema(description = "昨日新增合同数") + private Integer yesterdayAdditions; + + @Schema(description = "较昨日百分比 | 数量") + private BigDecimal countPercentage; + + @Schema(description = "今日新增合同金额") + private BigDecimal todayAddMoney; + + @Schema(description = "昨日新增合同金额") + private BigDecimal yesterdayAddMoney; + + @Schema(description = "较昨日百分比 | 金额") + private BigDecimal moneyPercentage; + + @Schema(description = "合同总数") + private Integer count; + + @Schema(description = "合同总金额") + private BigDecimal money; +} diff --git a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/BpmOAEntryDTO.java b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/entry/BpmOAEntryDTO.java similarity index 97% rename from yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/BpmOAEntryDTO.java rename to yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/entry/BpmOAEntryDTO.java index e6ac4839..dc00e571 100644 --- a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/BpmOAEntryDTO.java +++ b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/entry/BpmOAEntryDTO.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.bpm.api.oa.vo; +package cn.iocoder.yudao.module.bpm.api.oa.vo.entry; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; diff --git a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/BpmOAEvectionDTO.java b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/evection/BpmOAEvectionDTO.java similarity index 97% rename from yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/BpmOAEvectionDTO.java rename to yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/evection/BpmOAEvectionDTO.java index 0b549f1a..89c3ff7d 100644 --- a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/BpmOAEvectionDTO.java +++ b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/evection/BpmOAEvectionDTO.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.bpm.api.oa.vo; +package cn.iocoder.yudao.module.bpm.api.oa.vo.evection; import cn.iocoder.yudao.framework.common.pojo.UploadUserFile; import io.swagger.v3.oas.annotations.media.Schema; diff --git a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/invoice/BpmOAInvoiceDTO.java b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/invoice/BpmOAInvoiceDTO.java new file mode 100644 index 00000000..fec366fd --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/invoice/BpmOAInvoiceDTO.java @@ -0,0 +1,88 @@ +package cn.iocoder.yudao.module.bpm.api.oa.vo.invoice; + +import cn.iocoder.yudao.framework.common.pojo.UploadUserFile; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import javax.validation.constraints.NotNull; +import java.math.BigDecimal; +import java.time.LocalDate; +import java.util.List; + +@Schema(description = "管理后台 - 开票申请创建 Request VO") +@Data +@EqualsAndHashCode() +@ToString(callSuper = true) +public class BpmOAInvoiceDTO { + + @Schema(description = "计划开票日期", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "计划开票日期不能为空") + private LocalDate invoiceDate; + + @Schema(description = "关联合同业务编号", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "合同编号不能为空") + private Long contractId; + + @Schema(description = "关联合同流程实例编号", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private String contractInstanceId; + + @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private Long customerId; + + @Schema(description = "开票主体", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "开票主体不能为空") + private String invoiceBody; + + @Schema(description = "发票抬头", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "发票抬头不能为空") + private String invoiceName; + + @Schema(description = "抬头类型 | 1企业2个人3事业单位", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "抬头类型不能为空") + private Integer invoiceIssue; + + @Schema(description = "发票类型 | 1普票 2专票", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "发票类型不能为空") + private Integer invoiceType; + + @Schema(description = "统一社会信用代码", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "统一社会信用代码不能为空") + private String registerNo; + + @Schema(description = "开票金额", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "开票金额不能为空") + private BigDecimal amount; + + @Schema(description = "开票内容", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "开票内容不能为空") + private String content; + + @Schema(description = "开票单位地址") + private String unitAddress; + + @Schema(description = "开票单位电话") + private String unitPhone; + + @Schema(description = "开票单位开户银行") + private String unitBankName; + + @Schema(description = "开票单位银行账号") + private String unitBankNo; + + @Schema(description = "开票单位邮箱") + private String email; + + @Schema(description = "开票状态", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private Integer status; + + @Schema(description = "流程实例编号") + private String processInstanceId; + + @Schema(description = "状态-参见 bpm_process_instance_result 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Integer result; + + @Schema(description = "上传文件", requiredMode = Schema.RequiredMode.REQUIRED) + private List fileItems ; +} diff --git a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/BpmOALeaveRpcVO.java b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/leave/BpmOALeaveRpcVO.java similarity index 96% rename from yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/BpmOALeaveRpcVO.java rename to yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/leave/BpmOALeaveRpcVO.java index 3779966a..f91485b2 100644 --- a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/BpmOALeaveRpcVO.java +++ b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/leave/BpmOALeaveRpcVO.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.bpm.api.oa.vo; +package cn.iocoder.yudao.module.bpm.api.oa.vo.leave; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; diff --git a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/BpmOARefundDTO.java b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/refund/BpmOARefundDTO.java similarity index 96% rename from yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/BpmOARefundDTO.java rename to yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/refund/BpmOARefundDTO.java index 443a8d5f..1db5c8a4 100644 --- a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/BpmOARefundDTO.java +++ b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/vo/refund/BpmOARefundDTO.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.bpm.api.oa.vo; +package cn.iocoder.yudao.module.bpm.api.oa.vo.refund; import cn.iocoder.yudao.framework.common.pojo.UploadUserFile; import io.swagger.v3.oas.annotations.media.Schema; 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 8775f08a..d2051942 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 @@ -59,7 +59,7 @@ public interface ErrorCodeConstants { ErrorCode OA_REPLACEMENT_CARD_NOT_EXISTS = new ErrorCode(1_009_001_122, "补卡申请不存在"); ErrorCode OA_REFUND_NOT_EXISTS = new ErrorCode(1_009_001_123, "退款申请不存在"); ErrorCode OA_PROJECT_NOT_EXISTS = new ErrorCode(1_009_001_124, "项目申请不存在"); - + ErrorCode OA_CONTRACT_INVOICE_AMOUNT_LACK = new ErrorCode(1_009_001_125, "该合同的开票余额不足!"); // ========== 流程模型 1-009-002-000 ========== ErrorCode MODEL_KEY_EXISTS = new ErrorCode(1_009_002_000, "已经存在流程标识为【{}】的流程"); diff --git a/yudao-module-bpm/yudao-module-bpm-biz/pom.xml b/yudao-module-bpm/yudao-module-bpm-biz/pom.xml index 64054212..08c54964 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/pom.xml +++ b/yudao-module-bpm/yudao-module-bpm-biz/pom.xml @@ -118,6 +118,22 @@ cn.iocoder.cloud yudao-spring-boot-starter-flowable + + cn.iocoder.cloud + yudao-module-product-api + 2.0.0-jdk8-snapshot + compile + + + cn.iocoder.cloud + yudao-module-crm-api + 2.0.0-jdk8-snapshot + compile + + + cn.iocoder.cloud + yudao-spring-boot-starter-protection + diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOAContractApiImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOAContractApiImpl.java new file mode 100644 index 00000000..b46c3eac --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOAContractApiImpl.java @@ -0,0 +1,55 @@ +package cn.iocoder.yudao.module.bpm.api.oa; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.bpm.api.oa.vo.contract.BpmOAContractDTO; +import cn.iocoder.yudao.module.bpm.api.oa.vo.contract.BpmOAContractVO; +import cn.iocoder.yudao.module.bpm.api.oa.vo.contract.ContractStatisticsDTO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.contract.BpmOAContractCreateReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.contract.ContractStatisticsRespVO; +import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAContractDO; +import cn.iocoder.yudao.module.bpm.service.oa.BpmOAContractService; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; + +/** + * Flowable 流程实例 Api 实现类 + */ +@RestController +@Validated +public class BpmOAContractApiImpl implements BpmOAContractApi{ + + @Resource + private BpmOAContractService contractService; + + @Override + public CommonResult create(BpmOAContractDTO createReqVO) { + + return success(contractService.createContract(getLoginUserId(), BeanUtils.toBean(createReqVO, BpmOAContractCreateReqVO.class))); + } + + @Override + public CommonResult getContractCount(String relation) { + ContractStatisticsRespVO respVO = contractService.getContractStatistics(getLoginUserId(), relation); + return success(BeanUtils.toBean(respVO, ContractStatisticsDTO.class)); + } + + @Override + public CommonResult> getContractStatistics(List userIds, LocalDateTime[] createTime) { + List respVOS = contractService.getContractStatisticsListByUserIds(userIds, createTime); + return success(BeanUtils.toBean(respVOS, ContractStatisticsDTO.class)); + } + + @Override + public CommonResult> getContractList(BpmOAContractVO respVO) { + List contractDO = contractService.getContractList(respVO); + return success(BeanUtils.toBean(contractDO, BpmOAContractDTO.class)); + } +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOAEntryApiImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOAEntryApiImpl.java index 989015b2..d168bc10 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOAEntryApiImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOAEntryApiImpl.java @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.bpm.api.oa; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; -import cn.iocoder.yudao.module.bpm.api.oa.vo.BpmOAEntryDTO; +import cn.iocoder.yudao.module.bpm.api.oa.vo.entry.BpmOAEntryDTO; import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAEntryDO; import cn.iocoder.yudao.module.bpm.service.oa.BpmOAEntryService; import org.springframework.validation.annotation.Validated; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOAInvoiceApiImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOAInvoiceApiImpl.java new file mode 100644 index 00000000..f4da6fac --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOAInvoiceApiImpl.java @@ -0,0 +1,32 @@ +package cn.iocoder.yudao.module.bpm.api.oa; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.bpm.api.oa.vo.invoice.BpmOAInvoiceDTO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.invoice.BpmOAInvoiceCreateReqVO; +import cn.iocoder.yudao.module.bpm.service.oa.BpmOAInvoiceService; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; + +/** + * Flowable 流程实例 Api 实现类 + */ +@RestController +@Validated +public class BpmOAInvoiceApiImpl implements BpmOAInvoiceApi{ + + @Resource + private BpmOAInvoiceService invoiceService; + + + @Override + public CommonResult create(BpmOAInvoiceDTO createReqVO) { + + return success(invoiceService.createInvoice(getLoginUserId(), BeanUtils.toBean(createReqVO, BpmOAInvoiceCreateReqVO.class))); + } +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOALeaveApiImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOALeaveApiImpl.java index 46eae554..265e0d0f 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOALeaveApiImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOALeaveApiImpl.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.bpm.api.oa; import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.module.bpm.api.oa.vo.BpmOALeaveRpcVO; +import cn.iocoder.yudao.module.bpm.api.oa.vo.leave.BpmOALeaveRpcVO; import cn.iocoder.yudao.module.bpm.service.oa.BpmOALeaveService; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.RestController; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOARefundApiImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOARefundApiImpl.java index 257625b7..3cb6b141 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOARefundApiImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/api/oa/BpmOARefundApiImpl.java @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.bpm.api.oa; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; -import cn.iocoder.yudao.module.bpm.api.oa.vo.BpmOARefundDTO; +import cn.iocoder.yudao.module.bpm.api.oa.vo.refund.BpmOARefundDTO; import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOARefundDO; import cn.iocoder.yudao.module.bpm.service.oa.BpmOARefundService; import org.springframework.validation.annotation.Validated; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOAContractController.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOAContractController.java index 9ce67c43..ad0b33b4 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOAContractController.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOAContractController.java @@ -1,13 +1,23 @@ package cn.iocoder.yudao.module.bpm.controller.admin.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.util.object.BeanUtils; +import cn.iocoder.yudao.framework.idempotent.core.annotation.Idempotent; import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.contract.BpmOAContractCreateReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.contract.BpmOAContractPageReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.contract.BpmOAContractRespVO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.contract.ContractStatisticsRespVO; import cn.iocoder.yudao.module.bpm.convert.oa.BpmOAContractConvert; import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAContractDO; import cn.iocoder.yudao.module.bpm.service.oa.BpmOAContractService; +import cn.iocoder.yudao.module.hrm.api.crmbusiness.BusinessApi; +import cn.iocoder.yudao.module.hrm.api.crmbusiness.dto.CrmBusinessDTO; +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 io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; @@ -16,7 +26,9 @@ import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.validation.Valid; +import java.util.Arrays; import java.util.List; +import java.util.Map; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; @@ -39,8 +51,15 @@ public class BpmOAContractController { @Resource private AdminUserApi userApi; + @Resource + private DeptApi deptApi; + + @Resource + private BusinessApi businessApi; + @PostMapping("/create") @Operation(summary = "创建请求申请") + @Idempotent(timeout = 10) public CommonResult createContract(@Valid @RequestBody BpmOAContractCreateReqVO createReqVO) { return success(contractService.createContract(getLoginUserId(), createReqVO)); } @@ -51,8 +70,31 @@ public class BpmOAContractController { public CommonResult getContract(@RequestParam("id") Long id) { BpmOAContractDO contract = contractService.getContract(id); + BpmOAContractRespVO respVO = BpmOAContractConvert.INSTANCE.convert(contract); + if (respVO != null) { + // 获取用户和签约人信息 + List userIds = Arrays.asList(contract.getUserId(), contract.getSignatoryId()); + Map userMap = userApi.getUserMap(userIds); + if (CollectionUtil.isNotEmpty(userMap)) { + // 设置创建人、签约人名称 + respVO.setSignatoryName(userMap.get(contract.getSignatoryId()).getNickname()); + respVO.setCreateName(userMap.get(contract.getUserId()).getNickname()); + } - return success(BpmOAContractConvert.INSTANCE.convert(contract)); + // 获取公司信息 + DeptRespDTO dto = deptApi.getDept(contract.getCompanyId()).getCheckedData(); + if (dto != null) { + respVO.setCompanyName(dto.getName()); + } + + if (respVO.getBusinessId() != null) { + // 获取商机信息 + CrmBusinessDTO businessDTO = businessApi.getBusiness(respVO.getBusinessId()).getCheckedData(); + respVO.setBusinessName(businessDTO != null ? businessDTO.getName() : null); + } + } + + return success(respVO); } @GetMapping("/getByProcessInstanceId") @@ -61,12 +103,42 @@ public class BpmOAContractController { public CommonResult getContractByProcessInstanceId(@RequestParam("processInstanceId") String processInstanceId) { BpmOAContractDO contract = contractService.getByProcessInstanceId(processInstanceId); + BpmOAContractRespVO respVO = BpmOAContractConvert.INSTANCE.convert(contract); + if (respVO != null) { + // 获取用户和签约人信息 + List userIds = Arrays.asList(contract.getUserId(), contract.getSignatoryId()); + Map userMap = userApi.getUserMap(userIds); + if (CollectionUtil.isNotEmpty(userMap)) { + // 设置创建人、签约人名称 + respVO.setSignatoryName(userMap.get(contract.getSignatoryId()).getNickname()); + respVO.setCreateName(userMap.get(contract.getUserId()).getNickname()); + } - return success(BpmOAContractConvert.INSTANCE.convert(contract)); + // 获取公司信息 + DeptRespDTO dto = deptApi.getDept(contract.getCompanyId()).getCheckedData(); + if (dto != null) { + respVO.setCompanyName(dto.getName()); + } + + if (respVO.getBusinessId() != null) { + // 获取商机信息 + CrmBusinessDTO businessDTO = businessApi.getBusiness(respVO.getBusinessId()).getCheckedData(); + respVO.setBusinessName(businessDTO != null ? businessDTO.getName() : null); + } + } + + return success(respVO); + } + + @GetMapping("/page") + @Operation(summary = "获得合同审批分页列表") + public CommonResult> getPage(@Valid BpmOAContractPageReqVO pageReqVO) { + + return success(contractService.getContractPage(pageReqVO)); } @GetMapping("/getListByDeptId") - @Operation(summary = "获得同部门的合同审批") + @Operation(summary = "获得同部门的销售合同") public CommonResult> getListByDeptId() { // 获取同部门所有用户id @@ -76,4 +148,16 @@ public class BpmOAContractController { return success(BeanUtils.toBean(contracts, BpmOAContractRespVO.class)); } + + @GetMapping("/get-contract-statistics") + @Operation(summary = "获得当日合同统计 | 新增数量、新增金额") + @Parameter(name = "relation", description = "查询类型 my我的 sub下属| ", required = true) + public CommonResult getListByDeptId(@RequestParam("relation") String relation) { + + ContractStatisticsRespVO respVO = contractService.getContractStatistics(getLoginUserId(), relation); + + return success(respVO); + } + + } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOAInvoiceController.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOAInvoiceController.java index 38b74947..93d49146 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOAInvoiceController.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOAInvoiceController.java @@ -1,8 +1,10 @@ package cn.iocoder.yudao.module.bpm.controller.admin.oa; import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.invoice.BpmOAInvoiceCreateReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.invoice.BpmOAInvoicePageReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.invoice.BpmOAInvoiceRespVO; import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAInvoiceDO; import cn.iocoder.yudao.module.bpm.service.oa.BpmOAInvoiceService; @@ -61,4 +63,11 @@ public class BpmOAInvoiceController { BpmOAInvoiceRespVO bpmOAInvoiceRespVO = BeanUtils.toBean(invoice, BpmOAInvoiceRespVO.class); return success(bpmOAInvoiceRespVO); } + + @GetMapping("/page") + @Operation(summary = "获得开票申请分页列表") + public CommonResult> getPage(@Valid BpmOAInvoicePageReqVO pageReqVO) { + + return success(invoiceService.getInvoicePage(pageReqVO)); + } } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/contract/BpmOAContractCreateReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/contract/BpmOAContractCreateReqVO.java index c5853fb1..2c7a26cc 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/contract/BpmOAContractCreateReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/contract/BpmOAContractCreateReqVO.java @@ -2,9 +2,11 @@ package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.contract; import cn.iocoder.yudao.framework.common.pojo.UploadUserFile; import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; import javax.validation.constraints.NotNull; +import java.math.BigDecimal; import java.time.LocalDate; import java.util.List; @@ -16,32 +18,78 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ * @author 符溶馨 */ @Schema(description = "管理后台 - 合同审批创建 Request VO") +@Data public class BpmOAContractCreateReqVO { + @Schema(description = "ID", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private Long id; + + @Schema(description = "合同类型 | 字典值 bpm_oa_contract_type", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "合同类型不能为空") + private Integer contractType; + @Schema(description = "合同名称", requiredMode = Schema.RequiredMode.REQUIRED) @NotNull(message = "合同名称不能为空") private String contractName; - @Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED) - @NotNull(message = "合同编号不能为空") - private String contractNumber; + @Schema(description = "合同编号", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private String contractNo; @Schema(description = "签约日期", requiredMode = Schema.RequiredMode.REQUIRED) @NotNull(message = "签约日期不能为空") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY) private LocalDate signingDate; - @Schema(description = "我方公司名称", requiredMode = Schema.RequiredMode.NOT_REQUIRED) - private String mCompanyName; + @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private Long customerId; - @Schema(description = "我方负责人", requiredMode = Schema.RequiredMode.NOT_REQUIRED) - private String mHeadName; + @Schema(description = "客户名称", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private String customerName; - @Schema(description = "对方公司名称", requiredMode = Schema.RequiredMode.NOT_REQUIRED) - private String oCompanyName; + @Schema(description = "客户签约人(联系人ID)", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private Long contactsId; - @Schema(description = "对方负责人", requiredMode = Schema.RequiredMode.NOT_REQUIRED) - private String oHeadName; + @Schema(description = "客户签约人(联系人)名称", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private String contactsName; + + @Schema(description = "签约公司编号", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "签约公司不能为空") + private Long companyId; + + @Schema(description = "签约人编号", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private Long signatoryId; + + @Schema(description = "合同金额", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private BigDecimal contractMoney; + + @Schema(description = "已收/已付金额", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private BigDecimal returnMoney; + + @Schema(description = "已开票金额", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private BigDecimal invoiceMoney; + + @Schema(description = "产品总金额", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private BigDecimal totalPrice; + + @Schema(description = "整单优惠金额", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private BigDecimal discountRate; + + @Schema(description = "商机ID", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private Long businessId; + + @Schema(description = "合同开始时间", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY) + private LocalDate startDate; + + @Schema(description = "合同结束时间", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY) + private LocalDate endDate; + + @Schema(description = "合同状态 | 1已签约 2过期", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private Integer status; + + @Schema(description = "合同产品关系列表") + private List contractProducts; @Schema(description = "流程实例编号") private String processInstanceId; @@ -51,103 +99,4 @@ public class BpmOAContractCreateReqVO { @Schema(description = "上传文件", requiredMode = Schema.RequiredMode.REQUIRED) private List fileItems; - - public BpmOAContractCreateReqVO() { - } - - public BpmOAContractCreateReqVO(String contractName, String contractNumber, LocalDate signingDate, - String mCompanyName, String mHeadName, String oCompanyName, - String oHeadName, String processInstanceId, List fileItems, - Integer result) { - this.contractName = contractName; - this.contractNumber = contractNumber; - this.signingDate = signingDate; - this.mCompanyName = mCompanyName; - this.mHeadName = mHeadName; - this.oCompanyName = oCompanyName; - this.oHeadName = oHeadName; - this.processInstanceId = processInstanceId; - this.result = result; - this.fileItems = fileItems; - } - - public Integer getResult() { - return result; - } - - public void setResult(Integer result) { - this.result = result; - } - - public String getContractName() { - return contractName; - } - - public String getProcessInstanceId() { - return processInstanceId; - } - - public void setProcessInstanceId(String processInstanceId) { - this.processInstanceId = processInstanceId; - } - - public void setContractName(String contractName) { - this.contractName = contractName; - } - - public String getContractNumber() { - return contractNumber; - } - - public void setContractNumber(String contractNumber) { - this.contractNumber = contractNumber; - } - - public LocalDate getSigningDate() { - return signingDate; - } - - public void setSigningDate(LocalDate signingDate) { - this.signingDate = signingDate; - } - - public String getmCompanyName() { - return mCompanyName; - } - - public void setmCompanyName(String mCompanyName) { - this.mCompanyName = mCompanyName; - } - - public String getmHeadName() { - return mHeadName; - } - - public void setmHeadName(String mHeadName) { - this.mHeadName = mHeadName; - } - - public String getoCompanyName() { - return oCompanyName; - } - - public void setoCompanyName(String oCompanyName) { - this.oCompanyName = oCompanyName; - } - - public String getoHeadName() { - return oHeadName; - } - - public void setoHeadName(String oHeadName) { - this.oHeadName = oHeadName; - } - - public List getFileItems() { - return fileItems; - } - - public void setFileItems(List fileItems) { - this.fileItems = fileItems; - } } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/contract/BpmOAContractPageReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/contract/BpmOAContractPageReqVO.java new file mode 100644 index 00000000..94e370ec --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/contract/BpmOAContractPageReqVO.java @@ -0,0 +1,43 @@ +package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.contract; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +@Schema(description = "管理后台 - 合同审批分页 Request VO") +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class BpmOAContractPageReqVO extends PageParam { + + @Schema(description = "合同类型 | 字典值 bpm_oa_contract_type", example = "1") + private Integer contractType; + + @Schema(description = "客户名称,模糊匹配") + private String customerName; + + @Schema(description = "合同名称,模糊匹配") + private String contractName; + + @Schema(description = "合同编号") + private String contractNo; + + @Schema(description = "审批结果") + private Integer result; + + @Schema(description = "合同状态", example = "1") + private Integer status; + + @Schema(description = "签约人名称") + private String signatoryName; + + @Schema(description = "创建人名称") + private String createName; + + @Schema(description = "查询模式") + private String relation; +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/contract/BpmOAContractRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/contract/BpmOAContractRespVO.java index e8ed1f3b..eaa30611 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/contract/BpmOAContractRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/contract/BpmOAContractRespVO.java @@ -1,13 +1,12 @@ package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.contract; -import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.BpmOABaseRespVO; import cn.iocoder.yudao.framework.common.pojo.UploadUserFile; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.BpmOABaseRespVO; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; -import javax.validation.constraints.NotNull; -import java.time.LocalDate; +import java.math.BigDecimal; import java.util.List; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY; @@ -19,31 +18,81 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ @Data public class BpmOAContractRespVO extends BpmOABaseRespVO { + @Schema(description = "发起人用户编号", requiredMode = Schema.RequiredMode.REQUIRED) + private Long userId; + + @Schema(description = "合同类型 | 字典值 bpm_oa_contract_type", requiredMode = Schema.RequiredMode.REQUIRED) + private Integer contractType; + @Schema(description = "合同名称", requiredMode = Schema.RequiredMode.REQUIRED) - @NotNull(message = "合同名称不能为空") private String contractName; @Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED) - @NotNull(message = "合同编号不能为空") - private String contractNumber; + private String contractNo; @Schema(description = "签约日期", requiredMode = Schema.RequiredMode.REQUIRED) - @NotNull(message = "签约日期不能为空") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY) - private LocalDate signingDate; + private String signingDate; - @Schema(description = "我方公司名称", requiredMode = Schema.RequiredMode.NOT_REQUIRED) - private String mCompanyName; + @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private Long customerId; - @Schema(description = "我方负责人", requiredMode = Schema.RequiredMode.NOT_REQUIRED) - private String mHeadName; + @Schema(description = "客户名称", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private String customerName; - @Schema(description = "对方公司名称", requiredMode = Schema.RequiredMode.NOT_REQUIRED) - private String oCompanyName; + @Schema(description = "客户签约人(联系人ID)", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private Long contactsId; - @Schema(description = "对方负责人", requiredMode = Schema.RequiredMode.NOT_REQUIRED) - private String oHeadName; + @Schema(description = "客户签约人(联系人)名称", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private String contactsName; + + @Schema(description = "签约公司编号", requiredMode = Schema.RequiredMode.REQUIRED) + private Long companyId; + + @Schema(description = "签约公司名称", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private String companyName; + + @Schema(description = "签约人编号", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private Long signatoryId; + + @Schema(description = "签约人名称", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private String signatoryName; + + @Schema(description = "合同金额", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private BigDecimal contractMoney; + + @Schema(description = "已收/已付金额", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private BigDecimal returnMoney; + + @Schema(description = "已开票金额", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private BigDecimal invoiceMoney; + + @Schema(description = "产品总金额", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private BigDecimal totalPrice; + + @Schema(description = "整单优惠金额", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private BigDecimal discountRate; + + @Schema(description = "商机ID", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private Long businessId; + + @Schema(description = "商机名称", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private String businessName; + + @Schema(description = "合同开始时间", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY) + private String startDate; + + @Schema(description = "合同结束时间", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY) + private String endDate; + + @Schema(description = "合同状态 | 1已签约 2过期", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private Integer status; @Schema(description = "上传文件", requiredMode = Schema.RequiredMode.REQUIRED) private List fileItems; + + @Schema(description = "创建人名称", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private String createName; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/contract/ContractStatisticsRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/contract/ContractStatisticsRespVO.java new file mode 100644 index 00000000..e35ae618 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/contract/ContractStatisticsRespVO.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.contract; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + +@Schema(description = "管理后台 - 合同审批 请求Request VO") +@Data +public class ContractStatisticsRespVO { + + @Schema(description = "用户编号") + private Long userId; + + @Schema(description = "今日新增合同数") + private Integer todayAdditions; + + @Schema(description = "昨日新增合同数") + private Integer yesterdayAdditions; + + @Schema(description = "较昨日百分比 | 数量") + private BigDecimal countPercentage; + + @Schema(description = "今日新增合同金额") + private BigDecimal todayAddMoney; + + @Schema(description = "昨日新增合同金额") + private BigDecimal yesterdayAddMoney; + + @Schema(description = "较昨日百分比 | 金额") + private BigDecimal moneyPercentage; + + @Schema(description = "合同总数") + private Integer count; + + @Schema(description = "合同总金额") + private BigDecimal money; +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/contract/CrmContractProductVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/contract/CrmContractProductVO.java new file mode 100644 index 00000000..42a0c3ce --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/contract/CrmContractProductVO.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.contract; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + +@Schema(description = "管理后台 - 合同产品关联 Response VO") +@Data +public class CrmContractProductVO { + + @Schema(description = "合同编号") + private Long contractId; + + @Schema(description = "产品编号") + private Long productId; + + @Schema(description = "产品名称") + private String name; + + @Schema(description = "产品属性") + private String productAttrUnique; + + @Schema(description = "产品单价") + private BigDecimal price; + + @Schema(description = "数量") + private Integer nums; + + @Schema(description = "折扣") + private BigDecimal discount; + + @Schema(description = "小计") + private BigDecimal subtotal; + + @Schema(description = "备注") + private String remarks; +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/invoice/BpmOAInvoiceCreateReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/invoice/BpmOAInvoiceCreateReqVO.java index 66ae8887..2a30a20d 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/invoice/BpmOAInvoiceCreateReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/invoice/BpmOAInvoiceCreateReqVO.java @@ -21,8 +21,35 @@ public class BpmOAInvoiceCreateReqVO { @NotNull(message = "计划开票日期不能为空") private LocalDate invoiceDate; - @Schema(description = "项目编号") - private Long projectId; + @Schema(description = "关联合同业务编号", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "合同编号不能为空") + private Long contractId; + + @Schema(description = "关联合同流程实例编号", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private String contractInstanceId; + + @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private Long customerId; + + @Schema(description = "开票主体", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "开票主体不能为空") + private String invoiceBody; + + @Schema(description = "发票抬头", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "发票抬头不能为空") + private String invoiceName; + + @Schema(description = "抬头类型 | 1企业2个人3事业单位", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "抬头类型不能为空") + private Integer invoiceIssue; + + @Schema(description = "发票类型 | 1普票 2专票", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "发票类型不能为空") + private Integer invoiceType; + + @Schema(description = "统一社会信用代码", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "统一社会信用代码不能为空") + private String registerNo; @Schema(description = "开票金额", requiredMode = Schema.RequiredMode.REQUIRED) @NotNull(message = "开票金额不能为空") @@ -32,14 +59,6 @@ public class BpmOAInvoiceCreateReqVO { @NotNull(message = "开票内容不能为空") private String content; - @Schema(description = "开票单位名称", requiredMode = Schema.RequiredMode.REQUIRED) - @NotNull(message = "开票单位名称不能为空") - private String unitName; - - @Schema(description = "开票单位纳税人识别号", requiredMode = Schema.RequiredMode.REQUIRED) - @NotNull(message = "开票单位纳税人识别号不能为空") - private String unitTin; - @Schema(description = "开票单位地址") private String unitAddress; @@ -52,8 +71,11 @@ public class BpmOAInvoiceCreateReqVO { @Schema(description = "开票单位银行账号") private String unitBankNo; - @Schema(description = "关联合同业务流程编号") - private String contractInstanceId; + @Schema(description = "开票单位邮箱") + private String email; + + @Schema(description = "开票状态", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private Integer status; @Schema(description = "流程实例编号") private String processInstanceId; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/invoice/BpmOAInvoicePageReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/invoice/BpmOAInvoicePageReqVO.java new file mode 100644 index 00000000..9f6916a0 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/invoice/BpmOAInvoicePageReqVO.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.invoice; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +@Schema(description = "管理后台 - 合同审批分页 Request VO") +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class BpmOAInvoicePageReqVO extends PageParam { + + @Schema(description = "合同名称") + private String contractName; + + @Schema(description = "客户名称,模糊匹配") + private String customerName; + + @Schema(description = "审批结果") + private Integer result; + + @Schema(description = "开票状态", example = "1") + private Integer status; + + @Schema(description = "查询模式") + private String relation; +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/invoice/BpmOAInvoiceRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/invoice/BpmOAInvoiceRespVO.java index 0e2af3c8..ad6dd51f 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/invoice/BpmOAInvoiceRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/invoice/BpmOAInvoiceRespVO.java @@ -20,8 +20,35 @@ public class BpmOAInvoiceRespVO extends BpmOABaseRespVO { @Schema(description = "计划开票日期", requiredMode = Schema.RequiredMode.REQUIRED) private LocalDate invoiceDate; - @Schema(description = "项目编号") - private Long projectId; + @Schema(description = "关联合同业务编号", requiredMode = Schema.RequiredMode.REQUIRED) + private Long contractId; + + @Schema(description = "合同名称", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private String contractName; + + @Schema(description = "关联合同流程实例编号", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private String contractInstanceId; + + @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private Long customerId; + + @Schema(description = "客户名称", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private String customerName; + + @Schema(description = "开票主体", requiredMode = Schema.RequiredMode.REQUIRED) + private String invoiceBody; + + @Schema(description = "发票抬头", requiredMode = Schema.RequiredMode.REQUIRED) + private String invoiceName; + + @Schema(description = "抬头类型 | 1企业2个人3事业单位", requiredMode = Schema.RequiredMode.REQUIRED) + private Integer invoiceIssue; + + @Schema(description = "发票类型 | 1普票 2专票", requiredMode = Schema.RequiredMode.REQUIRED) + private Integer invoiceType; + + @Schema(description = "统一社会信用代码", requiredMode = Schema.RequiredMode.REQUIRED) + private String registerNo; @Schema(description = "开票金额", requiredMode = Schema.RequiredMode.REQUIRED) private BigDecimal amount; @@ -29,12 +56,6 @@ public class BpmOAInvoiceRespVO extends BpmOABaseRespVO { @Schema(description = "开票内容", requiredMode = Schema.RequiredMode.REQUIRED) private String content; - @Schema(description = "开票单位名称", requiredMode = Schema.RequiredMode.REQUIRED) - private String unitName; - - @Schema(description = "开票单位纳税人识别号", requiredMode = Schema.RequiredMode.REQUIRED) - private String unitTin; - @Schema(description = "开票单位地址") private String unitAddress; @@ -47,9 +68,12 @@ public class BpmOAInvoiceRespVO extends BpmOABaseRespVO { @Schema(description = "开票单位银行账号") private String unitBankNo; - @Schema(description = "关联合同业务流程编号") - private String contractInstanceId; + @Schema(description = "开票单位邮箱") + private String email; - @Schema(description = "上传文件") + @Schema(description = "开票状态", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private Integer status; + + @Schema(description = "上传文件", requiredMode = Schema.RequiredMode.REQUIRED) private List fileItems ; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java index 0784a922..0ae0bbe8 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java @@ -5,17 +5,25 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission; import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.contract.BpmOAContractRespVO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.invoice.BpmOAInvoiceRespVO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*; import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmHistoryProcessInstanceDO; +import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO; +import cn.iocoder.yudao.module.bpm.service.oa.BpmOAContractService; +import cn.iocoder.yudao.module.bpm.service.oa.BpmOAInvoiceService; import cn.iocoder.yudao.module.bpm.service.task.BpmHistoryProcessInstanceService; import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService; 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.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; import org.flowable.task.api.history.HistoricTaskInstance; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; @@ -36,6 +44,7 @@ import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLogi @RestController @RequestMapping("/bpm/task") @Validated +@Slf4j @DataPermission(enable = false) public class BpmTaskController { @@ -51,9 +60,16 @@ public class BpmTaskController { @Resource private DeptApi deptApi; + @Resource + private BpmOAContractService bpmOAContractService; + + @Resource + private BpmOAInvoiceService bpmOAInvoiceService; + /** * add by yaojun 2024.1.3 * 流程审核添加了抄送用户(多用户)的功能 + * * @param pageReqVO * @return */ @@ -213,7 +229,7 @@ public class BpmTaskController { if (CollUtil.isEmpty(userIds)) { return success(userRespDTO); } - Map userMap = userApi.getUserMap(userIds.stream().map(Long::parseLong).collect(Collectors.toList())); + Map userMap = userApi.getUserMap(userIds.stream().map(Long::parseLong).collect(Collectors.toList())); return success(convertList(userIds, id -> userMap.get(Long.valueOf(id)))); } @@ -236,9 +252,43 @@ public class BpmTaskController { @GetMapping("getCurrentToDoProcessInstacePreAndNex-page") @Operation(summary = "获取当前待处理流程实例(带查询条件),上一个流程和下一个流程的实例ID") - public CommonResult> getCurrentToDoProcessInstacePreAndNex(@RequestParam("processInstanceId") String processInstanceId,@Valid BpmTaskTodoPageReqVO pageVO) { + public CommonResult> getCurrentToDoProcessInstacePreAndNex(@RequestParam("processInstanceId") String processInstanceId, @Valid BpmTaskTodoPageReqVO pageVO) { return success(taskService.getCurrentToDoProcessInstacePreAndNex(getLoginUserId(), processInstanceId, pageVO)); } + @GetMapping("/get-crm-task") + @Operation(summary = "获得CRM审批任务") + @Parameter(name = "processDefinitionId", description = "流程定义编号", required = true, example = "1024") + @Parameter(name = "isTodo", description = "是否待办", required = true) + public CommonResult>> getCrmTask(BpmCrmTaskPageReqVO pageReqVO) { + List> respVOs = new ArrayList<>(); + + PageResult tasks = taskService.getCrmTask(getLoginUserId(), pageReqVO); + // 获取流程实例编号 + List processInstanceIds = tasks.getList().stream().map(BpmTaskExtDO::getProcessInstanceId).distinct().collect(Collectors.toList()); + + try { + ObjectMapper objectMapper = new ObjectMapper(); + switch (pageReqVO.getProcessDefinitionId()) { + case "oa_contract": + List contractRespVOS = bpmOAContractService.getListByProcessInstanceIds(processInstanceIds); + respVOs = contractRespVOS.stream() + .map(item -> objectMapper.convertValue(item, new TypeReference>(){})) + .collect(Collectors.toList()); + break; + case "oa_invoice": + List invoiceRespVOS = bpmOAInvoiceService.getListByProcessInstanceIds(processInstanceIds); + respVOs = invoiceRespVOS.stream() + .map(item -> objectMapper.convertValue(item, new TypeReference>(){})) + .collect(Collectors.toList()); + break; + } + + return success(new PageResult<>(respVOs, tasks.getTotal())); + } catch (Exception e) { + log.error("json parse err,json:{}", processInstanceIds, e); + return success(null); + } + } } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmCrmTaskPageReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmCrmTaskPageReqVO.java new file mode 100644 index 00000000..584f0c4d --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmCrmTaskPageReqVO.java @@ -0,0 +1,20 @@ +package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task; + +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; + +@Schema(description = "管理后台 - CRM流程任务的分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class BpmCrmTaskPageReqVO extends PageParam { + + @Schema(description = "流程定义编号", example = "oa_contract") + private String processDefinitionId; + + @Schema(description = "是否是待办", example = "true") + private Boolean isTodo; +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/BpmOAContractDO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/BpmOAContractDO.java index 3e191495..c6ec9f50 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/BpmOAContractDO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/BpmOAContractDO.java @@ -9,6 +9,7 @@ import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; import lombok.*; +import java.math.BigDecimal; import java.time.LocalDate; import java.util.List; @@ -21,13 +22,12 @@ import java.util.List; @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) -//@Builder @NoArgsConstructor @AllArgsConstructor public class BpmOAContractDO extends BaseDO { /** - * 出差表单主键 + * 合同审批表单主键 */ @TableId private Long id; @@ -39,6 +39,11 @@ public class BpmOAContractDO extends BaseDO { */ private Long userId; + /** + * 合同类型 | 字典值 bpm_oa_contract_type + */ + private Integer contractType; + /** * 合同名称 */ @@ -47,7 +52,7 @@ public class BpmOAContractDO extends BaseDO { /** * 合同编号 */ - private String contractNumber; + private String contractNo; /** * 签约日期 @@ -55,28 +60,82 @@ public class BpmOAContractDO extends BaseDO { private LocalDate signingDate; /** - * 我方公司名称 + * 客户编号 */ - private String mCompanyName; + private Long customerId; /** - * 我方负责人 + * 客户名称 */ - private String mHeadName; + private String customerName; /** - * 对方公司名称 + * 客户签约人(联系人ID) */ - private String oCompanyName; + private Long contactsId; /** - * 对方负责人 + * 客户签约人(联系人)名称 */ - private String oHeadName; + private String contactsName; /** - * 用章的结果 - * + * 签约公司编号 + */ + private Long companyId; + + /** + * 签约人用户编号 + */ + private Long signatoryId; + + /** + * 合同金额 + */ + private BigDecimal contractMoney; + + /** + * 已收/已付金额 + */ + private BigDecimal returnMoney; + + /** + * 已开票金额 + */ + private BigDecimal invoiceMoney; + + /** + * 产品总金额 + */ + private BigDecimal totalPrice; + + /** + * 整单优惠金额 + */ + private BigDecimal discountRate; + + /** + * 商机ID + */ + private Long businessId; + + /** + * 合同有效期开始时间 + */ + private LocalDate startDate; + + /** + * 合同有效期结束时间 + */ + private LocalDate endDate; + + /** + * 合同状态 | 1已签约 2过期 + */ + private Integer status; + + /** + * 审批结果 * 枚举 {@link BpmProcessInstanceResultEnum} * 考虑到简单,所以直接复用了 BpmProcessInstanceResultEnum 枚举,也可以自己定义一个枚举哈 */ diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/BpmOAInvoiceDO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/BpmOAInvoiceDO.java index 764f590c..f1e180f1 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/BpmOAInvoiceDO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/BpmOAInvoiceDO.java @@ -44,9 +44,44 @@ public class BpmOAInvoiceDO extends BaseDO { private LocalDate invoiceDate; /** - * 项目编号 + * 关联合同业务编号 */ - private Long projectId; + private Long contractId; + + /** + * 关联合同业务的流程实例编号 + */ + private String contractInstanceId; + + /** + * 客户编号 + */ + private Long customerId; + + /** + * 开票主体 + */ + private String invoiceBody; + + /** + * 发票抬头 + */ + private String invoiceName; + + /** + * 抬头类型 | 1企业2个人3事业单位 + */ + private Integer invoiceIssue; + + /** + * 发票类型 | 1普票 2专票 + */ + private Integer invoiceType; + + /** + * 统一社会信用代码 + */ + private String registerNo; /** * 开票金额 @@ -58,16 +93,6 @@ public class BpmOAInvoiceDO extends BaseDO { */ private String content; - /** - * 开票单位名称 - */ - private String unitName; - - /** - * 开票单位纳税人识别号 - */ - private String unitTin; - /** * 开票单位地址 */ @@ -89,9 +114,14 @@ public class BpmOAInvoiceDO extends BaseDO { private String unitBankNo; /** - * 关联合同业务流程编号 + * 接收发票邮箱 */ - private String contractInstanceId; + private String email; + + /** + * 开票状态 | 0未开票 1已开票 + */ + private Integer status; /** * 申请的结果 diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/oa/BpmOAContractMapper.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/oa/BpmOAContractMapper.java index f91205eb..98c6959b 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/oa/BpmOAContractMapper.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/oa/BpmOAContractMapper.java @@ -1,8 +1,18 @@ package cn.iocoder.yudao.module.bpm.dal.mysql.oa; +import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.contract.BpmOAContractPageReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.contract.BpmOAContractRespVO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.contract.ContractStatisticsRespVO; import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAContractDO; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Objects; /** * 合同审批 Mapper @@ -12,4 +22,50 @@ import org.apache.ibatis.annotations.Mapper; */ @Mapper public interface BpmOAContractMapper extends BaseMapperX { + default PageResult selectPage(BpmOAContractPageReqVO pageReqVO, + Long userId) { + + MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); + query.selectAll(BpmOAContractDO.class); + query.selectAs("u.nickname", BpmOAContractRespVO::getSignatoryName); + query.selectAs("u1.nickname", BpmOAContractRespVO::getCreateName); + query.selectAs("d.name", BpmOAContractRespVO::getCompanyName); + query.leftJoin("system_users u on u.id = t.signatory_id"); + query.leftJoin("system_users u1 on u1.id = t.creator"); + query.leftJoin("system_dept d on d.id = t.company_id"); + query.eqIfPresent(BpmOAContractDO::getContractType, pageReqVO.getContractType()); + query.likeIfPresent(BpmOAContractDO::getContractName, pageReqVO.getContractName()); + query.likeIfPresent(BpmOAContractDO::getContractNo, pageReqVO.getContractNo()); + query.likeIfPresent(BpmOAContractDO::getCustomerName, pageReqVO.getCustomerName()); + query.eqIfPresent(BpmOAContractDO::getStatus, pageReqVO.getStatus()); + query.eqIfPresent(BpmOAContractDO::getResult, pageReqVO.getResult()); + query.apply(Objects.nonNull(pageReqVO.getSignatoryName()),"u.nickname Like CONCAT('%', {0}, '%')", pageReqVO.getSignatoryName()); + query.apply(Objects.nonNull(pageReqVO.getCreateName()),"u1.nickname Like CONCAT('%', {0}, '%')", pageReqVO.getCreateName()); + if ("my".equals(pageReqVO.getRelation())) { + query.eq(BpmOAContractDO::getUserId, userId); + }else if ("sub".equals(pageReqVO.getRelation())){ + query.innerJoin("(" + + "\tSELECT DISTINCT\n" + + "\t\tu.id \n" + + "\tFROM\n" + + "\t\tsystem_users u\n" + + "\t\tINNER JOIN system_dept d ON d.leader_user_id = "+ userId +"\n" + + "\t\tINNER JOIN system_dept d1 ON d1.flag LIKE CONCAT( '%', d.id, '-' ) \n" + + "\t\tOR d1.flag LIKE CONCAT( '%-', d.id, '-%' ) \n" + + "\t\tOR d1.flag LIKE CONCAT( '-', d.id, '%' ) \n" + + "\tWHERE\n" + + "\t\tu.dept_id = d1.id \n" + + "\t\tAND u.STATUS = 0 \n" + + "\t) subordinate ON subordinate.id = t.user_id"); + } + query.orderByDesc(BpmOAContractDO::getCreateTime); + + return selectJoinPage(pageReqVO, BpmOAContractRespVO.class, query); + } + + ContractStatisticsRespVO selectContractStatistics(@Param("userId") Long userId, + @Param("relation") String relation); + + List selectContractStatisticsListByUserIds(@Param("userIds") List userIds, + @Param("createTime") LocalDateTime[] createTime); } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/oa/BpmOAInvoiceMapper.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/oa/BpmOAInvoiceMapper.java index 5da0887f..909deaef 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/oa/BpmOAInvoiceMapper.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/oa/BpmOAInvoiceMapper.java @@ -1,9 +1,61 @@ package cn.iocoder.yudao.module.bpm.dal.mysql.oa; +import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.invoice.BpmOAInvoicePageReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.invoice.BpmOAInvoiceRespVO; +import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAContractDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAInvoiceDO; import org.apache.ibatis.annotations.Mapper; +import java.util.List; +import java.util.Objects; + @Mapper public interface BpmOAInvoiceMapper extends BaseMapperX { + + default PageResult selectPage(BpmOAInvoicePageReqVO pageReqVO, + Long userId) { + + MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); + query.selectAll(BpmOAInvoiceDO.class); + query.selectAs(BpmOAContractDO::getContractName, BpmOAInvoiceRespVO::getContractName); + query.selectAs(BpmOAContractDO::getCustomerName, BpmOAInvoiceRespVO::getCustomerName); + query.leftJoin(BpmOAContractDO.class, "c", BpmOAContractDO::getId, BpmOAInvoiceDO::getContractId); + query.apply(Objects.nonNull(pageReqVO.getContractName()), "c.contract_name LIKE CONCAT('%', {0}, '%')", pageReqVO.getContractName()); + query.apply(Objects.nonNull(pageReqVO.getCustomerName()), "c.customer_name LIKE CONCAT('%', {0}, '%')", pageReqVO.getCustomerName()); + if ("my".equals(pageReqVO.getRelation())) { + query.eq(BpmOAContractDO::getUserId, userId); + }else if ("sub".equals(pageReqVO.getRelation())){ + query.innerJoin("(" + + "\tSELECT DISTINCT\n" + + "\t\tu.id \n" + + "\tFROM\n" + + "\t\tsystem_users u\n" + + "\t\tINNER JOIN system_dept d ON d.leader_user_id = "+ userId +"\n" + + "\t\tINNER JOIN system_dept d1 ON d1.flag LIKE CONCAT( '%', d.id, '-' ) \n" + + "\t\tOR d1.flag LIKE CONCAT( '%-', d.id, '-%' ) \n" + + "\t\tOR d1.flag LIKE CONCAT( '-', d.id, '%' ) \n" + + "\tWHERE\n" + + "\t\tu.dept_id = d1.id \n" + + "\t\tAND u.STATUS = 0 \n" + + "\t) subordinate ON subordinate.id = t.user_id"); + } + query.orderByDesc(BpmOAInvoiceDO::getCreateTime); + + return selectJoinPage(pageReqVO, BpmOAInvoiceRespVO.class, query); + } + + default List selectListByProcessInstanceIds(List processInstanceIds) { + + MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); + query.selectAll(BpmOAInvoiceDO.class); + query.selectAs(BpmOAContractDO::getContractName, BpmOAInvoiceRespVO::getContractName); + query.selectAs(BpmOAContractDO::getCustomerName, BpmOAInvoiceRespVO::getCustomerName); + query.leftJoin(BpmOAContractDO.class, BpmOAContractDO::getId, BpmOAInvoiceDO::getContractId); + query.inIfPresent(BpmOAInvoiceDO::getProcessInstanceId, processInstanceIds); + + return selectJoinList(BpmOAInvoiceRespVO.class, query); + } } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/oa/BpmOALeaveMapper.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/oa/BpmOALeaveMapper.java index e65608b1..564b0c0e 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/oa/BpmOALeaveMapper.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/oa/BpmOALeaveMapper.java @@ -1,6 +1,6 @@ package cn.iocoder.yudao.module.bpm.dal.mysql.oa; -import cn.iocoder.yudao.module.bpm.api.oa.vo.BpmOALeaveRpcVO; +import cn.iocoder.yudao.module.bpm.api.oa.vo.leave.BpmOALeaveRpcVO; import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.leave.BpmOALeavePageReqVO; import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOALeaveDO; import cn.iocoder.yudao.framework.common.pojo.PageResult; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/task/BpmTaskExtMapper.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/task/BpmTaskExtMapper.java index ce80b2f5..27d926c0 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/task/BpmTaskExtMapper.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/task/BpmTaskExtMapper.java @@ -1,7 +1,9 @@ package cn.iocoder.yudao.module.bpm.dal.mysql.task; +import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmCrmTaskPageReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskTodoPageReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskTodoPageRespVO; import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO; @@ -11,6 +13,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; +import java.util.Arrays; import java.util.Collection; import java.util.List; @@ -61,4 +64,15 @@ public interface BpmTaskExtMapper extends BaseMapperX { List selectTodoTaskDept(@Param("reqVO") BpmTaskTodoPageReqVO pageVO, @Param("userId") Long userId); + + default PageResult selectCrmPage(Long userId, BpmCrmTaskPageReqVO pageReqVO) { + + List approveOrReject = Arrays.asList(BpmProcessInstanceResultEnum.APPROVE.getResult(), BpmProcessInstanceResultEnum.REJECT.getResult()); + + return selectPage(pageReqVO, new LambdaQueryWrapperX() + .eq(BpmTaskExtDO::getAssigneeUserId, userId) + .likeIfPresent(BpmTaskExtDO::getProcessDefinitionId, pageReqVO.getProcessDefinitionId()) + .eq(pageReqVO.getIsTodo(), BpmTaskExtDO::getResult, BpmProcessInstanceResultEnum.PROCESS.getResult()) + .in(!pageReqVO.getIsTodo(), BpmTaskExtDO::getResult, approveOrReject)); + } } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/rpc/config/RpcConfiguration.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/rpc/config/RpcConfiguration.java index 033144ef..0bbb5ef9 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/rpc/config/RpcConfiguration.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/rpc/config/RpcConfiguration.java @@ -1,7 +1,12 @@ package cn.iocoder.yudao.module.bpm.framework.rpc.config; +import cn.iocoder.yudao.module.hrm.api.crmbusiness.BusinessApi; +import cn.iocoder.yudao.module.hrm.api.crmcontract.ContractApi; +import cn.iocoder.yudao.module.hrm.api.crmcustomer.CrmCustomerApi; import cn.iocoder.yudao.module.infra.api.config.ConfigApi; import cn.iocoder.yudao.module.infra.api.file.FileApi; +import cn.iocoder.yudao.module.product.api.storeproduct.StoreProductApi; +import cn.iocoder.yudao.module.product.api.storeproductattrvalue.StoreProductAttrValueApi; import cn.iocoder.yudao.module.system.api.assetreceive.AssetReceiveApi; import cn.iocoder.yudao.module.system.api.assets.AssetsApi; import cn.iocoder.yudao.module.system.api.assets.AssetsTypeApi; @@ -34,7 +39,8 @@ import org.springframework.context.annotation.Configuration; @EnableFeignClients(clients = {FileApi.class, RoleApi.class, DeptApi.class, PostApi.class, AdminUserApi.class, SmsSendApi.class, DictDataApi.class, NotifyMessageSendApi.class, SubscribeMessageSendApi.class, SocialClientApi.class, UsersExtApi.class, AttendanceApi.class, BankApi.class, ConfigApi.class, PositionApi.class, SupplierApi.class, AssetsApi.class, AssetsTypeApi.class, AssetReceiveApi.class, AttendanceApi.class, AttendanceGroupApi.class, WorkOvertimeApi.class, HolidayApi.class, - RentalOrderApi.class, RentalDepositRecordApi.class, ProjectApi.class, RentalItemsRecordApi.class,AdminOauthUserOtherInfoApi.class + RentalOrderApi.class, RentalDepositRecordApi.class, ProjectApi.class, RentalItemsRecordApi.class,AdminOauthUserOtherInfoApi.class, StoreProductAttrValueApi.class, StoreProductApi.class, + ContractApi.class, BusinessApi.class, CrmCustomerApi.class }) public class RpcConfiguration { } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAContractService.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAContractService.java index 41c267c5..76ede328 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAContractService.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAContractService.java @@ -1,15 +1,22 @@ 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.contract.BpmOAContractVO; import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.contract.BpmOAContractCreateReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.contract.BpmOAContractPageReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.contract.BpmOAContractRespVO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.contract.ContractStatisticsRespVO; import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAContractDO; import javax.validation.Valid; +import java.math.BigDecimal; +import java.time.LocalDateTime; import java.util.List; public interface BpmOAContractService { /** - * 创建出差申请 + * 创建合同申请 * * @param userId 用户编号 * @param createReqVO 创建信息 @@ -18,15 +25,28 @@ public interface BpmOAContractService { Long createContract(Long userId, @Valid BpmOAContractCreateReqVO createReqVO); /** - * 更新出差申请的状态 + * 更新合同 + * @param updateReqVO 更新信息 + */ + void updateContract(BpmOAContractDO updateReqVO); + + /** + * 修改开票金额 + * @param contractId 合同编号 + * @param amount 开票金额 + */ + void updateInvoiceMoney(Long contractId, BigDecimal amount); + + /** + * 更新合同申请的状态 * * @param id 编号 * @param result 结果 */ - void updateContractResult(Long id, Integer result); + void updateContractResult(String processInstanceId, Long id, Integer result); /** - * 获得出差申请 + * 获得合同申请 * * @param id 编号 * @return 出差申请 @@ -34,7 +54,7 @@ public interface BpmOAContractService { BpmOAContractDO getContract(Long id); /** - * 获得指定出差申请 + * 获得指定合同申请 * @param processInstanceId 流程实例编号 * @return 出差申请 */ @@ -46,4 +66,42 @@ public interface BpmOAContractService { * @return 合同列表 */ List getListByDeptId(List userIds); + + /** + * 获得合同分页 + * @param pageReqVO 分页参数 + * @return 分页列表 + */ + PageResult getContractPage(BpmOAContractPageReqVO pageReqVO); + + /** + * 获得指定流程实例的合同申请列表 + * @param processInstanceIds 流程实例编号集合 + * @return 合同列表 + */ + List getListByProcessInstanceIds(List processInstanceIds); + + /** + * 获得合同统计信息 + * @param userId 用户编号 + * @param relation 查询类型 + * @return 统计信息 + */ + ContractStatisticsRespVO getContractStatistics(Long userId, String relation); + + /** + * 获得指定用户的合同统计信息列表 + * + * @param userIds 用户编号集合 + * @param createTime 创建时间 + * @return 合同统计信息列表 + */ + List getContractStatisticsListByUserIds(List userIds, LocalDateTime[] createTime); + + /** + * 获得合同列表 + * @param respVO 参数列表 + * @return 合同列表 + */ + List getContractList(BpmOAContractVO respVO); } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAContractServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAContractServiceImpl.java index 789fbd23..7fc2ef72 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAContractServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAContractServiceImpl.java @@ -1,26 +1,62 @@ package cn.iocoder.yudao.module.bpm.service.oa; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollectionUtil; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -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.contract.BpmOAContractCreateReqVO; +import cn.hutool.core.util.NumberUtil; +import cn.iocoder.yudao.framework.common.enums.ShopCommonEnum; +import cn.iocoder.yudao.framework.common.exception.ErrorCode; +import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.UploadUserFile; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.bpm.api.oa.vo.contract.BpmOAContractVO; +import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.contract.*; import cn.iocoder.yudao.module.bpm.convert.oa.BpmOAContractConvert; import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAContractDO; import cn.iocoder.yudao.module.bpm.dal.mysql.oa.BpmOAContractMapper; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; import cn.iocoder.yudao.module.bpm.service.task.BpmHistoryProcessInstanceService; +import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService; +import cn.iocoder.yudao.module.hrm.api.crmcontract.ContractApi; +import cn.iocoder.yudao.module.hrm.api.crmcontract.dto.CrmContractProductDTO; +import cn.iocoder.yudao.module.hrm.api.crmcustomer.CrmCustomerApi; +import cn.iocoder.yudao.module.hrm.api.crmcustomer.dto.CrmCustomerDTO; +import cn.iocoder.yudao.module.product.api.storeproduct.StoreProductApi; +import cn.iocoder.yudao.module.product.api.storeproductattrvalue.StoreProductAttrValueApi; +import cn.iocoder.yudao.module.product.api.storeproductattrvalue.dto.StoreProductAttrValueApiDTO; +import cn.iocoder.yudao.module.product.api.storeproductattrvalue.vo.StoreProductAttrValueApiVO; +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.update.LambdaUpdateWrapper; +import lombok.extern.slf4j.Slf4j; +import org.flowable.engine.runtime.ProcessInstance; +import org.redisson.api.RLock; +import org.redisson.api.RedissonClient; +import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; +import java.util.stream.Stream; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.SECOND_MILLIS; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.OA_CONTRACT_NOT_EXISTS; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.PRODUCT_STOCK_LESS; /** * OA 合同审批 Service 实现类 @@ -30,6 +66,7 @@ import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.OA_CONTRACT_N */ @Service @Validated +@Slf4j public class BpmOAContractServiceImpl extends BpmOABaseService implements BpmOAContractService{ /** @@ -41,28 +78,79 @@ public class BpmOAContractServiceImpl extends BpmOABaseService implements BpmOAC private BpmOAContractMapper contractMapper; @Resource - private BpmProcessInstanceApi processInstanceApi; + private BpmProcessInstanceService processInstanceService; @Resource private BpmHistoryProcessInstanceService historyProcessInstanceService; + @Resource + private RedissonClient redissonClient; + + @Resource + private StringRedisTemplate stringRedisTemplate; + + @Resource + private AdminUserApi userApi; + + @Resource + private DeptApi deptApi; + + @Resource + private StoreProductAttrValueApi storeProductAttrValueApi; + + @Resource + private StoreProductApi storeProductApi; + + @Resource + private ContractApi contractApi; + + @Resource + private CrmCustomerApi customerApi; + @Override public Long createContract(Long userId, BpmOAContractCreateReqVO createReqVO) { + // 新增合同DO + BpmOAContractDO contract = BpmOAContractConvert.INSTANCE.convert(createReqVO) + .setUserId(userId) + .setResult(BpmProcessInstanceResultEnum.PROCESS.getResult()) + .setStatus(1); - //插入OA 出差申请 - BpmOAContractDO contract = BpmOAContractConvert.INSTANCE.convert(createReqVO).setUserId(userId) - .setResult(BpmProcessInstanceResultEnum.PROCESS.getResult()); - contract.setMCompanyName(createReqVO.getmCompanyName()); - contract.setMHeadName(createReqVO.getmHeadName()); - contract.setOCompanyName(createReqVO.getoCompanyName()); - contract.setOHeadName(createReqVO.getoHeadName()); + // 自动生成合同编号 + // 获取当前日期 + String now = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")); + String key = "bpm_contract_no_" + now; + // 获取分布式锁 + String LOCK_KEY = "lock:rental:order:create"; + RLock lock = redissonClient.getLock(LOCK_KEY); + try { + lock.lock(); + // redis 获取当天订单号 + String no = stringRedisTemplate.opsForValue().get(key); + if (no != null) { + no = "HT" + now + String.format("%03d", Integer.parseInt(no) + 1); + // redis 缓存订单号 + stringRedisTemplate.opsForValue().increment(key, 1); + }else { + no = "HT" + now + String.format("%03d", 1); + // redis 缓存订单号 + stringRedisTemplate.opsForValue().set(key, "1", 1, TimeUnit.DAYS); + } + // 设置合同编号 + contract.setContractNo(no); + } catch (Exception ex) { + log.error("[messageResend][执行异常]", ex); + } finally { + lock.unlock(); + } + + //插入OA 合同审批 contractMapper.insert(contract) ; // 发起 BPM 流程 Map processInstanceVariables = new HashMap<>(); - String processInstanceId = processInstanceApi.createProcessInstance(userId, + String processInstanceId = processInstanceService.createProcessInstance(userId, new BpmProcessInstanceCreateReqDTO().setProcessDefinitionKey(PROCESS_KEY) - .setVariables(processInstanceVariables).setBusinessKey(String.valueOf(contract.getId()))).getCheckedData(); + .setVariables(processInstanceVariables).setBusinessKey(String.valueOf(contract.getId()))); // 将工作流的编号,更新到 OA 请假单中 contractMapper.updateById(new BpmOAContractDO().setId(contract.getId()).setProcessInstanceId(processInstanceId)); @@ -78,20 +166,74 @@ public class BpmOAContractServiceImpl extends BpmOABaseService implements BpmOAC if (fileItems != null && !fileItems.isEmpty()) { uploadBpmFileProcessInstanceId(processInstanceId,fileItems) ; } + + // 同步插入关联产品记录 + createContractProductList(contract.getId(), createReqVO.getContractProducts()); + return contract.getId(); } @Override - public void updateContractResult(Long id, Integer result) { + public void updateContract(BpmOAContractDO updateReqVO) { + validateLeaveExists(updateReqVO.getId()); - validateLeaveExists(id); - contractMapper.updateById(new BpmOAContractDO().setId(id).setResult(result)); + //更新合同 + contractMapper.updateById(updateReqVO); } - private void validateLeaveExists(Long id) { - if (contractMapper.selectById(id) == null) { + @Override + public void updateInvoiceMoney(Long contractId, BigDecimal amount) { + + contractMapper.update(null, new LambdaUpdateWrapper() + .setSql("invoice_money = invoice_money - " + amount) + .eq(BpmOAContractDO::getId, contractId)); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateContractResult(String processInstanceId, Long id, Integer result) { + + BpmOAContractDO contract = validateLeaveExists(id); + contractMapper.updateById(new BpmOAContractDO().setId(id).setResult(result)); + + //审核通过 (最后节点) + if (BpmProcessInstanceResultEnum.APPROVE.getResult().equals(result)) { + + ProcessInstance instance = processInstanceService.getProcessInstance(processInstanceId); + + if (instance.isEnded()) { + + // 审批通过后,更新客户成交信息 + customerApi.updateCustomerPurchaseTotal(new CrmCustomerDTO() + .setId(contract.getCustomerId()) + .setDealStatus(ShopCommonEnum.IS_STATUS_1.getValue()) + .setDealTime(LocalDateTime.now()) + .setPurchaseTotal(contract.getContractMoney())); + } + } + + // -- 自己取消 + // -- 审核拒绝 + if (BpmProcessInstanceResultEnum.REJECT.getResult().equals(result) + || BpmProcessInstanceResultEnum.CANCEL.getResult().equals(result) + || BpmProcessInstanceResultEnum.BACK.getResult().equals(result)) { + + // 获取合同商品详情 + List productDTOS = contractApi.getProduct(id).getCheckedData(); + + for (CrmContractProductDTO product : productDTOS) { + // 回复商品库存 + this.inProductStock(product.getNums(), product.getProductId(), product.getProductAttrUnique()); + } + } + } + + private BpmOAContractDO validateLeaveExists(Long id) { + BpmOAContractDO contractDO = contractMapper.selectById(id); + if (contractDO == null) { throw exception(OA_CONTRACT_NOT_EXISTS); } + return contractDO; } @Override @@ -115,6 +257,169 @@ public class BpmOAContractServiceImpl extends BpmOABaseService implements BpmOAC return contractMapper.selectList(new LambdaQueryWrapperX() .eq(BpmOAContractDO::getResult, BpmProcessInstanceResultEnum.APPROVE.getResult()) - .inIfPresent(BpmOAContractDO::getUserId, userIds)); + .inIfPresent(BpmOAContractDO::getUserId, userIds) + .eq(BpmOAContractDO::getContractType, 1) + .apply("return_money > invoice_money")); + } + + @Override + public PageResult getContractPage(BpmOAContractPageReqVO pageReqVO) { + + return contractMapper.selectPage(pageReqVO, getLoginUserId()); + } + + @Override + public List getListByProcessInstanceIds(List processInstanceIds) { + + List bpmOAContractDOS = contractMapper.selectList(new LambdaQueryWrapperX() + .inIfPresent(BpmOAContractDO::getProcessInstanceId, processInstanceIds)); + + List respVOS = BeanUtils.toBean(bpmOAContractDOS, BpmOAContractRespVO.class); + // 获取用户和签约人信息 + List userIds = bpmOAContractDOS.stream() + .flatMap(item -> Stream.of(item.getUserId(), item.getSignatoryId())) + .collect(Collectors.toList()); + Map userMap = userApi.getUserMap(userIds); + + // 获取公司信息 + Map deptMap = deptApi.getDeptMap(convertSet(bpmOAContractDOS, BpmOAContractDO::getCompanyId)); + + respVOS.forEach(respVO -> { + // 设置创建人、签约人名称 + respVO.setSignatoryName(userMap.get(respVO.getSignatoryId()) != null ? userMap.get(respVO.getSignatoryId()).getNickname() : null); + respVO.setCreateName(userMap.get(respVO.getUserId()) != null ? userMap.get(respVO.getUserId()).getNickname() : null); + + // 设置公司名称 + respVO.setCompanyName(deptMap.get(respVO.getCompanyId()) != null ? deptMap.get(respVO.getCompanyId()).getName() : null); + }); + + return respVOS; + } + + @Override + public ContractStatisticsRespVO getContractStatistics(Long userId, String relation) { + + ContractStatisticsRespVO respVO = contractMapper.selectContractStatistics(userId, relation); + + // 设置数量、金额百分比 + respVO.setCountPercentage(calculatePercentageChange(respVO.getTodayAdditions(), respVO.getYesterdayAdditions())); + respVO.setMoneyPercentage(calculatePercentageChange(respVO.getTodayAddMoney(), respVO.getYesterdayAddMoney())); + return respVO; + } + + @Override + public List getContractStatisticsListByUserIds(List userIds, LocalDateTime[] createTime) { + + return contractMapper.selectContractStatisticsListByUserIds(userIds, createTime); + } + + @Override + public List getContractList(BpmOAContractVO respVO) { + + Date[] dateArray = new Date[] { respVO.getStarTime(), respVO.getEndTime() }; + + return contractMapper.selectList(new LambdaQueryWrapperX() + .inIfPresent(BpmOAContractDO::getUserId, respVO.getUserId()) + .eqIfPresent(BpmOAContractDO::getContractType, respVO.getContractType()) + .betweenIfPresent(BpmOAContractDO::getSigningDate, dateArray) + .eq(BpmOAContractDO::getResult, BpmProcessInstanceResultEnum.APPROVE.getResult())); + } + + public static BigDecimal calculatePercentageChange(Object today, Object yesterday) { + + // 转换为 BigDecimal 进行高精度计算 + BigDecimal bigToday = new BigDecimal(today.toString()); + BigDecimal bigYesterday = new BigDecimal(yesterday.toString()); + + if (bigYesterday.compareTo(BigDecimal.ZERO) == 0) { + return BigDecimal.ZERO; + } + + // 计算百分比变化 + BigDecimal difference = bigToday.subtract(bigYesterday); // a - b + BigDecimal percentageChange = difference.divide(bigYesterday, 2, RoundingMode.HALF_UP); // (a - b) / b + + // 转为百分比并返回 + return percentageChange.multiply(new BigDecimal(100)); // (result) * 100 + } + + private void createContractProductList(Long contractId, List list) { + List storeProductAttrValueList = new ArrayList<>(); + if (CollUtil.isNotEmpty(list)) { + List productIds = list.stream().map(CrmContractProductVO::getProductId).collect(Collectors.toList()); + List productAttrUnique = list.stream().map(CrmContractProductVO::getProductAttrUnique).collect(Collectors.toList()); + storeProductAttrValueList = storeProductAttrValueApi.getStoreProductAttrValueList(new StoreProductAttrValueApiDTO() + .setProductIds(productIds) + .setUniques(productAttrUnique)).getCheckedData(); + } + Map> map = storeProductAttrValueList.stream().collect(Collectors.groupingBy(a -> a.getProductId() + "_" + a.getUnique())); + list.forEach(o -> { + o.setContractId(contractId); + //库存处理 + List storeProductAttrValueApiVOS = map.get(o.getProductId() + "_" + o.getProductAttrUnique()); + + int count = 0; + if (CollUtil.isNotEmpty(storeProductAttrValueApiVOS)) { + count = storeProductAttrValueApiVOS.stream().mapToInt(StoreProductAttrValueApiVO::getStock).sum(); + } + if (NumberUtil.compare(count, o.getNums()) < 0) { + throw exception(new ErrorCode(202408250, "该商品ID:" + o.getProductId() + "库存不足")); + } + // TODO: 2024/11/21 这里的库存扣件完后 - 如果审批不通过 库存退回 + this.decProductStock(o.getNums(), o.getProductId(), o.getProductAttrUnique()); + }); + + contractApi.createProduct(BeanUtils.toBean(list, CrmContractProductDTO.class)); + } + + /** + * 减少库存 + * + * @param num 数量 + * @param productId 产品ID + * @param unique sku唯一值 + */ + private void decProductStock(int num, Long productId, String unique) { + String lockKey = productId + "_" + unique; + // -- 分布式锁 + RLock lock = redissonClient.getLock(lockKey); + try { + lock.lock(120 * SECOND_MILLIS, TimeUnit.MILLISECONDS); + // 执行逻辑 + int res = 0; + res = storeProductAttrValueApi.decStockIncSales(num, productId, unique).getCheckedData(); + + if (res == 0) { + throw exception(PRODUCT_STOCK_LESS); + } + + int product = storeProductApi.decStockIncSales(num, productId).getCheckedData(); + if (product == 0) { + throw exception(PRODUCT_STOCK_LESS); + } + } finally { + lock.unlock(); + } + } + + /** + * 加库存 + * + * @param num 数量 + * @param productId 产品ID + * @param unique sku唯一值 + */ + private void inProductStock(int num, Long productId, String unique) { + String lockKey = productId + "_" + unique; + // -- 分布式锁 + RLock lock = redissonClient.getLock(lockKey); + try { + lock.lock(120 * SECOND_MILLIS, TimeUnit.MILLISECONDS); + // 执行逻辑 + storeProductAttrValueApi.inStockIncSales(num, productId, unique).getCheckedData(); + storeProductApi.inStockIncSales(num, productId).getCheckedData(); + } finally { + lock.unlock(); + } } } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAInvoiceService.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAInvoiceService.java index 0c89c696..d8b70500 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAInvoiceService.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAInvoiceService.java @@ -1,9 +1,13 @@ package cn.iocoder.yudao.module.bpm.service.oa; +import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.invoice.BpmOAInvoiceCreateReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.invoice.BpmOAInvoicePageReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.invoice.BpmOAInvoiceRespVO; import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAInvoiceDO; import javax.validation.Valid; +import java.util.List; /** * 开票申请 Service 接口 @@ -44,4 +48,18 @@ public interface BpmOAInvoiceService { * @return 开票申请 */ BpmOAInvoiceDO getByProcessInstanceId(String processInstanceId); + + /** + * 获得开票申请分页列表 + * @param pageReqVO 分页参数 + * @return 开票分页 + */ + PageResult getInvoicePage(BpmOAInvoicePageReqVO pageReqVO); + + /** + * 获得开票申请列表 + * @param processInstanceIds 流程实例编号 + * @return 开票申请列表 + */ + List getListByProcessInstanceIds(List processInstanceIds); } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAInvoiceServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAInvoiceServiceImpl.java index 37ef8ccb..4261a384 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAInvoiceServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOAInvoiceServiceImpl.java @@ -1,25 +1,36 @@ package cn.iocoder.yudao.module.bpm.service.oa; import cn.hutool.core.collection.CollectionUtil; +import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.UploadUserFile; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi; import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.invoice.BpmOAInvoiceCreateReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.invoice.BpmOAInvoicePageReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.invoice.BpmOAInvoiceRespVO; +import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAContractDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAInvoiceDO; import cn.iocoder.yudao.module.bpm.dal.mysql.oa.BpmOAInvoiceMapper; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; import cn.iocoder.yudao.module.bpm.service.task.BpmHistoryProcessInstanceService; +import org.redisson.api.RLock; +import org.redisson.api.RedissonClient; 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.concurrent.TimeUnit; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.OA_INVOICE_NOT_EXISTS; +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.SECOND_MILLIS; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; /** * OA 开票申请 Service 实现类 @@ -45,12 +56,23 @@ public class BpmOAInvoiceServiceImpl extends BpmOABaseService implements BpmOAIn @Resource private BpmHistoryProcessInstanceService historyProcessInstanceService; + @Resource + private BpmOAContractService contractService; + + @Resource + private RedissonClient redissonClient; + @Override + @Transactional(rollbackFor = Exception.class) public Long createInvoice(Long userId, BpmOAInvoiceCreateReqVO createReqVO) { + // 校验关联合同 是否还有开票余额 + validateContractBalance(createReqVO.getContractId(), createReqVO.getAmount()); + //插入OA 开票申请 BpmOAInvoiceDO invoice = BeanUtils.toBean(createReqVO, BpmOAInvoiceDO.class) .setUserId(userId) + .setStatus(0) .setResult(BpmProcessInstanceResultEnum.PROCESS.getResult()); invoiceMapper.insert(invoice) ; @@ -73,20 +95,75 @@ public class BpmOAInvoiceServiceImpl extends BpmOABaseService implements BpmOAIn if (fileItems != null && !fileItems.isEmpty()) { uploadBpmFileProcessInstanceId(processInstanceId,fileItems) ; } + return invoice.getId(); } + private void validateContractBalance(Long contractId, BigDecimal amount) { + + String lockKey = "bpm:invoice:create_" + contractId; + // -- 分布式锁 + RLock lock = redissonClient.getLock(lockKey); + try { + lock.lock(120 * SECOND_MILLIS, TimeUnit.MILLISECONDS); + + // 获取合同信息 + BpmOAContractDO contractDO = contractService.getContract(contractId); + if (contractDO == null) { + throw exception(OA_CONTRACT_NOT_EXISTS); + } + + // 判断是否还有开票余额 + BigDecimal balance = contractDO.getReturnMoney().subtract(contractDO.getInvoiceMoney()); + if (balance.compareTo(amount) <= 0) { + throw exception(OA_CONTRACT_INVOICE_AMOUNT_LACK); + } + + // 余额足够时 更新合同的开票金额 + contractService.updateContract(new BpmOAContractDO() + .setId(contractDO.getId()) + .setInvoiceMoney(contractDO.getInvoiceMoney().add(amount))); + + } finally { + lock.unlock(); + } + } + @Override public void updateInvoiceResult(Long id, Integer result) { - validateLeaveExists(id); + BpmOAInvoiceDO invoiceDO = validateLeaveExists(id); invoiceMapper.updateById(new BpmOAInvoiceDO().setId(id).setResult(result)); + + // -- 自己取消 + // -- 审核拒绝 + if (BpmProcessInstanceResultEnum.REJECT.getResult().equals(result) + || BpmProcessInstanceResultEnum.CANCEL.getResult().equals(result) + || BpmProcessInstanceResultEnum.BACK.getResult().equals(result)) { + + String lockKey = "bpm:invoice:create_" + invoiceDO.getContractId(); + // -- 分布式锁 + RLock lock = redissonClient.getLock(lockKey); + try { + lock.lock(120 * SECOND_MILLIS, TimeUnit.MILLISECONDS); + + // 取消时,回复合同之前的开票金额 + contractService.updateInvoiceMoney(invoiceDO.getContractId(), invoiceDO.getAmount()); + + } finally { + lock.unlock(); + } + + } } - private void validateLeaveExists(Long id) { - if (invoiceMapper.selectById(id) == null) { + private BpmOAInvoiceDO validateLeaveExists(Long id) { + BpmOAInvoiceDO invoice = invoiceMapper.selectById(id); + if (invoice == null) { throw exception(OA_INVOICE_NOT_EXISTS); } + + return invoice; } @Override @@ -104,4 +181,16 @@ public class BpmOAInvoiceServiceImpl extends BpmOABaseService implements BpmOAIn } return bpmOAInvoiceDOS.get(0); } + + @Override + public PageResult getInvoicePage(BpmOAInvoicePageReqVO pageReqVO) { + + return invoiceMapper.selectPage(pageReqVO, getLoginUserId()); + } + + @Override + public List getListByProcessInstanceIds(List processInstanceIds) { + + return invoiceMapper.selectListByProcessInstanceIds(processInstanceIds); + } } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOALeaveService.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOALeaveService.java index a7f56240..1250ea2c 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOALeaveService.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOALeaveService.java @@ -2,7 +2,7 @@ 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.BpmOALeaveRpcVO; +import cn.iocoder.yudao.module.bpm.api.oa.vo.leave.BpmOALeaveRpcVO; import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.leave.BpmOALeaveCreateReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.leave.BpmOALeavePageReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.leave.CalculateAndVerifyLeaveDTO; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOALeaveServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOALeaveServiceImpl.java index c0d7b149..44a67792 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOALeaveServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/BpmOALeaveServiceImpl.java @@ -11,7 +11,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.UploadUserFile; import cn.iocoder.yudao.framework.common.util.date.DateUtils; import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils; -import cn.iocoder.yudao.module.bpm.api.oa.vo.BpmOALeaveRpcVO; +import cn.iocoder.yudao.module.bpm.api.oa.vo.leave.BpmOALeaveRpcVO; 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.leave.BpmOALeaveCreateReqVO; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/listener/BpmOAContractResultListener.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/listener/BpmOAContractResultListener.java index f754b41b..1cd64f7d 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/listener/BpmOAContractResultListener.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/listener/BpmOAContractResultListener.java @@ -28,6 +28,6 @@ public class BpmOAContractResultListener extends BpmProcessInstanceResultEventLi @Override protected void onEvent(BpmProcessInstanceResultEvent event) { - contractService.updateContractResult(Long.parseLong(event.getBusinessKey()), event.getResult()); + contractService.updateContractResult(event.getId(), Long.parseLong(event.getBusinessKey()), event.getResult()); } } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java index 67a6bb5e..81dcef20 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java @@ -264,4 +264,12 @@ public interface BpmTaskService { * @return 公司列表 */ List getTodoTaskDept(BpmTaskTodoPageReqVO pageVO, Long userId); + + /** + * 获取CRM审批任务 + * @param userId 当前登录用户编号 + * @param pageReqVO 分页参数 + * @return CRM审批任务 + */ + PageResult getCrmTask(Long userId, BpmCrmTaskPageReqVO pageReqVO); } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java index 5da542e4..e3006477 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java @@ -1513,5 +1513,11 @@ public class BpmTaskServiceImpl implements BpmTaskService { return taskExtMapper.selectTodoTaskDept(pageVO, userId); } + + @Override + public PageResult getCrmTask(Long userId, BpmCrmTaskPageReqVO pageReqVO) { + + return taskExtMapper.selectCrmPage(userId, pageReqVO); + } } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/mapper/oa/BpmOAContractMapper.xml b/yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/mapper/oa/BpmOAContractMapper.xml new file mode 100644 index 00000000..4779d392 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/mapper/oa/BpmOAContractMapper.xml @@ -0,0 +1,65 @@ + + + + + + + + + diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/mapper/oa/BpmOALeaveMapper.xml b/yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/mapper/oa/BpmOALeaveMapper.xml index ed0e2f06..179ab4e0 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/mapper/oa/BpmOALeaveMapper.xml +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/mapper/oa/BpmOALeaveMapper.xml @@ -9,7 +9,7 @@ 文档可见:https://www.iocoder.cn/MyBatis/x-plugins/ --> - SELECT * FROM diff --git a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/hrm/api/crmbusiness/BusinessApi.java b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/hrm/api/crmbusiness/BusinessApi.java new file mode 100644 index 00000000..9f91c7d3 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/hrm/api/crmbusiness/BusinessApi.java @@ -0,0 +1,23 @@ +package cn.iocoder.yudao.module.hrm.api.crmbusiness; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.module.hrm.api.crmbusiness.dto.CrmBusinessDTO; +import cn.iocoder.yudao.module.hrm.enums.ApiConstants; +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.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; + +@FeignClient(name = ApiConstants.NAME) // TODO 芋艿:fallbackFactory = +@Tag(name = "RPC 服务 - 流程实例") +public interface BusinessApi { + + String PREFIX = ApiConstants.PREFIX + "/crm/business"; + + @GetMapping(PREFIX + "/get") + @Operation(summary = "获得商机信息") + @Parameter(name = "id", description = "ID", required = true) + CommonResult getBusiness(@RequestParam("id") Long id); +} diff --git a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/hrm/api/crmbusiness/dto/CrmBusinessDTO.java b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/hrm/api/crmbusiness/dto/CrmBusinessDTO.java new file mode 100644 index 00000000..a477f92d --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/hrm/api/crmbusiness/dto/CrmBusinessDTO.java @@ -0,0 +1,62 @@ +package cn.iocoder.yudao.module.hrm.api.crmbusiness.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 商机新增/修改 Request VO") +@Data +public class CrmBusinessDTO { + + @Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED, example = "20239") + private Long id; + + @Schema(description = "客户ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "16784") + private Long customerId; + + @Schema(description = "客户") + private String customerName; + + @Schema(description = "销售阶段", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Integer status; + + @Schema(description = "阶段推进时间") + private LocalDateTime statusTime; + + @Schema(description = "0洽淡中,1成交2失败3无效", requiredMode = Schema.RequiredMode.REQUIRED) + private Integer isEnd; + + @Schema(description = "下次联系时间", requiredMode = Schema.RequiredMode.REQUIRED) + private LocalDateTime nextTime; + + @Schema(description = "商机名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五") + private String name; + + @Schema(description = "商机金额", requiredMode = Schema.RequiredMode.REQUIRED) + private BigDecimal money; + + @Schema(description = "产品总金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "30725") + private BigDecimal totalPrice; + + @Schema(description = "预计成交日期") + private LocalDateTime dealTime; + + @Schema(description = "整单折扣", requiredMode = Schema.RequiredMode.REQUIRED) + private BigDecimal discountRate; + + @Schema(description = "备注", example = "随便") + private String remark; + + @Schema(description = "负责人ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "24317") + private Long ownerUserId; + + + @Schema(description = "添加时间") + private LocalDateTime createTime; + + @Schema(description = "负责人") + private String ownUserName; + +} diff --git a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/hrm/api/crmcontract/ContractApi.java b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/hrm/api/crmcontract/ContractApi.java new file mode 100644 index 00000000..1c67e1d5 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/hrm/api/crmcontract/ContractApi.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.hrm.api.crmcontract; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.module.hrm.api.crmcontract.dto.CrmContractProductDTO; +import cn.iocoder.yudao.module.hrm.enums.ApiConstants; +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.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; + +import java.util.List; + +@FeignClient(name = ApiConstants.NAME) // TODO 芋艿:fallbackFactory = +@Tag(name = "RPC 服务 - 流程实例") +public interface ContractApi { + + String PREFIX = ApiConstants.PREFIX + "/crm/contract"; + + @PostMapping(PREFIX + "/create") + @Operation(summary = "创建合同商品信息") + CommonResult createProduct(@RequestBody List createReqVO); + + @GetMapping(PREFIX + "/get-product") + @Operation(summary = "获得合同商品信息") + @Parameter(name = "contractId", description = "合同ID", required = true) + CommonResult> getProduct(@RequestParam("contractId") Long contractId); +} diff --git a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/hrm/api/crmcontract/dto/CrmContractProductDTO.java b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/hrm/api/crmcontract/dto/CrmContractProductDTO.java new file mode 100644 index 00000000..98d48b7c --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/hrm/api/crmcontract/dto/CrmContractProductDTO.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.hrm.api.crmcontract.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + +@Schema(description = "管理后台 - 合同产品关联 DTO") +@Data +public class CrmContractProductDTO { + + @Schema(description = "合同编号") + private Long contractId; + + @Schema(description = "产品编号") + private Long productId; + + @Schema(description = "产品名称") + private String name; + + @Schema(description = "产品属性") + private String productAttrUnique; + + @Schema(description = "产品单价") + private BigDecimal price; + + @Schema(description = "数量") + private Integer nums; + + @Schema(description = "折扣") + private BigDecimal discount; + + @Schema(description = "小计") + private BigDecimal subtotal; + + @Schema(description = "备注") + private String remarks; +} diff --git a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/hrm/api/crmcustomer/CrmCustomerApi.java b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/hrm/api/crmcustomer/CrmCustomerApi.java new file mode 100644 index 00000000..89f668dc --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/hrm/api/crmcustomer/CrmCustomerApi.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.hrm.api.crmcustomer; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.module.hrm.api.crmcustomer.dto.CrmCustomerDTO; +import cn.iocoder.yudao.module.hrm.enums.ApiConstants; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +@FeignClient(name = ApiConstants.NAME) // TODO 芋艿:fallbackFactory = +@Tag(name = "RPC 服务 - 流程实例") +public interface CrmCustomerApi { + + String PREFIX = ApiConstants.PREFIX + "/crm/customer"; + + @PostMapping(PREFIX + "/update") + @Operation(summary = "更新客户信息") + CommonResult updateCustomerPurchaseTotal(@RequestBody CrmCustomerDTO updateReqVO); +} diff --git a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/hrm/api/crmcustomer/dto/CrmCustomerDTO.java b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/hrm/api/crmcustomer/dto/CrmCustomerDTO.java new file mode 100644 index 00000000..7dd18b2f --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/hrm/api/crmcustomer/dto/CrmCustomerDTO.java @@ -0,0 +1,113 @@ +package cn.iocoder.yudao.module.hrm.api.crmcustomer.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotEmpty; +import java.math.BigDecimal; +import java.time.LocalDateTime; + + +@Schema(description = "管理后台 - 客户新增/修改 Request VO") +@Data +public class CrmCustomerDTO { + + @Schema(description = "是否转移记录 1-是 2-否") + private Integer isTransfer; + + @Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "12015") + private Long id; + + @Schema(description = "客户名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四") + @NotEmpty(message = "客户名称不能为空") + private String name; + + @Schema(description = "手机", requiredMode = Schema.RequiredMode.REQUIRED) + // @NotEmpty(message = "手机不能为空") + private String mobile; + + @Schema(description = "电话", requiredMode = Schema.RequiredMode.REQUIRED) + //@NotEmpty(message = "电话不能为空") + private String telephone; + + @Schema(description = "成交状态0未成交1成交", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + // @NotNull(message = "成交状态0未成交1成交不能为空") + private Integer dealStatus; + + @Schema(description = "成交时间") + private LocalDateTime dealTime; + + @Schema(description = "1锁定") + private Boolean isLock; + + @Schema(description = "客户级别ID", requiredMode = Schema.RequiredMode.REQUIRED) + //@NotNull(message = "客户级别ID不能为空") + private Integer level; + + @Schema(description = "客户行业ID", requiredMode = Schema.RequiredMode.REQUIRED) + //@NotNull(message = "客户行业ID不能为空") + private Integer industry; + + @Schema(description = " 客户标签") + private String tags; + + @Schema(description = "客户来源ID", requiredMode = Schema.RequiredMode.REQUIRED) + //@NotNull(message = "客户来源ID不能为空") + private Integer source; + + @Schema(description = "备注", example = "你说的对") + private String remark; + + + @Schema(description = "省份id") + private Integer province; + + @Schema(description = "城市ID") + private Integer city; + + @Schema(description = "区域ID") + private Integer area; + + /** + * 地址组合字符串 + */ + private String addressStr; + + @Schema(description = "详细地址", requiredMode = Schema.RequiredMode.REQUIRED) + //@NotEmpty(message = "详细地址不能为空") + private String detailAddress; + + @Schema(description = "地理位置经度") + private Double lng; + + @Schema(description = "地理位置维度") + private Double lat; + + @Schema(description = "下次联系时间", requiredMode = Schema.RequiredMode.REQUIRED) + //@NotNull(message = "下次联系时间不能为空") + private LocalDateTime nextTime; + + @Schema(description = "最后跟进时间") + private LocalDateTime followTime; + + @Schema(description = "领取时间") + private LocalDateTime collectTime; + + @Schema(description = "微信") + private String weixin; + + @Schema(description = "QQ") + private String qq; + + @Schema(description = "消费总额") + private BigDecimal purchaseTotal; + + @Schema(description = "消费次数") + private Integer purchaseTimes; + + @Schema(description = "跟进状态", example = "1") + private Integer followStatus; + + + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/.flattened-pom.xml b/yudao-module-crm/yudao-module-crm-biz/.flattened-pom.xml index b08e53c4..cb436732 100644 --- a/yudao-module-crm/yudao-module-crm-biz/.flattened-pom.xml +++ b/yudao-module-crm/yudao-module-crm-biz/.flattened-pom.xml @@ -119,6 +119,12 @@ cn.iocoder.cloud yudao-spring-boot-starter-file + + cn.iocoder.cloud + yudao-module-bpm-api + 2.0.0-jdk8-snapshot + compile + ${project.artifactId} diff --git a/yudao-module-crm/yudao-module-crm-biz/pom.xml b/yudao-module-crm/yudao-module-crm-biz/pom.xml index e0094bd2..e94d3370 100644 --- a/yudao-module-crm/yudao-module-crm-biz/pom.xml +++ b/yudao-module-crm/yudao-module-crm-biz/pom.xml @@ -155,6 +155,12 @@ cn.iocoder.cloud yudao-spring-boot-starter-file + + cn.iocoder.cloud + yudao-module-bpm-api + 2.0.0-jdk8-snapshot + compile + diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/api/crmbusiness/BusinessApiImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/api/crmbusiness/BusinessApiImpl.java new file mode 100644 index 00000000..de05b68d --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/api/crmbusiness/BusinessApiImpl.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.crm.api.crmbusiness; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.crm.controller.admin.crmbusiness.vo.CrmBusinessRespVO; +import cn.iocoder.yudao.module.crm.service.crmbusiness.CrmBusinessService; +import cn.iocoder.yudao.module.hrm.api.crmbusiness.BusinessApi; +import cn.iocoder.yudao.module.hrm.api.crmbusiness.dto.CrmBusinessDTO; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +/** + * Flowable CRM Api 实现类 + */ +@RestController +@Validated +public class BusinessApiImpl implements BusinessApi { + + @Resource + private CrmBusinessService businessService; + + @Override + public CommonResult getBusiness(Long id) { + CrmBusinessRespVO businessDO = businessService.getBusiness(id); + return success(BeanUtils.toBean(businessDO, CrmBusinessDTO.class)); + } +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/api/crmcontract/ContractApiImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/api/crmcontract/ContractApiImpl.java new file mode 100644 index 00000000..6541fe24 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/api/crmcontract/ContractApiImpl.java @@ -0,0 +1,40 @@ +package cn.iocoder.yudao.module.crm.api.crmcontract; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.crm.dal.dataobject.crmcontract.CrmContractProductDO; +import cn.iocoder.yudao.module.crm.service.crmcontract.CrmContractService; +import cn.iocoder.yudao.module.hrm.api.crmcontract.ContractApi; +import cn.iocoder.yudao.module.hrm.api.crmcontract.dto.CrmContractProductDTO; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +import java.util.List; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +/** + * Flowable CRM Api 实现类 + */ +@RestController +@Validated +public class ContractApiImpl implements ContractApi { + + @Resource + private CrmContractService crmContractService; + + @Override + public CommonResult createProduct(List createReqVO) { + + crmContractService.createProduct(BeanUtils.toBean(createReqVO, CrmContractProductDO.class)); + return success(true); + } + + @Override + public CommonResult> getProduct(Long contractId) { + List contractProductDOS = crmContractService.getContractProductListByContractId(contractId); + return success(BeanUtils.toBean(contractProductDOS, CrmContractProductDTO.class)); + } +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/api/crmcustomer/CrmCustomerApiImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/api/crmcustomer/CrmCustomerApiImpl.java new file mode 100644 index 00000000..29cfe118 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/api/crmcustomer/CrmCustomerApiImpl.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.crm.api.crmcustomer; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.crm.controller.admin.crmcustomer.vo.CrmCustomerSaveReqVO; +import cn.iocoder.yudao.module.crm.service.crmcustomer.CrmCustomerService; +import cn.iocoder.yudao.module.hrm.api.crmcustomer.CrmCustomerApi; +import cn.iocoder.yudao.module.hrm.api.crmcustomer.dto.CrmCustomerDTO; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +/** + * Flowable CRM Api 实现类 + */ +@RestController +@Validated +public class CrmCustomerApiImpl implements CrmCustomerApi { + + @Resource + private CrmCustomerService customerService; + + @Override + public CommonResult updateCustomerPurchaseTotal(CrmCustomerDTO updateReqVO) { + customerService.updateCustomerPurchaseTotal(BeanUtils.toBean(updateReqVO, CrmCustomerSaveReqVO.class)); + return success(true); + } +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmachievement/CrmAchievementController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmachievement/CrmAchievementController.java index fc84e92f..2de4c091 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmachievement/CrmAchievementController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmachievement/CrmAchievementController.java @@ -66,9 +66,9 @@ public class CrmAchievementController { @GetMapping("/depts") @Operation(summary = "获得部门业绩目标") @PreAuthorize("@ss.hasPermission('crm:achievement:query')") - public CommonResult> getDeptsAchievement(@RequestParam(name = "type", required = false) Integer type, + public CommonResult> getDeptsAchievement(@RequestParam(name = "config", required = false) Integer config, @RequestParam(name = "year", required = false) Integer year) { - List deptAchieveRespVOS = achievementService.getDeptAchieve(type, year); + List deptAchieveRespVOS = achievementService.getDeptAchieve(config, year); return success(deptAchieveRespVOS); } @@ -86,6 +86,4 @@ public class CrmAchievementController { @RequestParam(name = "year", required = false) Integer year) { return success(achievementService.getCount(type, year, month)); } - - } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/CustomerController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/CustomerController.java index 5d579507..053ffdbb 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/CustomerController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmanalysis/CustomerController.java @@ -60,8 +60,4 @@ public class CustomerController { public CommonResult> getRecord(@Valid AchievementPageReqVO pageReqVO) { return success(customerService.getRecord(pageReqVO)); } - - - - } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmclues/vo/CrmCluesStatisticsRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmclues/vo/CrmCluesStatisticsRespVO.java new file mode 100644 index 00000000..4fbdf8cc --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmclues/vo/CrmCluesStatisticsRespVO.java @@ -0,0 +1,18 @@ +package cn.iocoder.yudao.module.crm.controller.admin.crmclues.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Schema(description = "管理后台 - 线索统计 RespVO") +@Data +public class CrmCluesStatisticsRespVO { + + @Schema(description = "负责人用户编号") + private Long ownerUserId; + + @Schema(description = "线索总数量") + private Integer count; + + @Schema(description = "转客数量") + private Integer successCount; +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmcustomer/vo/CustomerStatisticRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmcustomer/vo/CustomerStatisticRespVO.java new file mode 100644 index 00000000..601f6af2 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmcustomer/vo/CustomerStatisticRespVO.java @@ -0,0 +1,18 @@ +package cn.iocoder.yudao.module.crm.controller.admin.crmcustomer.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Schema(description = "管理后台 - 客户统计 Response VO") +@Data +public class CustomerStatisticRespVO { + + @Schema(description = "负责人编号") + private Long ownerUserId; + + @Schema(description = "客户数量") + private Integer count; + + @Schema(description = "成交数量") + private Integer DealsCount; +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmrecord/vo/RecordStatisticsRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmrecord/vo/RecordStatisticsRespVO.java new file mode 100644 index 00000000..2ae8bbb2 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/crmrecord/vo/RecordStatisticsRespVO.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.crm.controller.admin.crmrecord.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Schema(description = "管理后台 - 跟进统计 Response VO") +@Data +public class RecordStatisticsRespVO { + + @Schema(description = "跟进人") + private String creator; + + @Schema(description = "跟进总数量") + private Integer count; + + @Schema(description = "客户跟进数量") + private Integer customerCount; + + @Schema(description = "商机跟进数量") + private Integer businessCount; + + @Schema(description = "线索跟进数量") + private Integer cluesCount; +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/crmachievement/CrmAchievementMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/crmachievement/CrmAchievementMapper.java index 75f3eb90..c27e2316 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/crmachievement/CrmAchievementMapper.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/crmachievement/CrmAchievementMapper.java @@ -3,10 +3,15 @@ package cn.iocoder.yudao.module.crm.dal.mysql.crmachievement; 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.crm.controller.admin.crmachievement.vo.DeptAchieveSaveVO; import cn.iocoder.yudao.module.crm.dal.dataobject.crmachievement.CrmAchievementDO; import cn.iocoder.yudao.module.crm.controller.admin.crmachievement.vo.CrmAchievementPageReqVO; +import cn.iocoder.yudao.module.hrm.enums.FlowStepEnum; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import org.apache.ibatis.annotations.Mapper; +import java.util.List; + /** * 业绩目标 Mapper * @@ -39,4 +44,21 @@ public interface CrmAchievementMapper extends BaseMapperX { .orderByDesc(CrmAchievementDO::getId)); } + default List selectAchievementList(Integer type, Integer year, List typeIds) { + + return selectList(new LambdaQueryWrapper() + .eq(CrmAchievementDO::getType, FlowStepEnum.TYPE_3.getValue()) + .eq(CrmAchievementDO::getConfig, type) + .in(CrmAchievementDO::getTypeId, typeIds) + .eq(CrmAchievementDO::getYear, year)); + } + + default List selectAchievementList(DeptAchieveSaveVO createReqVO, List typeIds) { + + return selectList(new LambdaQueryWrapperX() + .eq(CrmAchievementDO::getType, createReqVO.getAchievementRespVO().getType()) + .eq(CrmAchievementDO::getConfig, createReqVO.getAchievementRespVO().getConfig()) + .eq(CrmAchievementDO::getYear, createReqVO.getAchievementRespVO().getYear()) + .inIfPresent(CrmAchievementDO::getTypeId, typeIds)); + } } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/crmclues/CrmCluesMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/crmclues/CrmCluesMapper.java index 60624a30..fe08d5a4 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/crmclues/CrmCluesMapper.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/crmclues/CrmCluesMapper.java @@ -3,11 +3,13 @@ package cn.iocoder.yudao.module.crm.dal.mysql.crmclues; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.module.crm.controller.admin.crmclues.vo.CrmCluesPageReqVO; import cn.iocoder.yudao.module.crm.controller.admin.crmclues.vo.CrmCluesRespVO; +import cn.iocoder.yudao.module.crm.controller.admin.crmclues.vo.CrmCluesStatisticsRespVO; import cn.iocoder.yudao.module.crm.dal.dataobject.crmclues.CrmCluesDO; import com.baomidou.mybatisplus.core.metadata.IPage; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; +import java.time.LocalDateTime; import java.util.List; /** @@ -21,4 +23,7 @@ public interface CrmCluesMapper extends BaseMapperX { IPage selectPageList(@Param("page") IPage mpPage, @Param("dto") CrmCluesPageReqVO pageReqVO, @Param("ids") List ids); IPage selectPageList2(@Param("page") IPage mpPage, @Param("dto") CrmCluesPageReqVO pageReqVO); + + List selectStatisticsByUserIds(@Param("ownerUserIds") List ownerUserIds, + @Param("createTime") LocalDateTime[] createTime); } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/crmcontract/CrmContractMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/crmcontract/CrmContractMapper.java index 93302603..eae69ea2 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/crmcontract/CrmContractMapper.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/crmcontract/CrmContractMapper.java @@ -4,17 +4,13 @@ package cn.iocoder.yudao.module.crm.dal.mysql.crmcontract; 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.framework.security.core.util.SecurityFrameworkUtils; import cn.iocoder.yudao.module.crm.controller.admin.crmanalysis.vo.ContractVO; import cn.iocoder.yudao.module.crm.controller.admin.crmcontract.vo.CrmContractPageReqVO; import cn.iocoder.yudao.module.crm.controller.admin.crmcontract.vo.CrmContractRespVO; import cn.iocoder.yudao.module.crm.dal.dataobject.crmcontract.CrmContractDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.crmcustomer.CrmCustomerDO; import com.baomidou.mybatisplus.core.metadata.IPage; -import com.github.yulichang.wrapper.MPJLambdaWrapper; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; -import org.apache.ibatis.annotations.Select; import java.util.List; @@ -56,9 +52,6 @@ public interface CrmContractMapper extends BaseMapperX { .orderByDesc(CrmContractDO::getId)); } - @Select("select any_value(t.id) as id,COUNT(t.id) AS count,SUM(t.money) AS money,t1.nickname AS nickname from crm_contract t " + - "LEFT JOIN system_users t1 ON (t1.id = t.order_admin_id) " + - "where t.deleted=0 GROUP BY t.order_admin_id ORDER BY any_value(money) DESC limit 10") List selectContractTop(); } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/crmcustomer/CrmCustomerMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/crmcustomer/CrmCustomerMapper.java index 46d23ea8..6460d4ac 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/crmcustomer/CrmCustomerMapper.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/crmcustomer/CrmCustomerMapper.java @@ -5,12 +5,13 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.crm.controller.admin.crmcustomer.vo.CrmCustomerPageReqVO; import cn.iocoder.yudao.module.crm.controller.admin.crmcustomer.vo.CrmCustomerRespVO; +import cn.iocoder.yudao.module.crm.controller.admin.crmcustomer.vo.CustomerStatisticRespVO; import cn.iocoder.yudao.module.crm.dal.dataobject.crmcustomer.CrmCustomerDO; import com.baomidou.mybatisplus.core.metadata.IPage; -import com.github.yulichang.wrapper.MPJLambdaWrapper; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; +import java.time.LocalDateTime; import java.util.List; /** @@ -41,4 +42,6 @@ public interface CrmCustomerMapper extends BaseMapperX { } IPage selectPageList(@Param("page") IPage page, @Param("dto") CrmCustomerPageReqVO pageReqVO, @Param("ids") List ids); + + List selectStatistic(@Param("userIds") List userIds, @Param("createTime") LocalDateTime[] createTime); } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/crmrecord/CrmRecordMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/crmrecord/CrmRecordMapper.java index d049d84c..1743413e 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/crmrecord/CrmRecordMapper.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/crmrecord/CrmRecordMapper.java @@ -4,9 +4,12 @@ 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.crm.controller.admin.crmrecord.vo.CrmRecordPageReqVO; +import cn.iocoder.yudao.module.crm.controller.admin.crmrecord.vo.RecordStatisticsRespVO; import cn.iocoder.yudao.module.crm.dal.dataobject.crmrecord.CrmRecordDO; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import java.time.LocalDateTime; import java.util.List; /** @@ -28,4 +31,5 @@ public interface CrmRecordMapper extends BaseMapperX { .orderByDesc(CrmRecordDO::getId)); } + List selectStatistics(@Param("userIds") List userIds, @Param("createTime") LocalDateTime[] createTime); } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/rpc/config/RpcConfiguration.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/rpc/config/RpcConfiguration.java index 4b98844f..88728584 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/rpc/config/RpcConfiguration.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/rpc/config/RpcConfiguration.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.crm.framework.rpc.config; +import cn.iocoder.yudao.module.bpm.api.oa.BpmOAContractApi; import cn.iocoder.yudao.module.product.api.storeproduct.StoreProductApi; import cn.iocoder.yudao.module.product.api.storeproductattrvalue.StoreProductAttrValueApi; import cn.iocoder.yudao.module.system.api.dept.DeptApi; @@ -12,6 +13,7 @@ import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.context.annotation.Configuration; @Configuration(proxyBeanMethods = false) -@EnableFeignClients(clients = {DeptApi.class, DictDataApi.class, AdminUserApi.class, StoreProductApi.class, StoreProductAttrValueApi.class, SmsSendApi.class, MailSendApi.class, NoticeApi.class}) +@EnableFeignClients(clients = {DeptApi.class, DictDataApi.class, AdminUserApi.class, StoreProductApi.class, StoreProductAttrValueApi.class, SmsSendApi.class, MailSendApi.class, NoticeApi.class, + BpmOAContractApi.class}) public class RpcConfiguration { } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmachievement/CrmAchievementService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmachievement/CrmAchievementService.java index 295afb24..68652897 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmachievement/CrmAchievementService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmachievement/CrmAchievementService.java @@ -56,11 +56,11 @@ public interface CrmAchievementService { /** * 获取部门业绩 * - * @param type + * @param config * @param year * @return */ - List getDeptAchieve(Integer type, Integer year); + List getDeptAchieve(Integer config, Integer year); /** * 获取业绩完成度 diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmachievement/CrmAchievementServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmachievement/CrmAchievementServiceImpl.java index 8b42ab27..bb551ba0 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmachievement/CrmAchievementServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmachievement/CrmAchievementServiceImpl.java @@ -1,31 +1,32 @@ package cn.iocoder.yudao.module.crm.service.crmachievement; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.NumberUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.enums.DeptTypeEnum; import cn.iocoder.yudao.framework.common.enums.ShopCommonEnum; 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.framework.security.core.util.SecurityFrameworkUtils; +import cn.iocoder.yudao.module.bpm.api.oa.BpmOAContractApi; +import cn.iocoder.yudao.module.bpm.api.oa.vo.contract.BpmOAContractDTO; +import cn.iocoder.yudao.module.bpm.api.oa.vo.contract.BpmOAContractVO; import cn.iocoder.yudao.module.crm.controller.admin.crmachievement.vo.*; import cn.iocoder.yudao.module.crm.dal.dataobject.crmachievement.CrmAchievementDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.crmcontract.CrmContractDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.crmcontractreceivables.CrmContractReceivablesDO; import cn.iocoder.yudao.module.crm.dal.mysql.crmachievement.CrmAchievementMapper; import cn.iocoder.yudao.module.crm.dal.mysql.crmcontract.CrmContractMapper; import cn.iocoder.yudao.module.crm.dal.mysql.crmcontractreceivables.CrmContractReceivablesMapper; -import cn.iocoder.yudao.module.hrm.enums.ContractStatusEnum; import cn.iocoder.yudao.module.hrm.enums.FlowStepEnum; import cn.iocoder.yudao.module.system.api.dept.DeptApi; -import cn.iocoder.yudao.module.system.api.dept.dto.DeptApiDTO; -import cn.iocoder.yudao.module.system.api.dept.dto.DeptApiVO; +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.AdminUserApiDTO; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserApiVO; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserPageApiDTO; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -35,6 +36,8 @@ import java.util.*; 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.convertMap; import static cn.iocoder.yudao.module.hrm.enums.ErrorCodeConstants.ACHIEVEMENT_NOT_EXISTS; @@ -50,7 +53,7 @@ public class CrmAchievementServiceImpl implements CrmAchievementService { @Resource private CrmAchievementMapper achievementMapper; @Resource - private DeptApi deptService; + private DeptApi deptApi; @Resource private CrmContractMapper contractMapper; @Resource @@ -58,28 +61,53 @@ public class CrmAchievementServiceImpl implements CrmAchievementService { @Resource private AdminUserApi adminUserApi; + @Resource + private BpmOAContractApi contractApi; + @Override public void createAchievement(DeptAchieveSaveVO createReqVO) { + //计算年目标 + List bigDecimals = Arrays.asList( + createReqVO.getAchievementRespVO().getJanuary(), createReqVO.getAchievementRespVO().getFebruary(), + createReqVO.getAchievementRespVO().getMarch(), createReqVO.getAchievementRespVO().getApril(), + createReqVO.getAchievementRespVO().getMay(), createReqVO.getAchievementRespVO().getJune(), + createReqVO.getAchievementRespVO().getJuly(), createReqVO.getAchievementRespVO().getAugust(), + createReqVO.getAchievementRespVO().getSeptember(), createReqVO.getAchievementRespVO().getOctober(), + createReqVO.getAchievementRespVO().getNovember(), createReqVO.getAchievementRespVO().getDecember() + ); + BigDecimal yearTarget = bigDecimals.stream().reduce(BigDecimal.ZERO, BigDecimal::add); + createReqVO.getAchievementRespVO().setYeartarget(yearTarget); + if (createReqVO.getId() == 0) { + + List achievements; //批量 if (FlowStepEnum.TYPE_3.getValue().equals(createReqVO.getAchievementRespVO().getType())) { - List list = deptService.getDeptList( - new DeptApiDTO().setStatus(CommonStatusEnum.ENABLE.getStatus())).getCheckedData(); - list.forEach(dept -> { - createReqVO.setId(dept.getId()); - createReqVO.setName(dept.getName()); - saveAchievement(createReqVO); - }); + // 获取所有营销部门列表 + List list = deptApi.getDeptListByType(DeptTypeEnum.SALE_DEPT.getValue()).getCheckedData(); + // 获取 插入/更新信息列表 + achievements = list.stream().map(item -> { + CrmAchievementDO achievement = BeanUtils.toBean(createReqVO.getAchievementRespVO(), CrmAchievementDO.class); + achievement.setTypeId(item.getId()); + achievement.setName(item.getName()); + return achievement; + }).collect(Collectors.toList()); + } else { - List list = adminUserApi.getUserList(new AdminUserApiDTO().setStatus(CommonStatusEnum.ENABLE.getStatus())).getCheckedData(); - list.forEach(user -> { - createReqVO.setId(user.getId()); - createReqVO.setName(user.getNickname()); - saveAchievement(createReqVO); - }); + List list = adminUserApi.getUserListAll(1, null, CommonStatusEnum.ENABLE.getStatus(), "sale").getCheckedData(); + // 获取 插入/更新信息列表 + achievements = list.stream().map(item -> { + CrmAchievementDO achievement = BeanUtils.toBean(createReqVO.getAchievementRespVO(), CrmAchievementDO.class); + achievement.setTypeId(item.getId()); + achievement.setName(item.getNickname()); + return achievement; + }).collect(Collectors.toList()); } + + // 批量插入操作 + saveAchievementBatch(createReqVO, achievements); } else { //单个操作 if (FlowStepEnum.TYPE_3.getValue().equals(createReqVO.getAchievementRespVO().getType())) { @@ -89,8 +117,6 @@ public class CrmAchievementServiceImpl implements CrmAchievementService { } saveAchievement(createReqVO); } - - } /** @@ -103,29 +129,48 @@ public class CrmAchievementServiceImpl implements CrmAchievementService { CrmAchievementDO achievement = BeanUtils.toBean(createReqVO.getAchievementRespVO(), CrmAchievementDO.class); achievement.setTypeId(createReqVO.getId()); achievement.setName(createReqVO.getName()); - LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + LambdaQueryWrapperX wrapper = new LambdaQueryWrapperX<>(); wrapper.eq(CrmAchievementDO::getType, achievement.getType()) .eq(CrmAchievementDO::getTypeId, achievement.getTypeId()) .eq(CrmAchievementDO::getConfig, achievement.getConfig()) .eq(CrmAchievementDO::getYear, achievement.getYear()); CrmAchievementDO achievementOld = achievementMapper.selectOne(wrapper); + if (achievementOld == null) { achievementMapper.insert(achievement); } else { achievement.setId(achievementOld.getId()); achievementMapper.updateById(achievement); } + } - //更新年目标 - List bigDecimals = Arrays.asList( - achievement.getJanuary(), achievement.getFebruary(), achievement.getMarch(), achievement.getApril(), - achievement.getMay(), achievement.getJune(), achievement.getJuly(), achievement.getAugust(), - achievement.getSeptember(), achievement.getOctober(), achievement.getNovember(), achievement.getDecember() - ); - BigDecimal yearTarget = bigDecimals.stream() - .reduce(BigDecimal.ZERO, BigDecimal::add); - CrmAchievementDO achievementDO = CrmAchievementDO.builder().yeartarget(yearTarget).id(achievement.getId()).build(); - achievementMapper.updateById(achievementDO); + /** + * 批量插入操作 + * @param createReqVO 更新信息 + * @param achievements 更新信息 + */ + private void saveAchievementBatch(DeptAchieveSaveVO createReqVO, List achievements) { + + if (CollectionUtil.isNotEmpty(achievements)) { + + List typeIds = convertList(achievements, CrmAchievementDO::getId); + // 判断业绩数据是否已存在 + List achievementOld = achievementMapper.selectAchievementList(createReqVO, typeIds); + if (CollectionUtil.isEmpty(achievementOld)) { + + achievementMapper.insertBatch(achievements); + }else { + + // 获取之前业绩数据Map + Map oldMap = convertMap(achievementOld, CrmAchievementDO::getTypeId); + // 设置ID + achievements.forEach(item -> { + item.setId(oldMap.get(item.getTypeId()).getId()); + }); + + achievementMapper.updateBatch(achievements); + } + } } @Override @@ -158,62 +203,63 @@ public class CrmAchievementServiceImpl implements CrmAchievementService { @Override public PageResult getAchievementPage(CrmAchievementPageReqVO pageReqVO) { + + // 设置用户查询条件 AdminUserPageApiDTO userPageReqVO = new AdminUserPageApiDTO(); userPageReqVO.setPageNo(pageReqVO.getPageNo()); userPageReqVO.setPageSize(pageReqVO.getPageSize()); - PageResult pageResult = adminUserApi.getUserPage(userPageReqVO).getCheckedData(); - PageResult pageResult1 = BeanUtils.toBean(pageResult, UserAchieveRespVO.class); - List typeIds = new ArrayList<>(); - for (UserAchieveRespVO vo : pageResult1.getList()) { - typeIds.add(vo.getId()); + userPageReqVO.setNickname(pageReqVO.getName()); + userPageReqVO.setRoleCodes("sale"); // 设置查询用户的角色类型 + + // 查询用户分页列表 + PageResult pageResult = adminUserApi.getUserPageByRole(userPageReqVO).getCheckedData(); + PageResult userPage = BeanUtils.toBean(pageResult, UserAchieveRespVO.class); + if (CollectionUtil.isNotEmpty(pageResult.getList())) { + + // 查询用户的 业绩信息 + List typeIds = convertList(userPage.getList(), UserAchieveRespVO::getId); + List crmAchievementDOS = achievementMapper.selectList(new LambdaQueryWrapperX() + .eq(CrmAchievementDO::getType, FlowStepEnum.TYPE_2.getValue()) + .eq(CrmAchievementDO::getConfig, pageReqVO.getConfig()) + .in(CrmAchievementDO::getTypeId, typeIds) + .eq(CrmAchievementDO::getYear, pageReqVO.getYear()) + ); + // 获得业绩信息Map + Map achievementMap = convertMap(crmAchievementDOS, CrmAchievementDO::getTypeId); + + userPage.getList().forEach(item -> { + + CrmAchievementDO crmAchievementDO = achievementMap.get(item.getId()); + if (crmAchievementDO == null) { + crmAchievementDO = CrmAchievementDO.builder() + .january(BigDecimal.ZERO).february(BigDecimal.ZERO).march(BigDecimal.ZERO) + .april(BigDecimal.ZERO).may(BigDecimal.ZERO).june(BigDecimal.ZERO) + .july(BigDecimal.ZERO).august(BigDecimal.ZERO).september(BigDecimal.ZERO) + .october(BigDecimal.ZERO).november(BigDecimal.ZERO).december(BigDecimal.ZERO) + .yeartarget(BigDecimal.ZERO) + .build(); + } + + item.setAchievementRespVO(BeanUtils.toBean(crmAchievementDO, CrmAchievementRespVO.class)); + }); } - typeIds = typeIds.stream().distinct().collect(Collectors.toList()); - List crmAchievementDOS = achievementMapper.selectList(new LambdaQueryWrapper() - .eq(CrmAchievementDO::getType, FlowStepEnum.TYPE_2.getValue()) - .eq(CrmAchievementDO::getConfig, pageReqVO.getConfig()) - .in(CrmAchievementDO::getTypeId, typeIds) - .eq(CrmAchievementDO::getYear, pageReqVO.getYear()) - ); - Map> map = crmAchievementDOS.stream().collect(Collectors.groupingBy(CrmAchievementDO::getTypeId)); - - pageResult1.getList().forEach(v -> { - List doList = map.get(v.getId()); - CrmAchievementDO crmAchievementDO = null; - if (CollUtil.isNotEmpty(doList)) { - crmAchievementDO = doList.get(0); - } - if (crmAchievementDO == null) { - crmAchievementDO = CrmAchievementDO.builder() - .january(BigDecimal.ZERO).february(BigDecimal.ZERO).march(BigDecimal.ZERO) - .april(BigDecimal.ZERO).may(BigDecimal.ZERO).june(BigDecimal.ZERO) - .july(BigDecimal.ZERO).august(BigDecimal.ZERO).september(BigDecimal.ZERO) - .october(BigDecimal.ZERO).november(BigDecimal.ZERO).december(BigDecimal.ZERO) - .yeartarget(BigDecimal.ZERO) - .build(); - } - v.setAchievementRespVO(BeanUtils.toBean(crmAchievementDO, CrmAchievementRespVO.class)); - }); - return pageResult1; + return userPage; } @Override - public List getDeptAchieve(Integer type, Integer year) { - List list = deptService.getDeptList( - new DeptApiDTO().setStatus(CommonStatusEnum.ENABLE.getStatus())).getCheckedData(); - List achieveRespVOS = BeanUtils.toBean(list, DeptAchieveRespVO.class); - List typeIds = new ArrayList<>(); - for (DeptAchieveRespVO vo : achieveRespVOS) { - typeIds.add(vo.getId()); - } - typeIds = typeIds.stream().distinct().collect(Collectors.toList()); - List crmAchievementDOS = achievementMapper.selectList(new LambdaQueryWrapper() - .eq(CrmAchievementDO::getType, FlowStepEnum.TYPE_3.getValue()) - .eq(CrmAchievementDO::getConfig, type) - .in(CrmAchievementDO::getTypeId, typeIds) - .eq(CrmAchievementDO::getYear, year) - ); + public List getDeptAchieve(Integer config, Integer year) { + + // 获取销售部门列表 + List list = deptApi.getDeptListByType(DeptTypeEnum.SALE_DEPT.getValue()).getCheckedData(); + // 获取部门编号列表 + List typeIds = list.stream().map(DeptRespDTO::getId).distinct().collect(Collectors.toList()); + + // 获取部门业绩列表 + List crmAchievementDOS = achievementMapper.selectAchievementList(config, year, typeIds); Map> map = crmAchievementDOS.stream().collect(Collectors.groupingBy(CrmAchievementDO::getTypeId)); + + List achieveRespVOS = BeanUtils.toBean(list, DeptAchieveRespVO.class); achieveRespVOS.forEach(vo -> { List doList = map.get(vo.getId()); CrmAchievementDO crmAchievementDO = null; @@ -236,8 +282,11 @@ public class CrmAchievementServiceImpl implements CrmAchievementService { @Override public AchieveCountRespVO getCount(Integer type, Integer year, Integer month) { + + // 获取当前登录用户编号 List userIds = new ArrayList<>(); Long typeId = SecurityFrameworkUtils.getLoginUserId(); + if (FlowStepEnum.TYPE_2.getValue().equals(type)) { userIds.add(typeId); } else { @@ -265,43 +314,47 @@ public class CrmAchievementServiceImpl implements CrmAchievementService { endTime = DateUtil.endOfMonth(calendar.getTime()); } - //合同目标 - CrmAchievementDO crmAchievementDO = achievementMapper.selectOne(new LambdaQueryWrapperX() + List achievementDOS = achievementMapper.selectList(new LambdaQueryWrapperX() .eq(CrmAchievementDO::getType, type) .eq(CrmAchievementDO::getTypeId, typeId) - .eqIfPresent(CrmAchievementDO::getConfig, ShopCommonEnum.ACH_1.getValue()) - .eqIfPresent(CrmAchievementDO::getYear, year)); - //回款目标 - CrmAchievementDO crmAchievementDO2 = achievementMapper.selectOne(new LambdaQueryWrapperX() - .eq(CrmAchievementDO::getType, type) - .eq(CrmAchievementDO::getTypeId, typeId) - .eqIfPresent(CrmAchievementDO::getConfig, ShopCommonEnum.ACH_2.getValue()) .eqIfPresent(CrmAchievementDO::getYear, year)); + Map achievementMap = convertMap(achievementDOS, CrmAchievementDO::getConfig); + // 合同目标 + CrmAchievementDO crmAchievementDO = achievementMap.get(ShopCommonEnum.ACH_1.getValue()); + // 回款目标 + CrmAchievementDO crmAchievementDO2 = achievementMap.get(ShopCommonEnum.ACH_2.getValue()); + // 获取合同信息 + List contractDTOS = contractApi.getContractList(new BpmOAContractVO() + .setContractType(BpmOAContractVO.SALE_CONTRACT) + .setUserId(userIds) + .setStarTime(starTime) + .setEndTime(endTime)).getCheckedData(); - List crmContractDOS = contractMapper.selectList(new LambdaQueryWrapper() - .in(CrmContractDO::getOwnerUserId, userIds) - .eq(CrmContractDO::getCheckStatus, ContractStatusEnum.STATUS_2.getValue()) - .between(CrmContractDO::getOrderTime, starTime, endTime)); +// List crmContractDOS = contractMapper.selectList(new LambdaQueryWrapperX() +// .in(CrmContractDO::getOwnerUserId, userIds) +// .eq(CrmContractDO::getCheckStatus, ContractStatusEnum.STATUS_2.getValue()) +// .between(CrmContractDO::getOrderTime, starTime, endTime)); BigDecimal contractSuccessMoney = BigDecimal.ZERO; - if (!crmContractDOS.isEmpty()) { - contractSuccessMoney = crmContractDOS - .stream() - .map(CrmContractDO::getMoney) + if (CollectionUtil.isNotEmpty(contractDTOS)) { + // 累加合同金额 + contractSuccessMoney = contractDTOS.stream() + .map(BpmOAContractDTO::getContractMoney) .reduce(BigDecimal.ZERO, BigDecimal::add); } - List crmContractReceivablesDOS = contractReceivablesMapper - .selectList(new LambdaQueryWrapper() - .in(CrmContractReceivablesDO::getOwnerUserId, userIds) - .eq(CrmContractReceivablesDO::getCheckStatus, ContractStatusEnum.STATUS_2.getValue()) - .between(CrmContractReceivablesDO::getReturnTime, starTime, endTime)); + +// List crmContractReceivablesDOS = contractReceivablesMapper +// .selectList(new LambdaQueryWrapper() +// .in(CrmContractReceivablesDO::getOwnerUserId, userIds) +// .eq(CrmContractReceivablesDO::getCheckStatus, ContractStatusEnum.STATUS_2.getValue()) +// .between(CrmContractReceivablesDO::getReturnTime, starTime, endTime)); BigDecimal receivablesSuccessMoney = BigDecimal.ZERO; - if (!crmContractReceivablesDOS.isEmpty()) { - receivablesSuccessMoney = crmContractReceivablesDOS - .stream() - .map(CrmContractReceivablesDO::getMoney) - .reduce(BigDecimal.ZERO, BigDecimal::add); - } +// if (!crmContractReceivablesDOS.isEmpty()) { +// receivablesSuccessMoney = crmContractReceivablesDOS +// .stream() +// .map(CrmContractReceivablesDO::getMoney) +// .reduce(BigDecimal.ZERO, BigDecimal::add); +// } BigDecimal contractMoney = BigDecimal.ZERO; BigDecimal receivablesMoney = BigDecimal.ZERO; @@ -412,8 +465,6 @@ public class CrmAchievementServiceImpl implements CrmAchievementService { receivablesMoney = crmAchievementDO2.getDecember(); } } - - } if (contractMoney.compareTo(BigDecimal.ZERO) > 0) { contractPer = NumberUtil.round(NumberUtil.div(contractSuccessMoney, contractMoney), 2) diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmanalysis/AchievementServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmanalysis/AchievementServiceImpl.java index 265eecbd..a85103f1 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmanalysis/AchievementServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmanalysis/AchievementServiceImpl.java @@ -9,7 +9,10 @@ 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.framework.security.core.util.SecurityFrameworkUtils; +import cn.iocoder.yudao.module.bpm.api.oa.BpmOAContractApi; +import cn.iocoder.yudao.module.bpm.api.oa.vo.contract.ContractStatisticsDTO; import cn.iocoder.yudao.module.crm.controller.admin.crmanalysis.vo.*; +import cn.iocoder.yudao.module.crm.controller.admin.crmclues.vo.CrmCluesStatisticsRespVO; import cn.iocoder.yudao.module.crm.dal.dataobject.crmachievement.CrmAchievementDO; import cn.iocoder.yudao.module.crm.dal.dataobject.crmbusiness.CrmBusinessDO; import cn.iocoder.yudao.module.crm.dal.dataobject.crmclues.CrmCluesDO; @@ -22,7 +25,7 @@ import cn.iocoder.yudao.module.crm.dal.mysql.crmclues.CrmCluesMapper; import cn.iocoder.yudao.module.crm.dal.mysql.crmcontract.CrmContractMapper; import cn.iocoder.yudao.module.crm.dal.mysql.crmcontractreceivables.CrmContractReceivablesMapper; import cn.iocoder.yudao.module.crm.dal.mysql.crmcustomer.CrmCustomerMapper; -import cn.iocoder.yudao.module.hrm.enums.CluesStatusEnum; +import cn.iocoder.yudao.module.crm.service.crmclues.CrmCluesService; import cn.iocoder.yudao.module.hrm.enums.ContractStatusEnum; import cn.iocoder.yudao.module.hrm.enums.FlowStepEnum; import cn.iocoder.yudao.module.hrm.enums.RelationEnum; @@ -39,12 +42,12 @@ import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; -import java.util.List; +import java.util.*; import java.util.stream.Collectors; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; + /** * 业绩目标 Service 实现类 * @@ -71,55 +74,75 @@ public class AchievementServiceImpl implements AchievementService { @Resource private CrmCluesMapper crmCluesMapper; + @Resource + private BpmOAContractApi contractApi; + + @Resource + private CrmCluesService cluesService; + @Override public PageResult getAchievementPage(AchievementPageReqVO pageReqVO) { AdminUserPageApiDTO dto = new AdminUserPageApiDTO(); - dto.setUsername(pageReqVO.getName()); + dto.setNickname(pageReqVO.getName()); dto.setPageNo(pageReqVO.getPageNo()); dto.setPageSize(pageReqVO.getPageSize()); - PageResult pageResult = adminUserApi.getUserPage(dto).getCheckedData(); + dto.setRoleCodes("sale"); // 设置查询用户的角色类型 + + // 获取销售角色 分页列表 + PageResult pageResult = adminUserApi.getUserPageByRole(dto).getCheckedData(); PageResult pageResult1 = BeanUtils.toBean(pageResult, UserAchieveVO.class); - pageResult1.getList().forEach(v -> { - LambdaQueryWrapperX wrapperX = new LambdaQueryWrapperX<>(); - wrapperX.eq(CrmContractDO::getOwnerUserId, v.getId()) - .eq(CrmContractDO::getCheckStatus, ContractStatusEnum.STATUS_2.getValue()) - .betweenIfPresent(CrmContractDO::getCreateTime, pageReqVO.getCreateTime()); - v.setContractCount(contractMapper.selectCount(wrapperX)); - List crmContractDOS = contractMapper.selectList(wrapperX); - BigDecimal contractMoney = crmContractDOS - .stream() - .map(CrmContractDO::getMoney) - .reduce(BigDecimal.ZERO, BigDecimal::add); - v.setContractMoney(contractMoney); - List crmContractReceivablesDOS = contractReceivablesMapper - .selectList(new LambdaQueryWrapperX() - .eq(CrmContractReceivablesDO::getOwnerUserId, v.getId()) - .eq(CrmContractReceivablesDO::getCheckStatus, ContractStatusEnum.STATUS_2.getValue()) - .betweenIfPresent(CrmContractReceivablesDO::getCreateTime, pageReqVO.getCreateTime())); - BigDecimal receivablesMoney = crmContractReceivablesDOS - .stream() - .map(CrmContractReceivablesDO::getMoney) - .reduce(BigDecimal.ZERO, BigDecimal::add); - v.setReceivablesMoney(receivablesMoney); - LambdaQueryWrapperX wrapperX2 = new LambdaQueryWrapperX<>(); - wrapperX2.eq(CrmCluesDO::getOwnerUserId, v.getId()) - .betweenIfPresent(CrmCluesDO::getCreateTime, pageReqVO.getCreateTime()); - Long cluesCount = crmCluesMapper.selectCount(wrapperX2); - v.setCluesCount(cluesCount); + if (CollUtil.isNotEmpty(pageResult1.getList())) { - wrapperX2.eq(CrmCluesDO::getStatus, CluesStatusEnum.STATUS_1.getValue()); - Long cluesToCustomerCount = crmCluesMapper.selectCount(wrapperX2); - v.setCluesToCustomerCount(cluesToCustomerCount); - String per = "0"; - if (cluesCount > 0) { - per = NumberUtil.round(NumberUtil.div(cluesToCustomerCount, cluesCount), 2) - .multiply(new BigDecimal("100")).toString(); - } - v.setCluesToCustomerPer(per); + // 获取所有用户编号列表 + List userIds = convertList(pageResult1.getList(), UserAchieveVO::getId); - }); + // 获取所有用户的合同统计列表 + List contractStatisticsDTOS = contractApi.getContractStatistics(userIds, pageReqVO.getCreateTime()).getCheckedData(); + Map contractMap = convertMap(contractStatisticsDTOS, ContractStatisticsDTO::getUserId); + + // 获取所有用户的线索统计列表 + List cluesStatisticsRespVOS = cluesService.getCluesStatisticsByUserIds(userIds, pageReqVO.getCreateTime()); + Map clusesMap = convertMap(cluesStatisticsRespVOS, CrmCluesStatisticsRespVO::getOwnerUserId); + + pageResult1.getList().forEach(v -> { + + String per = "0"; + if (contractMap.get(v.getId()) == null) { + // 设置合同数量 + v.setContractCount(0L); + // 设置合同金额 + v.setContractMoney(BigDecimal.ZERO); + // 设置回款金额 + v.setReceivablesMoney(BigDecimal.ZERO); + // 设置线索数量 + v.setCluesCount(0L); + // 设置转客数量 + v.setCluesToCustomerCount(0L); + v.setCluesToCustomerPer(per); + }else { + + // 设置合同数量 + v.setContractCount(Long.valueOf(contractMap.get(v.getId()).getCount())); + // 设置合同金额 + v.setContractMoney(contractMap.get(v.getId()).getMoney()); + // 设置回款金额 + v.setReceivablesMoney(BigDecimal.ZERO); + // 设置线索数量 + v.setCluesCount(Long.valueOf(clusesMap.get(v.getId()).getCount())); + // 设置转客数量 + v.setCluesToCustomerCount(Long.valueOf(clusesMap.get(v.getId()).getSuccessCount())); + // 设置转客比率 + if (v.getCluesCount() > 0) { + per = NumberUtil.round(NumberUtil.div(v.getCluesToCustomerCount(), v.getCluesCount()), 2) + .multiply(new BigDecimal("100")).toString(); + } + v.setCluesToCustomerPer(per); + } + + }); + } return pageResult1; } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmanalysis/CustomerService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmanalysis/CustomerService.java index 0a806393..aae789b3 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmanalysis/CustomerService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmanalysis/CustomerService.java @@ -6,6 +6,10 @@ import cn.iocoder.yudao.module.crm.controller.admin.crmanalysis.vo.AchievementPa import cn.iocoder.yudao.module.crm.controller.admin.crmanalysis.vo.CustomerLevelVO; import cn.iocoder.yudao.module.crm.controller.admin.crmanalysis.vo.UserRecordVO; import cn.iocoder.yudao.module.crm.controller.admin.crmanalysis.vo.UserVolumeVO; +import cn.iocoder.yudao.module.crm.controller.admin.crmcustomer.vo.CustomerStatisticRespVO; + +import java.time.LocalDateTime; +import java.util.List; /** * 客户分析 Service 接口 @@ -45,5 +49,11 @@ public interface CustomerService { */ PageResult getRecord(AchievementPageReqVO pageReqVO); - + /** + * 获取指定用户的客户统计信息列表 + * @param userIds 用户id集合 + * @param createTime 创建时间 + * @return 客户统计信息 + */ + List getCustomerStatistic(List userIds, LocalDateTime[] createTime); } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmanalysis/CustomerServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmanalysis/CustomerServiceImpl.java index c93b8e42..3bf37d5d 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmanalysis/CustomerServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmanalysis/CustomerServiceImpl.java @@ -1,23 +1,24 @@ package cn.iocoder.yudao.module.crm.service.crmanalysis; +import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.NumberUtil; import cn.iocoder.yudao.framework.common.enums.ShopCommonEnum; 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.crm.controller.admin.crmanalysis.vo.AchievementPageReqVO; import cn.iocoder.yudao.module.crm.controller.admin.crmanalysis.vo.CustomerLevelVO; import cn.iocoder.yudao.module.crm.controller.admin.crmanalysis.vo.UserRecordVO; import cn.iocoder.yudao.module.crm.controller.admin.crmanalysis.vo.UserVolumeVO; +import cn.iocoder.yudao.module.crm.controller.admin.crmcustomer.vo.CustomerStatisticRespVO; +import cn.iocoder.yudao.module.crm.controller.admin.crmrecord.vo.RecordStatisticsRespVO; import cn.iocoder.yudao.module.crm.dal.dataobject.crmcustomer.CrmCustomerDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.crmrecord.CrmRecordDO; import cn.iocoder.yudao.module.crm.dal.mysql.crmachievement.CrmAchievementMapper; import cn.iocoder.yudao.module.crm.dal.mysql.crmclues.CrmCluesMapper; import cn.iocoder.yudao.module.crm.dal.mysql.crmcontract.CrmContractMapper; import cn.iocoder.yudao.module.crm.dal.mysql.crmcontractreceivables.CrmContractReceivablesMapper; import cn.iocoder.yudao.module.crm.dal.mysql.crmcustomer.CrmCustomerMapper; import cn.iocoder.yudao.module.crm.dal.mysql.crmrecord.CrmRecordMapper; -import cn.iocoder.yudao.module.hrm.enums.TypesEnum; +import cn.iocoder.yudao.module.crm.service.crmrecord.CrmRecordService; import cn.iocoder.yudao.module.system.api.dept.DeptApi; import cn.iocoder.yudao.module.system.api.dict.DictDataApi; import cn.iocoder.yudao.module.system.api.dict.dto.DictDataRespDTO; @@ -30,10 +31,15 @@ import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import java.math.BigDecimal; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; + /** * 客户分析 Service 实现类 * @@ -43,25 +49,17 @@ import java.util.stream.Collectors; @Validated public class CustomerServiceImpl implements CustomerService { - @Resource - private CrmAchievementMapper achievementMapper; - @Resource - private DeptApi deptApi; @Resource private DictDataApi dictDataApi; - @Resource - private CrmContractMapper contractMapper; - @Resource - private CrmContractReceivablesMapper contractReceivablesMapper; - @Resource - private CrmCluesMapper crmCluesMapper; + @Resource private AdminUserApi adminUserApi; @Resource private CrmCustomerMapper customerMapper; + @Resource - private CrmRecordMapper crmRecordMapper; + private CrmRecordService recordService; @Override public CustomerLevelVO getCustomerLevel() { @@ -127,31 +125,41 @@ public class CustomerServiceImpl implements CustomerService { @Override public PageResult getCustomerVolume(AchievementPageReqVO pageReqVO) { + AdminUserPageApiDTO dto = new AdminUserPageApiDTO(); - dto.setUsername(pageReqVO.getName()); + dto.setNickname(pageReqVO.getName()); dto.setPageNo(pageReqVO.getPageNo()); dto.setPageSize(pageReqVO.getPageSize()); - PageResult pageResult = adminUserApi.getUserPage(dto).getCheckedData(); + dto.setRoleCodes("sale"); // 设置查询用户的角色类型 + + PageResult pageResult = adminUserApi.getUserPageByRole(dto).getCheckedData(); PageResult pageResult1 = BeanUtils.toBean(pageResult, UserVolumeVO.class); - pageResult1.getList().forEach(v -> { - LambdaQueryWrapperX wrapperX = new LambdaQueryWrapperX<>(); - wrapperX.eq(CrmCustomerDO::getOwnerUserId, v.getId()) - .betweenIfPresent(CrmCustomerDO::getCreateTime, pageReqVO.getCreateTime()); - Long customerCount = customerMapper.selectCount(wrapperX); - wrapperX.eq(CrmCustomerDO::getDealStatus, ShopCommonEnum.IS_STATUS_1.getValue()); - Long successCount = customerMapper.selectCount(wrapperX); + if (CollectionUtil.isNotEmpty(pageResult1.getList())) { - v.setCustomerCount(customerCount); - v.setSuccessCount(successCount); + List userIds = convertList(pageResult1.getList(), UserVolumeVO::getId); + // 获取所有用户的客户统计列表 + List statisticRespVOS = this.getCustomerStatistic(userIds, pageReqVO.getCreateTime()); + Map customerMap = convertMap(statisticRespVOS, CustomerStatisticRespVO::getOwnerUserId); - String per = "0"; - if (customerCount > 0) { - per = NumberUtil.round(NumberUtil.div(successCount, customerCount), 2) - .multiply(new BigDecimal("100")).toString(); - } - v.setSuccessPer(per); + pageResult1.getList().forEach(v -> { - }); + String per = "0"; + if (customerMap.get(v.getId()) == null) { + v.setCustomerCount(0L); + v.setSuccessCount(0L); + v.setSuccessPer(per); + }else { + v.setCustomerCount(Long.valueOf(customerMap.get(v.getId()).getCount())); + v.setSuccessCount(Long.valueOf(customerMap.get(v.getId()).getDealsCount())); + + if (v.getCustomerCount() > 0) { + per = NumberUtil.round(NumberUtil.div(v.getSuccessCount(), v.getCustomerCount()), 2) + .multiply(new BigDecimal("100")).toString(); + } + v.setSuccessPer(per); + } + }); + } return pageResult1; } @@ -162,30 +170,48 @@ public class CustomerServiceImpl implements CustomerService { dto.setUsername(pageReqVO.getName()); dto.setPageNo(pageReqVO.getPageNo()); dto.setPageSize(pageReqVO.getPageSize()); - PageResult pageResult = adminUserApi.getUserPage(dto).getCheckedData(); + dto.setRoleCodes("sale"); // 设置查询用户的角色类型 + + PageResult pageResult = adminUserApi.getUserPageByRole(dto).getCheckedData(); PageResult pageResult1 = BeanUtils.toBean(pageResult, UserRecordVO.class); - pageResult1.getList().forEach(v -> { - LambdaQueryWrapperX wrapperX = new LambdaQueryWrapperX<>(); - wrapperX.eq(CrmRecordDO::getCreator, v.getId()) - .betweenIfPresent(CrmRecordDO::getCreateTime, pageReqVO.getCreateTime()); - Long totalCount = crmRecordMapper.selectCount(wrapperX); + if (CollectionUtil.isNotEmpty(pageResult1.getList())) { - wrapperX.eq(CrmRecordDO::getTypes, TypesEnum.CUSTOMER.getValue()); - Long customerCount = crmRecordMapper.selectCount(wrapperX); + // 获取所有用户跟进统计列表 + List userIds = convertList(pageResult1.getList(), UserRecordVO::getId); + List respVOS = recordService.getRecordStatistics(userIds, pageReqVO.getCreateTime()); + Map recordMap = convertMap(respVOS, RecordStatisticsRespVO::getCreator); - wrapperX.eq(CrmRecordDO::getTypes, TypesEnum.BUSINESS.getValue()); - Long businessCount = crmRecordMapper.selectCount(wrapperX); + pageResult1.getList().forEach(v -> { - wrapperX.eq(CrmRecordDO::getTypes, TypesEnum.CLUES.getValue()); - Long cluesCount = crmRecordMapper.selectCount(wrapperX); - - v.setTotalCount(totalCount); - v.setCustomerCount(customerCount); - v.setBusinessCount(businessCount); - v.setCluesCount(cluesCount); - - }); + RecordStatisticsRespVO respVO = recordMap.get(v.getId().toString()); + if (respVO == null) { + // 设置跟进总数量 + v.setTotalCount(0L); + // 设置跟进客户数量 + v.setCustomerCount(0L); + // 设置跟进商机数量 + v.setBusinessCount(0L); + // 设置跟进线索数量 + v.setCluesCount(0L); + }else { + // 设置跟进总数量 + v.setTotalCount(Long.valueOf(respVO.getCount())); + // 设置跟进客户数量 + v.setCustomerCount(Long.valueOf(respVO.getCustomerCount())); + // 设置跟进商机数量 + v.setBusinessCount(Long.valueOf(respVO.getBusinessCount())); + // 设置跟进线索数量 + v.setCluesCount(Long.valueOf(respVO.getCluesCount())); + } + }); + } return pageResult1; } + + @Override + public List getCustomerStatistic(List userIds, LocalDateTime[] createTime) { + + return customerMapper.selectStatistic(userIds, createTime); + } } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmclues/CrmCluesService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmclues/CrmCluesService.java index 6af6e1b6..941b94c7 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmclues/CrmCluesService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmclues/CrmCluesService.java @@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.crm.controller.admin.crmcustomer.vo.CustomerImpor import cn.iocoder.yudao.module.crm.dal.dataobject.crmclues.CrmCluesDO; import javax.validation.Valid; +import java.time.LocalDateTime; import java.util.List; /** @@ -88,5 +89,10 @@ public interface CrmCluesService { */ void transfer(CrmCluesTransferVO transferVO); - + /** + * 获取指定用户的线索统计信息 + * @param ownerUserIds 用户ID + * @return 线索统计信息列表 + */ + List getCluesStatisticsByUserIds(List ownerUserIds, LocalDateTime[] createTime); } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmclues/CrmCluesServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmclues/CrmCluesServiceImpl.java index 64e24f41..5588ee73 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmclues/CrmCluesServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmclues/CrmCluesServiceImpl.java @@ -268,4 +268,10 @@ public class CrmCluesServiceImpl implements CrmCluesService { } } + @Override + public List getCluesStatisticsByUserIds(List ownerUserIds, LocalDateTime[] createTime) { + + return cluesMapper.selectStatisticsByUserIds(ownerUserIds, createTime); + } + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmcontract/CrmContractService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmcontract/CrmContractService.java index 2c3ae567..549b0929 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmcontract/CrmContractService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmcontract/CrmContractService.java @@ -1,10 +1,13 @@ package cn.iocoder.yudao.module.crm.service.crmcontract; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.crm.controller.admin.crmcontract.vo.*; +import cn.iocoder.yudao.module.crm.controller.admin.crmcontract.vo.CheckInfoVO; +import cn.iocoder.yudao.module.crm.controller.admin.crmcontract.vo.CrmContractPageReqVO; +import cn.iocoder.yudao.module.crm.controller.admin.crmcontract.vo.CrmContractRespVO; +import cn.iocoder.yudao.module.crm.controller.admin.crmcontract.vo.CrmContractSaveReqVO; import cn.iocoder.yudao.module.crm.dal.dataobject.crmcontract.CrmContractProductDO; -import javax.validation.Valid; +import javax.validation.Valid; import java.util.List; /** @@ -74,4 +77,10 @@ public interface CrmContractService { */ void check(CheckInfoVO checkInfoVO); + /** + * 创建合同产品 + * @param createReqVO 创建信息 + * @return 编号 + */ + void createProduct(List createReqVO); } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmcontract/CrmContractServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmcontract/CrmContractServiceImpl.java index 0e4de528..2008ed51 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmcontract/CrmContractServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmcontract/CrmContractServiceImpl.java @@ -390,6 +390,12 @@ public class CrmContractServiceImpl implements CrmContractService { } + @Override + public void createProduct(List createReqVO) { + + contractProductMapper.insertBatch(createReqVO); + } + private void createContractProductList(Long contractId, List list) { List storeProductAttrValueList = new ArrayList<>(); if (CollUtil.isNotEmpty(list)) { diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmcustomer/CrmCustomerService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmcustomer/CrmCustomerService.java index b5709cb6..093f73a9 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmcustomer/CrmCustomerService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmcustomer/CrmCustomerService.java @@ -29,6 +29,13 @@ public interface CrmCustomerService { */ void updateCustomer(@Valid CrmCustomerSaveReqVO updateReqVO); + /** + * 更新客户成交信息 + * + * @param updateReqVO 更新信息 + */ + void updateCustomerPurchaseTotal(@Valid CrmCustomerSaveReqVO updateReqVO); + /** * 删除客户 * diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmcustomer/CrmCustomerServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmcustomer/CrmCustomerServiceImpl.java index 94ad22f3..95c8471f 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmcustomer/CrmCustomerServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmcustomer/CrmCustomerServiceImpl.java @@ -8,7 +8,6 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils; import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; -import cn.iocoder.yudao.module.crm.controller.admin.crmcontractreceivables.vo.CrmContractReceivablesRespVO; import cn.iocoder.yudao.module.crm.controller.admin.crmcustomer.vo.*; import cn.iocoder.yudao.module.crm.dal.dataobject.crmbusiness.CrmBusinessDO; import cn.iocoder.yudao.module.crm.dal.dataobject.crmcontract.CrmContractDO; @@ -116,7 +115,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { @Transactional(rollbackFor = Exception.class) public void updateCustomer(CrmCustomerSaveReqVO updateReqVO) { // 校验存在 - validateCustomerExists(updateReqVO.getId()); + CrmCustomerDO customerDO = validateCustomerExists(updateReqVO.getId()); // 更新 CrmCustomerDO updateObj = BeanUtils.toBean(updateReqVO, CrmCustomerDO.class); customerMapper.updateById(updateObj); @@ -125,6 +124,26 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { crmOperatelogService.createLog("修改客户", updateReqVO.getId(), 0L, 0L); } + @Override + @Transactional(rollbackFor = Exception.class) + public void updateCustomerPurchaseTotal(CrmCustomerSaveReqVO updateReqVO) { + + // 校验存在 + CrmCustomerDO customerDO = validateCustomerExists(updateReqVO.getId()); + + // 更新 + updateReqVO.setPurchaseTimes(customerDO.getPurchaseTimes() + 1); + updateReqVO.setPurchaseTotal(customerDO.getPurchaseTotal().add(updateReqVO.getPurchaseTotal())); + CrmCustomerDO updateObj = BeanUtils.toBean(updateReqVO, CrmCustomerDO.class); + + customerMapper.updateById(updateObj); + + //插入日志 + crmOperatelogService.createLog("修改客户", updateReqVO.getId(), 0L, 0L); + + } + + @Override @Transactional(rollbackFor = Exception.class) public void deleteCustomer(Long id) { @@ -197,10 +216,12 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { crmOperatelogService.createLog("公海领取客户", id, 0L, 0L); } - private void validateCustomerExists(Long id) { - if (customerMapper.selectById(id) == null) { + private CrmCustomerDO validateCustomerExists(Long id) { + CrmCustomerDO customerDO = customerMapper.selectById(id); + if (customerDO == null) { throw exception(CUSTOMER_NOT_EXISTS); } + return customerDO; } @Override diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmcustomercontacts/CrmCustomerContactsService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmcustomercontacts/CrmCustomerContactsService.java index 5c09a4dd..9852ad99 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmcustomercontacts/CrmCustomerContactsService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmcustomercontacts/CrmCustomerContactsService.java @@ -1,7 +1,10 @@ package cn.iocoder.yudao.module.crm.service.crmcustomercontacts; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.crm.controller.admin.crmcustomercontacts.vo.*; +import cn.iocoder.yudao.module.crm.controller.admin.crmcustomercontacts.vo.CrmCustomerContactsPageReqVO; +import cn.iocoder.yudao.module.crm.controller.admin.crmcustomercontacts.vo.CrmCustomerContactsRespVO; +import cn.iocoder.yudao.module.crm.controller.admin.crmcustomercontacts.vo.CrmCustomerContactsSaveReqVO; + import javax.validation.Valid; /** @@ -48,5 +51,4 @@ public interface CrmCustomerContactsService { * @return 联系人分页 */ PageResult getCustomerContactsPage(CrmCustomerContactsPageReqVO pageReqVO); - } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmcustomercontacts/CrmCustomerContactsServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmcustomercontacts/CrmCustomerContactsServiceImpl.java index 952007a6..fac34e6b 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmcustomercontacts/CrmCustomerContactsServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmcustomercontacts/CrmCustomerContactsServiceImpl.java @@ -95,5 +95,4 @@ public class CrmCustomerContactsServiceImpl implements CrmCustomerContactsServic IPage pageResult = customerContactsMapper.selectPageList(mpPage, pageReqVO, ids); return new PageResult<>(pageResult.getRecords(), pageResult.getTotal()); } - } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmindex/CrmIndexServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmindex/CrmIndexServiceImpl.java index ee91cc98..b6fbf6e4 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmindex/CrmIndexServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmindex/CrmIndexServiceImpl.java @@ -5,12 +5,12 @@ import cn.hutool.core.util.NumberUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.enums.ShopCommonEnum; import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; +import cn.iocoder.yudao.module.bpm.api.oa.BpmOAContractApi; +import cn.iocoder.yudao.module.bpm.api.oa.vo.contract.ContractStatisticsDTO; import cn.iocoder.yudao.module.crm.controller.admin.crmindex.vo.BrieCountVO; import cn.iocoder.yudao.module.crm.controller.admin.crmindex.vo.CrmIndexRespVO; import cn.iocoder.yudao.module.crm.dal.dataobject.crmbusiness.CrmBusinessDO; import cn.iocoder.yudao.module.crm.dal.dataobject.crmclues.CrmCluesDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.crmcontract.CrmContractDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.crmcontractreceivables.CrmContractReceivablesDO; import cn.iocoder.yudao.module.crm.dal.dataobject.crmcustomer.CrmCustomerDO; import cn.iocoder.yudao.module.crm.dal.dataobject.crmcustomercontacts.CrmCustomerContactsDO; import cn.iocoder.yudao.module.crm.dal.dataobject.crmrecord.CrmRecordDO; @@ -26,7 +26,6 @@ import cn.iocoder.yudao.module.system.api.notice.NoticeApi; import cn.iocoder.yudao.module.system.api.notice.dto.NoticeDTO; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -64,6 +63,9 @@ public class CrmIndexServiceImpl implements CrmIndexService { @Resource private AdminUserApi adminUserApi; + @Resource + private BpmOAContractApi bpmOAContractApi; + @Override public CrmIndexRespVO getIndexCount(String relation) { @@ -180,65 +182,81 @@ public class CrmIndexServiceImpl implements CrmIndexService { .multiply(new BigDecimal("100")).toString(); } - Long count05 = contractMapper.selectCount(new LambdaQueryWrapper() - .in(!ids.isEmpty(), CrmContractDO::getOwnerUserId, ids) - .between(CrmContractDO::getCreateTime, todayStart, todayEnd)); - Long count005 = contractMapper.selectCount(new LambdaQueryWrapper() - .in(!ids.isEmpty(), CrmContractDO::getOwnerUserId, ids) - .between(CrmContractDO::getCreateTime, yesterdayStart, yesterdayEnd)); - String per005 = "0"; - if (count005 > 0) { - per005 = NumberUtil.div(NumberUtil.sub(count05, count005), count005, 2) - .multiply(new BigDecimal("100")).toString(); - } + // 获取今日合同新增数量 + ContractStatisticsDTO contractStatisticsDTO = bpmOAContractApi.getContractCount(relation).getCheckedData(); + // 设置今日新增数量 + Long count05 = Long.valueOf(contractStatisticsDTO.getTodayAdditions()); + // 设置昨日新增数量 + Long count005 = Long.valueOf(contractStatisticsDTO.getYesterdayAdditions()); + // 设置较昨日比率 + String per005 = contractStatisticsDTO.getCountPercentage().toString(); + // 设置今日新增金额 + BigDecimal count06 = contractStatisticsDTO.getTodayAddMoney(); + // 设置昨日新增金额 + BigDecimal count006 = contractStatisticsDTO.getYesterdayAddMoney(); + // 设置较昨日比率 + String per006 = contractStatisticsDTO.getMoneyPercentage().toString(); - QueryWrapper queryWrapper06 = new QueryWrapper<>(); - queryWrapper06.select("sum(money) as count06"); - queryWrapper06.eq("to_days(create_time)", "to_days(now())"); - queryWrapper06.in(!ids.isEmpty(), "owner_user_id", ids); - CrmContractDO crmContractDO = contractMapper.selectOne(queryWrapper06); - BigDecimal count06 = BigDecimal.ZERO; - if (crmContractDO != null) { - count06 = crmContractDO.getCount06(); - } +// Long count05 = contractMapper.selectCount(new LambdaQueryWrapper() +// .in(!ids.isEmpty(), CrmContractDO::getOwnerUserId, ids) +// .between(CrmContractDO::getCreateTime, todayStart, todayEnd)); +// Long count005 = contractMapper.selectCount(new LambdaQueryWrapper() +// .in(!ids.isEmpty(), CrmContractDO::getOwnerUserId, ids) +// .between(CrmContractDO::getCreateTime, yesterdayStart, yesterdayEnd)); +// String per005 = "0"; +// if (count005 > 0) { +// per005 = NumberUtil.div(NumberUtil.sub(count05, count005), count005, 2) +// .multiply(new BigDecimal("100")).toString(); +// } - QueryWrapper queryWrapper006 = new QueryWrapper<>(); - queryWrapper006.select("sum(money) as count006"); - queryWrapper006.eq("to_days(now())-to_days(create_time)", 1); - queryWrapper006.in(!ids.isEmpty(), "owner_user_id", ids); - CrmContractDO crmContractDO006 = contractMapper.selectOne(queryWrapper006); - BigDecimal count006 = BigDecimal.ZERO; - if (crmContractDO006 != null) { - count006 = crmContractDO006.getCount006(); - } - String per006 = "0"; - if (count006.compareTo(BigDecimal.ZERO) > 0) { - per006 = NumberUtil.div(NumberUtil.sub(count06, count006), count006, 2) - .multiply(new BigDecimal("100")).toString(); - } +// QueryWrapper queryWrapper06 = new QueryWrapper<>(); +// queryWrapper06.select("sum(money) as count06"); +// queryWrapper06.eq("to_days(create_time)", "to_days(now())"); +// queryWrapper06.in(!ids.isEmpty(), "owner_user_id", ids); +// CrmContractDO crmContractDO = contractMapper.selectOne(queryWrapper06); +// BigDecimal count06 = BigDecimal.ZERO; +// if (crmContractDO != null) { +// count06 = crmContractDO.getCount06(); +// } +// +// QueryWrapper queryWrapper006 = new QueryWrapper<>(); +// queryWrapper006.select("sum(money) as count006"); +// queryWrapper006.eq("to_days(now())-to_days(create_time)", 1); +// queryWrapper006.in(!ids.isEmpty(), "owner_user_id", ids); +// CrmContractDO crmContractDO006 = contractMapper.selectOne(queryWrapper006); +// BigDecimal count006 = BigDecimal.ZERO; +// if (crmContractDO006 != null) { +// count006 = crmContractDO006.getCount006(); +// } +// String per006 = "0"; +// if (count006.compareTo(BigDecimal.ZERO) > 0) { +// per006 = NumberUtil.div(NumberUtil.sub(count06, count006), count006, 2) +// .multiply(new BigDecimal("100")).toString(); +// } - QueryWrapper queryWrapper07 = new QueryWrapper<>(); - queryWrapper07.select("sum(money) as count07"); - queryWrapper07.eq("to_days(create_time)", "to_days(now())"); - CrmContractReceivablesDO crmContractReceivablesDO = contractReceivablesMapper.selectOne(queryWrapper07); +// QueryWrapper queryWrapper07 = new QueryWrapper<>(); +// queryWrapper07.select("sum(money) as count07"); +// queryWrapper07.eq("to_days(create_time)", "to_days(now())"); +// CrmContractReceivablesDO crmContractReceivablesDO = contractReceivablesMapper.selectOne(queryWrapper07); BigDecimal count07 = BigDecimal.ZERO; - if (crmContractDO != null) { - count07 = crmContractReceivablesDO.getCount07(); - } - QueryWrapper queryWrapper007 = new QueryWrapper<>(); - queryWrapper007.select("sum(money) as count007"); - queryWrapper007.eq("to_days(now())-to_days(create_time)", 1); - CrmContractReceivablesDO crmContractReceivablesDO007 = contractReceivablesMapper.selectOne(queryWrapper007); +// if (crmContractDO != null) { +// count07 = crmContractReceivablesDO.getCount07(); +// } +// QueryWrapper queryWrapper007 = new QueryWrapper<>(); +// queryWrapper007.select("sum(money) as count007"); +// queryWrapper007.eq("to_days(now())-to_days(create_time)", 1); +// CrmContractReceivablesDO crmContractReceivablesDO007 = contractReceivablesMapper.selectOne(queryWrapper007); BigDecimal count007 = BigDecimal.ZERO; - if (crmContractReceivablesDO007 != null) { - count007 = crmContractReceivablesDO007.getCount007(); - } +// if (crmContractReceivablesDO007 != null) { +// count007 = crmContractReceivablesDO007.getCount007(); +// } String per007 = "0"; - if (count007.compareTo(BigDecimal.ZERO) > 0) { - per007 = NumberUtil.div(NumberUtil.sub(count07, count007), count007, 2) - .multiply(new BigDecimal("100")).toString(); - } +// if (count007.compareTo(BigDecimal.ZERO) > 0) { +// per007 = NumberUtil.div(NumberUtil.sub(count07, count007), count007, 2) +// .multiply(new BigDecimal("100")).toString(); +// } + Long count08 = customerContactsMapper.selectCount(new LambdaQueryWrapper() .in(!ids.isEmpty(), CrmCustomerContactsDO::getOwnerUserId, ids) diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crminvoice/CrmInvoiceServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crminvoice/CrmInvoiceServiceImpl.java index 20013578..96f73cb1 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crminvoice/CrmInvoiceServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crminvoice/CrmInvoiceServiceImpl.java @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.crm.service.crminvoice; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.enums.ShopCommonEnum; -import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.exception.ErrorCode; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; @@ -25,7 +24,6 @@ import cn.iocoder.yudao.module.crm.dal.mysql.crmflowlog.CrmFlowLogMapper; import cn.iocoder.yudao.module.crm.dal.mysql.crminvoice.CrmInvoiceMapper; import cn.iocoder.yudao.module.hrm.enums.*; import cn.iocoder.yudao.module.system.api.mail.MailSendApi; -import cn.iocoder.yudao.module.system.api.mail.dto.MailSendSingleReqDTO; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import lombok.extern.slf4j.Slf4j; @@ -38,9 +36,7 @@ import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import java.math.BigDecimal; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.hrm.enums.ErrorCodeConstants.*; @@ -71,8 +67,6 @@ public class CrmInvoiceServiceImpl implements CrmInvoiceService { private RedissonClient redissonClient; @Resource private CrmFlowLogMapper crmFlowLogMapper; - @Resource - private MailSendApi mailSendApi; private static final String LOCK_KEY = "invoice:check:lock"; @@ -301,13 +295,13 @@ public class CrmInvoiceServiceImpl implements CrmInvoiceService { crmContractDO.setInvoiceMoney(money); contractMapper.updateById(crmContractDO); - //发送邮件 - if(StrUtil.isNotEmpty(updateObj.getFiles()) && StrUtil.isNotEmpty(updateObj.getEmail())){ - Map templateParams = new HashMap<>(); - templateParams.put("files",updateObj.getFiles()); - mailSendApi.sendSingleMail(new MailSendSingleReqDTO() - .setMail(updateObj.getEmail()).setUserId(updateObj.getCustomerId()).setUserType(UserTypeEnum.CUSTOMER.getValue()) - .setTemplateCode("invoice-send").setTemplateParams(templateParams)); - } +// //发送邮件 +// if(StrUtil.isNotEmpty(updateObj.getFiles()) && StrUtil.isNotEmpty(updateObj.getEmail())){ +// Map templateParams = new HashMap<>(); +// templateParams.put("files",updateObj.getFiles()); +// mailSendApi.sendSingleMail(new MailSendSingleReqDTO() +// .setMail(updateObj.getEmail()).setUserId(updateObj.getCustomerId()).setUserType(UserTypeEnum.CUSTOMER.getValue()) +// .setTemplateCode("invoice-send").setTemplateParams(templateParams)); +// } } } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmrecord/CrmRecordService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmrecord/CrmRecordService.java index 2e7d1f64..3db2ae2d 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmrecord/CrmRecordService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmrecord/CrmRecordService.java @@ -4,6 +4,8 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.crm.controller.admin.crmrecord.vo.*; import cn.iocoder.yudao.module.crm.dal.dataobject.crmrecord.CrmRecordDO; import javax.validation.Valid; +import java.time.LocalDateTime; +import java.util.List; /** * 跟进记录 Service 接口 @@ -50,4 +52,12 @@ public interface CrmRecordService { */ PageResult getRecordPage(CrmRecordPageReqVO pageReqVO); + /** + * 获得跟进统计 + * @param userIds 跟进人用户编号 + * @param createTime 创建时间 + * @return 跟进统计列表 + */ + List getRecordStatistics(List userIds, LocalDateTime[] createTime); + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmrecord/CrmRecordServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmrecord/CrmRecordServiceImpl.java index 08facbb1..71fd6aa4 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmrecord/CrmRecordServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/crmrecord/CrmRecordServiceImpl.java @@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; import cn.iocoder.yudao.module.crm.controller.admin.crmrecord.vo.CrmRecordPageReqVO; import cn.iocoder.yudao.module.crm.controller.admin.crmrecord.vo.CrmRecordRespVO; import cn.iocoder.yudao.module.crm.controller.admin.crmrecord.vo.CrmRecordSaveReqVO; +import cn.iocoder.yudao.module.crm.controller.admin.crmrecord.vo.RecordStatisticsRespVO; import cn.iocoder.yudao.module.crm.dal.dataobject.crmbusiness.CrmBusinessDO; import cn.iocoder.yudao.module.crm.dal.dataobject.crmclues.CrmCluesDO; import cn.iocoder.yudao.module.crm.dal.dataobject.crmcustomer.CrmCustomerDO; @@ -155,4 +156,10 @@ public class CrmRecordServiceImpl implements CrmRecordService { return pageResult1; } + @Override + public List getRecordStatistics(List userIds, LocalDateTime[] createTime) { + + return recordMapper.selectStatistics(userIds, createTime); + } + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/crmclues/CrmCluesMapper.xml b/yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/crmclues/CrmCluesMapper.xml index a662e964..990365c9 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/crmclues/CrmCluesMapper.xml +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/crmclues/CrmCluesMapper.xml @@ -88,4 +88,28 @@ order by a.id desc + + diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/crmcontract/CrmContractMapper.xml b/yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/crmcontract/CrmContractMapper.xml index c4658ed2..1e2a6290 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/crmcontract/CrmContractMapper.xml +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/crmcontract/CrmContractMapper.xml @@ -60,4 +60,25 @@ + + diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/crmcustomer/CrmCustomerMapper.xml b/yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/crmcustomer/CrmCustomerMapper.xml index ca1612a3..4fcd69a9 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/crmcustomer/CrmCustomerMapper.xml +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/crmcustomer/CrmCustomerMapper.xml @@ -50,4 +50,28 @@ order by a.id desc + + diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/crmrecord/CrmRecordMapper.xml b/yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/crmrecord/CrmRecordMapper.xml new file mode 100644 index 00000000..4f6b3d66 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/resources/mapper/crmrecord/CrmRecordMapper.xml @@ -0,0 +1,37 @@ + + + + + + + + diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/storeproduct/StoreProductApi.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/storeproduct/StoreProductApi.java index 3791c778..45456471 100644 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/storeproduct/StoreProductApi.java +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/storeproduct/StoreProductApi.java @@ -1,19 +1,13 @@ package cn.iocoder.yudao.module.product.api.storeproduct; import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.module.product.api.storeproductattrvalue.dto.StoreProductAttrValueApiDTO; -import cn.iocoder.yudao.module.product.api.storeproductattrvalue.vo.StoreProductAttrValueApiVO; import cn.iocoder.yudao.module.product.enums.ApiConstants; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; -import java.util.List; - @FeignClient(name = ApiConstants.NAME) // TODO 芋艿:fallbackFactory = @Tag(name = "RPC 服务 - 商品属性值 API") public interface StoreProductApi { @@ -21,10 +15,15 @@ public interface StoreProductApi { String PREFIX = ApiConstants.PREFIX + "/storeProduct"; @GetMapping(PREFIX + "/decStockIncSales") - @Schema(description = "正常商品 加库存 减销量") + @Schema(description = "正常商品库存 减库存 加销量") CommonResult decStockIncSales(@RequestParam(name = "num") Integer num, @RequestParam(name = "productId") Long productId); + @GetMapping(PREFIX + "/inStockIncSales") + @Schema(description = "正常商品库存 加库存 减销量") + CommonResult inStockIncSales(@RequestParam(name = "num") Integer num, + @RequestParam(name = "productId") Long productId); + @GetMapping(PREFIX + "/selectCount") @Schema(description = "获取数量") CommonResult selectCount(); diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/storeproductattrvalue/StoreProductAttrValueApi.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/storeproductattrvalue/StoreProductAttrValueApi.java index 696e05ae..65cf527f 100644 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/storeproductattrvalue/StoreProductAttrValueApi.java +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/storeproductattrvalue/StoreProductAttrValueApi.java @@ -25,9 +25,15 @@ public interface StoreProductAttrValueApi { CommonResult> getStoreProductAttrValueList(@RequestBody StoreProductAttrValueApiDTO dto); @GetMapping(PREFIX + "/decStockIncSales") - @Schema(description = "正常商品 加库存 减销量") + @Schema(description = "普通商品 减库存 加销量") CommonResult decStockIncSales(@RequestParam(name = "num") Integer num, @RequestParam(name = "productId") Long productId, @RequestParam(name = "unique") String unique); + @GetMapping(PREFIX + "/inStockIncSales") + @Schema(description = "普通商品 加库存 减销量") + CommonResult inStockIncSales(@RequestParam(name = "num") Integer num, + @RequestParam(name = "productId") Long productId, + @RequestParam(name = "unique") String unique); + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/storeproduct/StoreProductApiImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/storeproduct/StoreProductApiImpl.java index 069df775..14a091b0 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/storeproduct/StoreProductApiImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/storeproduct/StoreProductApiImpl.java @@ -7,6 +7,8 @@ import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + /** * 商品 SPU API 接口实现类 * @@ -22,12 +24,17 @@ public class StoreProductApiImpl implements StoreProductApi { @Override public CommonResult decStockIncSales(Integer num, Long productId) { - return CommonResult.success(storeProductService.decStockIncSales(num, productId)); + return success(storeProductService.decStockIncSales(num, productId)); + } + + @Override + public CommonResult inStockIncSales(Integer num, Long productId) { + return success(storeProductService.inStockIncSales(num, productId)); } @Override public CommonResult selectCount() { - return CommonResult.success(storeProductService.count()); + return success(storeProductService.count()); } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/storeproductattrvalue/StoreProductAttrValueApiImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/storeproductattrvalue/StoreProductAttrValueApiImpl.java index 0fadde00..d8c1888e 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/storeproductattrvalue/StoreProductAttrValueApiImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/storeproductattrvalue/StoreProductAttrValueApiImpl.java @@ -1,19 +1,20 @@ package cn.iocoder.yudao.module.product.api.storeproductattrvalue; import cn.hutool.core.bean.BeanUtil; -import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.product.api.storeproductattrvalue.dto.StoreProductAttrValueApiDTO; import cn.iocoder.yudao.module.product.api.storeproductattrvalue.vo.StoreProductAttrValueApiVO; import cn.iocoder.yudao.module.product.dal.dataobject.storeproductattrvalue.StoreProductAttrValueDO; import cn.iocoder.yudao.module.product.service.storeproductattrvalue.StoreProductAttrValueService; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import java.util.List; +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + /** * 商品 SPU API 接口实现类 * @@ -29,17 +30,22 @@ public class StoreProductAttrValueApiImpl implements StoreProductAttrValueApi { @Override public CommonResult> getStoreProductAttrValueList(StoreProductAttrValueApiDTO dto) { - List list = storeProductAttrValueService.list(new LambdaQueryWrapper() - .in(CollUtil.isNotEmpty(dto.getProductIds()), StoreProductAttrValueDO::getProductId, dto.getProductIds()) - .in(CollUtil.isNotEmpty(dto.getUniques()), StoreProductAttrValueDO::getUnique, dto.getUniques()) + List list = storeProductAttrValueService.list(new LambdaQueryWrapperX() + .inIfPresent(StoreProductAttrValueDO::getProductId, dto.getProductIds()) + .inIfPresent(StoreProductAttrValueDO::getUnique, dto.getUniques()) ); List result = BeanUtil.copyToList(list, StoreProductAttrValueApiVO.class); - return CommonResult.success(result); + return success(result); } @Override public CommonResult decStockIncSales(Integer num, Long productId, String unique) { - return CommonResult.success(storeProductAttrValueService.decStockIncSales(num, productId, unique)); + return success(storeProductAttrValueService.decStockIncSales(num, productId, unique)); + } + + @Override + public CommonResult inStockIncSales(Integer num, Long productId, String unique) { + return success(storeProductAttrValueService.inStockIncSales(num, productId, unique)); } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/storeproductattrvalue/StoreProductAttrValueMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/storeproductattrvalue/StoreProductAttrValueMapper.java index 40438162..89d590e9 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/storeproductattrvalue/StoreProductAttrValueMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/storeproductattrvalue/StoreProductAttrValueMapper.java @@ -28,7 +28,7 @@ public interface StoreProductAttrValueMapper extends BaseMapperX { * @return */ int decStockIncSales(Integer num, Long productId); + + /** + * 正常商品库存 加库存 减销量 + * @param num 数量 + * @param productId 产品编号 + * @return + */ + Integer inStockIncSales(Integer num, Long productId); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/storeproduct/StoreProductServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/storeproduct/StoreProductServiceImpl.java index dff8b86a..c9edee88 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/storeproduct/StoreProductServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/storeproduct/StoreProductServiceImpl.java @@ -559,6 +559,11 @@ public class StoreProductServiceImpl extends ServiceImpl getUserCompanyDept(@RequestParam("userId") Long userId); + + @GetMapping("/getDeptListByType") + @Operation(summary = "获取指定类型的部门列表") + @Parameter(name = "type", description = "部门类型", required = true) + CommonResult> getDeptListByType(@RequestParam("type") String type); } diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApi.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApi.java index cd736455..04396461 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApi.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApi.java @@ -116,4 +116,15 @@ public interface AdminUserApi { @GetMapping(PREFIX + "/getUserListBySubordinateIds") @Operation(summary = "获取当前部门以及下级部门所有人员(负责人)") CommonResult> getUserListBySubordinateIds(@RequestParam(name = "adminId") Long adminId); + + @GetMapping(PREFIX + "/list-all") + @Operation(summary = "获取当前部门以及下级部门所有人员(负责人)") + CommonResult> getUserListAll(@RequestParam(name = "userType", required = false, defaultValue = "1") Integer userType, + @RequestParam(name = "deptId", required = false) Long deptId, + @RequestParam(name = "status", required = false, defaultValue = "0") Integer status, + @RequestParam(name = "roleCodes", required = false) String roleCodes); + + @PostMapping(PREFIX + "/getUserPageByRole") + @Operation(summary = "获取用户分页列表") + CommonResult> getUserPageByRole(@RequestBody AdminUserPageApiDTO dto); } diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/dto/AdminUserPageApiDTO.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/dto/AdminUserPageApiDTO.java index 7d9c2842..f5b9bee4 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/dto/AdminUserPageApiDTO.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/dto/AdminUserPageApiDTO.java @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.system.api.user.dto; import cn.iocoder.yudao.framework.common.pojo.PageParam; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -import lombok.experimental.Accessors; import org.springframework.format.annotation.DateTimeFormat; import java.time.LocalDateTime; @@ -13,14 +12,13 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ @Schema(description = "RPC 服务 - Admin 用户 Response DTO") @Data -@Accessors(chain = true) public class AdminUserPageApiDTO extends PageParam { @Schema(description = "用户账号,模糊匹配", example = "yudao") private String username; @Schema(description = "用户昵称,模糊匹配", example = "yudao") - private String nickName; + private String nickname; @Schema(description = "手机号码,模糊匹配", example = "yudao") private String mobile; @@ -28,6 +26,9 @@ public class AdminUserPageApiDTO extends PageParam { @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1") private Integer status; + @Schema(description = "角色code") + private String roleCodes; + @Schema(description = "创建时间", example = "[2022-07-01 00:00:00, 2022-07-01 23:59:59]") @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/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 1a2b4cce..3f32755d 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 @@ -150,4 +150,12 @@ public class DeptApiImpl implements DeptApi { DeptDO deptDO = deptService.getUserCompanyDept(userId); return success(BeanUtils.toBean(deptDO, DeptRespDTO.class)); } + + @Override + @DataPermission(enable = false) + public CommonResult> getDeptListByType(String type) { + + List deptList = deptService.getDeptListByType(type); + return success(BeanUtils.toBean(deptList, DeptRespDTO.class)); + } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApiImpl.java index d83abd31..086cbfdd 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApiImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApiImpl.java @@ -145,4 +145,15 @@ public class AdminUserApiImpl implements AdminUserApi { return success(ids); } + @Override + public CommonResult> getUserListAll(Integer userType, Long deptId, Integer status, String roleCodes) { + List userList = userService.getUserListByStatus(userType, deptId, status, roleCodes); + return success(BeanUtils.toBean(userList, AdminUserRespDTO.class)); + } + + @Override + public CommonResult> getUserPageByRole(AdminUserPageApiDTO dto) { + + return success(BeanUtils.toBean(userService.getUserPageByRole(dto), AdminUserApiVO.class)); + } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/DeptController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/DeptController.java index 4262dd1d..ddcb33dc 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/DeptController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/DeptController.java @@ -164,6 +164,33 @@ public class DeptController { return success(BeanUtils.toBean(list, DeptSimpleRespVO.class)); } + @GetMapping(value = {"/getListByType"}) + @Operation(summary = "获取指定类型的部门精简信息列表", description = "只包含被开启的部门,主要用于前端的下拉选项") + @Parameter(name = "type", description = "类型", required = true, example = "1") + @DataPermission(enable = false) + public CommonResult> getListByType(@RequestParam("type") String type) { + List list = deptService.getDeptListByType(type); + + // 获得所有得虚机构部门信息 + List virtuallyDeptId = list.stream() + .filter(dept -> dept.getVirtuallyStatus() == 1) + .collect(Collectors.toList()); + + virtuallyDeptId.forEach(data -> { + + // 将虚机构的子部门,父部门设置为虚机构的父部门 + list.stream().filter(dept -> dept.getParentId().equals(data.getId())) + .map(dept -> dept.setParentId(data.getParentId())) + .collect(Collectors.toList()); + + }); + + // 移除虚机构,不展示 + list.removeIf(dept -> dept.getVirtuallyStatus() == 1); + + return success(BeanUtils.toBean(list, DeptSimpleRespVO.class)); + } + @GetMapping("/get") @Operation(summary = "获得部门信息") @Parameter(name = "id", description = "编号", required = true, example = "1024") 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 1b44dddf..5325bf4a 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 @@ -5,7 +5,7 @@ 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.api.oa.BpmOARefundApi; -import cn.iocoder.yudao.module.bpm.api.oa.vo.BpmOARefundDTO; +import cn.iocoder.yudao.module.bpm.api.oa.vo.refund.BpmOARefundDTO; import cn.iocoder.yudao.module.system.controller.admin.rental.vo.order.RentalOrderPageReqVO; import cn.iocoder.yudao.module.system.controller.admin.rental.vo.order.RentalOrderRespVO; import cn.iocoder.yudao.module.system.controller.admin.rental.vo.order.RentalOrderSaveReqVO; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java index ef8a462c..4cbd3a07 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java @@ -175,8 +175,11 @@ public class UserController { @Operation(summary = "获取用户精简信息列表", description = "只包含被开启的用户,主要用于前端的下拉选项,无数据权限") @DataPermission(enable = false) public CommonResult> getAllUserList(@RequestParam(required = false, defaultValue = "1") Integer userType, - @RequestParam(required = false) Long deptId) { - List list = userService.getUserListByStatus(userType, deptId, CommonStatusEnum.ENABLE.getStatus(), null); + @RequestParam(required = false) Long deptId, + @RequestParam(required = false, defaultValue = "0") Integer status, + @RequestParam(required = false) String roleCodes) { + + List list = userService.getUserListByStatus(userType, deptId, status, roleCodes); // 拼接数据 Map deptMap = deptService.getDeptMap( convertList(list, AdminUserDO::getDeptId)); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/AdminUserMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/AdminUserMapper.java index 56317f4b..2ac898cd 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/AdminUserMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/AdminUserMapper.java @@ -5,6 +5,7 @@ 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.framework.mybatis.core.query.MPJLambdaWrapperX; +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserPageApiDTO; import cn.iocoder.yudao.module.system.controller.admin.laborcontract.vo.LaborContractPageReqVO; import cn.iocoder.yudao.module.system.controller.admin.laborcontract.vo.LaborContractRespVO; import cn.iocoder.yudao.module.system.controller.admin.user.dto.UserDTO; @@ -205,4 +206,8 @@ public interface AdminUserMapper extends BaseMapperX { return selectJoinPage(pageReqVO, UserBirthdayRespVO.class, queryWrapper); } + + IPage selectUserPageByRole(@Param("page") IPage mpPage, + @Param("pageReqVO") AdminUserPageApiDTO pageReqVO, + @Param("roleCodeList") List roleCodeList); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/job/fieldwork/FieldworkJob.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/job/fieldwork/FieldworkJob.java index 937d3448..c60f51ec 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/job/fieldwork/FieldworkJob.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/job/fieldwork/FieldworkJob.java @@ -6,7 +6,7 @@ import cn.iocoder.yudao.framework.tenant.core.job.TenantJob; import cn.iocoder.yudao.module.bpm.api.oa.BpmOAEntryApi; import cn.iocoder.yudao.module.bpm.api.oa.BpmOAEvectionApi; import cn.iocoder.yudao.module.bpm.api.oa.BpmOAGoOutApi; -import cn.iocoder.yudao.module.bpm.api.oa.vo.BpmOAEntryDTO; +import cn.iocoder.yudao.module.bpm.api.oa.vo.entry.BpmOAEntryDTO; import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; import cn.iocoder.yudao.module.system.dal.mysql.user.AdminUserMapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 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 326290a1..ff03e833 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 @@ -184,4 +184,11 @@ public interface DeptService { * @return */ List getAllList(); + + /** + * 获取指定类型的部门列表 + * @param type 部门类型 + * @return 部门列表 + */ + List getDeptListByType(String type); } 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 b7204dde..e6cbe8bd 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 @@ -384,6 +384,14 @@ public class DeptServiceImpl implements DeptService { .eq(DeptDO::getStatus, CommonStatusEnum.ENABLE.getStatus())); } + @Override + @DataPermission(enable = false) + public List getDeptListByType(String type) { + return deptMapper.selectList(new LambdaQueryWrapper() + .eq(DeptDO::getType, type) + .eq(DeptDO::getStatus, CommonStatusEnum.ENABLE.getStatus())); + } + @Override public List getDeptList(DeptApiDTO dto) { List list = deptMapper.selectList(new LambdaQueryWrapperX() diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserService.java index 88e5193e..fc2dad70 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserService.java @@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserApiDTO; +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserPageApiDTO; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import cn.iocoder.yudao.module.system.controller.admin.user.dto.UserDTO; import cn.iocoder.yudao.module.system.controller.admin.user.dto.UserPageDTO; @@ -441,4 +442,11 @@ public interface AdminUserService { void updateUnionId(Long id, String unionId); AdminUserDO getUserByUnionId(String unionId); + + /** + * 获取指定角色的用户分页 + * @param dto 分页参数 + * @return 分页列表 + */ + PageResult getUserPageByRole(AdminUserPageApiDTO dto); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java index b02121ee..743f7140 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java @@ -22,6 +22,7 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils; import cn.iocoder.yudao.module.infra.api.file.FileApi; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserApiDTO; +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserPageApiDTO; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import cn.iocoder.yudao.module.system.controller.admin.user.dto.UserDTO; import cn.iocoder.yudao.module.system.controller.admin.user.dto.UserPageDTO; @@ -888,6 +889,18 @@ public class AdminUserServiceImpl implements AdminUserService { .eq(AdminUserDO::getUnionId, unionId)); } + @Override + public PageResult getUserPageByRole(AdminUserPageApiDTO pageReqVO) { + List roleCodeList = new ArrayList<>(); + if (StringUtil.isNotEmpty(pageReqVO.getRoleCodes())) { + roleCodeList = Arrays.asList(pageReqVO.getRoleCodes().split(",")); + } + + IPage mpPage = MyBatisUtils.buildPage(pageReqVO); + IPage page = userMapper.selectUserPageByRole(mpPage, pageReqVO, roleCodeList); + return new PageResult<>(page.getRecords(), page.getTotal()); + } + @Override public List getUserListByDepts(Integer userType, List deptIds, Integer status) { return userMapper.selectList(new LambdaQueryWrapperX() diff --git a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/user/AdminUserMapper.xml b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/user/AdminUserMapper.xml index 31ade189..f7f422d5 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/user/AdminUserMapper.xml +++ b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/user/AdminUserMapper.xml @@ -201,4 +201,30 @@ + +